diff --git a/.gitignore b/.gitignore index 65700fe6..59ec847b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,20 +2,21 @@ .DS_Store *.swp *.tmp +*~ # Project files that should not be in the repo -.project -.settings/ -.settings.xml -.c9settings.xml -.settings.xml.old +.* +\#* +!/.gitignore .*.gz +*.tmTheme.js # A handy place to put stuff that git should ignore: /ignore/ -support/async/ -support/dryice/ -support/jsdom/ -support/node-htmlparser/ -support/node-o3-xml/ -support/requirejs/ \ No newline at end of file +node_modules/ +jam/ +* * + +.git-ref +npm-debug.log +deps/ diff --git a/.gitmodules b/.gitmodules index 6074430c..07bbe371 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ -[submodule "support/cockpit"] - path = support/cockpit - url = git://github.com/ajaxorg/cockpit.git -[submodule "support/pilot"] - path = support/pilot - url = git://github.com/ajaxorg/pilot.git \ No newline at end of file +[submodule "doc/wiki"] + path = doc/wiki + url = https://github.com/ajaxorg/ace.wiki.git +[submodule "build"] + path = build + url = https://github.com/ajaxorg/ace-builds.git diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..d2f32091 --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: node_js \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 00000000..75431b15 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +ace.c9.io diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..062af59c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,15 @@ +Contributing +------------ + +Ace is a community project and wouldn't be what it is without contributions! We actively encourage and support contributions. The Ace source code is released under the BSD License. This license is very simple, and is friendly to all kinds of projects, whether open source or not. Take charge of your editor and add your favorite language highlighting and keybindings! + +Feel free to fork and improve/enhance Ace any way you want. If you feel that the editor or the Ace community will benefit from your changes, please open a pull request. To protect the interests of the Ace contributors and users we require contributors to sign a Contributors License Agreement (CLA) before we pull the changes into the main repository. Our CLA is the simplest of agreements, requiring that the contributions you make to an ajax.org project are only those you're allowed to make. This helps us significantly reduce future legal risk for everyone involved. It is easy, helps everyone, takes ten minutes, and only needs to be completed once. + +There are two versions of the agreement: + +1. [The Individual CLA](https://docs.google.com/a/c9.io/forms/d/1MfmfrxqD_PNlNsuK0lC2KSelRLxGLGfh_wEcG0ijVvo/viewform): use this version if you're working on the Cloud9 SDK or open source projects in your spare time, or can clearly claim ownership of copyright in what you'll be submitting. +2. [The Corporate CLA](https://docs.google.com/a/c9.io/forms/d/1vFejn4111GdnCNuQ6BfnJDaxdsUEMD4KCo1ayovAfu0/viewform): have your corporate lawyer review and submit this if your company is going to be contributing to the Cloud9 SDK and/or open source projects. + +If you want to contribute to the Cloud9 SDK and/or open source projects please go to the online form, fill it out and submit it. + +Happy coding, Cloud9 diff --git a/ChangeLog.txt b/ChangeLog.txt index 9eb65941..3077d171 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,8 +1,295 @@ +Version 1.2.0-pre + +* New Features + - Indented soft wrap (danyaPostfactum) + +* API Changes + - unified delta types `{start, end, action, lines}` (Alden Daniels https://github.com/ajaxorg/ace/pull/1745) + - "change" event listeners on session and editor get delta objects directly + +2015.04.03 Version 1.1.9 + + - Small Enhancements and Bugfixes + +2014.11.08 Version 1.1.8 + +* API Changes + - `editor.commands.commandKeyBinding` now contains direct map from keys to commands instead of grouping them by hashid + +* New Features + - Improved autoindent for html and php modes (Adam Jimenez) + - Find All from searchbox (Colton Voege) + +* new language modes + - Elixir, Elm + +2014.09.21 Version 1.1.7 + +* Bugfixes + - fix several bugs in autocompletion + - workaround for inaccurate getBoundingClientRect on chrome 37 + +2014.08.17 Version 1.1.6 + +* Bugfixes + - fix regression in double tap to highlight + - Improved Latex Mode (Daniel Felder) + +* API Changes + - editor.destroy destroys editor.session too (call editor.setSession(null) to prevent that) + +* new language modes + - Praat (José Joaquín Atria) + - Eiffel (Victorien Elvinger) + - G-code (Adam Joseph Cook) + +2014.07.09 Version 1.1.5 + +* Bugfixes + - fix regression in autocomplete popup + +* new language modes + - gitignore (Devon Carew) + +2014.07.01 Version 1.1.4 + +* New Features + - Highlight matching tags (Adam Jimenez) + - Improved jump to matching command (Adam Jimenez) + +* new language modes + - AppleScript (Yaogang Lian) + - Vala + +2014.03.08 Version 1.1.3 + +* New Features + - Allow syntax checkers to be loaded from CDN (Derk-Jan Hartman) + - Add ColdFusion behavior (Abram Adams) + - add showLineNumbers option + - Add html syntax checker (danyaPostfactum) + +* new language modes + - Gherkin (Patrick Nevels) + - Smarty + +2013.12.02 Version 1.1.2 + +* New Features + - Accessibility Theme for Ace (Peter Xiao) + - use snipetManager for expanding emmet snippets + - update jshint to 2.1.4 + - improve php syntax checker (jdalegonzalez) + - add option for autoresizing + - add option for autohiding vertical scrollbar + - improvements to highlighting of xml like languages (danyaPostfactum) + - add support for autocompletion and snippets (gjtorikyan danyaPostfactum and others) + - add option to merge similar changes in undo history + - add scrollPastEnd option + - use html5 dragndrop for text dragging (danyaPostfactum) + +* API Changes + - fixed typo in HashHandler commmandManager + +* new language modes + - Nix (Zef Hemel) + - Protobuf (Zef Hemel) + - Soy + - Handlebars + +2013.06.04 Version 1.1.1 + + - Improved emacs keybindings (Robert Krahn) + - Added markClean, isClean methods to UndoManager (Joonsoo Jeon) + - Do not allow `Toggle comments` command to remove spaces from indentation + - Softer colors for indent guides in dark themes + +* new language modes + - Ada + - Assembly_x86 + - Cobol + - D + - ejs + - MATLAB + - MySQL + - Twig + - Verilog + +2013.05.01, Version 1.1.0 + +* API Changes + - Default position of the editor container is changed to relative. Add `.ace_editor {position: absolute}` css rule to restore old behavior + - Changed default line-height to `normal` to not conflict with bootstrap. Use `line-height: inherit` for old behavior. + - Changed marker types accepted by session.addMarker. It now accepts "text"|"line"|"fullLine"|"screenLine" + - Internal classnames used by editor were made more consistent + - Introduced `editor.setOption/getOption/setOptions/getOptions` methods + - Introduced positionToIndex, indexToPosition methods + +* New Features + - Improved emacs mode (chetstone) + with Incremental search and Occur modes (Robert Krahn) + + - Improved ime handling + - Searchbox (Vlad Zinculescu) + + - Added elastic tabstops lite extension (Garen Torikian) + - Added extension for whitespace manipulation + - Added extension for enabling spellchecking from contextmenu + - Added extension for displaying available keyboard shortcuts (Matthew Christopher Kastor-Inare III) + - Added extension for displaying options panel (Matthew Christopher Kastor-Inare III) + - Added modelist extension (Matthew Christopher Kastor-Inare III) + + - Improved toggleCommentLines and added ToggleCommentBlock command + - `:;` pairing in CSS mode (danyaPostfactum) + + - Added suppoert for Delete and SelectAll from context menu (danyaPostfactum) + + - Make wrapping behavior optional + - Selective bracket insertion/skipping + + - Added commands for increase/decrease numbers, sort lines (Vlad Zinculescu) + - Folding for Markdown, Lua, LaTeX + - Selective bracket insertion/skipping for C-like languages + +* Many new languages + - Scheme (Mu Lei) + - Dot (edwardsp) + - FreeMarker (nguillaumin) + - Tiny Mushcode (h3rb) + - Velocity (Ryan Griffith) + - TOML (Garen Torikian) + - LSL (Nemurimasu Neiro, Builders Brewery) + - Curly (Libo Cannici) + - vbScript (Jan Jongboom) + - R (RStudio) + - ABAP + - Lucene (Graham Scott) + - Haml (Garen Torikian) + - Objective-C (Garen Torikian) + - Makefile (Garen Torikian) + - TypeScript (Garen Torikian) + - Lisp (Garen Torikian) + - Stylus (Garen Torikian) + - Dart (Garen Torikian) + +* Live syntax checks + - PHP (danyaPostfactum) + - Lua + +* New Themes + - Chaos + - Terminal + +2012.09.17, Version 1.0.0 + +* New Features + - Multiple cursors and selections (https://c9.io/site/blog/2012/08/be-an-armenian-warrior-with-block-selection-on-steroids/) + - Fold buttons displayed in the gutter + - Indent Guides + - Completely reworked vim mode (Sergi Mansilla) + - Improved emacs keybindings + - Autoclosing of html tags (danyaPostfactum) + +* 20 New language modes + - Coldfusion (Russ) + - Diff + - GLSL (Ed Mackey) + - Go (Davide Saurino) + - Haxe (Jason O'Neil) + - Jade (Garen Torikian) + - jsx (Syu Kato) + - LaTeX (James Allen) + - Less (John Roepke) + - Liquid (Bernie Telles) + - Lua (Lee Gao) + - LuaPage (Choonster) + - Markdown (Chris Spencer) + - PostgreSQL (John DeSoi) + - Powershell (John Kane) + - Sh (Richo Healey) + - SQL (Jonathan Camile) + - Tcl (Cristoph Hochreiner) + - XQuery (William Candillion) + - Yaml (Meg Sharkey) + + * Live syntax checks + - for XQuery and JSON + +* New Themes + - Ambiance (Irakli Gozalishvili) + - Dreamweaver (Adam Jimenez) + - Github (bootstraponline) + - Tommorrow themes (https://github.com/chriskempson/tomorrow-theme) + - XCode + +* Many Small Enhancements and Bugfixes + +2011.08.02, Version 0.2.0 + +* Split view (Julian Viereck) + - split editor area horizontally or vertivally to show two files at the same + time + +* Code Folding (Julian Viereck) + - Unstructured code folding + - Will be the basis for language aware folding + +* Mode behaviours (Chris Spencer) + - Adds mode specific hooks which allow transformations of entered text + - Autoclosing of braces, paranthesis and quotation marks in C style modes + - Autoclosing of angular brackets in XML style modes + +* New language modes + - Clojure (Carin Meier) + - C# (Rob Conery) + - Groovy (Ben Tilford) + - Scala (Ben Tilford) + - JSON + - OCaml (Sergi Mansilla) + - Perl (Panagiotis Astithas) + - SCSS/SASS (Andreas Madsen) + - SVG + - Textile (Kelley van Evert) + - SCAD (Jacob Hansson) + +* Live syntax checks + - Lint for CSS using CSS Lint + - CoffeeScript + +* New Themes + - Crimson Editor (iebuggy) + - Merbivore (Michael Schwartz) + - Merbivore soft (Michael Schwartz) + - Solarized dark/light (David Alan Hjelle) + - Vibrant Ink (Michael Schwartz) + +* Small Features/Enhancements + - Lots of render performance optimizations (Harutyun Amirjanyan) + - Improved Ruby highlighting (Chris Wanstrath, Trent Ogren) + - Improved PHP highlighting (Thomas Hruska) + - Improved CSS highlighting (Sean Kellogg) + - Clicks which cause the editor to be focused don't reset the selection + - Make padding text layer specific so that print margin and active line + highlight are not affected (Irakli Gozalishvili) + - Added setFontSize method + - Improved vi keybindings (Trent Ogren) + - When unfocused make cursor transparent instead of removing it (Harutyun Amirjanyan) + - Support for matching groups in tokenizer with arrays of tokens (Chris Spencer) + +* Bug fixes + - Add support for the new OSX scroll bars + - Properly highlight JavaScript regexp literals + - Proper handling of unicode characters in JavaScript identifiers + - Fix remove lines command on last line (Harutyun Amirjanyan) + - Fix scroll wheel sluggishness in Safari + - Make keyboard infrastructure route keys like []^$ the right way (Julian Viereck) + 2011.02.14, Version 0.1.6 * Floating Anchors - 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 + - Whenever text is inserted or deleted before the cursor, the position of + the cursor is updated - Usesd for the cursor and selection - Basis for bookmarks, multiple cursors and snippets in the future * Extensive support for Cocoa style keybindings on the Mac @@ -16,7 +303,8 @@ - Markers can be in front or behind the text - Markers are now stored in the session (was in the renderer) * Lots of IE8 fixes including copy, cut and selections -* Unit tests can also be run in the browser +* Unit tests can also be run in the browser + * Soft wrap can adapt to the width of the editor (Mike Ratcliffe, Joe Cheng) * Add minimal node server server.js to run the Ace demo in Chrome * The top level editor.html demo has been renamed to index.html @@ -47,4 +335,4 @@ * Add Ruby mode contributed by Shlomo Zalman Heigh * Add Java mode contributed by Tom Tasche * Fix annotation bug -* Changing a document added a new empty line at the end \ No newline at end of file +* Changing a document added a new empty line at the end diff --git a/LICENSE b/LICENSE index 853e4fd5..4760be2a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,476 +1,24 @@ -Licensed under the tri-license MPL/LGPL/GPL. - - MOZILLA PUBLIC LICENSE - Version 1.1 - - --------------- - -1. Definitions. - - 1.0.1. "Commercial Use" means distribution or otherwise making the - Covered Code available to a third party. - - 1.1. "Contributor" means each entity that creates or contributes to - the creation of Modifications. - - 1.2. "Contributor Version" means the combination of the Original - Code, prior Modifications used by a Contributor, and the Modifications - made by that particular Contributor. - - 1.3. "Covered Code" means the Original Code or Modifications or the - combination of the Original Code and Modifications, in each case - including portions thereof. - - 1.4. "Electronic Distribution Mechanism" means a mechanism generally - accepted in the software development community for the electronic - transfer of data. - - 1.5. "Executable" means Covered Code in any form other than Source - Code. - - 1.6. "Initial Developer" means the individual or entity identified - as the Initial Developer in the Source Code notice required by Exhibit - A. - - 1.7. "Larger Work" means a work which combines Covered Code or - portions thereof with code not governed by the terms of this License. - - 1.8. "License" means this document. - - 1.8.1. "Licensable" means having the right to grant, to the maximum - extent possible, whether at the time of the initial grant or - subsequently acquired, any and all of the rights conveyed herein. - - 1.9. "Modifications" means any addition to or deletion from the - substance or structure of either the Original Code or any previous - Modifications. When Covered Code is released as a series of files, a - Modification is: - A. Any addition to or deletion from the contents of a file - containing Original Code or previous Modifications. - - B. Any new file that contains any part of the Original Code or - previous Modifications. - - 1.10. "Original Code" means Source Code of computer software code - which is described in the Source Code notice required by Exhibit A as - Original Code, and which, at the time of its release under this - License is not already Covered Code governed by this License. - - 1.10.1. "Patent Claims" means any patent claim(s), now owned or - hereafter acquired, including without limitation, method, process, - and apparatus claims, in any patent Licensable by grantor. - - 1.11. "Source Code" means the preferred form of the Covered Code for - making modifications to it, including all modules it contains, plus - any associated interface definition files, scripts used to control - compilation and installation of an Executable, or source code - differential comparisons against either the Original Code or another - well known, available Covered Code of the Contributor's choice. The - Source Code can be in a compressed or archival form, provided the - appropriate decompression or de-archiving software is widely available - for no charge. - - 1.12. "You" (or "Your") means an individual or a legal entity - exercising rights under, and complying with all of the terms of, this - License or a future version of this License issued under Section 6.1. - For legal entities, "You" includes any entity which controls, is - controlled by, or is under common control with You. For purposes of - this definition, "control" means (a) the power, direct or indirect, - to cause the direction or management of such entity, whether by - contract or otherwise, or (b) ownership of more than fifty percent - (50%) of the outstanding shares or beneficial ownership of such - entity. - -2. Source Code License. - - 2.1. The Initial Developer Grant. - The Initial Developer hereby grants You a world-wide, royalty-free, - non-exclusive license, subject to third party intellectual property - claims: - (a) under intellectual property rights (other than patent or - trademark) Licensable by Initial Developer to use, reproduce, - modify, display, perform, sublicense and distribute the Original - Code (or portions thereof) with or without Modifications, and/or - as part of a Larger Work; and - - (b) under Patents Claims infringed by the making, using or - selling of Original Code, to make, have made, use, practice, - sell, and offer for sale, and/or otherwise dispose of the - Original Code (or portions thereof). - - (c) the licenses granted in this Section 2.1(a) and (b) are - effective on the date Initial Developer first distributes - Original Code under the terms of this License. - - (d) Notwithstanding Section 2.1(b) above, no patent license is - granted: 1) for code that You delete from the Original Code; 2) - separate from the Original Code; or 3) for infringements caused - by: i) the modification of the Original Code or ii) the - combination of the Original Code with other software or devices. - - 2.2. Contributor Grant. - Subject to third party intellectual property claims, each Contributor - hereby grants You a world-wide, royalty-free, non-exclusive license - - (a) under intellectual property rights (other than patent or - trademark) Licensable by Contributor, to use, reproduce, modify, - display, perform, sublicense and distribute the Modifications - created by such Contributor (or portions thereof) either on an - unmodified basis, with other Modifications, as Covered Code - and/or as part of a Larger Work; and - - (b) under Patent Claims infringed by the making, using, or - selling of Modifications made by that Contributor either alone - and/or in combination with its Contributor Version (or portions - of such combination), to make, use, sell, offer for sale, have - made, and/or otherwise dispose of: 1) Modifications made by that - Contributor (or portions thereof); and 2) the combination of - Modifications made by that Contributor with its Contributor - Version (or portions of such combination). - - (c) the licenses granted in Sections 2.2(a) and 2.2(b) are - effective on the date Contributor first makes Commercial Use of - the Covered Code. - - (d) Notwithstanding Section 2.2(b) above, no patent license is - granted: 1) for any code that Contributor has deleted from the - Contributor Version; 2) separate from the Contributor Version; - 3) for infringements caused by: i) third party modifications of - Contributor Version or ii) the combination of Modifications made - by that Contributor with other software (except as part of the - Contributor Version) or other devices; or 4) under Patent Claims - infringed by Covered Code in the absence of Modifications made by - that Contributor. - -3. Distribution Obligations. - - 3.1. Application of License. - The Modifications which You create or to which You contribute are - governed by the terms of this License, including without limitation - Section 2.2. The Source Code version of Covered Code may be - distributed only under the terms of this License or a future version - of this License released under Section 6.1, and You must include a - copy of this License with every copy of the Source Code You - distribute. You may not offer or impose any terms on any Source Code - version that alters or restricts the applicable version of this - License or the recipients' rights hereunder. However, You may include - an additional document offering the additional rights described in - Section 3.5. - - 3.2. Availability of Source Code. - Any Modification which You create or to which You contribute must be - made available in Source Code form under the terms of this License - either on the same media as an Executable version or via an accepted - Electronic Distribution Mechanism to anyone to whom you made an - Executable version available; and if made available via Electronic - Distribution Mechanism, must remain available for at least twelve (12) - months after the date it initially became available, or at least six - (6) months after a subsequent version of that particular Modification - has been made available to such recipients. You are responsible for - ensuring that the Source Code version remains available even if the - Electronic Distribution Mechanism is maintained by a third party. - - 3.3. Description of Modifications. - You must cause all Covered Code to which You contribute to contain a - file documenting the changes You made to create that Covered Code and - the date of any change. You must include a prominent statement that - the Modification is derived, directly or indirectly, from Original - Code provided by the Initial Developer and including the name of the - Initial Developer in (a) the Source Code, and (b) in any notice in an - Executable version or related documentation in which You describe the - origin or ownership of the Covered Code. - - 3.4. Intellectual Property Matters - (a) Third Party Claims. - If Contributor has knowledge that a license under a third party's - intellectual property rights is required to exercise the rights - granted by such Contributor under Sections 2.1 or 2.2, - Contributor must include a text file with the Source Code - distribution titled "LEGAL" which describes the claim and the - party making the claim in sufficient detail that a recipient will - know whom to contact. If Contributor obtains such knowledge after - the Modification is made available as described in Section 3.2, - Contributor shall promptly modify the LEGAL file in all copies - Contributor makes available thereafter and shall take other steps - (such as notifying appropriate mailing lists or newsgroups) - reasonably calculated to inform those who received the Covered - Code that new knowledge has been obtained. - - (b) Contributor APIs. - If Contributor's Modifications include an application programming - interface and Contributor has knowledge of patent licenses which - are reasonably necessary to implement that API, Contributor must - also include this information in the LEGAL file. - - (c) Representations. - Contributor represents that, except as disclosed pursuant to - Section 3.4(a) above, Contributor believes that Contributor's - Modifications are Contributor's original creation(s) and/or - Contributor has sufficient rights to grant the rights conveyed by - this License. - - 3.5. Required Notices. - You must duplicate the notice in Exhibit A in each file of the Source - Code. If it is not possible to put such notice in a particular Source - Code file due to its structure, then You must include such notice in a - location (such as a relevant directory) where a user would be likely - to look for such a notice. If You created one or more Modification(s) - You may add your name as a Contributor to the notice described in - Exhibit A. You must also duplicate this License in any documentation - for the Source Code where You describe recipients' rights or ownership - rights relating to Covered Code. You may choose to offer, and to - charge a fee for, warranty, support, indemnity or liability - obligations to one or more recipients of Covered Code. However, You - may do so only on Your own behalf, and not on behalf of the Initial - Developer or any Contributor. You must make it absolutely clear than - any such warranty, support, indemnity or liability obligation is - offered by You alone, and You hereby agree to indemnify the Initial - Developer and every Contributor for any liability incurred by the - Initial Developer or such Contributor as a result of warranty, - support, indemnity or liability terms You offer. - - 3.6. Distribution of Executable Versions. - You may distribute Covered Code in Executable form only if the - requirements of Section 3.1-3.5 have been met for that Covered Code, - and if You include a notice stating that the Source Code version of - the Covered Code is available under the terms of this License, - including a description of how and where You have fulfilled the - obligations of Section 3.2. The notice must be conspicuously included - in any notice in an Executable version, related documentation or - collateral in which You describe recipients' rights relating to the - Covered Code. You may distribute the Executable version of Covered - Code or ownership rights under a license of Your choice, which may - contain terms different from this License, provided that You are in - compliance with the terms of this License and that the license for the - Executable version does not attempt to limit or alter the recipient's - rights in the Source Code version from the rights set forth in this - License. If You distribute the Executable version under a different - license You must make it absolutely clear that any terms which differ - from this License are offered by You alone, not by the Initial - Developer or any Contributor. You hereby agree to indemnify the - Initial Developer and every Contributor for any liability incurred by - the Initial Developer or such Contributor as a result of any such - terms You offer. - - 3.7. Larger Works. - You may create a Larger Work by combining Covered Code with other code - not governed by the terms of this License and distribute the Larger - Work as a single product. In such a case, You must make sure the - requirements of this License are fulfilled for the Covered Code. - -4. Inability to Comply Due to Statute or Regulation. - - If it is impossible for You to comply with any of the terms of this - License with respect to some or all of the Covered Code due to - statute, judicial order, or regulation then You must: (a) comply with - the terms of this License to the maximum extent possible; and (b) - describe the limitations and the code they affect. Such description - must be included in the LEGAL file described in Section 3.4 and must - be included with all distributions of the Source Code. Except to the - extent prohibited by statute or regulation, such description must be - sufficiently detailed for a recipient of ordinary skill to be able to - understand it. - -5. Application of this License. - - This License applies to code to which the Initial Developer has - attached the notice in Exhibit A and to related Covered Code. - -6. Versions of the License. - - 6.1. New Versions. - Netscape Communications Corporation ("Netscape") may publish revised - and/or new versions of the License from time to time. Each version - will be given a distinguishing version number. - - 6.2. Effect of New Versions. - Once Covered Code has been published under a particular version of the - License, You may always continue to use it under the terms of that - version. You may also choose to use such Covered Code under the terms - of any subsequent version of the License published by Netscape. No one - other than Netscape has the right to modify the terms applicable to - Covered Code created under this License. - - 6.3. Derivative Works. - If You create or use a modified version of this License (which you may - only do in order to apply it to code which is not already Covered Code - governed by this License), You must (a) rename Your license so that - the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", - "MPL", "NPL" or any confusingly similar phrase do not appear in your - license (except to note that your license differs from this License) - and (b) otherwise make it clear that Your version of the license - contains terms which differ from the Mozilla Public License and - Netscape Public License. (Filling in the name of the Initial - Developer, Original Code or Contributor in the notice described in - Exhibit A shall not of themselves be deemed to be modifications of - this License.) - -7. DISCLAIMER OF WARRANTY. - - COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, - WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF - DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. - THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE - IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, - YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE - COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER - OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF - ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. - -8. TERMINATION. - - 8.1. This License and the rights granted hereunder will terminate - automatically if You fail to comply with terms herein and fail to cure - such breach within 30 days of becoming aware of the breach. All - sublicenses to the Covered Code which are properly granted shall - survive any termination of this License. Provisions which, by their - nature, must remain in effect beyond the termination of this License - shall survive. - - 8.2. If You initiate litigation by asserting a patent infringement - claim (excluding declatory judgment actions) against Initial Developer - or a Contributor (the Initial Developer or Contributor against whom - You file such action is referred to as "Participant") alleging that: - - (a) such Participant's Contributor Version directly or indirectly - infringes any patent, then any and all rights granted by such - Participant to You under Sections 2.1 and/or 2.2 of this License - shall, upon 60 days notice from Participant terminate prospectively, - unless if within 60 days after receipt of notice You either: (i) - agree in writing to pay Participant a mutually agreeable reasonable - royalty for Your past and future use of Modifications made by such - Participant, or (ii) withdraw Your litigation claim with respect to - the Contributor Version against such Participant. If within 60 days - of notice, a reasonable royalty and payment arrangement are not - mutually agreed upon in writing by the parties or the litigation claim - is not withdrawn, the rights granted by Participant to You under - Sections 2.1 and/or 2.2 automatically terminate at the expiration of - the 60 day notice period specified above. - - (b) any software, hardware, or device, other than such Participant's - Contributor Version, directly or indirectly infringes any patent, then - any rights granted to You by such Participant under Sections 2.1(b) - and 2.2(b) are revoked effective as of the date You first made, used, - sold, distributed, or had made, Modifications made by that - Participant. - - 8.3. If You assert a patent infringement claim against Participant - alleging that such Participant's Contributor Version directly or - indirectly infringes any patent where such claim is resolved (such as - by license or settlement) prior to the initiation of patent - infringement litigation, then the reasonable value of the licenses - granted by such Participant under Sections 2.1 or 2.2 shall be taken - into account in determining the amount or value of any payment or - license. - - 8.4. In the event of termination under Sections 8.1 or 8.2 above, - all end user license agreements (excluding distributors and resellers) - which have been validly granted by You or any distributor hereunder - prior to termination shall survive termination. - -9. LIMITATION OF LIABILITY. - - UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT - (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL - DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, - OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR - ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY - CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, - WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER - COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN - INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF - LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY - RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW - PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE - EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO - THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. - -10. U.S. GOVERNMENT END USERS. - - The Covered Code is a "commercial item," as that term is defined in - 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer - software" and "commercial computer software documentation," as such - terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 - C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), - all U.S. Government End Users acquire Covered Code with only those - rights set forth herein. - -11. MISCELLANEOUS. - - This License represents the complete agreement concerning subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. This License shall be governed by - California law provisions (except to the extent applicable law, if - any, provides otherwise), excluding its conflict-of-law provisions. - With respect to disputes in which at least one party is a citizen of, - or an entity chartered or registered to do business in the United - States of America, any litigation relating to this License shall be - subject to the jurisdiction of the Federal Courts of the Northern - District of California, with venue lying in Santa Clara County, - California, with the losing party responsible for costs, including - without limitation, court costs and reasonable attorneys' fees and - expenses. The application of the United Nations Convention on - Contracts for the International Sale of Goods is expressly excluded. - Any law or regulation which provides that the language of a contract - shall be construed against the drafter shall not apply to this - License. - -12. RESPONSIBILITY FOR CLAIMS. - - As between Initial Developer and the Contributors, each party is - responsible for claims and damages arising, directly or indirectly, - out of its utilization of rights under this License and You agree to - work with Initial Developer and Contributors to distribute such - responsibility on an equitable basis. Nothing herein is intended or - shall be deemed to constitute any admission of liability. - -13. MULTIPLE-LICENSED CODE. - - Initial Developer may designate portions of the Covered Code as - "Multiple-Licensed". "Multiple-Licensed" means that the Initial - Developer permits you to utilize portions of the Covered Code under - Your choice of the NPL or the alternative licenses, if any, specified - by the Initial Developer in the file described in Exhibit A. - -EXHIBIT A -Mozilla Public License. - - ``The contents of this file are subject to the Mozilla Public License - Version 1.1 (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.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - License for the specific language governing rights and limitations - under the License. - - The Original Code is ______________________________________. - - The Initial Developer of the Original Code is ________________________. - Portions created by ______________________ are Copyright (C) ______ - _______________________. All Rights Reserved. - - Contributor(s): ______________________________________. - - Alternatively, the contents of this file may be used under the terms - of the _____ license (the "[___] License"), in which case the - provisions of [______] License are applicable instead of those - above. If you wish to allow use of your version of this file only - under the terms of the [____] License and not to allow others to use - your version of this file under the MPL, indicate your decision by - deleting the provisions above and replace them with the notice and - other provisions required by the [___] License. If you do not delete - the provisions above, a recipient may use your version of this file - under either the MPL or the [___] License." - - [NOTE: The text of this Exhibit A may differ slightly from the text of - the notices in the Source Code files of the Original Code. You should - use the text of this Exhibit A rather than the text found in the - Original Code Source Code for Your Modifications.] - - - - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 \ No newline at end of file +Copyright (c) 2010, Ajax.org B.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Ajax.org B.V. nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Makefile b/Makefile index d272888f..29cf0495 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,34 @@ -build: +.PHONY : doc build clean dist + +pre_build: + git rev-parse HEAD > .git-ref mkdir -p build/src + mkdir -p build/demo/kitchen-sink mkdir -p build/textarea/src + + cp -r demo/kitchen-sink/styles.css build/demo/kitchen-sink/styles.css + cp demo/kitchen-sink/logo.png build/demo/kitchen-sink/logo.png + cp -r doc/site/images build/textarea + +build: pre_build + ./Makefile.dryice.js normal + ./Makefile.dryice.js demo + +# Minimal build: call Makefile.dryice.js only if our sources changed +basic: build/src/ace.js + +build/src/ace.js : ${wildcard lib/*} \ + ${wildcard lib/*/*} \ + ${wildcard lib/*/*/*} \ + ${wildcard lib/*/*/*/*} \ + ${wildcard lib/*/*/*/*/*} \ + ${wildcard lib/*/*/*/*/*/*} ./Makefile.dryice.js - ./Makefile.dryice.textarea.js + +doc: + cd doc;\ + (test -d node_modules && npm update) || npm install;\ + node build.js clean: rm -rf build diff --git a/Makefile.dryice.js b/Makefile.dryice.js index d4fd1e0a..0ce7c657 100755 --- a/Makefile.dryice.js +++ b/Makefile.dryice.js @@ -1,305 +1,571 @@ #!/usr/bin/env node /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ -var copy = require('dryice').copy; +var fs = require("fs"); +var path = require("path"); +var copy = require('architect-build/copy'); +var build = require('architect-build/build'); -var aceHome = __dirname; +var ACE_HOME = __dirname; +var BUILD_DIR = ACE_HOME + "/build"; +var CACHE = {}; -console.log('# ace ---------'); +function main(args) { + if (args.indexOf("updateModes") !== -1) { + return updateModes(); + } + var type = "minimal"; + args = args.map(function(x) { + if (x[0] == "-" && x[1] != "-") + return "-" + x; + return x; + }).filter(Boolean); -var project = copy.createCommonJsProject([ - aceHome + '/support/pilot/lib', - aceHome + '/lib', - aceHome + '/demo' -]); + if (args[2] && (args[2][0] != "-" || args[2].indexOf("h") != -1)) + type = args[2]; -copy({ - source: "build_support/editor.html", - dest: 'build/editor.html' -}); + var i = args.indexOf("--target"); + if (i != -1 && args[i+1]) + BUILD_DIR = args[i+1]; -var ace = copy.createDataObject(); -copy({ - source: [ - 'build_support/mini_require.js' - ], - dest: ace -}); -copy({ - source: [ - copy.source.commonjs({ - project: project, - require: [ - "pilot/fixoldbrowsers", - "pilot/index", - "pilot/plugin_manager", - "pilot/environment", - "ace/editor", - "ace/edit_session", - "ace/undomanager", - "ace/theme/textmate", - "ace/mode/text", - "ace/mode/matching_brace_outdent", - "ace/virtual_renderer" - ] - }) - ], - filter: [ copy.filter.moduleDefines ], - dest: ace -}); -copy({ - source: { - root: project, - include: /.*\.css$|.*\.html$/, - exclude: /tests?\// - }, - filter: [ copy.filter.addDefines ], - dest: ace -}); -copy({ - source: { - root: project, - include: /.*\.png$|.*\.gif$/, - exclude: /tests?\// - }, - filter: [ copy.filter.base64 ], - dest: ace -}); -copy({ - source: [ - 'build_support/boot.js' - ], - dest: ace -}); + if (args.indexOf("--h") == -1) { + if (type == "minimal") { + buildAce({ + compress: args.indexOf("--m") != -1, + noconflict: args.indexOf("--nc") != -1, + shrinkwrap: args.indexOf("--s") != -1 + }); + } else if (type == "normal") { + ace(); + } else if (type == "demo") { + demo(); + } else if (type == "full") { + ace(); + demo(); + } else if (type == "highlighter") { + // TODO + } + } +} +function showHelp(type) { + console.log("--- Ace Dryice Build Tool ---"); + console.log(""); + console.log("Options:"); + console.log(" minimal Places necessary Ace files out in build dir; uses configuration flags below [default]"); + console.log(" normal Runs four Ace builds--minimal, minimal-noconflict, minimal-min, and minimal-noconflict-min"); + console.log(" demo Runs demo build of Ace"); + console.log(" full all of above"); + console.log(" highlighter "); + console.log("args:"); + console.log(" --target ./path path to build folder"); + console.log("flags:"); + console.log(" --h print this help"); + console.log(" --m minify"); + console.log(" --nc namespace require"); + console.log(" --s shrinkwrap (combines all output files into one)"); + console.log(""); + if (type) + console.log(" output for " + type + " generated in " + BUILD_DIR); +} -// Create the compressed and uncompressed output files -copy({ - source: ace, - filter: copy.filter.uglifyjs, - dest: 'build/src/ace.js' -}); -copy({ - source: ace, - dest: 'build/src/ace-uncompressed.js' -}); +function ace() { + console.log('# ace License | Readme | Changelog ---------'); -console.log('# cockpit ---------'); + copy.file(ACE_HOME + "/build_support/editor.html", BUILD_DIR + "/editor.html"); + copy.file(ACE_HOME + "/LICENSE", BUILD_DIR + "/LICENSE"); + copy.file(ACE_HOME + "/ChangeLog.txt", BUILD_DIR + "/ChangeLog.txt"); + + console.log('# ace ---------'); + for (var i = 0; i < 4; i++) + buildAce({compress: i & 2, noconflict: i & 1}); +} -project.assumeAllFilesLoaded(); -project.addRoot(aceHome + '/support/cockpit/lib'); +function demo() { + console.log('# kitchen sink ---------'); -var cockpit = copy.createDataObject(); -copy({ - source: [ - copy.source.commonjs({ - project: project, - require: [ 'cockpit/index' ] - }) - ], - filter: [ copy.filter.moduleDefines ], - dest: cockpit -}); -copy({ - source: { - root: aceHome + '/support/cockpit/lib', - include: /.*\.css$|.*\.html$/, - exclude: /tests?\// - }, - filter: [ copy.filter.addDefines ], - dest: cockpit -}); -copy({ - source: { - root: aceHome + '/support/cockpit/lib', - include: /.*\.png$|.*\.gif$/, - exclude: /tests?\// - }, - filter: [ copy.filter.base64 ], - dest: cockpit -}); + var version = "", ref = ""; + try { + version = JSON.parse(fs.readFileSync(ACE_HOME + "/package.json")).version; + ref = fs.readFileSync(ACE_HOME + "/.git-ref").toString(); + } catch(e) {} -// Create the compressed and uncompressed output files -copy({ - source: cockpit, - filter: copy.filter.uglifyjs, - dest: 'build/src/cockpit.js' -}); -copy({ - source: cockpit, - dest: 'build/src/cockpit-uncompressed.js' -}); + function changeComments(data) { + return (data + .replace("doc/site/images/ace-logo.png", "demo/kitchen-sink/ace-logo.png") + .replace(//g, "") + .replace(/PACKAGE\-\->|")} + function script(str) {result.push('')} + scripts.forEach(function(s) { + s = s.replace(/"/g, ""); + if (s == "ace/ace") { + comment("load ace"); + script("ace"); + } else { + var extName = s.match(/[^/]*$/)[0]; + comment("load ace " + extName + " extension"); + script("ext-" + extName); + } + }); + result.push("'; -// }).join("\n"); -// return ( -// data.replace('', includes) -// .replace('', '\n') -// ) -// } ], -// dest: "build/editor-demo.html" -//}); -//copy({ -// source: [{ -// root: aceHome + '/demo', -// include: "demo.js" -// }], -// filter: [ copy.filter.moduleDefines ], -// dest: "build/demo/demo.js" -//}); -//copy({ -// source: aceHome + '/demo/styles.css', -// dest: "build/demo/styles.css" -//}); -//copy({ -// source: aceHome + '/demo/logo.png', -// dest: "build/demo/logo.png" -//}); +function namespace(ns) { + return function(text) { + text = text + .toString() + .replace(/ACE_NAMESPACE\s*=\s*""/, 'ACE_NAMESPACE = "' + ns +'"') + .replace(/(\.define)|\bdefine\(/g, function(_, a) { + return a || ns + ".define("; + }); + + return text; + }; +} + +function exportAce(ns, modules, requireBase, extModules) { + requireBase = requireBase || "window"; + return function(text) { + /*globals REQUIRE_NS, MODULES, NS*/ + var template = function() { + (function() { + REQUIRE_NS.require(MODULES, function(a) { + a && a.config.init(true); + if (!window.NS) + window.NS = a; + for (var key in a) if (a.hasOwnProperty(key)) + window.NS[key] = a[key]; + }); + })(); + }; + + if (extModules) { + template = function() { + (function() { + REQUIRE_NS.require(MODULES, function() {}); + })(); + }; + } + + text = text.replace(/function init\(packaged\) {/, "init(true);$&\n"); + + if (typeof modules == "string") + modules = [modules]; + + return (text.replace(/;\s*$/, "") + ";" + template + .toString() + .replace(/MODULES/g, JSON.stringify(modules)) + .replace(/REQUIRE_NS/g, requireBase) + .replace(/NS/g, ns) + .slice(13, -1) + ); + }; +} + +function updateModes() { + modeList().forEach(function(m) { + var filepath = __dirname + "/lib/ace/mode/" + m + ".js"; + var source = fs.readFileSync(filepath, "utf8"); + if (!/this.\$id\s*=\s*"/.test(source)) + source = source.replace(/\n([ \t]*)(\}\).call\(\w*Mode.prototype\))/, '\n$1 this.$id = "";\n$1$2'); + + source = source.replace(/(this.\$id\s*=\s*)"[^"]*"/, '$1"ace/mode/' + m + '"'); + fs.writeFileSync(filepath, source, "utf8"); + }); +} + +function generateThemesModule(themes) { + var themelist = [ + 'define(function(require, exports, module) {', + '\n\nmodule.exports.themes = ' + JSON.stringify(themes, null, ' '), + ';\n\n});' + ].join(''); + fs.writeFileSync(__dirname + '/lib/ace/ext/themelist_utils/themes.js', themelist, 'utf8'); +} + +function addSnippetFile(modeName) { + var snippetFilePath = ACE_HOME + "/lib/ace/snippets/" + modeName; + if (!fs.existsSync(snippetFilePath + ".js")) { + copy.file(ACE_HOME + "/tool/templates/snippets.js", snippetFilePath + ".js", function(t) { + return t.replace(/%modeName%/g, modeName); + }); + } + if (!fs.existsSync(snippetFilePath + ".snippets")) { + fs.writeFileSync(snippetFilePath + ".snippets", ""); + } +} + +function compress(text) { + var ujs = require("dryice").copy.filter.uglifyjs; + ujs.options.mangle_toplevel = {except: ["ACE_NAMESPACE", "requirejs"]}; + ujs.options.beautify = {ascii_only: true, inline_script: true} + return ujs(text); +} + +function extend(base, extra) { + Object.keys(extra).forEach(function(k) { + base[k] = extra[k]; + }); + return base; +} + +if (!module.parent) + main(process.argv); +else + exports.buildAce = buildAce; diff --git a/Makefile.dryice.textarea.js b/Makefile.dryice.textarea.js deleted file mode 100755 index dd1420c5..00000000 --- a/Makefile.dryice.textarea.js +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env node -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -var copy = require('dryice').copy; - -var aceHome = __dirname; - -function shadow(input) { - if (typeof input !== 'string') { - input = input.toString(); - } - - return input.replace(/define\(/g, "__ace_shadowed__.define("); -} - -console.log('# ace ---------'); - -var project = copy.createCommonJsProject([ - aceHome + '/support/pilot/lib', - aceHome + '/lib' -]); - -copy({ - source: "build_support/editor_textarea.html", - dest: 'build/textarea/editor.html' -}); - -var ace = copy.createDataObject(); -copy({ - source: [ - 'build_support/mini_require_textarea.js' - ], - dest: ace -}); -copy({ - source: [ - copy.source.commonjs({ - project: project, - require: [ - "pilot/fixoldbrowsers", - "pilot/index", - "pilot/plugin_manager", - "pilot/environment", - "ace/editor", - "ace/edit_session", - "ace/undomanager", - "ace/theme/textmate", - "ace/mode/text", - "ace/mode/matching_brace_outdent", - "ace/virtual_renderer" - ] - }) - ], - filter: [ copy.filter.moduleDefines ], - dest: ace -}); -copy({ - source: { - root: project, - include: /.*\.css$|.*\.html$/, - exclude: /tests?\// - }, - filter: [ copy.filter.addDefines ], - dest: ace -}); -copy({ - source: { - root: project, - include: /.*\.png$|.*\.gif$/, - exclude: /tests?\// - }, - filter: [ copy.filter.base64 ], - dest: ace -}); -copy({ - source: [ - 'build_support/boot_textarea.js' - ], - dest: ace -}); - -// Create the compressed and uncompressed output files -copy({ - source: ace, - filter: [ - shadow, - copy.filter.uglifyjs - ], - dest: 'build/textarea/src/ace.js' -}); -copy({ - source: ace, - filter: [ - shadow, - ], - dest: 'build/textarea/src/ace-uncompressed.js' -}); - -console.log('# ace modes ---------'); - -// create modes -project.assumeAllFilesLoaded(); -[ - "css", "html", "javascript", "php", "python", "xml", "ruby", "java", "c_cpp", - "coffee", "perl" -].forEach(function(mode) { - console.log("mode " + mode); - copy({ - source: [ - copy.source.commonjs({ - project: project.clone(), - require: [ 'ace/mode/' + mode ] - }) - ], - filter: [ - copy.filter.moduleDefines, - shadow, - copy.filter.uglifyjs - ], - dest: "build/textarea/src/mode-" + mode + ".js" - }); -}); - -console.log('# ace themes ---------'); - -// create themes -[ - "clouds", "clouds_midnight", "cobalt", "dawn", "idle_fingers", "kr_theme", - "mono_industrial", "monokai", "pastel_on_dark", "twilight", "eclipse" -].forEach(function(theme) { - console.log("theme " + theme); - copy({ - source: [{ - root: aceHome + '/lib', - include: "ace/theme/" + theme + ".js" - }], - filter: [ - copy.filter.moduleDefines, - shadow, - copy.filter.uglifyjs - ], - dest: "build/textarea/src/theme-" + theme + ".js" - }); -}); - -console.log('# License | Readme | Changelog ---------'); diff --git a/Readme.md b/Readme.md index 693d6643..42e81567 100644 --- a/Readme.md +++ b/Readme.md @@ -1,104 +1,168 @@ Ace (Ajax.org Cloud9 Editor) ============================ -Ace is a standalone code editor written in JavaScript. Our goal is to create a web based code editor that matches and extends the features, usability and performance of existing native editors such as TextMate, Vim or Eclipse. It can be easily embedded in any web page and JavaScript application. Ace is developed as the primary editor for [Cloud9 IDE](http://www.cloud9ide.com/) and the successor of the Mozilla Skywriter (Bespin) Project. +_Note_: The new site at http://ace.c9.io contains all the info below along with an embedding guide and all the other resources you need to get started with Ace. + +Ace is a standalone code editor written in JavaScript. Our goal is to create a browser based editor that matches and extends the features, usability and performance of existing native editors such as TextMate, Vim or Eclipse. It can be easily embedded in any web page or JavaScript application. Ace is developed as the primary editor for [Cloud9 IDE](https://c9.io/) and the successor of the Mozilla Skywriter (Bespin) Project. Features -------- -* Syntax highlighting -* Auto indentation and outdent +* Syntax highlighting for over 110 languages (TextMate/Sublime/_.tmlanguage_ files can be imported) +* Over 20 themes (TextMate/Sublime/_.tmtheme_ files can be imported) +* Automatic indent and outdent * An optional command line -* Work with huge documents (100,000 lines and more are no problem) -* Fully customizable key bindings including VI and Emacs modes -* Themes (TextMate themes can be imported) +* Handles huge documents (at last check, 4,000,000 lines is the upper limit) +* Fully customizable key bindings including vim and Emacs modes * Search and replace with regular expressions * Highlight matching parentheses * Toggle between soft tabs and real tabs * Displays hidden characters +* Drag and drop text using the mouse +* Line wrapping +* Code folding +* Multiple cursors and selections +* Live syntax checker (currently JavaScript/CoffeeScript/CSS/XQuery) +* Cut, copy, and paste functionality Take Ace for a spin! -------------------- -Check out the Ace live [demo](http://ajaxorg.github.com/ace/build/editor.html) or get a [Cloud9 IDE account](http://run.cloud9ide.com) to experience Ace while editing one of your own GitHub projects. +Check out the Ace live [demo](http://ace.c9.io/build/kitchen-sink.html) or get a [Cloud9 IDE account](https://c9.io/) to experience Ace while editing one of your own GitHub projects. -If you want, you can use Ace as a textarea replacement thanks to the [Ace Bookmarklet](http://ajaxorg.github.com/ace/build/textarea/editor.html). - -History -------- - -Previously known as “Bespin” or lately “Skywriter” it’s now known as Ace (Ajax.org Cloud9 Editor)! Bespin and Ace started as two independent projects both aiming to build a no compromise code editor component for the web. Bespin started as part of Mozilla Labs and was based on the canvas tag, while Ace is the Editor component of the Cloud9 IDE and is using the DOM for rendering. After the release of Ace at JSConf.eu 2010 in Berlin the Skywriter team decided to merge Ace with a simplified version of Skywriter's plugin system and some of Skywriter's extensibility points. All these changes have been merged back to Ace now, which supersedes Skywriter. Both Ajax.org and Mozilla are actively developing and maintaining Ace. - -Getting the code ----------------- - -Ace is a community project. We actively encourage and support contributions. The Ace source code is hosted on GitHub. It is released under the Mozilla tri-license (MPL/GPL/LGPL). This is the same license used by Firefox. This license is friendly to all kinds of projects, whether open source or not. Take charge of your editor and add your favorite language highlighting and keybindings! - - git clone git://github.com/ajaxorg/ace.git - git submodule update --init --recursive +If you want, you can use Ace as a textarea replacement thanks to the [Ace Bookmarklet](http://ajaxorg.github.io/ace/build/demo/bookmarklet/index.html). Embedding Ace ------------- -Ace can be easily embedded into any existing web page. The Ace git repository ships with a pre-packaged version of Ace inside of the `build` directory. The same packaged files are also available as a separate [download](https://github.com/ajaxorg/ace/downloads). Simply copy the contents of the `src` subdirectory somewhere into your project and take a look at the included demos of how to use Ace. +Ace can be easily embedded into any existing web page. You can either use one of pre-packaged versions of [ace](https://github.com/ajaxorg/ace-builds/) (just copy one of `src*` subdirectories somewhere into your project), or use requireJS to load contents of [lib/ace](https://github.com/ajaxorg/ace/tree/master/lib/ace) as `ace` + The easiest version is simply: +```html
some text
- +``` + +With "editor" being the id of the DOM element, which should be converted to an editor. Note that this element must be explicitly sized and positioned `absolute` or `relative` for Ace to work. e.g. + +```css + #editor { + position: absolute; + width: 500px; + height: 400px; + } +``` + To change the theme simply include the Theme's JavaScript file +```html - +``` + and configure the editor to use the theme: +```javascript editor.setTheme("ace/theme/twilight"); - -By default the editor only supports plain text mode. However all other language modes are available as separate modules. After including the mode's Javascript file +``` +By default the editor only supports plain text mode; many other languages are available as separate modules. After including the mode's JavaScript file: + +```html - -the mode can be used like this: +``` - var JavaScriptMode = require("ace/mode/javascript").Mode; +The mode can then be used like this: + +```javascript + var JavaScriptMode = ace.require("ace/mode/javascript").Mode; editor.getSession().setMode(new JavaScriptMode()); +``` + +Documentation +------------- + +Additional usage information, including events to listen to and extending syntax highlighters, can be found [on the main Ace website](http://ace.c9.io). + +You can also find API documentation at [http://ace.c9.io/#nav=api](http://ace.c9.io/#nav=api). + +Also check out the sample code for the kitchen sink [demo app](https://github.com/ajaxorg/ace/blob/master/demo/kitchen-sink/demo.js). + +If you still need help, feel free to drop a mail on the [ace mailing list](http://groups.google.com/group/ace-discuss), or at `irc.freenode.net#ace`. Running Ace ----------- -After the checkout Ace works out of the box. No build step is required. Simply open 'editor.html' in any browser except Google Chrome. Google Chrome doesn't allow XMLHTTPRequests from files loaded from disc (i.e. with a file:/// URL). To open the Ace in Chrome simply start the bundled mini HTTP server: +After the checkout Ace works out of the box. No build step is required. To try it out, simply start the bundled mini HTTP server: +```bash ./static.py +``` -The editor can then be opened at http://localhost:9999/editor.html. +Or using Node.JS -Package Ace +```bash + npm install mime + node ./static.js +``` + +The editor can then be opened at http://localhost:8888/kitchen-sink.html. + +To open the editor with a file:/// URL see [the wiki](https://github.com/ajaxorg/ace/wiki/Running-Ace-from-file). + +Building Ace ----------- -To package Ace we use the dryice build tool developed by the Mozilla Skywriter team. To install dryice and all its dependencies simply call: +You do not generally need to build ACE. The [ace-builds repository](https://github.com/ajaxorg/ace-builds/) endeavours to maintain the latest build, and you can just copy one of _src*_ subdirectories somewhere into your project. - npm link . +However, all you need is Node.js and npm installed to package ACE. Just run `npm install` in the ace folder to install dependencies: -Afterwards Ace can by build by calling +```bash + npm install + node ./Makefile.dryice.js +``` - ./Makefile.dryice.js +To package Ace, we use the dryice build tool developed by the Mozilla Skywriter team. Call `node Makefile.dryice.js` on the command-line to start the packing. This build script accepts the following options -The packaged Ace will be put in the 'build' folder. +```bash +-m minify build files with uglify-js +-nc namespace require and define calls with "ace" +-bm builds the bookmarklet version +--target ./path specify relative path for output folder (default value is "./build") +``` + +To generate all the files in the ace-builds repository, run `node Makefile.dryice.js full --target ../ace-builds` Running the Unit Tests ---------------------- -The Ace unit tests run on node.js. Before the first run a couple of node mudules have to be installed. The easiest way to do this is by using the node package manager (npm). In the Ace base directory simply call - - npm link . - -To run the tests call: +The Ace unit tests can run on node.js. Assuming you have already done `npm install`, just call: +```bash node lib/ace/test/all.js +``` + +You can also run the tests in your browser by serving: + + http://localhost:8888/lib/ace/test/tests.html + +This makes debugging failing tests way more easier. + +Contributing +----------------------------- + +Ace is a community project and wouldn't be what it is without contributions! We actively encourage and support contributions. The Ace source code is released under the BSD License. This license is very simple, and is friendly to all kinds of projects, whether open source or not. Take charge of your editor and add your favorite language highlighting and keybindings! + +Feel free to fork and improve/enhance Ace any way you want. If you feel that the editor or the Ace community will benefit from your changes, please open a pull request. For more information on our contributing guidelines, see [CONTRIBUTING.md](https://github.com/ajaxorg/ace/blob/master/CONTRIBUTING.md). + +Continuous Integration status +----------------------------- + +This project is tested with [Travis CI](http://travis-ci.org) +[![Build Status](https://secure.travis-ci.org/ajaxorg/ace.png?branch=master)](http://travis-ci.org/ajaxorg/ace) + diff --git a/api/ace.html b/api/ace.html new file mode 100644 index 00000000..c0f40b1d --- /dev/null +++ b/api/ace.html @@ -0,0 +1,149 @@ + +
+
+
+
+
+

Ace +

+ +
+
+
+
+

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

+ +
+
+
+

Methods

+
+
+
+
+ +
+
+

Creates a new EditSession, and returns the associated Document.

+ +
+

Creates a new EditSession, and returns the associated Document.

+ +

Arguments

textDocument | String

Required. If text is a Document, it associates the EditSession with it. Otherwise, a new Document is created, with the initial text

+
modeTextMode

Required. The inital language mode to use for the document

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

Embeds the Ace editor into the DOM, at the element provided by el.

+ +
+

Embeds the Ace editor into the DOM, at the element provided by el.

+ +

Arguments

elString | DOMElement

Required. Either the id of an element, or the element itself

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

Provides access to require in packed noconflict mode

+ +
+

Provides access to require in packed noconflict mode

+ +

Arguments

moduleNameString

Required.

+
+
+
+
+
+
+
+ + + + + +
+
\ No newline at end of file diff --git a/api/anchor.html b/api/anchor.html new file mode 100644 index 00000000..727c1cb8 --- /dev/null +++ b/api/anchor.html @@ -0,0 +1,272 @@ + +
+
+
+
+
+

Anchor +

+ +
+
+
+
+

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

docDocument

Required. The document to associate with the anchor

+
rowNumber

Required. The starting row position

+
columnNumber

Required. The starting column position

+
+
+
+
+
+
+

Events

+
+
+
+
+
    +
  • +
      +
    • Anchor.on("change", function(Object e))
    • +
    +
      +
    +
  • +
+
+
+

Fires whenever the anchor position changes.

+ +
+

Fires whenever the anchor position changes.

+

Both of these objects have a row and column property corresponding to the position.

+

Events that can trigger this function include setPosition().

+ +

Arguments

eObject

Required. An object containing information about the anchor position. It has two properties:

+
    +
  • old: An object describing the old Anchor position
  • +
  • value: An object describing the new Anchor position
  • +
+
+
+
+
+
+
+

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.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Anchor.onChange()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+

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

rowNumber

Required. The row index to move the anchor to

+
columnNumber

Required. The column index to move the anchor to

+
noClipBoolean

Required. 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..a4ef22c2 --- /dev/null +++ b/api/background_tokenizer.html @@ -0,0 +1,320 @@ + +
+
+
+
+
+

BackgroundTokenizer +

+ +
+
+
+
+

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

tokenizerTokenizer

Required. The tokenizer to use

+
editorEditor

Required. The editor to associate with

+
+
+
+
+
+
+

Events

+
+
+
+
+
    +
  • +
      +
    • BackgroundTokenizer.on("update", function(Object e))
    • +
    +
      +
    +
  • +
+
+
+

Fires whenever the background tokeniziers between a range of rows are going to be updated.

+ +
+

Fires whenever the background tokeniziers between a range of rows are going to be updated.

+ +

Arguments

eObject

Required. An object containing two properties, first and last, which indicate the rows of the region being updated.

+
+
+
+
+
+
+

Methods

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

firstRowNumber

Required. The starting row region

+
lastRowNumber

Required. The final row region

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • BackgroundTokenizer.getState(Number row)
    • +
    +
      +
    +
  • +
+
+
+

Returns the state of tokenization at the end of a row.

+ +
+

Returns the state of tokenization at the end of a row.

+ +

Arguments

rowNumber

Required. The row to get state at

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • BackgroundTokenizer.getTokens(Number row)
    • +
    +
      +
    +
  • +
+
+
+

Gives list of tokens of the row. (tokens are cached)

+ +
+

Gives list of tokens of the row. (tokens are cached)

+ +

Arguments

rowNumber

Required. The row to get tokens at

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • BackgroundTokenizer.setDocument(Document doc)
    • +
    +
      +
    +
  • +
+
+
+

Sets a new document to associate with this object.

+ +
+

Sets a new document to associate with this object.

+ +

Arguments

docDocument

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

tokenizerTokenizer

Required. The new tokenizer to use

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • BackgroundTokenizer.start(Number startRow)
    • +
    +
      +
    +
  • +
+
+
+

Starts tokenizing at the row indicated.

+ +
+

Starts tokenizing at the row indicated.

+ +

Arguments

startRowNumber

Required. The row to start at

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • BackgroundTokenizer.stop()
    • +
    +
      +
    +
  • +
+
+
+

Stops tokenizing.

+ +
+

Stops tokenizing.

+ +
+
+
+
+
+
+ + + + + +
+
\ No newline at end of file diff --git a/api/command_manager.html b/api/command_manager.html new file mode 100644 index 00000000..142ca741 --- /dev/null +++ b/api/command_manager.html @@ -0,0 +1,55 @@ + +
+
+
+
+
+

CommandManager +

+ +
+
+
+
+

new CommandManager(platform, commands)

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

Contains the text of the document. Document can be attached to several EditSessions.

+

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

Required. The starting text

+
+
+
+
+
+
+

Events

+
+
+
+
+
    +
  • +
      +
    • Document.on("change", function(Object e))
    • +
    +
      +
    +
  • +
+
+
+

Fires whenever the document changes.

+ +
+

Fires whenever the document changes.

+

Several methods trigger different "change" events. Below is a list of each action type, followed by each property that's also available:

+ + +

Arguments

eObject

Required. Contains at least one property called "action". "action" indicates the action that triggered the change. Each action also has a set of additional properties.

+
+
+
+
+
+
+

Methods

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

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

+ +
+

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

+ +

Arguments

deltasObject

Required.

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

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

rowNumber

Required. The row number to use

+
columnNumber

Required. The column number to use

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.getAllLines()
    • +
    +
      +
    +
  • +
+
+
+

Returns all lines in the document as string 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.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.getLine(Number row)
    • +
    +
      +
    +
  • +
+
+
+

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

rowNumber

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

firstRowNumber

Required. The first row index to retrieve

+
lastRowNumber

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

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

+ +
+

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

+ +

Arguments

rangeRange

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

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

Converts an index position in a document to a {row, column} object.

+ +
+

Converts an index position in a document to a {row, column} object.

+

Index refers to the "absolute position" of a character in the document. For example:

+
var x = 0; // 10 characters, plus one for newline
+var y = -1;
+

Here, y is an index 15: 11 characters for the first row, and 5 characters until y in the second.

+ +

Arguments

indexNumber

Required. An index to convert

+
startRowNumber

Required. =0 The row from which to start the conversion

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

Inserts a block of text and the indicated position.

+ +
+

Inserts a block of text and the indicated position.

+ +

Arguments

positionObject

Required. The position to start inserting at

+
textString

Required. A chunk of text to insert

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

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

positionObject

Required. The position to insert at

+
textString

Required. A chunk of text

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

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

+ +
+

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

+ +

Arguments

rowNumber

Required. The index of the row to insert at

+
linesArray

Required. An array of strings

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.insertNewLine(Object 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

positionObject

Required. The position to insert at

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.isNewLine(String text)
    • +
    +
      +
    +
  • +
+
+
+

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

textString

Required. The text to check

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

Converts the {row, column} position in a document to the character's index.

+ +
+

Converts the {row, column} position in a document to the character's index.

+

Index refers to the "absolute position" of a character in the document. For example:

+
var x = 0; // 10 characters, plus one for newline
+var y = -1;
+

Here, y is an index 15: 11 characters for the first row, and 5 characters until y in the second.

+ +

Arguments

posObject

Required. The {row, column} to convert

+
startRowNumber

Required. =0 The row from which to start the conversion

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

Removes the range from the document.

+ +
+

Removes the range from the document.

+ +

Arguments

rangeRange

Required. A specified Range to remove

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

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

rowNumber

Required. The row to remove from

+
startColumnNumber

Required. The column to start removing at

+
endColumnNumber

Required. The column to stop removing at

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

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

firstRowNumber

Required. The first row to be removed

+
lastRowNumber

Required. The last row to be removed

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.removeNewLine(Number row)
    • +
    +
      +
    +
  • +
+
+
+

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

rowNumber

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

rangeRange

Required. A specified Range to replace

+
textString

Required. The new text to use as a replacement

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.revertDeltas(Object deltas)
    • +
    +
      +
    +
  • +
+
+
+

Reverts any changes previously applied. These can be either 'includeText', 'insertLines', 'removeText', and 'removeLines'.

+ +
+

Reverts any changes previously applied. These can be either 'includeText', 'insertLines', 'removeText', and 'removeLines'.

+ +

Arguments

deltasObject

Required.

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

Sets the new line mode.

+ +
+

Sets the new line mode.

+ +

Arguments

newLineModeString

Required. The newline mode to use; can be either windows, unix, or auto

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.setValue(String text)
    • +
    +
      +
    +
  • +
+
+
+

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

textString

Required. 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..11e79ed0 --- /dev/null +++ b/api/edit_session.html @@ -0,0 +1,3235 @@ + +
+
+
+
+
+

EditSession +

+ +
+
+
+
+

Stores all the data about Editor state providing easy way to change editors state.

+

EditSession can be attached to only one Document. Same Document can be attached to several EditSessions.

+ +
+
+
+

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

Required. If text is a Document, it associates the EditSession with it. Otherwise, a new Document is created, with the initial text

+
modeTextMode

Required. The inital language mode to use for the document

+
+
+
+
+
+
+

Events

+
+
+
+
+
    +
  • +
      +
    • EditSession.on("change", function(Object e))
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the document changes.

+ +
+

Emitted when the document changes.

+ +

Arguments

eObject

Required. An object containing a delta of information about the change.

+
+
+
+
+
+
+ +
+
+
+
+
    +
  • +
      +
    • EditSession.on("changeBackMarker", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when a back marker changes.

+ +
+

Emitted when a back marker changes.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.on("changeBreakpoint", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the gutter changes, either by setting or removing breakpoints, or when the gutter decorations change.

+ +
+

Emitted when the gutter changes, either by setting or removing breakpoints, or when the gutter decorations change.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.on("changeFold", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when a code fold is added or removed.

+ +
+

Emitted when a code fold is added or removed.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.on("changeFrontMarker", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when a front marker changes.

+ +
+

Emitted when a front marker changes.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.on("changeMode", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the current mode changes.

+ +
+

Emitted when the current mode changes.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.on("changeOverwrite", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the ability to overwrite text changes, via EditSession.setOverwrite().

+ +
+

Emitted when the ability to overwrite text changes, via EditSession.setOverwrite().

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.on("changeScrollLeft", function(Number scrollLeft))
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the scroll left changes.

+ +
+

Emitted when the scroll left changes.

+ +

Arguments

scrollLeftNumber

Required. The new scroll left value

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.on("changeScrollTop", function(Number scrollTop))
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the scroll top changes.

+ +
+

Emitted when the scroll top changes.

+ +

Arguments

scrollTopNumber

Required. The new scroll top value

+
+
+
+
+
+
+ +
+
+
+
+
    +
  • +
      +
    • EditSession.on("changeWrapLimit", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the wrapping limit changes.

+ +
+

Emitted when the wrapping limit changes.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.on("changeWrapMode", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the wrap mode changes.

+ +
+

Emitted when the wrap mode changes.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.on("tokenizerUpdate", function(Object e))
    • +
    +
      +
    +
  • +
+
+
+

Emitted when a background tokenizer asynchronously processes new rows.

+ +
+

Emitted when a background tokenizer asynchronously processes new rows.

+ +

Arguments

eObject

Required. An object containing one property, "data", that contains information about the changing rows

+
+
+
+
+
+
+

Methods

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

Adds a dynamic marker to the session.

+ +
+

Adds a dynamic marker to the session.

+ +

Arguments

markerObject

Required. object with update method

+
inFrontBoolean

Required. Set to true to establish a front marker

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.addGutterDecoration(Number row, String className)
    • +
    +
      +
    +
  • +
+
+
+

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

rowNumber

Required. The row number

+
classNameString

Required. The class to add

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

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.

+ +
+

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

rangeRange

Required. Define the range of the marker

+
clazzString

Required. Set the CSS class for the marker

+
typeFunction | String

Required. Identify the type of the marker

+
inFrontBoolean

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

rowNumber

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

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

For the given document row and column, returns the screen column.

+ +
+

For the given document row and column, returns the screen column.

+ +

Arguments

rowNumber

Required.

+
docColumnNumber

Required.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.documentToScreenPosition(Number docRow, Number docColumn) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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

docRowNumber

Required. The document row to check

+
docColumnNumber

Required. The document column to check

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.documentToScreenRow(Number docRow, Number docColumn)
    • +
    +
      +
    +
  • +
+
+
+

For the given document row and column, returns the screen row.

+ +
+

For the given document row and column, returns the screen row.

+ +

Arguments

docRowNumber

Required.

+
docColumnNumber

Required.

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

Duplicates all the text between firstRow and lastRow.

+ +
+

Duplicates all the text between firstRow and lastRow.

+ +

Arguments

firstRowNumber

Required. The starting row to duplicate

+
lastRowNumber

Required. The final row to duplicate

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

rowNumber

Required. The row number to start from

+
columnNumber

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

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getDocumentLastRowColumn(Number docRow, Number docColumn)
    • +
    +
      +
    +
  • +
+
+
+

For the given document row and column, this returns the column position of the last screen row.

+ +
+

For the given document row and column, this returns the column position of the last screen row.

+ +

Arguments

docRowNumber

Required.

+
docColumnNumber

Required.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getDocumentLastRowColumnPosition(Number docRow, Number docColumn)
    • +
    +
      +
    +
  • +
+
+
+

For the given document row and column, this returns the document position of the last row.

+ +
+

For the given document row and column, this returns the document position of the last row.

+ +

Arguments

docRowNumber

Required.

+
docColumnNumber

Required.

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

rowNumber

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

firstRowNumber

Required. The first row index to retrieve

+
lastRowNumber

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

inFrontBoolean

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

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getNewLineMode() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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 number of screenrows in a wrapped line.

+ +
+

Returns number of screenrows in a wrapped line.

+ +

Arguments

rowNumber

Required. The row number to check

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getRowSplitData(Object row) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

For the given row, this returns the split data.

+ +
+

For the given row, this returns the split data.

+ +

Arguments

rowObject

Required.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getScreenLastRowColumn(Number screenRow) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the position (on screen) for the last character in the provided screen row.

+ +
+

Returns the position (on screen) for the last character in the provided screen row.

+ +

Arguments

screenRowNumber

Required. The screen row 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

screenColumnNumber

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

+ +
+

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.

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

Returns the state of tokenization at the end of a row.

+ +
+

Returns the state of tokenization at the end of a row.

+ +

Arguments

rowNumber

Required. 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 getTabSize()); otherwise it's simply '\t'.

+ +
+

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

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

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

rangeRange

Required. The range to work with

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

Returns an object indicating the token at the current row. The object has two properties: index and start.

+ +
+

Returns an object indicating the token at the current row. The object has two properties: index and start.

+ +

Arguments

rowNumber

Required. The row number to retrieve from

+
columnNumber

Required. The column number to retrieve from

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

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

rowNumber

Required. The row to start 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.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getValue() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the current Document as a string.

+ +
+

Returns the current Document as a string.

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

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

rowNumber

Required. The row to start at

+
columnNumber

Required. 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 }

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.highlight()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.highlightLines()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

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

startRowNumber

Required. Starting row

+
endRowNumber

Required. Ending row

+
indentStringString

Required. The indent token

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

Inserts a block of text and the indicated position.

+ +
+

Inserts a block of text and the indicated position.

+ +

Arguments

positionObject

Required. The position {row, column} to start inserting at

+
textString

Required. A chunk of text to insert

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.isTabStop(Object 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

positionObject

Required. The position to check

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

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

+ +
+

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

+ +

Arguments

firstRowNumber

Required. The starting row to move down

+
lastRowNumber

Required. The final row to move down

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

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

firstRowNumber

Required. The starting row to move up

+
lastRowNumber

Required. The final row to move up

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

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

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

fromRangeRange

Required. The range of text you want moved within the document

+
toPositionObject

Required. The location (row and column) where you want to move the text to

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.onChange()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.onChangeFold()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.onReloadTokenizer(Object e)
    • +
    +
      +
    +
  • +
+
+
+

Reloads all the tokens on the current session. This function calls BackgroundTokenizer.start () to all the rows; it also emits the 'tokenizerUpdate' event.

+ +
+

Reloads all the tokens on the current session. This function calls BackgroundTokenizer.start () to all the rows; it also emits the 'tokenizerUpdate' event.

+ +

Arguments

eObject

Required.

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

rangeRange

Required. A range of rows

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.redo()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Re-implements a previously undone change to your document.

+ +
+

Re-implements a previously undone change to your document.

+ +

Arguments

deltasArray

Required. An array of previous changes

+
dontSelectBoolean

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

rangeRange

Required. A specified Range to remove

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.removeGutterDecoration(Number row, String className)
    • +
    +
      +
    +
  • +
+
+
+

Removes className from the row.

+ +
+

Removes className from the row.

+ +

Arguments

rowNumber

Required. The row number

+
classNameString

Required. The class to add

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.removeMarker(Number markerId)
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+

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

markerIdNumber

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

rangeRange

Required. A specified Range to replace

+
textString

Required. The new text to use as a replacement

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.reset()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.resetCaches()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.screenToDocumentColumn()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.screenToDocumentPosition(Number screenRow, Number screenColumn) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+

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.

+ +

Arguments

screenRowNumber

Required. The screen row to check

+
screenColumnNumber

Required. The screen column to check

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.screenToDocumentRow()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • 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

annotationsArray

Required. A list of annotations

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setBreakpoint(Number row, String className)
    • +
    +
      +
    +
  • +
+
+
+

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

rowNumber

Required. A row index

+
classNameString

Required. Class of the breakpoint

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

rowsArray

Required. An array of row indices

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

docDocument

Required. The new Document to use

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setMode()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setNewLineMode(String newLineMode)
    • +
    +
      +
    +
  • +
+
+
+

Sets the new line mode.

+ +
+

Sets the new line mode.

+ +

Arguments

newLineModeString

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

+ +
+

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

overwriteBoolean

Required. Defines wheter or not to set overwrites

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setScrollLeft(Object scrollLeft)
    • +
    +
      +
    +
  • +
+
+
+

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

+ +
+

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

+ +

Arguments

scrollLeftObject

Required.

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

scrollTopNumber

Required. 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 equivalent to four spaces. This function also emits the changeTabSize event.

+ +
+

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

tabSizeNumber

Required. The new tab size

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setUndoManager(UndoManager undoManager)
    • +
    +
      +
    +
  • +
+
+
+

Sets the undo manager.

+ +
+

Sets the undo manager.

+ +

Arguments

undoManagerUndoManager

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

enableBoolean

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

useSoftTabsBoolean

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

useWorkerBoolean

Required. 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 'changeWrapMode' event is emitted.

+ +
+

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

+ +

Arguments

useWrapModeBoolean

Required. Enable (or disable) wrap mode

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setValue(String text)
    • +
    +
      +
    +
  • +
+
+
+

Sets the session text.

+ +
+

Sets the session text.

+ +

Arguments

textString

Required. 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 number to pin the limit. If the wrap limits for min or max are different, this method also emits the 'changeWrapMode' event.

+ +
+

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

minNumber

Required. The minimum wrap value (the left side wrap)

+
maxNumber

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

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.toString() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the current Document as a string.

+ +
+

Returns the current Document as a string.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.undo()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Reverts previous changes to your document.

+ +
+

Reverts previous changes to your document.

+ +

Arguments

deltasArray

Required. An array of previous changes

+
dontSelectBoolean

Required. 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..6ffe4369 --- /dev/null +++ b/api/editor.html @@ -0,0 +1,4689 @@ + +
+
+
+
+
+

Editor +

+ +
+
+
+
+

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

rendererVirtualRenderer

Required. Associated VirtualRenderer that draws everything

+
sessionEditSession

Required. The EditSession to refer to

+
+
+
+
+
+
+

Events

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

Emitted once the editor has been blurred.

+ +
+

Emitted once the editor has been blurred.

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

Emitted whenever the document is changed.

+ +
+

Emitted whenever the document is changed.

+ +

Arguments

eObject

Required. Contains a single property, data, which has the delta of changes

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("changeSelectionStyle", function(Object data))
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the selection style changes, via Editor.setSelectionStyle().

+ +
+

Emitted when the selection style changes, via Editor.setSelectionStyle().

+ +

Arguments

dataObject

Required. Contains one property, data, which indicates the new selection style

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

Emitted whenever the EditSession changes.

+ +
+

Emitted whenever the EditSession changes.

+ +

Arguments

eObject

Required. An object with two properties, oldSession and session, that represent the old and new EditSessions.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("copy", function(String text))
    • +
    +
      +
    +
  • +
+
+
+

Emitted when text is copied.

+ +
+

Emitted when text is copied.

+ +

Arguments

textString

Required. The copied text

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

Emitted once the editor comes into focus.

+ +
+

Emitted once the editor comes into focus.

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

Emitted when text is pasted.

+ +
+

Emitted when text is pasted.

+ +

Arguments

eObject

Required. An object which contains one property, text, that represents the text to be pasted. Editing this property will alter the text that is pasted.

+
+
+
+
+
+
+

Methods

+
+
+
+
+
    +
  • +
      +
    • Editor.addSelectionMarker(Range orientedRange) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Adds the selection and cursor.

+ +
+

Adds the selection and cursor.

+ +

Arguments

orientedRangeRange

Required. A range containing a cursor

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.alignCursors()
    • +
    +
      +
    +
  • +
+
+
+

Aligns the cursors or selected text.

+ +
+

Aligns the cursors or selected text.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.blockOutdent()
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.clearSelection()
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.copyLinesDown() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Copies all the selected lines down one row.

+ +
+

Copies all the selected lines down one row.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.copyLinesUp() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Copies all the selected lines up one row.

+ +
+

Copies all the selected lines up one row.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.destroy()
    • +
    +
      +
    +
  • +
+
+
+

Cleans up the entire editor.

+ +
+

Cleans up the entire editor.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.duplicateSelection()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.execCommand()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • 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

needleString

Required. The text to search for (optional)

+
optionsObject

Required. An object defining various search properties

+
animateBoolean

Required. If true animate scrolling

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

Finds and selects all the occurences of needle.

+ +
+

Finds and selects all the occurences of needle.

+ +

Arguments

TheString

Required. text to find

+
TheObject

Required. search options

+
keepsBoolean

Required.

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

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.

+ +

Arguments

optionsObject

Required. search options

+
animateBoolean

Required. If true animate scrolling

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

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.

+ +

Arguments

optionsObject

Required. search options

+
animateBoolean

Required. If true animate scrolling

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

cmdString

Required. The command to execute

+
argsString

Required. Any arguments for the command

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getAnimatedScroll()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • 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.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getCursorPosition() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Gets the current position of the cursor.

+ +
+

Gets the current position of the cursor.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getCursorPositionScreen() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the screen position of the cursor.

+ +
+

Returns the screen position of the cursor.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getDisplayIndentGuides()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getDragDelay() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the current mouse drag delay.

+ +
+

Returns the current mouse drag delay.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getFadeFoldWidgets()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getFirstVisibleRow() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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.getHighlightGutterLine()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • 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, such as "vim" or "windows".

+ +
+

Returns the keyboard handler, such as "vim" or "windows".

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getLastSearchOptions() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getLastVisibleRow() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the index of the last visible row.

+ +
+

Returns the index of the last visible row.

+ +
+
+
+
+
+ +
+
+
+
+
    +
  • +
      +
    • Editor.getOverwrite() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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 (in milliseconds).

+ +
+

Returns the value indicating how fast the mouse scroll speed is (in milliseconds).

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

Returns the currently highlighted selection.

+ +
+

Returns the currently highlighted selection.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getSelectionRange() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getTheme() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the path of the current theme.

+ +
+

Returns the path of the current theme.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getValue() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the current session's content.

+ +
+

Returns the current session's content.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getWrapBehavioursEnabled()
    • +
    +
      +
    +
  • +
+
+
+

Returns true if the wrapping behaviors are currently enabled.

+ +
+

Returns true if the wrapping behaviors are currently enabled.

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

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

lineNumberNumber

Required. The line number to go to

+
columnNumber

Required. A column number to go to

+
animateBoolean

Required. If true animates scolling

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

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.indent()
    • +
    +
      +
    +
  • +
+
+
+

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

textString

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

rowNumber

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

rowNumber

Required. The row to check

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.jumpToMatching(Object select)
    • +
    +
      +
    +
  • +
+
+
+

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

+ +
+

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

+ +

Arguments

selectObject

Required.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.modifyNumber(Number amount)
    • +
    +
      +
    +
  • +
+
+
+

If the character before the cursor is a number, this functions changes its value by amount.

+ +
+

If the character before the cursor is a number, this functions changes its value by amount.

+ +

Arguments

amountNumber

Required. The value to change the numeral by (can be negative to decrease value)

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

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

rowNumber

Required. The new row number

+
columnNumber

Required. The new column number

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.moveCursorToPosition(Object pos)
    • +
    +
      +
    +
  • +
+
+
+

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

posObject

Required. An object with two properties, row and column

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.moveLinesDown() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Shifts all the selected lines down one row.

+ +
+

Shifts all the selected lines down one row.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.moveLinesUp() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Shifts all the selected lines up one row.

+ +
+

Shifts all the selected lines up one row.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.moveText()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.navigateDown(Number times)
    • +
    +
      +
    +
  • +
+
+
+

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

+ +
+

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

+ +

Arguments

timesNumber

Required. 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 selection.

+ +
+

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

+ +

Arguments

timesNumber

Required. 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 selection.

+ +
+

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

+ +

Arguments

timesNumber

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

rowNumber

Required. The new row number

+
columnNumber

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

timesNumber

Required. 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 current selection.

+ +
+

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 current selection.

+ +
+

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

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onBlur()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onChangeAnnotation()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onChangeBackMarker()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onChangeBreakpoint()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onChangeFold()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onChangeFrontMarker()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onChangeMode()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onChangeWrapLimit()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onChangeWrapMode()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onCommandKey()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onCompositionEnd()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onCompositionStart()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onCompositionUpdate()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onCopy()
    • +
    +
      +
    +
  • +
+
+
+

Called whenever a text "copy" happens.

+ +
+

Called whenever a text "copy" happens.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onCursorChange()
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the selection changes.

+ +
+

Emitted when the selection changes.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onCut()
    • +
    +
      +
    +
  • +
+
+
+

Called whenever a text "cut" happens.

+ +
+

Called whenever a text "cut" happens.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onDocumentChange()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onFocus()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onPaste(String text)
    • +
    +
      +
    +
  • +
+
+
+

Called whenever a text "paste" happens.

+ +
+

Called whenever a text "paste" happens.

+ +

Arguments

textString

Required. The pasted text

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onScrollLeftChange()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onScrollTopChange()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onSelectionChange()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onTextInput()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onTokenizerUpdate()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.redo()
    • +
    +
      +
    +
  • +
+
+
+

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

dirString

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

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.removeLines()
    • +
    +
      +
    +
  • +
+
+
+

Removes all the lines in the current selection

+ +
+

Removes all the lines in the current selection

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

Removes the selection marker.

+ +
+

Removes the selection marker.

+ +

Arguments

TheRange

Required. selection range added with addSelectionMarker().

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

replacementString

Required. The text to replace with

+
optionsObject

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

replacementString

Required. The text to replace with

+
optionsObject

Required. The Search options to use

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

Triggers a resize of the editor.

+ +
+

Triggers a resize of the editor.

+ +

Arguments

forceBoolean

Required. If true, recomputes the size, even if the height and width haven't changed

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.revealRange()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • 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.

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

Scrolls to a line. If center is true, it puts the line in middle of screen (or attempts to).

+ +
+

Scrolls to a line. If center is true, it puts the line in middle of screen (or attempts to).

+ +

Arguments

lineNumber

Required. The line to scroll to

+
centerBoolean

Required. If true

+
animateBoolean

Required. If true animates scrolling

+
callbackFunction

Required. Function to be called when the animation has finished

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.scrollToRow(Object row)
    • +
    +
      +
    +
  • +
+
+
+

Moves the editor to the specified row.

+ +
+

Moves the editor to the specified row.

+ +

Arguments

rowObject

Required.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.selectAll()
    • +
    +
      +
    +
  • +
+
+
+

Selects all the text in editor.

+ +
+

Selects all the text in editor.

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

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

dirNumber

Required. The direction of lines to select: -1 for up, 1 for down

+
skipBoolean

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

dirNumber

Required. The direction of lines to select: -1 for up, 1 for down

+
skipBoolean

Required. If true, removes the active selection range

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • 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.setAnimatedScroll()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setBehavioursEnabled(Boolean enabled)
    • +
    +
      +
    +
  • +
+
+
+

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

+ +
+

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

+ +

Arguments

enabledBoolean

Required. Enables or disables behaviors

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setDisplayIndentGuides()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setDragDelay(Number dragDelay)
    • +
    +
      +
    +
  • +
+
+
+

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

+ +
+

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

+ +

Arguments

dragDelayNumber

Required. A value indicating the new delay

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setFadeFoldWidgets()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • 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

sizeNumber

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

shouldHighlightBoolean

Required. Set to true to highlight the current line

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setHighlightGutterLine()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setHighlightSelectedWord(Boolean shouldHighlight)
    • +
    +
      +
    +
  • +
+
+
+

Determines if the currently selected word should be highlighted.

+ +
+

Determines if the currently selected word should be highlighted.

+ +

Arguments

shouldHighlightBoolean

Required. Set to true to highlight the currently selected word

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setKeyboardHandler(String keyboardHandler)
    • +
    +
      +
    +
  • +
+
+
+

Sets a new key handler, such as "vim" or "windows".

+ +
+

Sets a new key handler, such as "vim" or "windows".

+ +

Arguments

keyboardHandlerString

Required. The new key handler

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setOverwrite(Boolean overwrite)
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+

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

overwriteBoolean

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

showPrintMarginNumber

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

readOnlyBoolean

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

speedNumber

Required. A value indicating the new speed (in milliseconds)

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setSelectionStyle(String style)
    • +
    +
      +
    +
  • +
+
+
+

Indicates how selections should occur.

+ +
+

Indicates how selections should occur.

+

By default, selections are set to "line". There are no other styles at the moment, +although this code change in the future.

+

This function also emits the 'changeSelectionStyle' event.

+ +

Arguments

styleString

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

sessionEditSession

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

showBoolean

Required. Specifies whether the fold widgets are shown

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setShowInvisibles(Boolean showInvisibles)
    • +
    +
      +
    +
  • +
+
+
+

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

+ +
+

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

+ +

Arguments

showInvisiblesBoolean

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

showPrintMarginBoolean

Required. Specifies whether or not to show the print margin

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setStyle(String style)
    • +
    +
      +
    +
  • +
+
+
+

Adds a new class, style, to the editor.

+ +
+

Adds a new class, style, to the editor.

+ +

Arguments

styleString

Required. A class name

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setTheme(String 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.

+ +

Arguments

themeString

Required. The path to a theme

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

Sets the current document to val.

+ +
+

Sets the current document to val.

+ +

Arguments

valString

Required. The new value to set for the document

+
cursorPosNumber

Required. Where to set the new value. undefined or 0 is selectAll, -1 is at the document start, and 1 is at the end

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setWrapBehavioursEnabled(Boolean enabled)
    • +
    +
      +
    +
  • +
+
+
+

Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets +when such a character is typed in.

+ +
+

Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets +when such a character is typed in.

+ +

Arguments

enabledBoolean

Required. Enables or disables wrapping behaviors

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.sortLines()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • 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 the lines, or uncomments all of them.

+ +
+

Given the currently selected range, this function either comments all the lines, or uncomments all of them.

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

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

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.transposeSelections(Number dir)
    • +
    +
      +
    +
  • +
+
+
+

Transposes the selected ranges.

+ +
+

Transposes the selected ranges.

+ +

Arguments

dirNumber

Required. The direction to rotate selections

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.undo()
    • +
    +
      +
    +
  • +
+
+
+

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

+ +
+

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

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.unsetStyle(Object style)
    • +
    +
      +
    +
  • +
+
+
+

Removes the class style from the editor.

+ +
+

Removes the class style from the editor.

+ +

Arguments

styleObject

Required.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.updateSelectionMarkers()
    • +
    +
      +
    +
  • +
+
+
+

Updates the cursor and marker layers.

+ +
+

Updates the cursor and marker layers.

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

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/placeholder.html b/api/placeholder.html new file mode 100644 index 00000000..fa12a958 --- /dev/null +++ b/api/placeholder.html @@ -0,0 +1,293 @@ + +
+
+
+
+
+

PlaceHolder +

+ +
+
+
+
+

Constructors

+
+
+
+
+
    +
  • +
      +
    • new PlaceHolder()
    • +
    +
      +
    +
  • +
+
+
+
    +
  • 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):
  • +
+ +
+
    +
  • 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):
  • +
+ +
+
+
+
+
+

Methods

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

PlaceHolder.cancel()

+ +
+

PlaceHolder.cancel()

+

TODO

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

PlaceHolder.detach()

+ +
+

PlaceHolder.detach()

+

TODO

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

PlaceHolder.hideOtherMarkers()

+ +
+

PlaceHolder.hideOtherMarkers()

+

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

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • PlaceHolder.onCursorChange(Object event)
    • +
    +
      +
    +
  • +
+
+
+

PlaceHolder@onCursorChange(e)

+ +
+

PlaceHolder@onCursorChange(e)

+

Emitted when the cursor changes.

+ +

Arguments

eventObject

Required.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • PlaceHolder.onUpdate(Object event)
    • +
    +
      +
    +
  • +
+
+
+

PlaceHolder@onUpdate(e)

+ +
+

PlaceHolder@onUpdate(e)

+

Emitted when the place holder updates.

+ +

Arguments

eventObject

Required.

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

PlaceHolder.setup()

+ +
+

PlaceHolder.setup()

+

TODO

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

PlaceHolder.showOtherMarkers()

+ +
+

PlaceHolder.showOtherMarkers()

+

TODO

+ +
+
+
+
+
+
+ + + + + +
+
\ No newline at end of file diff --git a/api/range.html b/api/range.html new file mode 100644 index 00000000..9779fe27 --- /dev/null +++ b/api/range.html @@ -0,0 +1,968 @@ + +
+
+
+
+
+

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.

+ +
+
+
+

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

startRowNumber

Required. The starting row

+
startColumnNumber

Required. The starting column

+
endRowNumber

Required. The ending row

+
endColumnNumber

Required. The ending column

+
+
+
+
+
+
+

Methods

+
+
+
+
+ +
+
+

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

+ +
+

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

+ +

Arguments

firstRowNumber

Required. The starting row

+
lastRowNumber

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

rowNumber

Required. A row point to compare with

+
columnNumber

Required. A column point to compare with

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

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

rowNumber

Required. A row point to compare with

+
columnNumber

Required. A column point to compare with

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

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

rowNumber

Required. A row point to compare with

+
columnNumber

Required. A column point to compare with

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

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

pRange

Required. A point to compare with

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

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

+ +
+

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

+ +

Arguments

rangeRange

Required. A range to compare with

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

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

rowNumber

Required. A row point to compare with

+
columnNumber

Required. A column point to compare with

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

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

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

rowNumber

Required. A row to check for

+
columnNumber

Required. 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 contained within the caller's range.

+ +
+

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

rangeRange

Required. A range to compare with

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

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

+ +
+

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

+ +

Arguments

rowNumber

Required. A new row to extend to

+
columnNumber

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

startRange

Required. A starting point to use

+
endRange

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

rowNumber

Required. A row point to compare with

+
columnNumber

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

rowNumber

Required. A row point to compare with

+
columnNumber

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

rowNumber

Required. A row point to compare with

+
columnNumber

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

rangeRange

Required. A range to compare with

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Range.isEmpty()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+

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.

+ +
+

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

rowNumber

Required. A row point to compare with

+
columnNumber

Required. A column point to compare with

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

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

+ +
+

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

+ +

Arguments

rangeRange

Required. 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 same as column.

+ +
+

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

rowNumber

Required. A row point to compare with

+
columnNumber

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

rowNumber

Required. A row point to set

+
columnNumber

Required. A column point to set

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

Sets the starting row and column for the range.

+ +
+

Sets the starting row and column for the range.

+ +

Arguments

rowNumber

Required. A row point to set

+
columnNumber

Required. A column point to set

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

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

+ +
+

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

+ +

Arguments

sessionEditSession

Required. The EditSession to retrieve coordinates from

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Range.toString() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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

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

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/renderloop.html b/api/renderloop.html new file mode 100644 index 00000000..59c98a0c --- /dev/null +++ b/api/renderloop.html @@ -0,0 +1,55 @@ + +
+
+
+
+
+

RenderLoop +

+ +
+
+
+
+

Batches changes (that force something to be redrawn) in the background.

+ +
+
+
+
+ + + + + +
+
\ 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..7a90b4c3 --- /dev/null +++ b/api/resources/csses/ace_api.css @@ -0,0 +1,912 @@ +/* + Generic "affects everything" stuff +*/ + +#wrapper .content .column2 { + float: none; +} + +#documentation ul { + font-size: 13px; +} + +#documentation li { + color: black; +} + +pre { + background-color: #FFFFFF; +} + +code { + font-size: 12px; + line-height: 16px; + font-family: 'Ubuntu Mono',Monaco,Consolas,monospace !important; + background-color: #F9F9F9; + border-radius: 3px 3px 3px 3px; + display: inline-block; + padding: 0 4px; + margin: 2px 1px; + color: inherit; +} + +#documentation 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; +} + +#documentation pre code { + background-color: transparent; + border-radius: none; + box-shadow: none; +} + +#documentation a code { + color: #00438a; +} + +#documentation h2 { + font-size: 26px; +} +#documentation p { + font-size: 13px; +} +#documentation li p:last-child { + margin-bottom : 5px; +} + +#documentation 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 .nav > li > a { + padding: 10px 15px 11px; +} + +.navbar { + text-align:center; +} + +#topSection { + width: 1000px; +} +.small_win #topSection { + width: 100%; +} +.small_win #topSection .dropdown { + margin-right: 40%; +} +.navbar .brand { + margin-left: 0px; +} +.brand { + background: transparent url(../images/ace_logo_menu.png) no-repeat 33px 5px; + width: 80px; + 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; +} + +.headerTitle { + position: relative; + top: 100px; + left: 250px; +} + +/* + Menu venue +*/ + + +h3.api_title { + padding-top: 10px; +} + +ul.menu { + margin-left: 2px; +} + +.menu li { + list-style-image: url(../images/menu_disc.png); + margin-bottom: 4px; + font-weight: 700; + padding-left: 10px; + margin-left: 0; +} + +.menu li .menu-item a.menuLink, .menu li .menu-item span.menuLink { + color: #3E7096; + font-weight: 100; +} +.menuTwo { + margin-bottom: 5px; + margin-top: 2px; +} +.menuTwo li .menu-item a.menuLink { + color: #3E7096; + font-weight: 100; +} + +/* 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 +*/ + +.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;*/ + 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; + padding-right: 10px; + margin-right: -5px; + /*width: 700px;*/ +} +.srolledHeader .membersContent { + line-height: 3; +} +.srolled .membersContent { + /*top : 0;*/ + width: 625px; + padding-left: 327px; + margin : 0 auto 0 auto; +} + +.srolled ul.nav { + padding-right: 10px; +} + +.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; + +} + +ul.tabs li:first-child ul{ + left: -63px; +} + +.tabs a.menu:after, .tabs .dropdown-toggle:after { + margin-top: 22px; +} + +.nav .dropdown-toggle .caret { + margin-top: 12px; + border-top-color: #6D8CA0; + border-bottom-color: #6D8CA0; +} + +li.dropdown { + color: #2D2D2D; + font-weight: bold; +} + +.editInC9 { + font-size: 11px; + color: #657383; +} + +.editInC9 a { + color: #657383; + font-weight: normal; + position : relative; + top : -2px; +} + +.tabs { + padding-top: 14px; + /*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; +} + +.memberLink a { + margin-left: 0 !important; +} +.menu-dropdown { + 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; +} + +.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; + left: 10px; + width: 160px; +} +.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") +*/ + +#nonFooter { + padding-top: 40px; +} +#wrapper { + height: 100%; +} + +.content { + height: 100%; +} + +header.filler { + position: relative; + height: 40px; + width: 100%; +} + +/* +.container-fluid .row-fluid { + width: 1000px; + margin-left: auto; + margin-right: auto; +}*/ + +.divider { + height: 3px; + background-color: #BEDAEA; + margin-bottom: 3px; +} + +#sidebar h3 a, +#sidebar h3 a:hover { + color: #404040; +} + +#sidebarContainer { + padding-top: 20px; +} + +#mainContent { + margin-left: 30px; +} + +#documentation { + padding-top: 35px; + padding-bottom: 10px; +} + +#documentation article.article { + border-top: 1px solid #e9e9e9; + padding: 16px 10px 2px; + -webkit-transition: padding 0.2s; + -moz-transition: padding 0.2s; + -o-transition: padding 0.2s; +} + +#documentation h3.sectionHeader + article.article { + border-top: none; +} + +div#documentation article:last-child { + border-bottom: 1px solid #e9e9e9; + padding-bottom: 40px; +} +#documentation article.article.methodToggleOpen { + background: rgba(255, 255, 255, 0.5); + 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; +} + +#documentation .signature-call a { + color: #8e487e; +} + +.sigClassName { + display: none; +} + +.eventObjName { + font-style: italic; +} +.eventListenerStart, .eventListenerClose, .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; +} + +.undocumented { + background-color: #B94A48; + color: #ffffff; +} + +#documentation .alias a, #documentation .related-to a { + color: #ffffff; + /* text-decoration: underline; */ +} +#documentation .alias a:hover, #documentation .related-to a:hover { + text-decoration: none; +} +.#documentation alias:hover, #documentation .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 { + padding-top: 10px; + font-size: 18px; + 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; +} + +.argument-list { + margin-bottom : 13px; +} +.argName { + font-style: italic; +} + + +/* + Everyday I'm togglin' +*/ + +#documentation i.methodToggle { + cursor: pointer; + color: #9f9f9f; + padding-top: 2px; + float: left; +} +#documentation i.methodToggle.methodToggleHover { + text-shadow: 0 0 10px #4699d5; + color: #4699d5; +} +#documentation i.methodToggle.active { + text-shadow: 0 0 10px #4699d5; + color: #4699d5; + /* Safari */ + -webkit-transform: rotate(45deg); + + /* Firefox */ + -moz-transform: rotate(45deg); + + /* IE */ + -ms-transform: rotate(45deg); + + /* Opera */ + -o-transform: rotate(45deg); + padding-top: 9px; +} + +#documentation h3.sectionHeader { + 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 { + width:100%; + background: #101010 url(../images/dashed_back.png) repeat 0 0; + font-size: 12px; + color: white; + height: 40px; +} +#footer .footerInner { + padding-left: 300px; + margin-left: auto; + margin-right: auto; + min-height: 40px; +} +#footer .footer-text { + display: block; + font-size: 12px; + float: right; +} +#footer div.footerInner div.footer-text p { + font-size: 12px; + font-family: Arial; + line-height: 18px; + margin: 10px 15px 0px 1px; +} + +#footer a, #footer a:hover { + color: #8DD0FF; +} + +.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; +} diff --git a/api/resources/font/fontawesome-webfont.eot b/api/resources/font/fontawesome-webfont.eot new file mode 100644 index 00000000..89070c1e Binary files /dev/null and b/api/resources/font/fontawesome-webfont.eot differ diff --git a/api/resources/font/fontawesome-webfont.svg b/api/resources/font/fontawesome-webfont.svg new file mode 100644 index 00000000..1245f92c --- /dev/null +++ b/api/resources/font/fontawesome-webfont.svg @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/resources/font/fontawesome-webfont.ttf b/api/resources/font/fontawesome-webfont.ttf new file mode 100644 index 00000000..c17e9f8d Binary files /dev/null and b/api/resources/font/fontawesome-webfont.ttf differ diff --git a/api/resources/font/fontawesome-webfont.woff b/api/resources/font/fontawesome-webfont.woff new file mode 100644 index 00000000..09f2469a Binary files /dev/null and b/api/resources/font/fontawesome-webfont.woff differ diff --git a/api/resources/images/Ace_ERD.png b/api/resources/images/Ace_ERD.png new file mode 100644 index 00000000..78fb8dab Binary files /dev/null and b/api/resources/images/Ace_ERD.png differ 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/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/bbq.js b/api/resources/javascripts/bbq.js new file mode 100644 index 00000000..bcbf2483 --- /dev/null +++ b/api/resources/javascripts/bbq.js @@ -0,0 +1,18 @@ +/* + * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010 + * http://benalman.com/projects/jquery-bbq-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ +(function($,p){var i,m=Array.prototype.slice,r=decodeURIComponent,a=$.param,c,l,v,b=$.bbq=$.bbq||{},q,u,j,e=$.event.special,d="hashchange",A="querystring",D="fragment",y="elemUrlAttr",g="location",k="href",t="src",x=/^.*\?|#.*$/g,w=/^.*\#/,h,C={};function E(F){return typeof F==="string"}function B(G){var F=m.call(arguments,1);return function(){return G.apply(this,F.concat(m.call(arguments)))}}function n(F){return F.replace(/^[^#]*#?(.*)$/,"$1")}function o(F){return F.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function f(H,M,F,I,G){var O,L,K,N,J;if(I!==i){K=F.match(H?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/);J=K[3]||"";if(G===2&&E(I)){L=I.replace(H?w:x,"")}else{N=l(K[2]);I=E(I)?l[H?D:A](I):I;L=G===2?I:G===1?$.extend({},I,N):$.extend({},N,I);L=a(L);if(H){L=L.replace(h,r)}}O=K[1]+(H?"#":L||!K[1]?"?":"")+L+J}else{O=M(F!==i?F:p[g][k])}return O}a[A]=B(f,0,o);a[D]=c=B(f,1,n);c.noEscape=function(G){G=G||"";var F=$.map(G.split(""),encodeURIComponent);h=new RegExp(F.join("|"),"g")};c.noEscape(",/");$.deparam=l=function(I,F){var H={},G={"true":!0,"false":!1,"null":null};$.each(I.replace(/\+/g," ").split("&"),function(L,Q){var K=Q.split("="),P=r(K[0]),J,O=H,M=0,R=P.split("]["),N=R.length-1;if(/\[/.test(R[0])&&/\]$/.test(R[N])){R[N]=R[N].replace(/\]$/,"");R=R.shift().split("[").concat(R);N=R.length-1}else{N=0}if(K.length===2){J=r(K[1]);if(F){J=J&&!isNaN(J)?+J:J==="undefined"?i:G[J]!==i?G[J]:J}if(N){for(;M<=N;M++){P=R[M]===""?O.length:R[M];O=O[P]=M').hide().insertAfter("body")[0].contentWindow;q=function(){return a(n.document[c][l])};o=function(u,s){if(u!==s){var t=n.document;t.open().close();t[c].hash="#"+u}};o(a())}}m.start=function(){if(r){return}var t=a();o||p();(function s(){var v=a(),u=q(t);if(v!==t){o(t=v,u);$(i).trigger(d)}else{if(u!==t){i[c][l]=i[c][l].replace(/#.*/,"")+"#"+u}}r=setTimeout(s,$[d+"Delay"])})()};m.stop=function(){if(!n){r&&clearTimeout(r);r=0}};return m})()})(jQuery,this); \ No newline at end of file diff --git a/api/resources/javascripts/bootstrap.js b/api/resources/javascripts/bootstrap.js new file mode 100644 index 00000000..79241e74 --- /dev/null +++ b/api/resources/javascripts/bootstrap.js @@ -0,0 +1,389 @@ +/* ============================================================ + * bootstrap-dropdown.js v2.1.1 + * 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"; // jshint ;_; + + + /* 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) + , $parent + , isActive + + if ($this.is('.disabled, :disabled')) return + + $parent = getParent($this) + + isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + $parent.toggleClass('open') + $this.focus() + } + + return false + } + + , keydown: function (e) { + var $this + , $items + , $active + , $parent + , isActive + , index + + if (!/(38|40|27)/.test(e.keyCode)) return + + $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + $parent = getParent($this) + + isActive = $parent.hasClass('open') + + if (!isActive || (isActive && e.keyCode == 27)) return $this.click() + + $items = $('[role=menu] li:not(.divider) a', $parent) + + if (!$items.length) return + + index = $items.index($items.filter(':focus')) + + if (e.keyCode == 38 && index > 0) index-- // up + if (e.keyCode == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items + .eq(index) + .focus() + } + + } + + function clearMenus() { + getParent($(toggle)) + .removeClass('open') + } + + function getParent($this) { + var selector = $this.attr('data-target') + , $parent + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = $(selector) + $parent.length || ($parent = $this.parent()) + + return $parent + } + + + /* 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 touchstart.dropdown.data-api', clearMenus) + $('body') + .on('click.dropdown touchstart.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.dropdown.data-api touchstart.dropdown.data-api' , toggle, Dropdown.prototype.toggle) + .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown) + }) + +}(window.jQuery); +/* ======================================================== + * bootstrap-tab.js v2.1.1 + * http://twitter.github.com/bootstrap/javascript.html#tabs + * ======================================================== + * 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"; // jshint ;_; + + + /* TAB CLASS DEFINITION + * ==================== */ + + var Tab = function (element) { + this.element = $(element) + } + + Tab.prototype = { + + constructor: Tab + + , show: function () { + var $this = this.element + , $ul = $this.closest('ul:not(.dropdown-menu)') + , selector = $this.attr('data-target') + , previous + , $target + , e + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + if ( $this.parent('li').hasClass('active') ) return + + previous = $ul.find('.active a').last()[0] + + e = $.Event('show', { + relatedTarget: previous + }) + + $this.trigger(e) + + if (e.isDefaultPrevented()) return + + $target = $(selector) + + this.activate($this.parent('li'), $ul) + this.activate($target, $target.parent(), function () { + $this.trigger({ + type: 'shown' + , relatedTarget: previous + }) + }) + } + + , activate: function ( element, container, callback) { + var $active = container.find('> .active') + , transition = callback + && $.support.transition + && $active.hasClass('fade') + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + + element.addClass('active') + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') + } else { + element.removeClass('fade') + } + + if ( element.parent('.dropdown-menu') ) { + element.closest('li.dropdown').addClass('active') + } + + callback && callback() + } + + transition ? + $active.one($.support.transition.end, next) : + next() + + $active.removeClass('in') + } + } + + + /* TAB PLUGIN DEFINITION + * ===================== */ + + $.fn.tab = function ( option ) { + return this.each(function () { + var $this = $(this) + , data = $this.data('tab') + if (!data) $this.data('tab', (data = new Tab(this))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.tab.Constructor = Tab + + + /* TAB DATA-API + * ============ */ + + $(function () { + $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { + e.preventDefault() + $(this).tab('show') + }) + }) + +}(window.jQuery); +/* ========================================================== + * bootstrap-affix.js v2.1.1 + * http://twitter.github.com/bootstrap/javascript.html#affix + * ========================================================== + * 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"; // jshint ;_; + + + /* AFFIX CLASS DEFINITION + * ====================== */ + + var Affix = function (element, options) { + this.options = $.extend({}, $.fn.affix.defaults, options) + this.$window = $(window).on('scroll.affix.data-api', $.proxy(this.checkPosition, this)) + this.$element = $(element) + this.checkPosition() + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var scrollHeight = $(document).height() + , scrollTop = this.$window.scrollTop() + , position = this.$element.offset() + , offset = this.options.offset + , offsetBottom = offset.bottom + , offsetTop = offset.top + , reset = 'affix affix-top affix-bottom' + , affix + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top() + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom() + + affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? + false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? + 'bottom' : offsetTop != null && scrollTop <= offsetTop ? + 'top' : false + + if (this.affixed === affix) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? position.top - scrollTop : null + + this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : '')) + } + + + /* AFFIX PLUGIN DEFINITION + * ======================= */ + + $.fn.affix = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('affix') + , options = typeof option == 'object' && option + if (!data) $this.data('affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.affix.Constructor = Affix + + $.fn.affix.defaults = { + offset: 0 + } + + + /* AFFIX DATA-API + * ============== */ + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + , data = $spy.data() + + data.offset = data.offset || {} + + data.offsetBottom && (data.offset.bottom = data.offsetBottom) + data.offsetTop && (data.offset.top = data.offsetTop) + + $spy.affix(data) + }) + }) + + +}(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..90e7e12c --- /dev/null +++ b/api/resources/javascripts/clicker.js @@ -0,0 +1,69 @@ +function setupClicker() { + // when hovering over arrow, add highlight (only if inactive) + $("i.methodToggle").hover(function () { + if (!$("i.methodToggle").hasClass('active')) + $(this).addClass("methodToggleHover"); + }, + function () { + $(this).removeClass("methodToggleHover"); + } + ); + + function handleClick(e, linkHref) { + //if (linkHref.indexOf("nav=api&api=") >= 0) + // return; + if (linkHref == "api") + return; + + e.preventDefault(); + + var dstElem; + if (linkHref) { + dstElem = $("article[id='" + linkHref + "']"); + } + + var $article = (dstElem || $(this)).closest('.article'), + $arrow = $('i.methodClicker', $article); + + if (!$article.hasClass('methodToggleOpen') || this.force) { + $article.addClass('methodToggleOpen'); + $arrow.removeClass('inactive').addClass('active'); + + if (!$arrow[0]) + return; + + var data = $arrow[0].id.replace(/^js_/, ""); + //var state = {}; + //state.section = data; + //$.bbq.pushState(state); + + scrollTo(null, data); + } + else { + $article.removeClass('methodToggleOpen'); + $arrow.removeClass('active').addClass('inactive'); + } + } + + function transformHash(e) { + // some bs to figure out link hash + var hashId = (e.srcElement ? e.srcElement.href : (e.hash || e.target.href)) || e.currentTarget.hash; + + handleClick(e, hashId.substring(hashId.indexOf("#") + 1)); + } + + // for the arrow + $("i.methodToggle").click(handleClick); + + // for the signature + $('.member-name').click(handleClick); + + // for the top dropdown + $('li.memberLink a').click(transformHash); + + //$('a[href^="#"]').click(transformHash); + + $('.related-to', '.metaInfo').click(function(){ + location.hash = $(this).find('a').attr('href').split('#')[1]; + }); +} \ No newline at end of file diff --git a/api/resources/javascripts/disqus-ext.js b/api/resources/javascripts/disqus-ext.js new file mode 100644 index 00000000..6bb7ff4e --- /dev/null +++ b/api/resources/javascripts/disqus-ext.js @@ -0,0 +1,17 @@ +function setupDisqus(href) { + var disqus_shortname = 'aceapi'; + + //var paths = window.location.pathname.split("/"); + //var fileName = paths[paths.length - 2] + "/" + paths[paths.length - 1]; + + //var disqus_identifier = fileName; + var disqus_identifier = href.substring(2); + + (function() { + if (document.getElementById("disqusScript") === null) { + 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/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/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 1010) sx = 1010 - document.documentElement.offsetWidth;
+    }
+    else sx = 0;
+
+    $('span.methodClicker, article.article, i.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);
+    });
+    
+    function showMethodContent() {
+        var locationHash = location.hash.replace(/^#/, '').replace(/\./g, '\\.');
+        var equalsPos = location.hash.indexOf("=");
+        
+        if (equalsPos >=0) {
+            locationHash = locationHash.substring(0, location.hash.indexOf("="));
+        }
+        
+        var $clickerEl = $('span#' + locationHash);
+        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.indexOf("section") >= 1) {
+        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..5f311060
--- /dev/null
+++ b/api/scrollbar.html
@@ -0,0 +1,261 @@
+
+
+
+
+
+
+

ScrollBar +

+ +
+
+
+
+

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

parentDOMElement

Required. A DOM element

+
+
+
+
+
+
+

Events

+
+
+
+
+
    +
  • +
      +
    • ScrollBar.on("scroll", function(Object e))
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the scroll bar, well, scrolls.

+ +
+

Emitted when the scroll bar, well, scrolls.

+ +

Arguments

eObject

Required. Contains one property, "data", which indicates the current scroll top position

+
+
+
+
+
+
+

Methods

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

Returns the width of the scroll bar.

+ +
+

Returns the width of the scroll bar.

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

Sets the height of the scroll bar, in pixels.

+ +
+

Sets the height of the scroll bar, in pixels.

+ +

Arguments

heightNumber

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

heightNumber

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

scrollTopNumber

Required. 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..61616063 --- /dev/null +++ b/api/search.html @@ -0,0 +1,295 @@ + +
+
+
+
+
+

Search +

+ +
+
+
+
+

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

+ +
+
+
+

Constructors

+
+
+
+
+
    +
  • +
      +
    • new Search()
    • +
    +
      +
    +
  • +
+
+
+

Creates a new Search object. The following search options are avaliable:

+ +
+

Creates a new Search object. The following search options are avaliable:

+
    +
  • needle: The string or regular expression you're looking for
  • +
  • backwards: Whether to search backwards from where cursor currently is. Defaults to false.
  • +
  • wrap: Whether to wrap the search back to the beginning when it hits the end. Defaults to false.
  • +
  • caseSensitive: Whether the search ought to be case-sensitive. Defaults to false.
  • +
  • wholeWord: Whether the search matches only on whole words. Defaults to false.
  • +
  • range: The Range to search within. Set this to null for the whole document
  • +
  • regExp: Whether the search is a regular expression or not. Defaults to false.
  • +
  • start: The starting Range or cursor position to begin the search
  • +
  • skipCurrent: Whether or not to include the current line in the search. Default to false.
  • +
+ +
+
+
+
+
+

Methods

+
+
+
+
+ +
+
+

Searches for options.needle. If found, this method returns the Range where the text first occurs. If options.backwards is true, the search goes backwards in the session.

+ +
+

Searches for 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

sessionEditSession

Required. The session to search with

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

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.

+ +
+

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

sessionEditSession

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

inputString

Required. The text to search in

+
replacementString

Required. 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.
  • +
+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    • Chainable
    • +
    +
  • +
+
+
+

Sets the search options via the options parameter.

+ +
+

Sets the search options via the options parameter.

+ +

Arguments

optionsObject

Required. An object containing all the new search properties

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Search.setOptions()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+ + + + + +
+
\ No newline at end of file diff --git a/api/selection.html b/api/selection.html new file mode 100644 index 00000000..4da8f771 --- /dev/null +++ b/api/selection.html @@ -0,0 +1,1781 @@ + +
+
+
+ +
+
+

Contains the cursor position and the text selection of an edit session.

+

The row/columns used in the selection are in document coordinates representing the coordinates as they appear in the document before applying soft wrap and folding.

+ +
+
+
+

Constructors

+
+
+
+
+ +
+
+

Creates a new Selection object.

+ +
+

Creates a new Selection object.

+ +

Arguments

sessionEditSession

Required. The session to use

+
+
+
+
+
+
+

Events

+
+
+
+
+
    +
  • +
      +
    • Selection.on("changeCursor", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the cursor position changes.

+ +
+

Emitted when the cursor position changes.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.on("changeSelection", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the cursor selection changes.

+ +
+

Emitted when the cursor selection changes.

+ +
+
+
+
+
+

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

rangeRange

Required. The new range to add

+
$blockChangeEventsBoolean

Required. Whether or not to block changing events

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.clearSelection()
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.detach()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.fromOrientedRange()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.getAllRanges() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns a concatenation of all the ranges.

+ +
+

Returns a concatenation of all the ranges.

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

Gets the current position of the cursor.

+ +
+

Gets the current position of the cursor.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.getLineRange()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.getRange() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the Range for the selected text.

+ +
+

Returns the Range for the selected text.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.getSelectionAnchor() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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.

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

Moves the selection to highlight the entire word.

+ +
+

Moves the selection to highlight the entire word.

+ +

Arguments

rowObject

Required.

+
columnObject

Required.

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

rowsNumber

Required. The number of rows to move by

+
charsNumber

Required. 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.moveCursorLongWordLeft()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor to the word on the left.

+ +
+

Moves the cursor to the word on the left.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorLongWordRight()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor to the word on the right.

+ +
+

Moves the cursor to the word on the right.

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

Moves the cursor right one column.

+ +
+

Moves the cursor right one column.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorShortWordLeft()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorShortWordRight()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+

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.

+ +
+

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.

+ +

Arguments

rowNumber

Required. The row to move to

+
columnNumber

Required. The column to move to

+
keepDesiredColumnBoolean

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

positionObject

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

rowNumber

Required. The row to move to

+
columnNumber

Required. The column to move to

+
keepDesiredColumnBoolean

Required. 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()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorWordRight()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • 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

+ +

Arguments

screenCursorCursor

Required. The cursor to use

+
screenAnchorAnchor

Required. The anchor to use

+
includeEmptyLinesBoolean

Required. If true, this includes ranges inside the block which are empty due to clipping

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectAll()
    • +
    +
      +
    +
  • +
+
+
+

Selects all the text in the document.

+ +
+

Selects all the text in the document.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectAWord()
    • +
    +
      +
    +
  • +
+
+
+

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

rowNumber

Required. The row to select to

+
columnNumber

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

posObject

Required. An object containing the row and column

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectUp()
    • +
    +
      +
    +
  • +
+
+
+

Moves the selection up one row.

+ +
+

Moves the selection up one row.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectWord()
    • +
    +
      +
    +
  • +
+
+
+

Selects an entire word boundary.

+ +
+

Selects an entire word boundary.

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

rowNumber

Required. The new row

+
columnNumber

Required. The new column

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.setSelectionRange(Range range, Boolean reverse)
    • +
    +
      +
    +
  • +
+
+
+

Sets the selection to the provided range.

+ +
+

Sets the selection to the provided range.

+ +

Arguments

rangeRange

Required. The range of text to select

+
reverseBoolean

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

columnsNumber

Required. The number of columns to shift by

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.splitIntoLines()
    • +
    +
      +
    +
  • +
+
+
+

Splits all the ranges into lines.

+ +
+

Splits all the ranges into lines.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.substractPoint(Range pos)
    • +
    +
      +
    +
  • +
+
+
+

Removes a Range containing pos (if it exists).

+ +
+

Removes a Range containing pos (if it exists).

+ +

Arguments

posRange

Required. The position to remove, as a {row, column} object

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.toggleBlockSelection()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.toOrientedRange()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.toSingleRange()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+ + + + + +
+
diff --git a/api/split.html b/api/split.html new file mode 100644 index 00000000..fd75edce --- /dev/null +++ b/api/split.html @@ -0,0 +1,640 @@ + +
+
+
+
+
+

Split +

+ +
+
+
+
+

Methods

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

Blurs the current editor.

+ +
+

Blurs the current editor.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.execute()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.focus()
    • +
    +
      +
    +
  • +
+
+
+

Focuses the current editor.

+ +
+

Focuses the current editor.

+ +
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+

Arguments

callbackFunction

Required. A callback function to execute

+
scopeString

Required. The default scope for the callback

+

Executes callback on all of the available editors.

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

Returns the current editor.

+ +
+

Returns the current editor.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.getEditor(Number idx)
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+

Arguments

idxNumber

Required. The index of the editor you want

+

Returns the editor identified by the index idx.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.getOrientation() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the orientation.

+ +
+

Returns the orientation.

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

Returns the number of splits.

+ +
+

Returns the number of splits.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.hasRedo()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.hasUndo()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.redo()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.reset()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.resize()
    • +
    +
      +
    +
  • +
+
+
+

Resizes the editor.

+ +
+

Resizes the editor.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.setFontSize(Number size)
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+

Arguments

sizeNumber

Required. The new font size

+

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

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.setKeyboardHandler(String keybinding)
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+

Arguments

keybindingString

Required. Sets the keyboard handler for the editor.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.setOrientation(Number orientation)
    • +
    +
      +
    +
  • +
+
+
+

Sets the orientation.

+ +
+

Sets the orientation.

+ +

Arguments

orientationNumber

Required. The new orientation value

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

Arguments

sessionEditSession

Required. The new edit session

+
idxNumber

Required. The editor's index you're interested in

+

Sets a new EditSession for the indicated editor.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.setSplits()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.setTheme(String theme)
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+

Arguments

themeString

Required. The name of the theme to set

+

Sets a theme for each of the available editors.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.undo()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Split.UndoManagerProxy()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+ + + + + +
+
\ No newline at end of file diff --git a/api/token_iterator.html b/api/token_iterator.html new file mode 100644 index 00000000..7c025da0 --- /dev/null +++ b/api/token_iterator.html @@ -0,0 +1,248 @@ + +
+
+
+
+
+

TokenIterator +

+ +
+
+
+
+

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

sessionEditSession

Required. The session to associate with

+
initialRowNumber

Required. The row to start the tokenizing at

+
initialColumnNumber

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

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • TokenIterator.stepForward() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+

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..b45bd58d --- /dev/null +++ b/api/tokenizer.html @@ -0,0 +1,122 @@ + +
+
+
+
+
+

Tokenizer +

+ +
+
+ +

Constructors

+
+
+
+
+ +
+
+

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

+ +
+

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

+ +

Arguments

rulesObject

Required. The highlighting rules

+
flagString

Required. Any additional regular expression flags to pass (like "i" for case insensitive)

+
+
+
+
+
+
+

Methods

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

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.

+ +

Arguments

lineObject

Required.

+
startStateObject

Required.

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

UndoManager +

+ +
+
+
+
+

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

Provides a means for implementing your own undo manager. options has one property, args, an Array, with two elements:

+ +
+

Provides a means for implementing your own undo manager. options has one property, args, an Array, with two elements:

+
    +
  • args[0] is an array of deltas
  • +
  • args[1] is the document to associate with
  • +
+ +

Arguments

optionsObject

Required. 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)
    • +
    +
      +
    +
  • +
+
+
+

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

+ +
+

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

+ +

Arguments

dontSelectBoolean

Required. If true, doesn't select the range of where the change occured

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • UndoManager.reset()
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+

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

+ +

Arguments

dontSelectBoolean

Required. 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..952e6ae6 --- /dev/null +++ b/api/virtual_renderer.html @@ -0,0 +1,2190 @@ + +
+
+
+
+
+

VirtualRenderer +

+ +
+
+
+
+

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

containerDOMElement

Required. The root element of the editor

+
themeString

Required. The starting theme

+
+
+
+
+
+
+

Methods

+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer._loadTheme()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.addGutterDecoration(Object row, Object className)
    • +
    +
      +
    +
  • +
+
+
+

Deprecated; (moved to EditSession)

+ +
+

Deprecated; (moved to EditSession)

+ +

Arguments

rowObject

Required.

+
classNameObject

Required.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.adjustWrapLimit()
    • +
    +
      +
    +
  • +
+
+
+

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.alignCursor()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.animateScrolling()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • 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.getDisplayIndentGuides()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getFadeFoldWidgets()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getFirstFullyVisibleRow() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the index of the first fully visible row. "Fully" here means that the characters in the row are not truncated; that the top and the bottom of the row are on the screen.

+ +
+

Returns the index of the 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.getHighlightGutterLine()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • 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; that the top and the bottom of the row are on the screen.

+ +
+

Returns the index of the last fully visible row. "Fully" here means that the characters in the row are not truncated; 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.

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

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getScrollTop() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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 whether the print margin is being shown or not.

+ +
+

Returns whether the 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()
    • +
    +
      +
    +
  • +
+
+
+

Hides the current composition.

+ +
+

Hides the current composition.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.hideCursor()
    • +
    +
      +
    +
  • +
+
+
+

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 or line.

+ +
+

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

deltaXNumber

Required. The x value to scroll by

+
deltaYNumber

Required. The y value to scroll by

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.onChangeTabSize()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.onGutterResize()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+

Triggers a resize of the editor.

+ +
+

Triggers a resize of the editor.

+ +

Arguments

forceBoolean

Required. If true, recomputes the size, even if the height and width haven't changed

+
gutterWidthNumber

Required. The width of the gutter in pixels

+
widthNumber

Required. The width of the editor in pixels

+
heightNumber

Required. The hiehgt of the editor, in pixels

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.pixelToScreenCoordinates()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.removeGutterDecoration(Object row, Object className)
    • +
    +
      +
    +
  • +
+
+
+

Deprecated; (moved to EditSession)

+ +
+

Deprecated; (moved to EditSession)

+ +

Arguments

rowObject

Required.

+
classNameObject

Required.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.screenToTextCoordinates()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.scrollBy(Number deltaX, Number deltaY)
    • +
    +
      +
    +
  • +
+
+
+

Scrolls the editor across both x- and y-axes.

+ +
+

Scrolls the editor across both x- and y-axes.

+ +

Arguments

deltaXNumber

Required. The x value to scroll by

+
deltaYNumber

Required. The y value to scroll by

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.scrollCursorIntoView(Object cursor, Object offset)
    • +
    +
      +
    +
  • +
+
+
+

Scrolls the cursor into the first visibile area of the editor

+ +
+

Scrolls the cursor into the first visibile area of the editor

+ +

Arguments

cursorObject

Required.

+
offsetObject

Required.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.scrollSelectionIntoView()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+

Gracefully scrolls the editor to the row indicated.

+ +
+

Gracefully scrolls the editor to the row indicated.

+ +

Arguments

lineNumber

Required. A line number

+
centerBoolean

Required. If true, centers the editor the to indicated line

+
animateBoolean

Required. If true animates scrolling

+
callbackFunction

Required. Function to be called after the animation has finished

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.scrollToRow(Number row)
    • +
    +
      +
    +
  • +
+
+
+

Gracefully scrolls from the top of the editor to the row indicated.

+ +
+

Gracefully scrolls from the top of the editor to the row indicated.

+ +

Arguments

rowNumber

Required. A row id

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.scrollToX(Number scrollLeft) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Scrolls the editor across the x-axis to the pixel indicated.

+ +
+

Scrolls the editor across the x-axis to the pixel indicated.

+ +

Arguments

scrollLeftNumber

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

scrollTopNumber

Required. The position to scroll to

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setAnimatedScroll(Boolean shouldAnimate)
    • +
    +
      +
    +
  • +
+
+
+

Identifies whether you want to have an animated scroll or not.

+ +
+

Identifies whether you want to have an animated scroll or not.

+ +

Arguments

shouldAnimateBoolean

Required. Set to true to show animated scrolls

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setAnnotations(Array annotations)
    • +
    +
      +
    +
  • +
+
+
+

Sets annotations for the gutter.

+ +
+

Sets annotations for the gutter.

+ +

Arguments

annotationsArray

Required. An array containing annotations

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setCompositionText(String text)
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+

Arguments

textString

Required. A string of text to use

+

Sets the inner text of the current composition to text.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setDisplayIndentGuides()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setFadeFoldWidgets()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setHighlightGutterLine()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setHScrollBarAlwaysVisible(Boolean alwaysVisible)
    • +
    +
      +
    +
  • +
+
+
+

Identifies whether you want to show the horizontal scrollbar or not.

+ +
+

Identifies whether you want to show the horizontal scrollbar or not.

+ +

Arguments

alwaysVisibleBoolean

Required. Set to true to make the horizontal scroll bar visible

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setPadding(Number padding)
    • +
    +
      +
    +
  • +
+
+
+

Sets the padding for all the layers.

+ +
+

Sets the padding for all the layers.

+ +

Arguments

paddingNumber

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

showPrintMarginBoolean

Required. Set to true to show the print margin column

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setSession(Object session)
    • +
    +
      +
    +
  • +
+
+
+

Associates the renderer with an EditSession.

+ +
+

Associates the renderer with an EditSession.

+ +

Arguments

sessionObject

Required.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setShowGutter(Boolean show)
    • +
    +
      +
    +
  • +
+
+
+

Identifies whether you want to show the gutter or not.

+ +
+

Identifies whether you want to show the gutter or not.

+ +

Arguments

showBoolean

Required. Set to true to show the gutter

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setShowInvisibles(Boolean showInvisibles)
    • +
    +
      +
    +
  • +
+
+
+

Identifies whether you want to show invisible characters or not.

+ +
+

Identifies whether you want to show invisible characters or not.

+ +

Arguments

showInvisiblesBoolean

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

showPrintMarginBoolean

Required. Set to true to show the print margin

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setStyle()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setTheme(String 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.

+ +

Arguments

themeString

Required. The path to a theme

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.showCursor()
    • +
    +
      +
    +
  • +
+
+
+

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

rowNumber

Required. The document row position

+
columnNumber

Required. The document column position

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.unsetStyle(String style)
    • +
    +
      +
    +
  • +
+
+
+

Removes the class style from the editor.

+ +
+

Removes the class style from the editor.

+ +

Arguments

styleString

Required. A class name

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateBackMarkers()
    • +
    +
      +
    +
  • +
+
+
+

Schedules an update to all the back markers in the document.

+ +
+

Schedules an update to all the back markers in the document.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateBreakpoints(Object rows)
    • +
    +
      +
    +
  • +
+
+
+

Redraw breakpoints.

+ +
+

Redraw breakpoints.

+ +

Arguments

rowsObject

Required.

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateCharacterSize()
    • +
    +
      +
    • Undocumented
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateCursor()
    • +
    +
      +
    +
  • +
+
+
+

Updates the cursor icon.

+ +
+

Updates the cursor icon.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateFontSize()
    • +
    +
      +
    +
  • +
+
+
+

Updates the font size.

+ +
+

Updates the font size.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateFrontMarkers()
    • +
    +
      +
    +
  • +
+
+
+

Schedules an update to all the front markers in the document.

+ +
+

Schedules an update to all the front markers in the document.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateFull(Boolean force)
    • +
    +
      +
    +
  • +
+
+
+

Triggers a full update of all the layers, for all the rows.

+ +
+

Triggers a full update of all the layers, for all the rows.

+ +

Arguments

forceBoolean

Required. If true, forces the changes through

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateLines(Number firstRow, Number lastRow)
    • +
    +
      +
    +
  • +
+
+
+

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

firstRowNumber

Required. The first row to update

+
lastRowNumber

Required. The last row to update

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateText()
    • +
    +
      +
    +
  • +
+
+
+

Triggers a full update of the text, for all the rows.

+ +
+

Triggers a full update of the text, for all the rows.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.visualizeBlur()
    • +
    +
      +
    +
  • +
+
+
+

Blurs the current container.

+ +
+

Blurs the current container.

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.visualizeFocus()
    • +
    +
      +
    +
  • +
+
+
+

Focuses the current container.

+ +
+

Focuses the current container.

+ +
+
+
+
+
+
+ + + + + +
+
\ No newline at end of file diff --git a/build b/build new file mode 160000 index 00000000..a4e495d8 --- /dev/null +++ b/build @@ -0,0 +1 @@ +Subproject commit a4e495d8901876c6bafe3870a35cb8e32c827e97 diff --git a/build/ChangeLog.txt b/build/ChangeLog.txt deleted file mode 100644 index 9eb65941..00000000 --- a/build/ChangeLog.txt +++ /dev/null @@ -1,50 +0,0 @@ -2011.02.14, Version 0.1.6 - -* Floating Anchors - - 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 - - Usesd for the cursor and selection - - Basis for bookmarks, multiple cursors and snippets in the future -* Extensive support for Cocoa style keybindings on the Mac -* New commands: - - center selection in viewport - - remove to end/start of line - - split line - - transpose letters -* Refator markers - - Custom code can be used to render markers - - Markers can be in front or behind the text - - Markers are now stored in the session (was in the renderer) -* Lots of IE8 fixes including copy, cut and selections -* Unit tests can also be run in the browser -* Soft wrap can adapt to the width of the editor (Mike Ratcliffe, Joe Cheng) -* Add minimal node server server.js to run the Ace demo in Chrome -* The top level editor.html demo has been renamed to index.html -* Bug fixes - - Fixed gotoLine to consider wrapped lines when calculating where to scroll to (James Allen) - - Fixed isues when the editor was scrolled in the web page (Eric Allam) - - Highlighting of Python string literals - - Syntax rule for PHP comments - -2011.02.08, Version 0.1.5 - -* Add Coffeescript Mode (Satoshi Murakami) -* Fix word wrap bug (Julian Viereck) -* Fix packaged version of the Eclipse mode -* Loading of workers is more robust -* Fix "click selection" -* Allow tokizing empty lines (Daniel Krech) -* Make PageUp/Down behavior more consistent with native OS (Joe Cheng) - -2011.02.04, Version 0.1.4 - -* Add C/C++ mode contributed by Gastón Kleiman -* Fix exception in key input - -2011.02.04, Version 0.1.3 - -* Let the packaged version play nice with requireJS -* Add Ruby mode contributed by Shlomo Zalman Heigh -* Add Java mode contributed by Tom Tasche -* Fix annotation bug -* Changing a document added a new empty line at the end \ No newline at end of file diff --git a/build/LICENSE b/build/LICENSE deleted file mode 100644 index 853e4fd5..00000000 --- a/build/LICENSE +++ /dev/null @@ -1,476 +0,0 @@ -Licensed under the tri-license MPL/LGPL/GPL. - - MOZILLA PUBLIC LICENSE - Version 1.1 - - --------------- - -1. Definitions. - - 1.0.1. "Commercial Use" means distribution or otherwise making the - Covered Code available to a third party. - - 1.1. "Contributor" means each entity that creates or contributes to - the creation of Modifications. - - 1.2. "Contributor Version" means the combination of the Original - Code, prior Modifications used by a Contributor, and the Modifications - made by that particular Contributor. - - 1.3. "Covered Code" means the Original Code or Modifications or the - combination of the Original Code and Modifications, in each case - including portions thereof. - - 1.4. "Electronic Distribution Mechanism" means a mechanism generally - accepted in the software development community for the electronic - transfer of data. - - 1.5. "Executable" means Covered Code in any form other than Source - Code. - - 1.6. "Initial Developer" means the individual or entity identified - as the Initial Developer in the Source Code notice required by Exhibit - A. - - 1.7. "Larger Work" means a work which combines Covered Code or - portions thereof with code not governed by the terms of this License. - - 1.8. "License" means this document. - - 1.8.1. "Licensable" means having the right to grant, to the maximum - extent possible, whether at the time of the initial grant or - subsequently acquired, any and all of the rights conveyed herein. - - 1.9. "Modifications" means any addition to or deletion from the - substance or structure of either the Original Code or any previous - Modifications. When Covered Code is released as a series of files, a - Modification is: - A. Any addition to or deletion from the contents of a file - containing Original Code or previous Modifications. - - B. Any new file that contains any part of the Original Code or - previous Modifications. - - 1.10. "Original Code" means Source Code of computer software code - which is described in the Source Code notice required by Exhibit A as - Original Code, and which, at the time of its release under this - License is not already Covered Code governed by this License. - - 1.10.1. "Patent Claims" means any patent claim(s), now owned or - hereafter acquired, including without limitation, method, process, - and apparatus claims, in any patent Licensable by grantor. - - 1.11. "Source Code" means the preferred form of the Covered Code for - making modifications to it, including all modules it contains, plus - any associated interface definition files, scripts used to control - compilation and installation of an Executable, or source code - differential comparisons against either the Original Code or another - well known, available Covered Code of the Contributor's choice. The - Source Code can be in a compressed or archival form, provided the - appropriate decompression or de-archiving software is widely available - for no charge. - - 1.12. "You" (or "Your") means an individual or a legal entity - exercising rights under, and complying with all of the terms of, this - License or a future version of this License issued under Section 6.1. - For legal entities, "You" includes any entity which controls, is - controlled by, or is under common control with You. For purposes of - this definition, "control" means (a) the power, direct or indirect, - to cause the direction or management of such entity, whether by - contract or otherwise, or (b) ownership of more than fifty percent - (50%) of the outstanding shares or beneficial ownership of such - entity. - -2. Source Code License. - - 2.1. The Initial Developer Grant. - The Initial Developer hereby grants You a world-wide, royalty-free, - non-exclusive license, subject to third party intellectual property - claims: - (a) under intellectual property rights (other than patent or - trademark) Licensable by Initial Developer to use, reproduce, - modify, display, perform, sublicense and distribute the Original - Code (or portions thereof) with or without Modifications, and/or - as part of a Larger Work; and - - (b) under Patents Claims infringed by the making, using or - selling of Original Code, to make, have made, use, practice, - sell, and offer for sale, and/or otherwise dispose of the - Original Code (or portions thereof). - - (c) the licenses granted in this Section 2.1(a) and (b) are - effective on the date Initial Developer first distributes - Original Code under the terms of this License. - - (d) Notwithstanding Section 2.1(b) above, no patent license is - granted: 1) for code that You delete from the Original Code; 2) - separate from the Original Code; or 3) for infringements caused - by: i) the modification of the Original Code or ii) the - combination of the Original Code with other software or devices. - - 2.2. Contributor Grant. - Subject to third party intellectual property claims, each Contributor - hereby grants You a world-wide, royalty-free, non-exclusive license - - (a) under intellectual property rights (other than patent or - trademark) Licensable by Contributor, to use, reproduce, modify, - display, perform, sublicense and distribute the Modifications - created by such Contributor (or portions thereof) either on an - unmodified basis, with other Modifications, as Covered Code - and/or as part of a Larger Work; and - - (b) under Patent Claims infringed by the making, using, or - selling of Modifications made by that Contributor either alone - and/or in combination with its Contributor Version (or portions - of such combination), to make, use, sell, offer for sale, have - made, and/or otherwise dispose of: 1) Modifications made by that - Contributor (or portions thereof); and 2) the combination of - Modifications made by that Contributor with its Contributor - Version (or portions of such combination). - - (c) the licenses granted in Sections 2.2(a) and 2.2(b) are - effective on the date Contributor first makes Commercial Use of - the Covered Code. - - (d) Notwithstanding Section 2.2(b) above, no patent license is - granted: 1) for any code that Contributor has deleted from the - Contributor Version; 2) separate from the Contributor Version; - 3) for infringements caused by: i) third party modifications of - Contributor Version or ii) the combination of Modifications made - by that Contributor with other software (except as part of the - Contributor Version) or other devices; or 4) under Patent Claims - infringed by Covered Code in the absence of Modifications made by - that Contributor. - -3. Distribution Obligations. - - 3.1. Application of License. - The Modifications which You create or to which You contribute are - governed by the terms of this License, including without limitation - Section 2.2. The Source Code version of Covered Code may be - distributed only under the terms of this License or a future version - of this License released under Section 6.1, and You must include a - copy of this License with every copy of the Source Code You - distribute. You may not offer or impose any terms on any Source Code - version that alters or restricts the applicable version of this - License or the recipients' rights hereunder. However, You may include - an additional document offering the additional rights described in - Section 3.5. - - 3.2. Availability of Source Code. - Any Modification which You create or to which You contribute must be - made available in Source Code form under the terms of this License - either on the same media as an Executable version or via an accepted - Electronic Distribution Mechanism to anyone to whom you made an - Executable version available; and if made available via Electronic - Distribution Mechanism, must remain available for at least twelve (12) - months after the date it initially became available, or at least six - (6) months after a subsequent version of that particular Modification - has been made available to such recipients. You are responsible for - ensuring that the Source Code version remains available even if the - Electronic Distribution Mechanism is maintained by a third party. - - 3.3. Description of Modifications. - You must cause all Covered Code to which You contribute to contain a - file documenting the changes You made to create that Covered Code and - the date of any change. You must include a prominent statement that - the Modification is derived, directly or indirectly, from Original - Code provided by the Initial Developer and including the name of the - Initial Developer in (a) the Source Code, and (b) in any notice in an - Executable version or related documentation in which You describe the - origin or ownership of the Covered Code. - - 3.4. Intellectual Property Matters - (a) Third Party Claims. - If Contributor has knowledge that a license under a third party's - intellectual property rights is required to exercise the rights - granted by such Contributor under Sections 2.1 or 2.2, - Contributor must include a text file with the Source Code - distribution titled "LEGAL" which describes the claim and the - party making the claim in sufficient detail that a recipient will - know whom to contact. If Contributor obtains such knowledge after - the Modification is made available as described in Section 3.2, - Contributor shall promptly modify the LEGAL file in all copies - Contributor makes available thereafter and shall take other steps - (such as notifying appropriate mailing lists or newsgroups) - reasonably calculated to inform those who received the Covered - Code that new knowledge has been obtained. - - (b) Contributor APIs. - If Contributor's Modifications include an application programming - interface and Contributor has knowledge of patent licenses which - are reasonably necessary to implement that API, Contributor must - also include this information in the LEGAL file. - - (c) Representations. - Contributor represents that, except as disclosed pursuant to - Section 3.4(a) above, Contributor believes that Contributor's - Modifications are Contributor's original creation(s) and/or - Contributor has sufficient rights to grant the rights conveyed by - this License. - - 3.5. Required Notices. - You must duplicate the notice in Exhibit A in each file of the Source - Code. If it is not possible to put such notice in a particular Source - Code file due to its structure, then You must include such notice in a - location (such as a relevant directory) where a user would be likely - to look for such a notice. If You created one or more Modification(s) - You may add your name as a Contributor to the notice described in - Exhibit A. You must also duplicate this License in any documentation - for the Source Code where You describe recipients' rights or ownership - rights relating to Covered Code. You may choose to offer, and to - charge a fee for, warranty, support, indemnity or liability - obligations to one or more recipients of Covered Code. However, You - may do so only on Your own behalf, and not on behalf of the Initial - Developer or any Contributor. You must make it absolutely clear than - any such warranty, support, indemnity or liability obligation is - offered by You alone, and You hereby agree to indemnify the Initial - Developer and every Contributor for any liability incurred by the - Initial Developer or such Contributor as a result of warranty, - support, indemnity or liability terms You offer. - - 3.6. Distribution of Executable Versions. - You may distribute Covered Code in Executable form only if the - requirements of Section 3.1-3.5 have been met for that Covered Code, - and if You include a notice stating that the Source Code version of - the Covered Code is available under the terms of this License, - including a description of how and where You have fulfilled the - obligations of Section 3.2. The notice must be conspicuously included - in any notice in an Executable version, related documentation or - collateral in which You describe recipients' rights relating to the - Covered Code. You may distribute the Executable version of Covered - Code or ownership rights under a license of Your choice, which may - contain terms different from this License, provided that You are in - compliance with the terms of this License and that the license for the - Executable version does not attempt to limit or alter the recipient's - rights in the Source Code version from the rights set forth in this - License. If You distribute the Executable version under a different - license You must make it absolutely clear that any terms which differ - from this License are offered by You alone, not by the Initial - Developer or any Contributor. You hereby agree to indemnify the - Initial Developer and every Contributor for any liability incurred by - the Initial Developer or such Contributor as a result of any such - terms You offer. - - 3.7. Larger Works. - You may create a Larger Work by combining Covered Code with other code - not governed by the terms of this License and distribute the Larger - Work as a single product. In such a case, You must make sure the - requirements of this License are fulfilled for the Covered Code. - -4. Inability to Comply Due to Statute or Regulation. - - If it is impossible for You to comply with any of the terms of this - License with respect to some or all of the Covered Code due to - statute, judicial order, or regulation then You must: (a) comply with - the terms of this License to the maximum extent possible; and (b) - describe the limitations and the code they affect. Such description - must be included in the LEGAL file described in Section 3.4 and must - be included with all distributions of the Source Code. Except to the - extent prohibited by statute or regulation, such description must be - sufficiently detailed for a recipient of ordinary skill to be able to - understand it. - -5. Application of this License. - - This License applies to code to which the Initial Developer has - attached the notice in Exhibit A and to related Covered Code. - -6. Versions of the License. - - 6.1. New Versions. - Netscape Communications Corporation ("Netscape") may publish revised - and/or new versions of the License from time to time. Each version - will be given a distinguishing version number. - - 6.2. Effect of New Versions. - Once Covered Code has been published under a particular version of the - License, You may always continue to use it under the terms of that - version. You may also choose to use such Covered Code under the terms - of any subsequent version of the License published by Netscape. No one - other than Netscape has the right to modify the terms applicable to - Covered Code created under this License. - - 6.3. Derivative Works. - If You create or use a modified version of this License (which you may - only do in order to apply it to code which is not already Covered Code - governed by this License), You must (a) rename Your license so that - the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", - "MPL", "NPL" or any confusingly similar phrase do not appear in your - license (except to note that your license differs from this License) - and (b) otherwise make it clear that Your version of the license - contains terms which differ from the Mozilla Public License and - Netscape Public License. (Filling in the name of the Initial - Developer, Original Code or Contributor in the notice described in - Exhibit A shall not of themselves be deemed to be modifications of - this License.) - -7. DISCLAIMER OF WARRANTY. - - COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, - WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF - DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. - THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE - IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, - YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE - COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER - OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF - ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. - -8. TERMINATION. - - 8.1. This License and the rights granted hereunder will terminate - automatically if You fail to comply with terms herein and fail to cure - such breach within 30 days of becoming aware of the breach. All - sublicenses to the Covered Code which are properly granted shall - survive any termination of this License. Provisions which, by their - nature, must remain in effect beyond the termination of this License - shall survive. - - 8.2. If You initiate litigation by asserting a patent infringement - claim (excluding declatory judgment actions) against Initial Developer - or a Contributor (the Initial Developer or Contributor against whom - You file such action is referred to as "Participant") alleging that: - - (a) such Participant's Contributor Version directly or indirectly - infringes any patent, then any and all rights granted by such - Participant to You under Sections 2.1 and/or 2.2 of this License - shall, upon 60 days notice from Participant terminate prospectively, - unless if within 60 days after receipt of notice You either: (i) - agree in writing to pay Participant a mutually agreeable reasonable - royalty for Your past and future use of Modifications made by such - Participant, or (ii) withdraw Your litigation claim with respect to - the Contributor Version against such Participant. If within 60 days - of notice, a reasonable royalty and payment arrangement are not - mutually agreed upon in writing by the parties or the litigation claim - is not withdrawn, the rights granted by Participant to You under - Sections 2.1 and/or 2.2 automatically terminate at the expiration of - the 60 day notice period specified above. - - (b) any software, hardware, or device, other than such Participant's - Contributor Version, directly or indirectly infringes any patent, then - any rights granted to You by such Participant under Sections 2.1(b) - and 2.2(b) are revoked effective as of the date You first made, used, - sold, distributed, or had made, Modifications made by that - Participant. - - 8.3. If You assert a patent infringement claim against Participant - alleging that such Participant's Contributor Version directly or - indirectly infringes any patent where such claim is resolved (such as - by license or settlement) prior to the initiation of patent - infringement litigation, then the reasonable value of the licenses - granted by such Participant under Sections 2.1 or 2.2 shall be taken - into account in determining the amount or value of any payment or - license. - - 8.4. In the event of termination under Sections 8.1 or 8.2 above, - all end user license agreements (excluding distributors and resellers) - which have been validly granted by You or any distributor hereunder - prior to termination shall survive termination. - -9. LIMITATION OF LIABILITY. - - UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT - (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL - DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, - OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR - ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY - CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, - WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER - COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN - INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF - LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY - RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW - PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE - EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO - THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. - -10. U.S. GOVERNMENT END USERS. - - The Covered Code is a "commercial item," as that term is defined in - 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer - software" and "commercial computer software documentation," as such - terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 - C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), - all U.S. Government End Users acquire Covered Code with only those - rights set forth herein. - -11. MISCELLANEOUS. - - This License represents the complete agreement concerning subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. This License shall be governed by - California law provisions (except to the extent applicable law, if - any, provides otherwise), excluding its conflict-of-law provisions. - With respect to disputes in which at least one party is a citizen of, - or an entity chartered or registered to do business in the United - States of America, any litigation relating to this License shall be - subject to the jurisdiction of the Federal Courts of the Northern - District of California, with venue lying in Santa Clara County, - California, with the losing party responsible for costs, including - without limitation, court costs and reasonable attorneys' fees and - expenses. The application of the United Nations Convention on - Contracts for the International Sale of Goods is expressly excluded. - Any law or regulation which provides that the language of a contract - shall be construed against the drafter shall not apply to this - License. - -12. RESPONSIBILITY FOR CLAIMS. - - As between Initial Developer and the Contributors, each party is - responsible for claims and damages arising, directly or indirectly, - out of its utilization of rights under this License and You agree to - work with Initial Developer and Contributors to distribute such - responsibility on an equitable basis. Nothing herein is intended or - shall be deemed to constitute any admission of liability. - -13. MULTIPLE-LICENSED CODE. - - Initial Developer may designate portions of the Covered Code as - "Multiple-Licensed". "Multiple-Licensed" means that the Initial - Developer permits you to utilize portions of the Covered Code under - Your choice of the NPL or the alternative licenses, if any, specified - by the Initial Developer in the file described in Exhibit A. - -EXHIBIT A -Mozilla Public License. - - ``The contents of this file are subject to the Mozilla Public License - Version 1.1 (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.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - License for the specific language governing rights and limitations - under the License. - - The Original Code is ______________________________________. - - The Initial Developer of the Original Code is ________________________. - Portions created by ______________________ are Copyright (C) ______ - _______________________. All Rights Reserved. - - Contributor(s): ______________________________________. - - Alternatively, the contents of this file may be used under the terms - of the _____ license (the "[___] License"), in which case the - provisions of [______] License are applicable instead of those - above. If you wish to allow use of your version of this file only - under the terms of the [____] License and not to allow others to use - your version of this file under the MPL, indicate your decision by - deleting the provisions above and replace them with the notice and - other provisions required by the [___] License. If you do not delete - the provisions above, a recipient may use your version of this file - under either the MPL or the [___] License." - - [NOTE: The text of this Exhibit A may differ slightly from the text of - the notices in the Source Code files of the Original Code. You should - use the text of this Exhibit A rather than the text found in the - Original Code Source Code for Your Modifications.] - - - - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 \ No newline at end of file diff --git a/build/Readme.md b/build/Readme.md deleted file mode 100644 index 693d6643..00000000 --- a/build/Readme.md +++ /dev/null @@ -1,104 +0,0 @@ -Ace (Ajax.org Cloud9 Editor) -============================ - -Ace is a standalone code editor written in JavaScript. Our goal is to create a web based code editor that matches and extends the features, usability and performance of existing native editors such as TextMate, Vim or Eclipse. It can be easily embedded in any web page and JavaScript application. Ace is developed as the primary editor for [Cloud9 IDE](http://www.cloud9ide.com/) and the successor of the Mozilla Skywriter (Bespin) Project. - -Features --------- - -* Syntax highlighting -* Auto indentation and outdent -* An optional command line -* Work with huge documents (100,000 lines and more are no problem) -* Fully customizable key bindings including VI and Emacs modes -* Themes (TextMate themes can be imported) -* Search and replace with regular expressions -* Highlight matching parentheses -* Toggle between soft tabs and real tabs -* Displays hidden characters - -Take Ace for a spin! --------------------- - -Check out the Ace live [demo](http://ajaxorg.github.com/ace/build/editor.html) or get a [Cloud9 IDE account](http://run.cloud9ide.com) to experience Ace while editing one of your own GitHub projects. - -If you want, you can use Ace as a textarea replacement thanks to the [Ace Bookmarklet](http://ajaxorg.github.com/ace/build/textarea/editor.html). - -History -------- - -Previously known as “Bespin” or lately “Skywriter” it’s now known as Ace (Ajax.org Cloud9 Editor)! Bespin and Ace started as two independent projects both aiming to build a no compromise code editor component for the web. Bespin started as part of Mozilla Labs and was based on the canvas tag, while Ace is the Editor component of the Cloud9 IDE and is using the DOM for rendering. After the release of Ace at JSConf.eu 2010 in Berlin the Skywriter team decided to merge Ace with a simplified version of Skywriter's plugin system and some of Skywriter's extensibility points. All these changes have been merged back to Ace now, which supersedes Skywriter. Both Ajax.org and Mozilla are actively developing and maintaining Ace. - -Getting the code ----------------- - -Ace is a community project. We actively encourage and support contributions. The Ace source code is hosted on GitHub. It is released under the Mozilla tri-license (MPL/GPL/LGPL). This is the same license used by Firefox. This license is friendly to all kinds of projects, whether open source or not. Take charge of your editor and add your favorite language highlighting and keybindings! - - git clone git://github.com/ajaxorg/ace.git - git submodule update --init --recursive - -Embedding Ace -------------- - -Ace can be easily embedded into any existing web page. The Ace git repository ships with a pre-packaged version of Ace inside of the `build` directory. The same packaged files are also available as a separate [download](https://github.com/ajaxorg/ace/downloads). Simply copy the contents of the `src` subdirectory somewhere into your project and take a look at the included demos of how to use Ace. - -The easiest version is simply: - -
some text
- - - -To change the theme simply include the Theme's JavaScript file - - - -and configure the editor to use the theme: - - editor.setTheme("ace/theme/twilight"); - -By default the editor only supports plain text mode. However all other language modes are available as separate modules. After including the mode's Javascript file - - - -the mode can be used like this: - - var JavaScriptMode = require("ace/mode/javascript").Mode; - editor.getSession().setMode(new JavaScriptMode()); - -Running Ace ------------ - -After the checkout Ace works out of the box. No build step is required. Simply open 'editor.html' in any browser except Google Chrome. Google Chrome doesn't allow XMLHTTPRequests from files loaded from disc (i.e. with a file:/// URL). To open the Ace in Chrome simply start the bundled mini HTTP server: - - ./static.py - -The editor can then be opened at http://localhost:9999/editor.html. - -Package Ace ------------ - -To package Ace we use the dryice build tool developed by the Mozilla Skywriter team. To install dryice and all its dependencies simply call: - - npm link . - -Afterwards Ace can by build by calling - - ./Makefile.dryice.js - -The packaged Ace will be put in the 'build' folder. - -Running the Unit Tests ----------------------- - -The Ace unit tests run on node.js. Before the first run a couple of node mudules have to be installed. The easiest way to do this is by using the node package manager (npm). In the Ace base directory simply call - - npm link . - -To run the tests call: - - node lib/ace/test/all.js - diff --git a/build/src/ace-uncompressed.js b/build/src/ace-uncompressed.js deleted file mode 100644 index c6c48cb7..00000000 --- a/build/src/ace-uncompressed.js +++ /dev/null @@ -1,13154 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/** - * Define a module along with a payload - * @param module a name for the payload - * @param payload a function to call with (require, exports, module) params - */ - -(function() { - -if (window.require) { - require.packaged = true; - return; -} - -var _define = function(module, deps, payload) { - if (typeof module !== 'string') { - if (_define.original) - _define.original.apply(window, arguments); - else { - console.error('dropping module because define wasn\'t a string.'); - console.trace(); - } - return; - } - - if (!define.modules) - define.modules = {}; - - define.modules[module] = payload; -}; -if (window.define) - _define.original = window.define; - -window.define = _define; - - -/** - * Get at functionality define()ed using the function above - */ -var _require = function(module, callback) { - if (Object.prototype.toString.call(module) === "[object Array]") { - var params = []; - for (var i = 0, l = module.length; i < l; ++i) { - var dep = lookup(module[i]); - if (!dep && _require.original) - return _require.original.apply(window, arguments); - params.push(dep); - } - if (callback) { - callback.apply(null, params); - } - } - else if (typeof module === 'string') { - var payload = lookup(module); - if (!payload && _require.original) - return _require.original.apply(window, arguments); - - if (callback) { - callback(); - } - - return payload; - } - else { - if (_require.original) - return _require.original.apply(window, arguments); - } -}; - -if (window.require) - _require.original = window.require; - -window.require = _require; -require.packaged = true; - -/** - * Internal function to lookup moduleNames and resolve them by calling the - * definition function if needed. - */ -var lookup = function(moduleName) { - var module = define.modules[moduleName]; - if (module == null) { - console.error('Missing module: ' + moduleName); - return null; - } - - if (typeof module === 'function') { - var exports = {}; - module(require, exports, { id: moduleName, uri: '' }); - // cache the resulting module object for next time - define.modules[moduleName] = exports; - return exports; - } - - return module; -}; - -})();/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kevin Dangoor (kdangoor@mozilla.com) - * Irakli Gozalishvili (http://jeditoolkit.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/fixoldbrowsers', ['require', 'exports', 'module' ], function(require, exports, module) { - -// Should be the first thing, as we want to use that in this module. -if (!Function.prototype.bind) { - // from MDC - // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind - Function.prototype.bind = function (obj) { - var slice = [].slice; - var args = slice.call(arguments, 1); - var self = this; - var nop = function () {}; - - // optimize common case - if (arguments.length == 1) { - var bound = function() { - var useThis = self.prototype === undefined ? - this instanceof arguments.callee : - this instanceof nop; - return self.apply(useThis ? this : obj, arguments); - }; - } - else { - var bound = function () { - var useThis = self.prototype === undefined ? - this instanceof arguments.callee : - this instanceof nop; - return self.apply( - useThis ? this : ( obj || {} ), - args.concat( slice.call(arguments) ) - ); - }; - } - - nop.prototype = self.prototype; - bound.prototype = new nop(); - - // From Narwhal - bound.name = this.name; - bound.displayName = this.displayName; - bound.length = this.length; - bound.unbound = self; - - return bound; - }; -} - - -var F = function() {} -var call = Function.prototype.call; -// Shortcut for `Object.prototype.hasOwnProperty.call`. -var owns = call.bind(Object.prototype.hasOwnProperty); - -// Shortcuts for getter / setter utilities if supported by JS engine. -var getGetter, getSetter, setGetter, setSetter -getGetter = getSetter = setGetter = setSetter = F; - -if (Object.prototype.__lookupGetter__) - getGetter = call.bind(Object.prototype.__lookupGetter__); -if (Object.prototype.__lookupSetter__) - getSetter = call.bind(Object.prototype.__lookupSetter__); -if (Object.prototype.__defineGetter__) - setGetter = call.bind(Object.prototype.__defineGetter__); -if (Object.prototype.__defineSetter__) - setSetter = call.bind(Object.prototype.__defineSetter__); - -/** - * Array detector. - * Firefox 3.5 and Safari 4 have this already. Chrome 4 however ... - * Note to Dojo - your isArray is still broken: instanceof doesn't work with - * Arrays taken from a different frame/window. - */ -// ES5 15.4.3.2 -if (!Array.isArray) { - Array.isArray = function(data) { - return data && Object.prototype.toString.call(data) === "[object Array]"; - }; -} - -// from MDC -// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf -if (!Array.prototype.indexOf) -{ - Array.prototype.indexOf = function(searchElement /*, fromIndex */) - { - if (this === void 0 || this === null) - throw new TypeError(); - - var t = Object(this); - var len = t.length >>> 0; - if (len === 0) - return -1; - - var n = 0, zero = n; - if (arguments.length > 0) { - n = Number(arguments[1]); - if (n !== n) - n = 0; - else if (n !== 0 && n !== (1 / zero) && n !== -(1 / zero)) - n = (n > 0 || -1) * Math.floor(Math.abs(n)); - } - - if (n >= len) - return -1; - - var k = n >= 0 - ? n - : Math.max(len - Math.abs(n), 0); - - for (; k < len; k++) { - if (k in t && t[k] === searchElement) - return k; - } - return -1; - }; -} - -// from MDC -// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf -if (!Array.prototype.lastIndexOf) -{ - Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/) - { - "use strict"; - - if (this === void 0 || this === null) - throw new TypeError(); - - var t = Object(this); - var len = t.length >>> 0; - if (len === 0) - return -1; - - var n = len, zero = false | 0; - if (arguments.length > 0) - { - n = Number(arguments[1]); - if (n !== n) - n = 0; - else if (n !== 0 && n !== (1 / zero) && n !== -(1 / zero)) - n = (n > 0 || -1) * Math.floor(Math.abs(n)); - } - - var k = n >= 0 - ? Math.min(n, len - 1) - : len - Math.abs(n); - - while (k >= 0) - { - if (k in t && t[k] === searchElement) - return k; - } - return -1; - }; -} - -// from MDC -// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map -// ES5 15.4.4.19 -if (!Array.prototype.map) { - Array.prototype.map = function(fun /*, thisp */) { - if (this === void 0 || this === null) - throw new TypeError(); - - var t = Object(this); - var len = t.length >>> 0; - if (typeof fun !== "function") - throw new TypeError(); - - res = new Array(len); - var thisp = arguments[1]; - for (var i = 0; i < len; i++) { - if (i in t) - res[i] = fun.call(thisp, t[i], i, t); - } - - return res; - }; -} - -// from MDC -// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach -// ES5 15.4.4.18 -if (!Array.prototype.forEach) { - Array.prototype.forEach = function(fun /*, thisp */) { - if (this === void 0 || this === null) - throw new TypeError(); - - var t = Object(this); - var len = t.length >>> 0; - if (typeof fun !== "function") - throw new TypeError(); - - var thisp = arguments[1]; - for (var i = 0; i < len; i++) { - if (i in t) - fun.call(thisp, t[i], i, t); - } - }; -} - -// ES5 15.4.4.20 -if (!Array.prototype.filter) { - Array.prototype.filter = function filter(callback, scope) { - var values = [], i, ii; - for (i = 0, ii = this.length; i < ii; i++) { - if (callback.call(scope, this[i])) values.push(this[i]); - } - return values; - }; -} - -// ES5 15.4.4.16 -if (!Array.prototype.every) { - Array.prototype.every = function every(callback, scope) { - var i, ii; - for (i = 0, ii = this.length; i < ii; i++) { - if (!callback.call(scope, this[i])) return false; - } - return true; - }; -} - -// ES5 15.4.4.17 -if (!Array.prototype.some) { - Array.prototype.some = function (callback, scope) { - var i, ii; - for (i = 0, ii = this.length; i < ii; i++) { - if (callback.call(scope, this[i])) return true; - } - return false; - }; -} - -// ES5 15.4.4.21 -// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce -if (!Array.prototype.reduce) { - Array.prototype.reduce = function(fun /*, initial*/) { - var len = this.length >>> 0; - if (typeof fun != "function") - throw new TypeError(); - - // no value to return if no initial value and an empty array - if (len == 0 && arguments.length == 1) - throw new TypeError(); - - var i = 0; - if (arguments.length >= 2) { - var rv = arguments[1]; - } else { - do { - if (i in this) { - rv = this[i++]; - break; - } - - // if array contains no values, no initial value to return - if (++i >= len) - throw new TypeError(); - } while (true); - } - - for (; i < len; i++) { - if (i in this) - rv = fun.call(null, rv, this[i], i, this); - } - - return rv; - }; -} - -// ES5 15.4.4.22 -// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight -if (!Array.prototype.reduceRight) { - Array.prototype.reduceRight = function(fun /*, initial*/) { - var len = this.length >>> 0; - if (typeof fun != "function") - throw new TypeError(); - - // no value to return if no initial value, empty array - if (len == 0 && arguments.length == 1) - throw new TypeError(); - - var i = len - 1; - if (arguments.length >= 2) { - var rv = arguments[1]; - } else { - do { - if (i in this) { - rv = this[i--]; - break; - } - - // if array contains no values, no initial value to return - if (--i < 0) - throw new TypeError(); - } while (true); - } - - for (; i >= 0; i--) { - if (i in this) - rv = fun.call(null, rv, this[i], i, this); - } - - return rv; - }; -} - - -/** - * Retrieves the list of keys on an object. - */ -if (!Object.keys) { - Object.keys = function keys(object) { - var name, names = []; - for (name in object) - if (owns(object, name)) names.push(name); - - return names; - }; -} - -// Can not be implemented so we default to the Object.keys -// ES5 15.2.3.4 -if (!Object.getOwnPropertyNames) { - Object.getOwnPropertyNames = Object.keys; -} - -// ES5 15.2.3.3 -var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a non-object" -if (!Object.getOwnPropertyDescriptor) { - Object.getOwnPropertyDescriptor = - function getOwnPropertyDescriptor(object, name) { - var descriptor, getter, setter; - - if (typeof object !== "object" && typeof object !== "function" - || object === null) throw new TypeError(ERR_NON_OBJECT); - - if (owns(object, name)) { - descriptor = { configurable: true, enumerable: true }; - getter = descriptor.get = getGetter(object, name); - setter = descriptor.set = getSetter(object, name); - // If nor getter nor setter is not defined we default to - // normal value. This can mean that either it's data - // property or js engine does not supports getters / setters. - if (!getter && !setter) { - descriptor.writeable = true; - descriptor.value = object[name] - } - } - return descriptor - } -} - -// Returning `__proto__` of an object or `object.constructor.prototype` for IE. -if (!Object.getPrototypeOf) { - Object.getPrototypeOf = function getPrototypeOf(object) { - return object.__proto__ || object.constructor.prototype; - } -} - -// ES5 15.2.3.5 -if (!Object.create) { - Object.create = function create(prototype, properties) { - var object; - - if (prototype === null) { - object = { __proto__: null }; - } else if (typeof prototype !== "object") { - throw new TypeError(prototype + " is not an object or null"); - } else { - F.prototype = prototype; - object = new F(); - } - - if (typeof properties !== "undefined") - Object.defineProperties(object, properties); - - return object; - }; -} - -// ES5 15.2.3.6 -if (!Object.defineProperty) { - Object.defineProperty = function defineProperty(object, name, descriptor) { - var proto, setter, getter; - - if ("object" !== typeof object && "function" !== typeof object) - throw new TypeError(object + "is not an object"); - if (descriptor && 'object' !== typeof descriptor) - throw new TypeError('Property descriptor map must be an object'); - if ('value' in descriptor) { // if it's a data property - if ('get' in descriptor || 'set' in descriptor) { - throw new TypeError('Invalid property. "value" present on ' - + 'property with getter or setter.'); - } - - // Swapping __proto__ with default one to avoid calling inherited - // getters / setters with this `name`. - if (proto = object.__proto__) object.__proto__ = Object.prototype; - // Delete property cause it may be a setter. - delete object[name]; - object[name] = descriptor.value; - // Return __proto__ back. - if (proto) object.__proto__ = proto; - } else { - if (getter = descriptor.get) setGetter(object, getter); - if (setter = descriptor.set) setSetter(object, setter); - } - return object; - }; -} - -// ES5 15.2.3.7 -if (!Object.defineProperties) { - Object.defineProperties = function defineProperties(object, properties) { - Object.getOwnPropertyNames(properties).forEach(function (name) { - Object.defineProperty(object, name, properties[name]); - }); - return object; - }; -} - -var passThrough = function(object) { return object }; -// ES5 15.2.3.8 -if (!Object.seal) Object.seal = passThrough; - -// ES5 15.2.3.9 -if (!Object.freeze) Object.freeze = passThrough; - -// ES5 15.2.3.10 -if (!Object.preventExtensions) Object.preventExtension = passThrough; - -var no = function() { return false }; -var yes = function() { return true }; - -// ES5 15.2.3.11 -if (!Object.isSealed) Object.isSealed = no; -// ES5 15.2.3.12 -if (!Object.isFrozen) Object.isFrozen = no; -// ES5 15.2.3.13 -if (!Object.isExtensible) Object.isExtensible = yes; - -if (!String.prototype.trim) { - String.prototype.trim = function() { - return this.trimLeft().trimRight(); - } -} - -if (!String.prototype.trimRight) { - String.prototype.trimRight = function() { - return this.replace(/[\t\v\f\s\u00a0\ufeff]+$/, ""); - } -} - -if (!String.prototype.trimLeft) { - String.prototype.trimLeft = function() { - return this.replace(/^[\t\v\f\s\u00a0\ufeff]+/, ""); - } -} - -exports.globalsLoaded = true; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kevin Dangoor (kdangoor@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/index', ['require', 'exports', 'module' , 'pilot/fixoldbrowsers', 'pilot/types/basic', 'pilot/types/command', 'pilot/types/settings', 'pilot/commands/settings', 'pilot/commands/basic', 'pilot/settings/canon', 'pilot/canon'], function(require, exports, module) { - -exports.startup = function(data, reason) { - require('pilot/fixoldbrowsers'); - - require('pilot/types/basic').startup(data, reason); - require('pilot/types/command').startup(data, reason); - require('pilot/types/settings').startup(data, reason); - require('pilot/commands/settings').startup(data, reason); - require('pilot/commands/basic').startup(data, reason); - // require('pilot/commands/history').startup(data, reason); - require('pilot/settings/canon').startup(data, reason); - require('pilot/canon').startup(data, reason); -}; - -exports.shutdown = function(data, reason) { - require('pilot/types/basic').shutdown(data, reason); - require('pilot/types/command').shutdown(data, reason); - require('pilot/types/settings').shutdown(data, reason); - require('pilot/commands/settings').shutdown(data, reason); - require('pilot/commands/basic').shutdown(data, reason); - // require('pilot/commands/history').shutdown(data, reason); - require('pilot/settings/canon').shutdown(data, reason); - require('pilot/canon').shutdown(data, reason); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * Kevin Dangoor (kdangoor@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/types/basic', ['require', 'exports', 'module' , 'pilot/types'], function(require, exports, module) { - -var types = require("pilot/types"); -var Type = types.Type; -var Conversion = types.Conversion; -var Status = types.Status; - -/** - * These are the basic types that we accept. They are vaguely based on the - * Jetpack settings system (https://wiki.mozilla.org/Labs/Jetpack/JEP/24) - * although clearly more restricted. - * - *

In addition to these types, Jetpack also accepts range, member, password - * that we are thinking of adding. - * - *

This module probably should not be accessed directly, but instead used - * through types.js - */ - -/** - * 'text' is the default if no type is given. - */ -var text = new Type(); - -text.stringify = function(value) { - return value; -}; - -text.parse = function(value) { - if (typeof value != 'string') { - throw new Error('non-string passed to text.parse()'); - } - return new Conversion(value); -}; - -text.name = 'text'; - -/** - * We don't currently plan to distinguish between integers and floats - */ -var number = new Type(); - -number.stringify = function(value) { - if (!value) { - return null; - } - return '' + value; -}; - -number.parse = function(value) { - if (typeof value != 'string') { - throw new Error('non-string passed to number.parse()'); - } - - if (value.replace(/\s/g, '').length === 0) { - return new Conversion(null, Status.INCOMPLETE, ''); - } - - var reply = new Conversion(parseInt(value, 10)); - if (isNaN(reply.value)) { - reply.status = Status.INVALID; - reply.message = 'Can\'t convert "' + value + '" to a number.'; - } - - return reply; -}; - -number.decrement = function(value) { - return value - 1; -}; - -number.increment = function(value) { - return value + 1; -}; - -number.name = 'number'; - -/** - * One of a known set of options - */ -function SelectionType(typeSpec) { - if (!Array.isArray(typeSpec.data) && typeof typeSpec.data !== 'function') { - throw new Error('instances of SelectionType need typeSpec.data to be an array or function that returns an array:' + JSON.stringify(typeSpec)); - } - Object.keys(typeSpec).forEach(function(key) { - this[key] = typeSpec[key]; - }, this); -}; - -SelectionType.prototype = new Type(); - -SelectionType.prototype.stringify = function(value) { - return value; -}; - -SelectionType.prototype.parse = function(str) { - if (typeof str != 'string') { - throw new Error('non-string passed to parse()'); - } - if (!this.data) { - throw new Error('Missing data on selection type extension.'); - } - var data = (typeof(this.data) === 'function') ? this.data() : this.data; - - // The matchedValue could be the boolean value false - var hasMatched = false; - var matchedValue; - var completions = []; - data.forEach(function(option) { - if (str == option) { - matchedValue = this.fromString(option); - hasMatched = true; - } - else if (option.indexOf(str) === 0) { - completions.push(this.fromString(option)); - } - }, this); - - if (hasMatched) { - return new Conversion(matchedValue); - } - else { - // This is something of a hack it basically allows us to tell the - // setting type to forget its last setting hack. - if (this.noMatch) { - this.noMatch(); - } - - if (completions.length > 0) { - var msg = 'Possibilities' + - (str.length === 0 ? '' : ' for \'' + str + '\''); - return new Conversion(null, Status.INCOMPLETE, msg, completions); - } - else { - var msg = 'Can\'t use \'' + str + '\'.'; - return new Conversion(null, Status.INVALID, msg, completions); - } - } -}; - -SelectionType.prototype.fromString = function(str) { - return str; -}; - -SelectionType.prototype.decrement = function(value) { - var data = (typeof this.data === 'function') ? this.data() : this.data; - var index; - if (value == null) { - index = data.length - 1; - } - else { - var name = this.stringify(value); - var index = data.indexOf(name); - index = (index === 0 ? data.length - 1 : index - 1); - } - return this.fromString(data[index]); -}; - -SelectionType.prototype.increment = function(value) { - var data = (typeof this.data === 'function') ? this.data() : this.data; - var index; - if (value == null) { - index = 0; - } - else { - var name = this.stringify(value); - var index = data.indexOf(name); - index = (index === data.length - 1 ? 0 : index + 1); - } - return this.fromString(data[index]); -}; - -SelectionType.prototype.name = 'selection'; - -/** - * SelectionType is a base class for other types - */ -exports.SelectionType = SelectionType; - -/** - * true/false values - */ -var bool = new SelectionType({ - name: 'bool', - data: [ 'true', 'false' ], - stringify: function(value) { - return '' + value; - }, - fromString: function(str) { - return str === 'true' ? true : false; - } -}); - - -/** - * A we don't know right now, but hope to soon. - */ -function DeferredType(typeSpec) { - if (typeof typeSpec.defer !== 'function') { - throw new Error('Instances of DeferredType need typeSpec.defer to be a function that returns a type'); - } - Object.keys(typeSpec).forEach(function(key) { - this[key] = typeSpec[key]; - }, this); -}; - -DeferredType.prototype = new Type(); - -DeferredType.prototype.stringify = function(value) { - return this.defer().stringify(value); -}; - -DeferredType.prototype.parse = function(value) { - return this.defer().parse(value); -}; - -DeferredType.prototype.decrement = function(value) { - var deferred = this.defer(); - return (deferred.decrement ? deferred.decrement(value) : undefined); -}; - -DeferredType.prototype.increment = function(value) { - var deferred = this.defer(); - return (deferred.increment ? deferred.increment(value) : undefined); -}; - -DeferredType.prototype.name = 'deferred'; - -/** - * DeferredType is a base class for other types - */ -exports.DeferredType = DeferredType; - - -/** - * A set of objects of the same type - */ -function ArrayType(typeSpec) { - if (typeSpec instanceof Type) { - this.subtype = typeSpec; - } - else if (typeof typeSpec === 'string') { - this.subtype = types.getType(typeSpec); - if (this.subtype == null) { - throw new Error('Unknown array subtype: ' + typeSpec); - } - } - else { - throw new Error('Can\' handle array subtype'); - } -}; - -ArrayType.prototype = new Type(); - -ArrayType.prototype.stringify = function(values) { - // TODO: Check for strings with spaces and add quotes - return values.join(' '); -}; - -ArrayType.prototype.parse = function(value) { - return this.defer().parse(value); -}; - -ArrayType.prototype.name = 'array'; - -/** - * Registration and de-registration. - */ -exports.startup = function() { - types.registerType(text); - types.registerType(number); - types.registerType(bool); - types.registerType(SelectionType); - types.registerType(DeferredType); - types.registerType(ArrayType); -}; - -exports.shutdown = function() { - types.unregisterType(text); - types.unregisterType(number); - types.unregisterType(bool); - types.unregisterType(SelectionType); - types.unregisterType(DeferredType); - types.unregisterType(ArrayType); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/types', ['require', 'exports', 'module' ], function(require, exports, module) { - -/** - * Some types can detect validity, that is to say they can distinguish between - * valid and invalid values. - * TODO: Change these constants to be numbers for more performance? - */ -var Status = { - /** - * The conversion process worked without any problem, and the value is - * valid. There are a number of failure states, so the best way to check - * for failure is (x !== Status.VALID) - */ - VALID: { - toString: function() { return 'VALID'; }, - valueOf: function() { return 0; } - }, - - /** - * A conversion process failed, however it was noted that the string - * provided to 'parse()' could be VALID by the addition of more characters, - * so the typing may not be actually incorrect yet, just unfinished. - * @see Status.INVALID - */ - INCOMPLETE: { - toString: function() { return 'INCOMPLETE'; }, - valueOf: function() { return 1; } - }, - - /** - * The conversion process did not work, the value should be null and a - * reason for failure should have been provided. In addition some completion - * values may be available. - * @see Status.INCOMPLETE - */ - INVALID: { - toString: function() { return 'INVALID'; }, - valueOf: function() { return 2; } - }, - - /** - * A combined status is the worser of the provided statuses - */ - combine: function(statuses) { - var combined = Status.VALID; - for (var i = 0; i < arguments; i++) { - if (arguments[i] > combined) { - combined = arguments[i]; - } - } - return combined; - } -}; -exports.Status = Status; - -/** - * The type.parse() method returns a Conversion to inform the user about not - * only the result of a Conversion but also about what went wrong. - * We could use an exception, and throw if the conversion failed, but that - * seems to violate the idea that exceptions should be exceptional. Typos are - * not. Also in order to store both a status and a message we'd still need - * some sort of exception type... - */ -function Conversion(value, status, message, predictions) { - /** - * The result of the conversion process. Will be null if status != VALID - */ - this.value = value; - - /** - * The status of the conversion. - * @see Status - */ - this.status = status || Status.VALID; - - /** - * A message to go with the conversion. This could be present for any status - * including VALID in the case where we want to note a warning for example. - * I18N: On the one hand this nasty and un-internationalized, however with - * a command line it is hard to know where to start. - */ - this.message = message; - - /** - * A array of strings which are the systems best guess at better inputs than - * the one presented. - * We generally expect there to be about 7 predictions (to match human list - * comprehension ability) however it is valid to provide up to about 20, - * or less. It is the job of the predictor to decide a smart cut-off. - * For example if there are 4 very good matches and 4 very poor ones, - * probably only the 4 very good matches should be presented. - */ - this.predictions = predictions || []; -} -exports.Conversion = Conversion; - -/** - * Most of our types are 'static' e.g. there is only one type of 'text', however - * some types like 'selection' and 'deferred' are customizable. The basic - * Type type isn't useful, but does provide documentation about what types do. - */ -function Type() { -}; -Type.prototype = { - /** - * Convert the given value to a string representation. - * Where possible, there should be round-tripping between values and their - * string representations. - */ - stringify: function(value) { throw new Error("not implemented"); }, - - /** - * Convert the given str to an instance of this type. - * Where possible, there should be round-tripping between values and their - * string representations. - * @return Conversion - */ - parse: function(str) { throw new Error("not implemented"); }, - - /** - * The plug-in system, and other things need to know what this type is - * called. The name alone is not enough to fully specify a type. Types like - * 'selection' and 'deferred' need extra data, however this function returns - * only the name, not the extra data. - *

In old bespin, equality was based on the name. This may turn out to be - * important in Ace too. - */ - name: undefined, - - /** - * If there is some concept of a higher value, return it, - * otherwise return undefined. - */ - increment: function(value) { - return undefined; - }, - - /** - * If there is some concept of a lower value, return it, - * otherwise return undefined. - */ - decrement: function(value) { - return undefined; - }, - - /** - * There is interesting information (like predictions) in a conversion of - * nothing, the output of this can sometimes be customized. - * @return Conversion - */ - getDefault: function() { - return this.parse(''); - } -}; -exports.Type = Type; - -/** - * Private registry of types - * Invariant: types[name] = type.name - */ -var types = {}; - -/** - * Add a new type to the list available to the system. - * You can pass 2 things to this function - either an instance of Type, in - * which case we return this instance when #getType() is called with a 'name' - * that matches type.name. - * Also you can pass in a constructor (i.e. function) in which case when - * #getType() is called with a 'name' that matches Type.prototype.name we will - * pass the typeSpec into this constructor. See #reconstituteType(). - */ -exports.registerType = function(type) { - if (typeof type === 'object') { - if (type instanceof Type) { - if (!type.name) { - throw new Error('All registered types must have a name'); - } - types[type.name] = type; - } - else { - throw new Error('Can\'t registerType using: ' + type); - } - } - else if (typeof type === 'function') { - if (!type.prototype.name) { - throw new Error('All registered types must have a name'); - } - types[type.prototype.name] = type; - } - else { - throw new Error('Unknown type: ' + type); - } -}; - -exports.registerTypes = function registerTypes(types) { - Object.keys(types).forEach(function (name) { - var type = types[name]; - type.name = name; - exports.registerType(type); - }); -}; - -/** - * Remove a type from the list available to the system - */ -exports.deregisterType = function(type) { - delete types[type.name]; -}; - -/** - * See description of #exports.registerType() - */ -function reconstituteType(name, typeSpec) { - if (name.substr(-2) === '[]') { // i.e. endsWith('[]') - var subtypeName = name.slice(0, -2); - return new types['array'](subtypeName); - } - - var type = types[name]; - if (typeof type === 'function') { - type = new type(typeSpec); - } - return type; -} - -/** - * Find a type, previously registered using #registerType() - */ -exports.getType = function(typeSpec) { - if (typeof typeSpec === 'string') { - return reconstituteType(typeSpec); - } - - if (typeof typeSpec === 'object') { - if (!typeSpec.name) { - throw new Error('Missing \'name\' member to typeSpec'); - } - return reconstituteType(typeSpec.name, typeSpec); - } - - throw new Error('Can\'t extract type from ' + typeSpec); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * Kevin Dangoor (kdangoor@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/types/command', ['require', 'exports', 'module' , 'pilot/canon', 'pilot/types/basic', 'pilot/types'], function(require, exports, module) { - -var canon = require("pilot/canon"); -var SelectionType = require("pilot/types/basic").SelectionType; -var types = require("pilot/types"); - - -/** - * Select from the available commands - */ -var command = new SelectionType({ - name: 'command', - data: function() { - return canon.getCommandNames(); - }, - stringify: function(command) { - return command.name; - }, - fromString: function(str) { - return canon.getCommand(str); - } -}); - - -/** - * Registration and de-registration. - */ -exports.startup = function() { - types.registerType(command); -}; - -exports.shutdown = function() { - types.unregisterType(command); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/canon', ['require', 'exports', 'module' , 'pilot/console', 'pilot/stacktrace', 'pilot/oop', 'pilot/event_emitter', 'pilot/catalog', 'pilot/types', 'pilot/lang'], function(require, exports, module) { - -var console = require('pilot/console'); -var Trace = require('pilot/stacktrace').Trace; -var oop = require('pilot/oop'); -var EventEmitter = require('pilot/event_emitter').EventEmitter; -var catalog = require('pilot/catalog'); -var Status = require('pilot/types').Status; -var types = require('pilot/types'); -var lang = require('pilot/lang'); - -/* -// TODO: this doesn't belong here - or maybe anywhere? -var dimensionsChangedExtensionSpec = { - name: 'dimensionsChanged', - description: 'A dimensionsChanged is a way to be notified of ' + - 'changes to the dimension of Skywriter' -}; -exports.startup = function(data, reason) { - catalog.addExtensionSpec(commandExtensionSpec); -}; -exports.shutdown = function(data, reason) { - catalog.removeExtensionSpec(commandExtensionSpec); -}; -*/ - -var commandExtensionSpec = { - name: 'command', - description: 'A command is a bit of functionality with optional ' + - 'typed arguments which can do something small like moving ' + - 'the cursor around the screen, or large like cloning a ' + - 'project from VCS.', - indexOn: 'name' -}; - -exports.startup = function(data, reason) { - // TODO: this is probably all kinds of evil, but we need something working - catalog.addExtensionSpec(commandExtensionSpec); -}; - -exports.shutdown = function(data, reason) { - catalog.removeExtensionSpec(commandExtensionSpec); -}; - -/** - * Manage a list of commands in the current canon - */ - -/** - * A Command is a discrete action optionally with a set of ways to customize - * how it happens. This is here for documentation purposes. - * TODO: Document better - */ -var thingCommand = { - name: 'thing', - description: 'thing is an example command', - params: [{ - name: 'param1', - description: 'an example parameter', - type: 'text', - defaultValue: null - }], - exec: function(env, args, request) { - thing(); - } -}; - -/** - * A lookup hash of our registered commands - */ -var commands = {}; - -/** - * A sorted list of command names, we regularly want them in order, so pre-sort - */ -var commandNames = []; - -/** - * This registration method isn't like other Ace registration methods because - * it doesn't return a decorated command because there is no functional - * decoration to be done. - * TODO: Are we sure that in the future there will be no such decoration? - */ -function addCommand(command) { - if (!command.name) { - throw new Error('All registered commands must have a name'); - } - if (command.params == null) { - command.params = []; - } - if (!Array.isArray(command.params)) { - throw new Error('command.params must be an array in ' + command.name); - } - // Replace the type - command.params.forEach(function(param) { - if (!param.name) { - throw new Error('In ' + command.name + ': all params must have a name'); - } - upgradeType(command.name, param); - }, this); - commands[command.name] = command; - - commandNames.push(command.name); - commandNames.sort(); -}; - -function upgradeType(name, param) { - var lookup = param.type; - param.type = types.getType(lookup); - if (param.type == null) { - throw new Error('In ' + name + '/' + param.name + - ': can\'t find type for: ' + JSON.stringify(lookup)); - } -} - -function removeCommand(command) { - var name = (typeof command === 'string' ? command : command.name); - delete commands[name]; - lang.arrayRemove(commandNames, name); -}; - -function getCommand(name) { - return commands[name]; -}; - -function getCommandNames() { - return commandNames; -}; - -/** - * Entry point for keyboard accelerators or anything else that knows - * everything it needs to about the command params - * @param command Either a command, or the name of one - */ -function exec(command, env, args, typed) { - if (typeof command === 'string') { - command = commands[command]; - } - if (!command) { - // TODO: Should we complain more than returning false? - return false; - } - - var request = new Request({ - command: command, - args: args, - typed: typed - }); - command.exec(env, args || {}, request); - return true; -}; - -exports.removeCommand = removeCommand; -exports.addCommand = addCommand; -exports.getCommand = getCommand; -exports.getCommandNames = getCommandNames; -exports.exec = exec; -exports.upgradeType = upgradeType; - - -/** - * We publish a 'output' event whenever new command begins output - * TODO: make this more obvious - */ -oop.implement(exports, EventEmitter); - - -/** - * Current requirements are around displaying the command line, and provision - * of a 'history' command and cursor up|down navigation of history. - *

Future requirements could include: - *

    - *
  • Multiple command lines - *
  • The ability to recall key presses (i.e. requests with no output) which - * will likely be needed for macro recording or similar - *
  • The ability to store the command history either on the server or in the - * browser local storage. - *
- *

The execute() command doesn't really live here, except as part of that - * last future requirement, and because it doesn't really have anywhere else to - * live. - */ - -/** - * The array of requests that wish to announce their presence - */ -var requests = []; - -/** - * How many requests do we store? - */ -var maxRequestLength = 100; - -/** - * To create an invocation, you need to do something like this (all the ctor - * args are optional): - *

- * var request = new Request({
- *     command: command,
- *     args: args,
- *     typed: typed
- * });
- * 
- * @constructor - */ -function Request(options) { - options = options || {}; - - // Will be used in the keyboard case and the cli case - this.command = options.command; - - // Will be used only in the cli case - this.args = options.args; - this.typed = options.typed; - - // Have we been initialized? - this._begunOutput = false; - - this.start = new Date(); - this.end = null; - this.completed = false; - this.error = false; -}; - -oop.implement(Request.prototype, EventEmitter); - -/** - * Lazy init to register with the history should only be done on output. - * init() is expensive, and won't be used in the majority of cases - */ -Request.prototype._beginOutput = function() { - this._begunOutput = true; - this.outputs = []; - - requests.push(this); - // This could probably be optimized with some maths, but 99.99% of the - // time we will only be off by one, and I'm feeling lazy. - while (requests.length > maxRequestLength) { - requests.shiftObject(); - } - - exports._dispatchEvent('output', { requests: requests, request: this }); -}; - -/** - * Sugar for: - *
request.error = true; request.done(output);
- */ -Request.prototype.doneWithError = function(content) { - this.error = true; - this.done(content); -}; - -/** - * Declares that this function will not be automatically done when - * the command exits - */ -Request.prototype.async = function() { - if (!this._begunOutput) { - this._beginOutput(); - } -}; - -/** - * Complete the currently executing command with successful output. - * @param output Either DOM node, an SproutCore element or something that - * can be used in the content of a DIV to create a DOM node. - */ -Request.prototype.output = function(content) { - if (!this._begunOutput) { - this._beginOutput(); - } - - if (typeof content !== 'string' && !(content instanceof Node)) { - content = content.toString(); - } - - this.outputs.push(content); - this._dispatchEvent('output', {}); - - return this; -}; - -/** - * All commands that do output must call this to indicate that the command - * has finished execution. - */ -Request.prototype.done = function(content) { - this.completed = true; - this.end = new Date(); - this.duration = this.end.getTime() - this.start.getTime(); - - if (content) { - this.output(content); - } - - this._dispatchEvent('output', {}); -}; -exports.Request = Request; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * Patrick Walton (pwalton@mozilla.com) - * Julian Viereck (jviereck@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -define('pilot/console', ['require', 'exports', 'module' ], function(require, exports, module) { - -/** - * This object represents a "safe console" object that forwards debugging - * messages appropriately without creating a dependency on Firebug in Firefox. - */ - -var noop = function() {}; - -// These are the functions that are available in Chrome 4/5, Safari 4 -// and Firefox 3.6. Don't add to this list without checking browser support -var NAMES = [ - "assert", "count", "debug", "dir", "dirxml", "error", "group", "groupEnd", - "info", "log", "profile", "profileEnd", "time", "timeEnd", "trace", "warn" -]; - -if (typeof(window) === 'undefined') { - // We're in a web worker. Forward to the main thread so the messages - // will show up. - NAMES.forEach(function(name) { - exports[name] = function() { - var args = Array.prototype.slice.call(arguments); - var msg = { op: 'log', method: name, args: args }; - postMessage(JSON.stringify(msg)); - }; - }); -} else { - // For each of the console functions, copy them if they exist, stub if not - NAMES.forEach(function(name) { - if (window.console && window.console[name]) { - exports[name] = Function.prototype.bind.call(window.console[name], window.console); - } else { - exports[name] = noop; - } - }); -} - -}); -define('pilot/stacktrace', ['require', 'exports', 'module' , 'pilot/useragent', 'pilot/console'], function(require, exports, module) { - -var ua = require("pilot/useragent"); -var console = require('pilot/console'); - -// Changed to suit the specific needs of running within Skywriter - -// Domain Public by Eric Wendelin http://eriwen.com/ (2008) -// Luke Smith http://lucassmith.name/ (2008) -// Loic Dachary (2008) -// Johan Euphrosine (2008) -// Øyvind Sean Kinsey http://kinsey.no/blog -// -// Information and discussions -// http://jspoker.pokersource.info/skin/test-printstacktrace.html -// http://eriwen.com/javascript/js-stack-trace/ -// http://eriwen.com/javascript/stacktrace-update/ -// http://pastie.org/253058 -// http://browsershots.org/http://jspoker.pokersource.info/skin/test-printstacktrace.html -// - -// -// guessFunctionNameFromLines comes from firebug -// -// Software License Agreement (BSD License) -// -// Copyright (c) 2007, Parakey Inc. -// All rights reserved. -// -// Redistribution and use of this software in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above -// copyright notice, this list of conditions and the -// following disclaimer. -// -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// * Neither the name of Parakey Inc. nor the names of its -// contributors may be used to endorse or promote products -// derived from this software without specific prior -// written permission of Parakey Inc. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - -/** - * Different browsers create stack traces in different ways. - * Feature Browser detection baby ;). - */ -var mode = (function() { - - // We use SC's browser detection here to avoid the "break on error" - // functionality provided by Firebug. Firebug tries to do the right - // thing here and break, but it happens every time you load the page. - // bug 554105 - if (ua.isGecko) { - return 'firefox'; - } else if (ua.isOpera) { - return 'opera'; - } else { - return 'other'; - } - - // SC doesn't do any detection of Chrome at this time. - - // this is the original feature detection code that is used as a - // fallback. - try { - (0)(); - } catch (e) { - if (e.arguments) { - return 'chrome'; - } - if (e.stack) { - return 'firefox'; - } - if (window.opera && !('stacktrace' in e)) { //Opera 9- - return 'opera'; - } - } - return 'other'; -})(); - -/** - * - */ -function stringifyArguments(args) { - for (var i = 0; i < args.length; ++i) { - var argument = args[i]; - if (typeof argument == 'object') { - args[i] = '#object'; - } else if (typeof argument == 'function') { - args[i] = '#function'; - } else if (typeof argument == 'string') { - args[i] = '"' + argument + '"'; - } - } - return args.join(','); -} - -/** - * Extract a stack trace from the format emitted by each browser. - */ -var decoders = { - chrome: function(e) { - var stack = e.stack; - if (!stack) { - console.log(e); - return []; - } - return stack.replace(/^.*?\n/, ''). - replace(/^.*?\n/, ''). - replace(/^.*?\n/, ''). - replace(/^[^\(]+?[\n$]/gm, ''). - replace(/^\s+at\s+/gm, ''). - replace(/^Object.\s*\(/gm, '{anonymous}()@'). - split('\n'); - }, - - firefox: function(e) { - var stack = e.stack; - if (!stack) { - console.log(e); - return []; - } - // stack = stack.replace(/^.*?\n/, ''); - stack = stack.replace(/(?:\n@:0)?\s+$/m, ''); - stack = stack.replace(/^\(/gm, '{anonymous}('); - return stack.split('\n'); - }, - - // Opera 7.x and 8.x only! - opera: function(e) { - var lines = e.message.split('\n'), ANON = '{anonymous}', - lineRE = /Line\s+(\d+).*?script\s+(http\S+)(?:.*?in\s+function\s+(\S+))?/i, i, j, len; - - for (i = 4, j = 0, len = lines.length; i < len; i += 2) { - if (lineRE.test(lines[i])) { - lines[j++] = (RegExp.$3 ? RegExp.$3 + '()@' + RegExp.$2 + RegExp.$1 : ANON + '()@' + RegExp.$2 + ':' + RegExp.$1) + - ' -- ' + - lines[i + 1].replace(/^\s+/, ''); - } - } - - lines.splice(j, lines.length - j); - return lines; - }, - - // Safari, Opera 9+, IE, and others - other: function(curr) { - var ANON = '{anonymous}', fnRE = /function\s*([\w\-$]+)?\s*\(/i, stack = [], j = 0, fn, args; - - var maxStackSize = 10; - while (curr && stack.length < maxStackSize) { - fn = fnRE.test(curr.toString()) ? RegExp.$1 || ANON : ANON; - args = Array.prototype.slice.call(curr['arguments']); - stack[j++] = fn + '(' + stringifyArguments(args) + ')'; - - //Opera bug: if curr.caller does not exist, Opera returns curr (WTF) - if (curr === curr.caller && window.opera) { - //TODO: check for same arguments if possible - break; - } - curr = curr.caller; - } - return stack; - } -}; - -/** - * - */ -function NameGuesser() { -} - -NameGuesser.prototype = { - - sourceCache: {}, - - ajax: function(url) { - var req = this.createXMLHTTPObject(); - if (!req) { - return; - } - req.open('GET', url, false); - req.setRequestHeader('User-Agent', 'XMLHTTP/1.0'); - req.send(''); - return req.responseText; - }, - - createXMLHTTPObject: function() { - // Try XHR methods in order and store XHR factory - var xmlhttp, XMLHttpFactories = [ - function() { - return new XMLHttpRequest(); - }, function() { - return new ActiveXObject('Msxml2.XMLHTTP'); - }, function() { - return new ActiveXObject('Msxml3.XMLHTTP'); - }, function() { - return new ActiveXObject('Microsoft.XMLHTTP'); - } - ]; - for (var i = 0; i < XMLHttpFactories.length; i++) { - try { - xmlhttp = XMLHttpFactories[i](); - // Use memoization to cache the factory - this.createXMLHTTPObject = XMLHttpFactories[i]; - return xmlhttp; - } catch (e) {} - } - }, - - getSource: function(url) { - if (!(url in this.sourceCache)) { - this.sourceCache[url] = this.ajax(url).split('\n'); - } - return this.sourceCache[url]; - }, - - guessFunctions: function(stack) { - for (var i = 0; i < stack.length; ++i) { - var reStack = /{anonymous}\(.*\)@(\w+:\/\/([-\w\.]+)+(:\d+)?[^:]+):(\d+):?(\d+)?/; - var frame = stack[i], m = reStack.exec(frame); - if (m) { - var file = m[1], lineno = m[4]; //m[7] is character position in Chrome - if (file && lineno) { - var functionName = this.guessFunctionName(file, lineno); - stack[i] = frame.replace('{anonymous}', functionName); - } - } - } - return stack; - }, - - guessFunctionName: function(url, lineNo) { - try { - return this.guessFunctionNameFromLines(lineNo, this.getSource(url)); - } catch (e) { - return 'getSource failed with url: ' + url + ', exception: ' + e.toString(); - } - }, - - guessFunctionNameFromLines: function(lineNo, source) { - var reFunctionArgNames = /function ([^(]*)\(([^)]*)\)/; - var reGuessFunction = /['"]?([0-9A-Za-z_]+)['"]?\s*[:=]\s*(function|eval|new Function)/; - // Walk backwards from the first line in the function until we find the line which - // matches the pattern above, which is the function definition - var line = '', maxLines = 10; - for (var i = 0; i < maxLines; ++i) { - line = source[lineNo - i] + line; - if (line !== undefined) { - var m = reGuessFunction.exec(line); - if (m) { - return m[1]; - } - else { - m = reFunctionArgNames.exec(line); - } - if (m && m[1]) { - return m[1]; - } - } - } - return '(?)'; - } -}; - -var guesser = new NameGuesser(); - -var frameIgnorePatterns = [ - /http:\/\/localhost:4020\/sproutcore.js:/ -]; - -exports.ignoreFramesMatching = function(regex) { - frameIgnorePatterns.push(regex); -}; - -/** - * Create a stack trace from an exception - * @param ex {Error} The error to create a stacktrace from (optional) - * @param guess {Boolean} If we should try to resolve the names of anonymous functions - */ -exports.Trace = function Trace(ex, guess) { - this._ex = ex; - this._stack = decoders[mode](ex); - - if (guess) { - this._stack = guesser.guessFunctions(this._stack); - } -}; - -/** - * Log to the console a number of lines (default all of them) - * @param lines {number} Maximum number of lines to wrote to console - */ -exports.Trace.prototype.log = function(lines) { - if (lines <= 0) { - // You aren't going to have more lines in your stack trace than this - // and it still fits in a 32bit integer - lines = 999999999; - } - - var printed = 0; - for (var i = 0; i < this._stack.length && printed < lines; i++) { - var frame = this._stack[i]; - var display = true; - frameIgnorePatterns.forEach(function(regex) { - if (regex.test(frame)) { - display = false; - } - }); - if (display) { - console.debug(frame); - printed++; - } - } -}; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/useragent', ['require', 'exports', 'module' ], function(require, exports, module) { - -var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase(); -var ua = navigator.userAgent; -var av = navigator.appVersion; - -/** 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 */ -exports.isMac = (os == "mac"); - -/** Is the user using a browser that identifies itself as Linux */ -exports.isLinux = (os == "linux"); - -exports.isIE = ! + "\v1"; - -/** Is this Firefox or related? */ -exports.isGecko = exports.isMozilla = window.controllers && window.navigator.product === "Gecko"; - -/** oldGecko == rev < 2.0 **/ -exports.isOldGecko = exports.isGecko && /rv\:1/.test(navigator.userAgent); - -/** 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 */ -exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined; - -exports.isAIR = ua.indexOf("AdobeAIR") >= 0; - -exports.isIPad = ua.indexOf("iPad") >= 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. - * - * Take copy as an example, Mac people expect to use CMD or APPLE + C - * Windows folks expect to use CTRL + C - */ -exports.OS = { - LINUX: 'LINUX', - MAC: 'MAC', - WINDOWS: 'WINDOWS' -}; - -/** - * Return an exports.OS constant - */ -exports.getOS = function() { - if (exports.isMac) { - return exports.OS['MAC']; - } else if (exports.isLinux) { - return exports.OS['LINUX']; - } else { - return exports.OS['WINDOWS']; - } -}; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/oop', ['require', 'exports', 'module' ], function(require, exports, module) { - -exports.inherits = (function() { - var tempCtor = function() {}; - return function(ctor, superCtor) { - tempCtor.prototype = superCtor.prototype; - ctor.super_ = superCtor.prototype; - ctor.prototype = new tempCtor(); - ctor.prototype.constructor = ctor; - } -}()); - -exports.mixin = function(obj, mixin) { - for (var key in mixin) { - obj[key] = mixin[key]; - } -}; - -exports.implement = function(proto, mixin) { - exports.mixin(proto, mixin); -}; - -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Irakli Gozalishvili (http://jeditoolkit.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/event_emitter', ['require', 'exports', 'module' ], function(require, exports, module) { - -var EventEmitter = {}; - -EventEmitter._emit = -EventEmitter._dispatchEvent = function(eventName, e) { - this._eventRegistry = this._eventRegistry || {}; - - var listeners = this._eventRegistry[eventName]; - if (!listeners || !listeners.length) return; - - var e = e || {}; - e.type = eventName; - - for (var i=0; i - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/lang', ['require', 'exports', 'module' ], function(require, exports, module) { - -exports.stringReverse = function(string) { - return string.split("").reverse().join(""); -}; - -exports.stringRepeat = function (string, count) { - return new Array(count + 1).join(string); -}; - -exports.copyObject = function(obj) { - var copy = {}; - for (var key in obj) { - copy[key] = obj[key]; - } - return copy; -}; - -exports.arrayToMap = function(arr) { - var map = {}; - for (var i=0; i (http://jeditoolkit.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/settings', ['require', 'exports', 'module' , 'pilot/console', 'pilot/oop', 'pilot/types', 'pilot/event_emitter', 'pilot/catalog'], function(require, exports, module) { - -/** - * This plug-in manages settings. - */ - -var console = require('pilot/console'); -var oop = require('pilot/oop'); -var types = require('pilot/types'); -var EventEmitter = require('pilot/event_emitter').EventEmitter; -var catalog = require('pilot/catalog'); - -var settingExtensionSpec = { - name: 'setting', - description: 'A setting is something that the application offers as a ' + - 'way to customize how it works', - register: 'env.settings.addSetting', - indexOn: 'name' -}; - -exports.startup = function(data, reason) { - catalog.addExtensionSpec(settingExtensionSpec); -}; - -exports.shutdown = function(data, reason) { - catalog.removeExtensionSpec(settingExtensionSpec); -}; - - -/** - * Create a new setting. - * @param settingSpec An object literal that looks like this: - * { - * name: 'thing', - * description: 'Thing is an example setting', - * type: 'string', - * defaultValue: 'something' - * } - */ -function Setting(settingSpec, settings) { - this._settings = settings; - - Object.keys(settingSpec).forEach(function(key) { - this[key] = settingSpec[key]; - }, this); - - this.type = types.getType(this.type); - if (this.type == null) { - throw new Error('In ' + this.name + - ': can\'t find type for: ' + JSON.stringify(settingSpec.type)); - } - - if (!this.name) { - throw new Error('Setting.name == undefined. Ignoring.', this); - } - - if (!this.defaultValue === undefined) { - throw new Error('Setting.defaultValue == undefined', this); - } - - if (this.onChange) { - this.on('change', this.onChange.bind(this)) - } - - this.set(this.defaultValue); -} -Setting.prototype = { - get: function() { - return this.value; - }, - - set: function(value) { - if (this.value === value) { - return; - } - - this.value = value; - if (this._settings.persister) { - this._settings.persister.persistValue(this._settings, this.name, value); - } - - this._dispatchEvent('change', { setting: this, value: value }); - }, - - /** - * Reset the value of the key setting to it's default - */ - resetValue: function() { - this.set(this.defaultValue); - } -}; -oop.implement(Setting.prototype, EventEmitter); - - -/** - * A base class for all the various methods of storing settings. - *

Usage: - *

- * // Create manually, or require 'settings' from the container.
- * // This is the manual version:
- * var settings = plugins.catalog.getObject('settings');
- * // Add a new setting
- * settings.addSetting({ name:'foo', ... });
- * // Display the default value
- * alert(settings.get('foo'));
- * // Alter the value, which also publishes the change etc.
- * settings.set('foo', 'bar');
- * // Reset the value to the default
- * settings.resetValue('foo');
- * 
- * @constructor - */ -function Settings(persister) { - // Storage for deactivated values - this._deactivated = {}; - - // Storage for the active settings - this._settings = {}; - // We often want sorted setting names. Cache - this._settingNames = []; - - if (persister) { - this.setPersister(persister); - } -}; - -Settings.prototype = { - /** - * Function to add to the list of available settings. - *

Example usage: - *

-     * var settings = plugins.catalog.getObject('settings');
-     * settings.addSetting({
-     *     name: 'tabsize', // For use in settings.get('X')
-     *     type: 'number',  // To allow value checking.
-     *     defaultValue: 4  // Default value for use when none is directly set
-     * });
-     * 
- * @param {object} settingSpec Object containing name/type/defaultValue members. - */ - addSetting: function(settingSpec) { - var setting = new Setting(settingSpec, this); - this._settings[setting.name] = setting; - this._settingNames.push(setting.name); - this._settingNames.sort(); - }, - - addSettings: function addSettings(settings) { - Object.keys(settings).forEach(function (name) { - var setting = settings[name]; - if (!('name' in setting)) setting.name = name; - this.addSetting(setting); - }, this); - }, - - removeSetting: function(setting) { - var name = (typeof setting === 'string' ? setting : setting.name); - setting = this._settings[name]; - delete this._settings[name]; - util.arrayRemove(this._settingNames, name); - settings.removeAllListeners('change'); - }, - - removeSettings: function removeSettings(settings) { - Object.keys(settings).forEach(function(name) { - var setting = settings[name]; - if (!('name' in setting)) setting.name = name; - this.removeSettings(setting); - }, this); - }, - - getSettingNames: function() { - return this._settingNames; - }, - - getSetting: function(name) { - return this._settings[name]; - }, - - /** - * A Persister is able to store settings. It is an object that defines - * two functions: - * loadInitialValues(settings) and persistValue(settings, key, value). - */ - setPersister: function(persister) { - this._persister = persister; - if (persister) { - persister.loadInitialValues(this); - } - }, - - resetAll: function() { - this.getSettingNames().forEach(function(key) { - this.resetValue(key); - }, this); - }, - - /** - * Retrieve a list of the known settings and their values - */ - _list: function() { - var reply = []; - this.getSettingNames().forEach(function(setting) { - reply.push({ - 'key': setting, - 'value': this.getSetting(setting).get() - }); - }, this); - return reply; - }, - - /** - * Prime the local cache with the defaults. - */ - _loadDefaultValues: function() { - this._loadFromObject(this._getDefaultValues()); - }, - - /** - * Utility to load settings from an object - */ - _loadFromObject: function(data) { - // We iterate over data rather than keys so we don't forget values - // which don't have a setting yet. - for (var key in data) { - if (data.hasOwnProperty(key)) { - var setting = this._settings[key]; - if (setting) { - var value = setting.type.parse(data[key]); - this.set(key, value); - } else { - this.set(key, data[key]); - } - } - } - }, - - /** - * Utility to grab all the settings and export them into an object - */ - _saveToObject: function() { - return this.getSettingNames().map(function(key) { - return this._settings[key].type.stringify(this.get(key)); - }.bind(this)); - }, - - /** - * The default initial settings - */ - _getDefaultValues: function() { - return this.getSettingNames().map(function(key) { - return this._settings[key].spec.defaultValue; - }.bind(this)); - } -}; -exports.settings = new Settings(); - -/** - * Save the settings in a cookie - * This code has not been tested since reboot - * @constructor - */ -function CookiePersister() { -}; - -CookiePersister.prototype = { - loadInitialValues: function(settings) { - settings._loadDefaultValues(); - var data = cookie.get('settings'); - settings._loadFromObject(JSON.parse(data)); - }, - - persistValue: function(settings, key, value) { - try { - var stringData = JSON.stringify(settings._saveToObject()); - cookie.set('settings', stringData); - } catch (ex) { - console.error('Unable to JSONify the settings! ' + ex); - return; - } - } -}; - -exports.CookiePersister = CookiePersister; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Skywriter Team (skywriter@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/commands/settings', ['require', 'exports', 'module' , 'pilot/canon'], function(require, exports, module) { - - -var setCommandSpec = { - name: 'set', - params: [ - { - name: 'setting', - type: 'setting', - description: 'The name of the setting to display or alter', - defaultValue: null - }, - { - name: 'value', - type: 'settingValue', - description: 'The new value for the chosen setting', - defaultValue: null - } - ], - description: 'define and show settings', - exec: function(env, args, request) { - var html; - if (!args.setting) { - // 'set' by itself lists all the settings - var names = env.settings.getSettingNames(); - html = ''; - // first sort the settingsList based on the name - names.sort(function(name1, name2) { - return name1.localeCompare(name2); - }); - - names.forEach(function(name) { - var setting = env.settings.getSetting(name); - var url = 'https://wiki.mozilla.org/Labs/Skywriter/Settings#' + - setting.name; - html += '' + - setting.name + - ' = ' + - setting.value + - '
'; - }); - } else { - // set with only a setting, shows the value for that setting - if (args.value === undefined) { - html = '' + setting.name + ' = ' + - setting.get(); - } else { - // Actually change the setting - args.setting.set(args.value); - html = 'Setting: ' + args.setting.name + ' = ' + - args.setting.get(); - } - } - request.done(html); - } -}; - -var unsetCommandSpec = { - name: 'unset', - params: [ - { - name: 'setting', - type: 'setting', - description: 'The name of the setting to return to defaults' - } - ], - description: 'unset a setting entirely', - exec: function(env, args, request) { - var setting = env.settings.get(args.setting); - if (!setting) { - request.doneWithError('No setting with the name ' + - args.setting + '.'); - return; - } - - setting.reset(); - request.done('Reset ' + setting.name + ' to default: ' + - env.settings.get(args.setting)); - } -}; - -var canon = require('pilot/canon'); - -exports.startup = function(data, reason) { - canon.addCommand(setCommandSpec); - canon.addCommand(unsetCommandSpec); -}; - -exports.shutdown = function(data, reason) { - canon.removeCommand(setCommandSpec); - canon.removeCommand(unsetCommandSpec); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Skywriter Team (skywriter@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/commands/basic', ['require', 'exports', 'module' , 'pilot/typecheck', 'pilot/canon'], function(require, exports, module) { - - -var checks = require("pilot/typecheck"); -var canon = require('pilot/canon'); - -/** - * - */ -var helpMessages = { - plainPrefix: - '

Welcome to Skywriter - Code in the Cloud

', - plainSuffix: - 'For more information, see the Skywriter Wiki.' -}; - -/** - * 'help' command - */ -var helpCommandSpec = { - name: 'help', - params: [ - { - name: 'search', - type: 'text', - description: 'Search string to narrow the output.', - defaultValue: null - } - ], - description: 'Get help on the available commands.', - exec: function(env, args, request) { - var output = []; - - var command = canon.getCommand(args.search); - if (command && command.exec) { - // caught a real command - output.push(command.description ? - command.description : - 'No description for ' + args.search); - } else { - var showHidden = false; - - if (!args.search && helpMessages.plainPrefix) { - output.push(helpMessages.plainPrefix); - } - - if (command) { - // We must be looking at sub-commands - output.push('

Sub-Commands of ' + command.name + '

'); - output.push('

' + command.description + '

'); - } - else if (args.search) { - if (args.search == 'hidden') { // sneaky, sneaky. - args.search = ''; - showHidden = true; - } - output.push('

Commands starting with \'' + args.search + '\':

'); - } - else { - output.push('

Available Commands:

'); - } - - var commandNames = canon.getCommandNames(); - commandNames.sort(); - - output.push(''); - for (var i = 0; i < commandNames.length; i++) { - command = canon.getCommand(commandNames[i]); - if (!showHidden && command.hidden) { - continue; - } - if (command.description === undefined) { - // Ignore editor actions - continue; - } - if (args.search && command.name.indexOf(args.search) !== 0) { - // Filtered out by the user - continue; - } - if (!args.search && command.name.indexOf(' ') != -1) { - // sub command - continue; - } - if (command && command.name == args.search) { - // sub command, and we've already given that help - continue; - } - - // todo add back a column with parameter information, perhaps? - - output.push(''); - output.push(''); - output.push(''); - output.push(''); - } - output.push('
' + command.name + '' + command.description + '
'); - - if (!args.search && helpMessages.plainSuffix) { - output.push(helpMessages.plainSuffix); - } - } - - request.done(output.join('')); - } -}; - -/** - * 'eval' command - */ -var evalCommandSpec = { - name: 'eval', - params: [ - { - name: 'javascript', - type: 'text', - description: 'The JavaScript to evaluate' - } - ], - description: 'evals given js code and show the result', - hidden: true, - exec: function(env, args, request) { - var result; - var javascript = args.javascript; - try { - result = eval(javascript); - } catch (e) { - result = 'Error: ' + e.message + ''; - } - - var msg = ''; - var type = ''; - var x; - - if (checks.isFunction(result)) { - // converts the function to a well formated string - msg = (result + '').replace(/\n/g, '
').replace(/ /g, ' '); - type = 'function'; - } else if (checks.isObject(result)) { - if (Array.isArray(result)) { - type = 'array'; - } else { - type = 'object'; - } - - var items = []; - var value; - - for (x in result) { - if (result.hasOwnProperty(x)) { - if (checks.isFunction(result[x])) { - value = '[function]'; - } else if (checks.isObject(result[x])) { - value = '[object]'; - } else { - value = result[x]; - } - - items.push({name: x, value: value}); - } - } - - items.sort(function(a,b) { - return (a.name.toLowerCase() < b.name.toLowerCase()) ? -1 : 1; - }); - - for (x = 0; x < items.length; x++) { - msg += '' + items[x].name + ': ' + items[x].value + '
'; - } - - } else { - msg = result; - type = typeof result; - } - - request.done('Result for eval \'' + javascript + '\'' + - ' (type: '+ type+'):

'+ msg); - } -}; - -/** - * 'version' command - */ -var versionCommandSpec = { - name: 'version', - description: 'show the Skywriter version', - hidden: true, - exec: function(env, args, request) { - var version = 'Skywriter ' + skywriter.versionNumber + ' (' + - skywriter.versionCodename + ')'; - request.done(version); - } -}; - -/** - * 'skywriter' command - */ -var skywriterCommandSpec = { - name: 'skywriter', - hidden: true, - exec: function(env, args, request) { - var index = Math.floor(Math.random() * messages.length); - request.done('Skywriter ' + messages[index]); - } -}; -var messages = [ - 'really wants you to trick it out in some way.', - 'is your Web editor.', - 'would love to be like Emacs on the Web.', - 'is written on the Web platform, so you can tweak it.' -]; - - -var canon = require('pilot/canon'); - -exports.startup = function(data, reason) { - canon.addCommand(helpCommandSpec); - canon.addCommand(evalCommandSpec); - // canon.addCommand(versionCommandSpec); - canon.addCommand(skywriterCommandSpec); -}; - -exports.shutdown = function(data, reason) { - canon.removeCommand(helpCommandSpec); - canon.removeCommand(evalCommandSpec); - // canon.removeCommand(versionCommandSpec); - canon.removeCommand(skywriterCommandSpec); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/typecheck', ['require', 'exports', 'module' ], function(require, exports, module) { - -var objectToString = Object.prototype.toString; - -/** - * Return true if it is a String - */ -exports.isString = function(it) { - return it && objectToString.call(it) === "[object String]"; -}; - -/** - * Returns true if it is a Boolean. - */ -exports.isBoolean = function(it) { - return it && objectToString.call(it) === "[object Boolean]"; -}; - -/** - * Returns true if it is a Number. - */ -exports.isNumber = function(it) { - return it && objectToString.call(it) === "[object Number]" && isFinite(it); -}; - -/** - * Hack copied from dojo. - */ -exports.isObject = function(it) { - return it !== undefined && - (it === null || typeof it == "object" || - Array.isArray(it) || exports.isFunction(it)); -}; - -/** - * Is the passed object a function? - * From dojo.isFunction() - */ -exports.isFunction = function(it) { - return it && objectToString.call(it) === "[object Function]"; -}; - -});/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/settings/canon', ['require', 'exports', 'module' ], function(require, exports, module) { - - -var historyLengthSetting = { - name: "historyLength", - description: "How many typed commands do we recall for reference?", - type: "number", - defaultValue: 50 -}; - -exports.startup = function(data, reason) { - data.env.settings.addSetting(historyLengthSetting); -}; - -exports.shutdown = function(data, reason) { - data.env.settings.removeSetting(historyLengthSetting); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kevin Dangoor (kdangoor@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/plugin_manager', ['require', 'exports', 'module' , 'pilot/promise'], function(require, exports, module) { - -var Promise = require("pilot/promise").Promise; - -exports.REASONS = { - APP_STARTUP: 1, - APP_SHUTDOWN: 2, - PLUGIN_ENABLE: 3, - PLUGIN_DISABLE: 4, - PLUGIN_INSTALL: 5, - PLUGIN_UNINSTALL: 6, - PLUGIN_UPGRADE: 7, - PLUGIN_DOWNGRADE: 8 -}; - -exports.Plugin = function(name) { - this.name = name; - this.status = this.INSTALLED; -}; - -exports.Plugin.prototype = { - /** - * constants for the state - */ - NEW: 0, - INSTALLED: 1, - REGISTERED: 2, - STARTED: 3, - UNREGISTERED: 4, - SHUTDOWN: 5, - - install: function(data, reason) { - var pr = new Promise(); - if (this.status > this.NEW) { - pr.resolve(this); - return pr; - } - require([this.name], function(pluginModule) { - if (pluginModule.install) { - pluginModule.install(data, reason); - } - this.status = this.INSTALLED; - pr.resolve(this); - }.bind(this)); - return pr; - }, - - register: function(data, reason) { - var pr = new Promise(); - if (this.status != this.INSTALLED) { - pr.resolve(this); - return pr; - } - require([this.name], function(pluginModule) { - if (pluginModule.register) { - pluginModule.register(data, reason); - } - this.status = this.REGISTERED; - pr.resolve(this); - }.bind(this)); - return pr; - }, - - startup: function(data, reason) { - reason = reason || exports.REASONS.APP_STARTUP; - var pr = new Promise(); - if (this.status != this.REGISTERED) { - pr.resolve(this); - return pr; - } - require([this.name], function(pluginModule) { - if (pluginModule.startup) { - pluginModule.startup(data, reason); - } - this.status = this.STARTED; - pr.resolve(this); - }.bind(this)); - return pr; - }, - - shutdown: function(data, reason) { - if (this.status != this.STARTED) { - return; - } - pluginModule = require(this.name); - if (pluginModule.shutdown) { - pluginModule.shutdown(data, reason); - } - } -}; - -exports.PluginCatalog = function() { - this.plugins = {}; -}; - -exports.PluginCatalog.prototype = { - registerPlugins: function(pluginList, data, reason) { - var registrationPromises = []; - pluginList.forEach(function(pluginName) { - var plugin = this.plugins[pluginName]; - if (plugin === undefined) { - plugin = new exports.Plugin(pluginName); - this.plugins[pluginName] = plugin; - registrationPromises.push(plugin.register(data, reason)); - } - }.bind(this)); - return Promise.group(registrationPromises); - }, - - startupPlugins: function(data, reason) { - var startupPromises = []; - for (var pluginName in this.plugins) { - var plugin = this.plugins[pluginName]; - startupPromises.push(plugin.startup(data, reason)); - } - return Promise.group(startupPromises); - } -}; - -exports.catalog = new exports.PluginCatalog(); - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/promise', ['require', 'exports', 'module' , 'pilot/console', 'pilot/stacktrace'], function(require, exports, module) { - -var console = require("pilot/console"); -var Trace = require('pilot/stacktrace').Trace; - -/** - * A promise can be in one of 2 states. - * The ERROR and SUCCESS states are terminal, the PENDING state is the only - * start state. - */ -var ERROR = -1; -var PENDING = 0; -var SUCCESS = 1; - -/** - * We give promises and ID so we can track which are outstanding - */ -var _nextId = 0; - -/** - * Debugging help if 2 things try to complete the same promise. - * This can be slow (especially on chrome due to the stack trace unwinding) so - * we should leave this turned off in normal use. - */ -var _traceCompletion = false; - -/** - * Outstanding promises. Handy list for debugging only. - */ -var _outstanding = []; - -/** - * Recently resolved promises. Also for debugging only. - */ -var _recent = []; - -/** - * Create an unfulfilled promise - */ -Promise = function () { - this._status = PENDING; - this._value = undefined; - this._onSuccessHandlers = []; - this._onErrorHandlers = []; - - // Debugging help - this._id = _nextId++; - //this._createTrace = new Trace(new Error()); - _outstanding[this._id] = this; -}; - -/** - * Yeay for RTTI. - */ -Promise.prototype.isPromise = true; - -/** - * Have we either been resolve()ed or reject()ed? - */ -Promise.prototype.isComplete = function() { - return this._status != PENDING; -}; - -/** - * Have we resolve()ed? - */ -Promise.prototype.isResolved = function() { - return this._status == SUCCESS; -}; - -/** - * Have we reject()ed? - */ -Promise.prototype.isRejected = function() { - return this._status == ERROR; -}; - -/** - * Take the specified action of fulfillment of a promise, and (optionally) - * a different action on promise rejection. - */ -Promise.prototype.then = function(onSuccess, onError) { - if (typeof onSuccess === 'function') { - if (this._status === SUCCESS) { - onSuccess.call(null, this._value); - } else if (this._status === PENDING) { - this._onSuccessHandlers.push(onSuccess); - } - } - - if (typeof onError === 'function') { - if (this._status === ERROR) { - onError.call(null, this._value); - } else if (this._status === PENDING) { - this._onErrorHandlers.push(onError); - } - } - - return this; -}; - -/** - * Like then() except that rather than returning this we return - * a promise which - */ -Promise.prototype.chainPromise = function(onSuccess) { - var chain = new Promise(); - chain._chainedFrom = this; - this.then(function(data) { - try { - chain.resolve(onSuccess(data)); - } catch (ex) { - chain.reject(ex); - } - }, function(ex) { - chain.reject(ex); - }); - return chain; -}; - -/** - * Supply the fulfillment of a promise - */ -Promise.prototype.resolve = function(data) { - return this._complete(this._onSuccessHandlers, SUCCESS, data, 'resolve'); -}; - -/** - * Renege on a promise - */ -Promise.prototype.reject = function(data) { - return this._complete(this._onErrorHandlers, ERROR, data, 'reject'); -}; - -/** - * Internal method to be called on resolve() or reject(). - * @private - */ -Promise.prototype._complete = function(list, status, data, name) { - // Complain if we've already been completed - if (this._status != PENDING) { - console.group('Promise already closed'); - console.error('Attempted ' + name + '() with ', data); - console.error('Previous status = ', this._status, - ', previous value = ', this._value); - console.trace(); - - if (this._completeTrace) { - console.error('Trace of previous completion:'); - this._completeTrace.log(5); - } - console.groupEnd(); - return this; - } - - if (_traceCompletion) { - this._completeTrace = new Trace(new Error()); - } - - this._status = status; - this._value = data; - - // Call all the handlers, and then delete them - list.forEach(function(handler) { - handler.call(null, this._value); - }, this); - this._onSuccessHandlers.length = 0; - this._onErrorHandlers.length = 0; - - // Remove the given {promise} from the _outstanding list, and add it to the - // _recent list, pruning more than 20 recent promises from that list. - delete _outstanding[this._id]; - _recent.push(this); - while (_recent.length > 20) { - _recent.shift(); - } - - return this; -}; - -/** - * Takes an array of promises and returns a promise that that is fulfilled once - * all the promises in the array are fulfilled - * @param group The array of promises - * @return the promise that is fulfilled when all the array is fulfilled - */ -Promise.group = function(promiseList) { - if (!(promiseList instanceof Array)) { - promiseList = Array.prototype.slice.call(arguments); - } - - // If the original array has nothing in it, return now to avoid waiting - if (promiseList.length === 0) { - return new Promise().resolve([]); - } - - var groupPromise = new Promise(); - var results = []; - var fulfilled = 0; - - var onSuccessFactory = function(index) { - return function(data) { - results[index] = data; - fulfilled++; - // If the group has already failed, silently drop extra results - if (groupPromise._status !== ERROR) { - if (fulfilled === promiseList.length) { - groupPromise.resolve(results); - } - } - }; - }; - - promiseList.forEach(function(promise, index) { - var onSuccess = onSuccessFactory(index); - var onError = groupPromise.reject.bind(groupPromise); - promise.then(onSuccess, onError); - }); - - return groupPromise; -}; - -exports.Promise = Promise; -exports._outstanding = _outstanding; -exports._recent = _recent; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is DomTemplate. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) (original author) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/environment', ['require', 'exports', 'module' , 'pilot/settings'], function(require, exports, module) { - - -var settings = require("pilot/settings").settings; - -/** - * Create an environment object - */ -function create() { - return { - settings: settings - }; -}; - -exports.create = create; - - -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Irakli Gozalishvili (http://jeditoolkit.com) - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/editor', ['require', 'exports', 'module' , 'pilot/fixoldbrowsers', 'pilot/oop', 'pilot/event', 'pilot/lang', 'pilot/useragent', 'ace/keyboard/textinput', 'ace/mouse_handler', 'ace/keyboard/keybinding', 'ace/edit_session', 'ace/search', 'ace/background_tokenizer', 'ace/range', 'pilot/event_emitter'], function(require, exports, module) { - -require("pilot/fixoldbrowsers"); - -var oop = require("pilot/oop"); -var event = require("pilot/event"); -var lang = require("pilot/lang"); -var useragent = require("pilot/useragent"); -var TextInput = require("ace/keyboard/textinput").TextInput; -var MouseHandler = require("ace/mouse_handler").MouseHandler; -//var TouchHandler = require("ace/touch_handler").TouchHandler; -var KeyBinding = require("ace/keyboard/keybinding").KeyBinding; -var EditSession = require("ace/edit_session").EditSession; -var Search = require("ace/search").Search; -var BackgroundTokenizer = require("ace/background_tokenizer").BackgroundTokenizer; -var Range = require("ace/range").Range; -var EventEmitter = require("pilot/event_emitter").EventEmitter; - -var Editor =function(renderer, session) { - var container = renderer.getContainerElement(); - this.container = container; - this.renderer = renderer; - - this.textInput = new TextInput(renderer.getTextAreaContainer(), this); - this.keyBinding = new KeyBinding(this); - - // TODO detect touch event support - if (useragent.isIPad) { - //this.$mouseHandler = new TouchHandler(this); - } else { - this.$mouseHandler = new MouseHandler(this); - } - - this.$blockScrolling = 0; - this.$search = new Search().set({ - wrap: true - }); - - this.setSession(session || new EditSession("")); -}; - -(function(){ - - oop.implement(this, EventEmitter); - - this.$forwardEvents = { - gutterclick: 1, - gutterdblclick: 1 - }; - - this.$originalAddEventListener = this.addEventListener; - this.$originalRemoveEventListener = this.removeEventListener; - - this.addEventListener = function(eventName, callback) { - if (this.$forwardEvents[eventName]) { - return this.renderer.addEventListener(eventName, callback); - } else { - return this.$originalAddEventListener(eventName, callback); - } - }; - - this.removeEventListener = function(eventName, callback) { - if (this.$forwardEvents[eventName]) { - return this.renderer.removeEventListener(eventName, callback); - } else { - return this.$originalRemoveEventListener(eventName, callback); - } - }; - - this.setKeyboardHandler = function(keyboardHandler) { - this.keyBinding.setKeyboardHandler(keyboardHandler); - }; - - this.getKeyboardHandler = function() { - return this.keyBinding.getKeyboardHandler(); - } - - this.setSession = function(session) { - if (this.session == session) return; - - if (this.session) { - var oldSession = this.session; - this.session.removeEventListener("change", this.$onDocumentChange); - this.session.removeEventListener("changeMode", this.$onChangeMode); - this.session.removeEventListener("changeTabSize", this.$onChangeTabSize); - this.session.removeEventListener("changeWrapLimit", this.$onChangeWrapLimit); - this.session.removeEventListener("changeWrapMode", this.$onChangeWrapMode); - 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); - - var selection = this.session.getSelection(); - selection.removeEventListener("changeCursor", this.$onCursorChange); - selection.removeEventListener("changeSelection", this.$onSelectionChange); - - this.session.setScrollTopRow(this.renderer.getScrollTopRow()); - } - - this.session = session; - - this.$onDocumentChange = this.onDocumentChange.bind(this); - session.addEventListener("change", this.$onDocumentChange); - this.renderer.setSession(session); - - this.$onChangeMode = this.onChangeMode.bind(this); - session.addEventListener("changeMode", this.$onChangeMode); - - this.$onChangeTabSize = this.renderer.updateText.bind(this.renderer); - session.addEventListener("changeTabSize", this.$onChangeTabSize); - - this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this); - session.addEventListener("changeWrapLimit", this.$onChangeWrapLimit); - - this.$onChangeWrapMode = this.onChangeWrapMode.bind(this); - session.addEventListener("changeWrapMode", this.$onChangeWrapMode); - - 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.selection = session.getSelection(); - this.selection.addEventListener("changeCursor", this.$onCursorChange); - - this.$onSelectionChange = this.onSelectionChange.bind(this); - this.selection.addEventListener("changeSelection", this.$onSelectionChange); - - this.onChangeMode(); - this.bgTokenizer.setDocument(session.getDocument()); - this.bgTokenizer.start(0); - - this.onCursorChange(); - this.onSelectionChange(); - this.onChangeFrontMarker(); - this.onChangeBackMarker(); - this.onChangeBreakpoint(); - this.onChangeAnnotation(); - this.renderer.scrollToRow(session.getScrollTopRow()); - this.renderer.updateFull(); - - this._dispatchEvent("changeSession", { - session: session, - oldSession: oldSession - }); - }; - - this.getSession = function() { - return this.session; - }; - - this.getSelection = function() { - return this.selection; - }; - - this.resize = function() { - this.renderer.onResize(); - }; - - this.setTheme = function(theme) { - this.renderer.setTheme(theme); - }; - - this.setStyle = function(style) { - this.renderer.setStyle(style) - }; - - this.unsetStyle = function(style) { - this.renderer.unsetStyle(style) - } - - this.$highlightBrackets = function() { - if (this.session.$bracketHighlight) { - this.session.removeMarker(this.session.$bracketHighlight); - this.session.$bracketHighlight = null; - } - - if (this.$highlightPending) { - return; - } - - // perform highlight async to not block the browser during navigation - var self = this; - this.$highlightPending = true; - setTimeout(function() { - self.$highlightPending = false; - - var pos = self.session.findMatchingBracket(self.getCursorPosition()); - if (pos) { - var range = new Range(pos.row, pos.column, pos.row, pos.column+1); - self.session.$bracketHighlight = self.session.addMarker(range, "ace_bracket"); - } - }, 10); - }; - - this.focus = function() { - // Safari need the timeout - // iOS and Firefox need it called immediately - // to be on the save side we do both - var _self = this; - setTimeout(function() { - _self.textInput.focus(); - }); - this.textInput.focus(); - }; - - this.blur = function() { - this.textInput.blur(); - }; - - this.onFocus = function() { - this.renderer.showCursor(); - this.renderer.visualizeFocus(); - this._dispatchEvent("focus"); - }; - - this.onBlur = function() { - this.renderer.hideCursor(); - this.renderer.visualizeBlur(); - this._dispatchEvent("blur"); - }; - - this.onDocumentChange = function(e) { - var delta = e.data; - var range = delta.range; - - this.bgTokenizer.start(range.start.row); - if (range.start.row == range.end.row && delta.action != "insertLines" && delta.action != "removeLines") - var lastRow = range.end.row; - else - lastRow = Infinity; - this.renderer.updateLines(range.start.row, lastRow); - - // update cursor because tab characters can influence the cursor position - this.renderer.updateCursor(); - }; - - this.onTokenizerUpdate = function(e) { - var rows = e.data; - this.renderer.updateLines(rows.first, rows.last); - }; - - this.onCursorChange = function(e) { - this.renderer.updateCursor(); - - 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(); - }; - - this.$updateHighlightActiveLine = function() { - var session = this.getSession(); - - if (session.$highlightLineMarker) { - session.removeMarker(session.$highlightLineMarker); - } - session.$highlightLineMarker = null; - - if (this.getHighlightActiveLine() && (this.getSelectionStyle() != "line" || !this.selection.isMultiLine())) { - var cursor = this.getCursorPosition(); - var range = new Range(cursor.row, 0, cursor.row+1, 0); - session.$highlightLineMarker = session.addMarker(range, "ace_active_line", "line"); - } - }; - - this.onSelectionChange = function(e) { - var session = this.getSession(); - - if (session.$selectionMarker) { - session.removeMarker(session.$selectionMarker); - } - session.$selectionMarker = null; - - if (!this.selection.isEmpty()) { - var range = this.selection.getRange(); - var style = this.getSelectionStyle(); - session.$selectionMarker = session.addMarker(range, "ace_selection", style); - } - - this.onCursorChange(e); - - if (this.$highlightSelectedWord) - this.mode.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() { - var mode = this.session.getMode(); - if (this.mode == mode) - return; - - this.mode = mode; - var tokenizer = mode.getTokenizer(); - - if (!this.bgTokenizer) { - var onUpdate = this.onTokenizerUpdate.bind(this); - this.bgTokenizer = new BackgroundTokenizer(tokenizer, this); - this.bgTokenizer.addEventListener("update", onUpdate); - } else { - this.bgTokenizer.setTokenizer(tokenizer); - } - - this.renderer.setTokenizer(this.bgTokenizer); - }; - - this.onChangeWrapLimit = function() { - this.renderer.updateFull(); - }; - - this.onChangeWrapMode = function() { - this.renderer.onResize(true); - }; - - this.getCopyText = function() { - if (!this.selection.isEmpty()) { - return this.session.getTextRange(this.getSelectionRange()); - } - else { - return ""; - } - }; - - this.onCut = function() { - if (this.$readOnly) - return; - - if (!this.selection.isEmpty()) { - this.session.remove(this.getSelectionRange()) - this.clearSelection(); - } - }; - - this.insert = function(text) { - if (this.$readOnly) - return; - - var cursor = this.getCursorPosition(); - text = text.replace("\t", this.session.getTabString()); - - // remove selected text - if (!this.selection.isEmpty()) { - var cursor = this.session.remove(this.getSelectionRange()); - this.clearSelection(); - } - else if (this.session.getOverwrite()) { - var range = new Range.fromPoints(cursor, cursor); - range.end.column += text.length; - this.session.remove(range); - } - - this.clearSelection(); - - var lineState = this.bgTokenizer.getState(cursor.row); - var shouldOutdent = this.mode.checkOutdent(lineState, this.session.getLine(cursor.row), text); - var line = this.session.getLine(cursor.row); - var lineIndent = this.mode.getNextLineIndent(lineState, line.slice(0, cursor.column), this.session.getTabString()); - var end = this.session.insert(cursor, text); - - - var lineState = this.bgTokenizer.getState(cursor.row); - // TODO disabled multiline auto indent - // possibly doing the indent before inserting the text - // if (cursor.row !== end.row) { - if (this.session.getDocument().isNewLine(text)) { - this.moveCursorTo(cursor.row+1, 0); - - var size = this.session.getTabSize(), - minIndent = Number.MAX_VALUE; - - - for (var row = cursor.row + 1; row <= end.row; ++row) { - var indent = 0; - - line = this.session.getLine(row); - for (var i = 0; i < line.length; ++i) - if (line.charAt(i) == '\t') - indent += size; - else if (line.charAt(i) == ' ') - indent += 1; - else - break; - if (/[^\s]/.test(line)) - minIndent = Math.min(indent, minIndent); - } - - for (var row = cursor.row + 1; row <= end.row; ++row) { - var outdent = minIndent; - - line = this.session.getLine(row); - for (var i = 0; i < line.length && outdent > 0; ++i) - if (line.charAt(i) == '\t') - outdent -= size; - else if (line.charAt(i) == ' ') - outdent -= 1; - this.session.remove(new Range(row, 0, row, i)); - } - this.session.indentRows(cursor.row + 1, end.row, lineIndent); - } else { - if (shouldOutdent) { - this.mode.autoOutdent(lineState, this.session, cursor.row); - } - }; - } - - this.onTextInput = function(text) { - this.keyBinding.onTextInput(text); - }; - - this.onCommandKey = function(e, hashId, keyCode) { - this.keyBinding.onCommandKey(e, hashId, keyCode); - }; - - this.setOverwrite = function(overwrite) { - this.session.setOverwrite(); - }; - - this.getOverwrite = function() { - return this.session.getOverwrite(); - }; - - this.toggleOverwrite = function() { - this.session.toggleOverwrite(); - }; - - this.setScrollSpeed = function(speed) { - this.$mouseHandler.setScrollSpeed(speed); - }; - - this.getScrollSpeed = function() { - return this.$mouseHandler.getScrollSpeed() - }; - - this.$selectionStyle = "line"; - this.setSelectionStyle = function(style) { - if (this.$selectionStyle == style) return; - - this.$selectionStyle = style; - this.onSelectionChange(); - this._dispatchEvent("changeSelectionStyle", {data: style}); - }; - - this.getSelectionStyle = function() { - return this.$selectionStyle; - }; - - this.$highlightActiveLine = true; - this.setHighlightActiveLine = function(shouldHighlight) { - if (this.$highlightActiveLine == shouldHighlight) return; - - this.$highlightActiveLine = shouldHighlight; - this.$updateHighlightActiveLine(); - }; - - this.getHighlightActiveLine = function() { - return this.$highlightActiveLine; - }; - - this.$highlightSelectedWord = true; - this.setHighlightSelectedWord = function(shouldHighlight) { - if (this.$highlightSelectedWord == shouldHighlight) - return; - - this.$highlightSelectedWord = shouldHighlight; - if (shouldHighlight) - this.mode.highlightSelection(this); - else - this.mode.clearSelectionHighlight(this); - }; - - this.getHighlightSelectedWord = function() { - return this.$highlightSelectedWord; - }; - - this.setShowInvisibles = function(showInvisibles) { - if (this.getShowInvisibles() == showInvisibles) - return; - - this.renderer.setShowInvisibles(showInvisibles); - }; - - this.getShowInvisibles = function() { - return this.renderer.getShowInvisibles(); - }; - - this.setShowPrintMargin = function(showPrintMargin) { - this.renderer.setShowPrintMargin(showPrintMargin); - }; - - this.getShowPrintMargin = function() { - return this.renderer.getShowPrintMargin(); - }; - - this.setPrintMarginColumn = function(showPrintMargin) { - this.renderer.setPrintMarginColumn(showPrintMargin); - }; - - this.getPrintMarginColumn = function() { - return this.renderer.getPrintMarginColumn(); - }; - - this.$readOnly = false; - this.setReadOnly = function(readOnly) { - this.$readOnly = readOnly; - }; - - this.getReadOnly = function() { - return this.$readOnly; - }; - - this.removeRight = function() { - if (this.$readOnly) - return; - - if (this.selection.isEmpty()) { - this.selection.selectRight(); - } - this.session.remove(this.getSelectionRange()) - this.clearSelection(); - }; - - this.removeLeft = function() { - if (this.$readOnly) - return; - - if (this.selection.isEmpty()) - this.selection.selectLeft(); - - this.session.remove(this.getSelectionRange()); - this.clearSelection(); - }; - - this.removeWordRight = function() { - if (this.$readOnly) - return; - - if (this.selection.isEmpty()) - this.selection.selectWordRight(); - - this.session.remove(this.getSelectionRange()); - this.clearSelection(); - }; - - this.removeWordLeft = function() { - if (this.$readOnly) - return; - - if (this.selection.isEmpty()) - this.selection.selectWordLeft(); - - this.session.remove(this.getSelectionRange()); - this.clearSelection(); - }; - - this.removeToLineStart = function() { - if (this.$readOnly) - return; - - if (this.selection.isEmpty()) - this.selection.selectLineStart(); - - this.session.remove(this.getSelectionRange()); - this.clearSelection(); - }; - - this.removeToLineEnd = function() { - if (this.$readOnly) - return; - - if (this.selection.isEmpty()) - this.selection.selectLineEnd(); - - this.session.remove(this.getSelectionRange()); - this.clearSelection(); - }; - - this.splitLine = function() { - if (this.$readOnly) - return; - - if (!this.selection.isEmpty()) { - this.session.remove(this.getSelectionRange()); - this.clearSelection(); - } - - var cursor = this.getCursorPosition(); - this.insert("\n"); - this.moveCursorToPosition(cursor); - }; - - this.transposeLetters = function() { - if (this.$readOnly) - return; - - if (!this.selection.isEmpty()) { - return; - } - - var cursor = this.getCursorPosition(); - var column = cursor.column; - if (column == 0) - return; - - var line = this.session.getLine(cursor.row); - if (column < line.length) { - var swap = line.charAt(column) + line.charAt(column-1); - var range = new Range(cursor.row, column-1, cursor.row, column+1) - } - else { - var swap = line.charAt(column-1) + line.charAt(column-2); - var range = new Range(cursor.row, column-2, cursor.row, column) - } - this.session.replace(range, swap); - }; - - this.indent = function() { - if (this.$readOnly) - return; - - var session = this.session; - var range = this.getSelectionRange(); - - if (range.start.row < range.end.row || range.start.column < range.end.column) { - var rows = this.$getSelectedRows(); - session.indentRows(rows.first, rows.last, "\t"); - } else { - var indentString; - - if (this.session.getUseSoftTabs()) { - var size = session.getTabSize(), - position = this.getCursorPosition(), - column = session.documentToScreenColumn(position.row, position.column), - count = (size - column % size); - - indentString = lang.stringRepeat(" ", count); - } else - indentString = "\t"; - return this.onTextInput(indentString); - } - }; - - this.blockOutdent = function() { - if (this.$readOnly) - return; - - var selection = this.session.getSelection(); - this.session.outdentRows(selection.getRange()); - }; - - this.toggleCommentLines = function() { - if (this.$readOnly) - return; - - var state = this.bgTokenizer.getState(this.getCursorPosition().row); - var rows = this.$getSelectedRows() - this.mode.toggleCommentLines(state, this.session, rows.first, rows.last); - }; - - this.removeLines = function() { - if (this.$readOnly) - return; - - var rows = this.$getSelectedRows(); - this.session.remove(new Range(rows.first, 0, rows.last+1, 0)); - this.clearSelection(); - }; - - this.moveLinesDown = function() { - if (this.$readOnly) - return; - - this.$moveLines(function(firstRow, lastRow) { - return this.session.moveLinesDown(firstRow, lastRow); - }); - }; - - this.moveLinesUp = function() { - if (this.$readOnly) - return; - - this.$moveLines(function(firstRow, lastRow) { - return this.session.moveLinesUp(firstRow, lastRow); - }); - }; - - this.moveText = function(range, toPosition) { - if (this.$readOnly) - return null; - - return this.session.moveText(range, toPosition); - }; - - this.copyLinesUp = function() { - if (this.$readOnly) - return; - - this.$moveLines(function(firstRow, lastRow) { - this.session.duplicateLines(firstRow, lastRow); - return 0; - }); - }; - - this.copyLinesDown = function() { - if (this.$readOnly) - return; - - this.$moveLines(function(firstRow, lastRow) { - return this.session.duplicateLines(firstRow, lastRow); - }); - }; - - - this.$moveLines = function(mover) { - var rows = this.$getSelectedRows(); - - var linesMoved = mover.call(this, rows.first, rows.last); - - var selection = this.selection; - selection.setSelectionAnchor(rows.last+linesMoved+1, 0); - selection.$moveSelection(function() { - selection.moveCursorTo(rows.first+linesMoved, 0); - }); - }; - - this.$getSelectedRows = function() { - var range = this.getSelectionRange().collapseRows(); - - return { - first: range.start.row, - last: range.end.row - }; - }; - - this.onCompositionStart = function(text) { - this.renderer.showComposition(this.getCursorPosition()); - }; - - this.onCompositionUpdate = function(text) { - this.renderer.setCompositionText(text); - }; - - this.onCompositionEnd = function() { - this.renderer.hideComposition(); - }; - - - this.getFirstVisibleRow = function() { - return this.renderer.getFirstVisibleRow(); - }; - - this.getLastVisibleRow = function() { - return this.renderer.getLastVisibleRow(); - }; - - this.isRowVisible = function(row) { - return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow()); - }; - - 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.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.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.gotoPageDown = function() { - var row = this.$getPageDownRow(); - var column = this.getCursorPositionScreen().column; - - this.scrollToRow(row); - this.getSelection().moveCursorToScreen(row, column); - }; - - this.gotoPageUp = function() { - var row = this.$getPageUpRow(); - var column = this.getCursorPositionScreen().column; - - this.scrollToRow(row); - this.getSelection().moveCursorToScreen(row, column); - }; - - this.scrollPageDown = function() { - this.scrollToRow(this.$getPageDownRow()); - }; - - this.scrollPageUp = function() { - this.renderer.scrollToRow(this.$getPageUpRow()); - }; - - this.scrollToRow = function(row) { - this.renderer.scrollToRow(row); - }; - - this.scrollToLine = function(line, center) { - this.renderer.scrollToLine(line, center); - }; - - 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); - }; - - 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(row, column) { - this.selection.moveCursorTo(row, column); - }; - - this.moveCursorToPosition = function(pos) { - this.selection.moveCursorToPosition(pos); - }; - - - this.gotoLine = function(lineNumber, row) { - this.selection.clearSelection(); - - this.$blockScrolling += 1; - this.moveCursorTo(lineNumber-1, row || 0); - this.$blockScrolling -= 1; - - if (!this.isRowVisible(this.getCursorPosition().row)) { - this.scrollToLine(lineNumber, true); - } - }, - - this.navigateTo = function(row, column) { - this.clearSelection(); - this.moveCursorTo(row, column); - }; - - this.navigateUp = function(times) { - this.selection.clearSelection(); - times = times || 1; - this.selection.moveCursorBy(-times, 0); - }; - - this.navigateDown = function(times) { - this.selection.clearSelection(); - times = times || 1; - this.selection.moveCursorBy(times, 0); - }; - - this.navigateLeft = function(times) { - if (!this.selection.isEmpty()) { - var selectionStart = this.getSelectionRange().start; - this.moveCursorToPosition(selectionStart); - } - else { - times = times || 1; - while (times--) { - this.selection.moveCursorLeft(); - } - } - this.clearSelection(); - }; - - this.navigateRight = function(times) { - if (!this.selection.isEmpty()) { - var selectionEnd = this.getSelectionRange().end; - this.moveCursorToPosition(selectionEnd); - } - else { - times = times || 1; - while (times--) { - 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(replacement, options) { - if (options) - this.$search.set(options); - - var range = this.$search.find(this.session); - this.$tryReplace(range, replacement); - if (range !== null) - this.selection.setSelectionRange(range); - }, - - this.replaceAll = function(replacement, options) { - if (options) { - this.$search.set(options); - } - - var ranges = this.$search.findAll(this.session); - if (!ranges.length) - return; - - var selection = this.getSelectionRange(); - this.clearSelection(); - this.selection.moveCursorTo(0, 0); - - this.$blockScrolling += 1; - for (var i = ranges.length - 1; i >= 0; --i) - this.$tryReplace(ranges[i], replacement); - - this.selection.setSelectionRange(selection); - this.$blockScrolling -= 1; - }, - - this.$tryReplace = function(range, replacement) { - var input = this.session.getTextRange(range); - var replacement = this.$search.replace(input, replacement); - if (replacement !== null) { - range.end = this.session.replace(range, replacement); - return range; - } else { - return null; - } - }; - - this.getLastSearchOptions = function() { - return this.$search.getOptions(); - }; - - this.find = function(needle, options) { - this.clearSelection(); - options = options || {}; - options.needle = needle; - this.$search.set(options); - this.$find(); - }, - - this.findNext = function(options) { - options = options || {}; - if (typeof options.backwards == "undefined") - options.backwards = false; - this.$search.set(options); - this.$find(); - }; - - this.findPrevious = function(options) { - options = options || {}; - if (typeof options.backwards == "undefined") - options.backwards = true; - this.$search.set(options); - this.$find(); - }; - - this.$find = function(backwards) { - if (!this.selection.isEmpty()) { - this.$search.set({needle: this.session.getTextRange(this.getSelectionRange())}); - } - - if (typeof backwards != "undefined") - this.$search.set({backwards: backwards}); - - var range = this.$search.find(this.session); - if (range) { - this.gotoLine(range.end.row+1, range.end.column); - this.selection.setSelectionRange(range); - } - }; - - this.undo = function() { - this.session.getUndoManager().undo(); - }; - - this.redo = function() { - this.session.getUndoManager().redo(); - }; - -}).call(Editor.prototype); - - -exports.Editor = Editor; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/event', ['require', 'exports', 'module' , 'pilot/keys', 'pilot/useragent', 'pilot/dom'], function(require, exports, module) { - -var keys = require("pilot/keys"); -var useragent = require("pilot/useragent"); -var dom = require("pilot/dom"); - -exports.addListener = function(elem, type, callback) { - if (elem.addEventListener) { - return elem.addEventListener(type, callback, false); - } - if (elem.attachEvent) { - var wrapper = function() { - callback(window.event); - }; - callback._wrapper = wrapper; - elem.attachEvent("on" + type, wrapper); - } -}; - -exports.removeListener = function(elem, type, callback) { - if (elem.removeEventListener) { - return elem.removeEventListener(type, callback, false); - } - if (elem.detachEvent) { - elem.detachEvent("on" + type, callback._wrapper || callback); - } -}; - -/** -* Prevents propagation and clobbers the default action of the passed event -*/ -exports.stopEvent = function(e) { - exports.stopPropagation(e); - exports.preventDefault(e); - return false; -}; - -exports.stopPropagation = function(e) { - if (e.stopPropagation) - e.stopPropagation(); - else - e.cancelBubble = true; -}; - -exports.preventDefault = function(e) { - if (e.preventDefault) - e.preventDefault(); - else - 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) { - if (e.type == "dblclick") - return 0; - else if (e.type == "contextmenu") - return 2; - - // DOM Event - if (e.preventDefault) { - return e.button; - } - // old IE - else { - return {1:0, 2:2, 4:1}[e.button]; - } -}; - -if (document.documentElement.setCapture) { - exports.capture = function(el, eventHandler, releaseCaptureHandler) { - function onMouseMove(e) { - eventHandler(e); - return exports.stopPropagation(e); - } - - function onReleaseCapture(e) { - eventHandler && eventHandler(e); - releaseCaptureHandler && releaseCaptureHandler(); - - exports.removeListener(el, "mousemove", eventHandler); - exports.removeListener(el, "mouseup", onReleaseCapture); - exports.removeListener(el, "losecapture", onReleaseCapture); - - el.releaseCapture(); - } - - exports.addListener(el, "mousemove", eventHandler); - exports.addListener(el, "mouseup", onReleaseCapture); - exports.addListener(el, "losecapture", onReleaseCapture); - el.setCapture(); - }; -} -else { - exports.capture = function(el, eventHandler, releaseCaptureHandler) { - function onMouseMove(e) { - eventHandler(e); - e.stopPropagation(); - } - - function onMouseUp(e) { - eventHandler && eventHandler(e); - releaseCaptureHandler && releaseCaptureHandler(); - - document.removeEventListener("mousemove", onMouseMove, true); - document.removeEventListener("mouseup", onMouseUp, true); - - e.stopPropagation(); - } - - document.addEventListener("mousemove", onMouseMove, true); - document.addEventListener("mouseup", onMouseUp, true); - }; -} - -exports.addMouseWheelListener = function(el, callback) { - var listener = function(e) { - if (e.wheelDelta !== undefined) { - if (e.wheelDeltaX !== undefined) { - e.wheelX = -e.wheelDeltaX / 8; - e.wheelY = -e.wheelDeltaY / 8; - } else { - e.wheelX = 0; - e.wheelY = -e.wheelDelta / 8; - } - } - else { - if (e.axis && e.axis == e.HORIZONTAL_AXIS) { - e.wheelX = (e.detail || 0) * 5; - e.wheelY = 0; - } else { - e.wheelX = 0; - e.wheelY = (e.detail || 0) * 5; - } - } - callback(e); - }; - exports.addListener(el, "DOMMouseScroll", listener); - exports.addListener(el, "mousewheel", listener); -}; - -exports.addMultiMouseDownListener = function(el, button, count, timeout, callback) { - var clicks = 0; - var startX, startY; - - var listener = function(e) { - clicks += 1; - if (clicks == 1) { - startX = e.clientX; - startY = e.clientY; - - setTimeout(function() { - clicks = 0; - }, timeout || 600); - } - - if (exports.getButton(e) != button - || Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5) - clicks = 0; - - if (clicks == count) { - clicks = 0; - callback(e); - } - return exports.preventDefault(e); - }; - - exports.addListener(el, "mousedown", listener); - useragent.isIE && exports.addListener(el, "dblclick", listener); -}; - -function normalizeCommandKeys(callback, e, keyCode) { - var hashId = 0; - if (useragent.isOpera && useragent.isMac) { - hashId = 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0) - | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0); - } else { - hashId = 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) - | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0); - } - - if (keyCode in keys.MODIFIER_KEYS) { - switch (keys.MODIFIER_KEYS[keyCode]) { - case "Alt": - hashId = 2; - break; - case "Shift": - hashId = 4; - break - case "Ctrl": - hashId = 1; - break; - default: - hashId = 8; - break; - } - keyCode = 0; - } - - if (hashId & 8 && (keyCode == 91 || keyCode == 93)) { - keyCode = 0; - } - - // If there is no hashID and the keyCode is not a function key, then - // we don't call the callback as we don't handle a command key here - // (it's a normal key/character input). - if (hashId == 0 && !(keyCode in keys.FUNCTION_KEYS)) { - return false; - } - - return callback(e, hashId, keyCode); -} - -exports.addCommandKeyListener = function(el, callback) { - var addListener = exports.addListener; - if (useragent.isOldGecko) { - // Old versions of Gecko aka. Firefox < 4.0 didn't repeat the keydown - // event if the user pressed the key for a longer time. Instead, the - // keydown event was fired once and later on only the keypress event. - // To emulate the 'right' keydown behavior, the keyCode of the initial - // keyDown event is stored and in the following keypress events the - // stores keyCode is used to emulate a keyDown event. - var lastKeyDownKeyCode = null; - addListener(el, "keydown", function(e) { - lastKeyDownKeyCode = e.keyCode; - }); - addListener(el, "keypress", function(e) { - return normalizeCommandKeys(callback, e, lastKeyDownKeyCode); - }); - } else { - var lastDown = null; - - addListener(el, "keydown", function(e) { - lastDown = e.keyIdentifier || e.keyCode; - return normalizeCommandKeys(callback, e, e.keyCode); - }); - - // repeated keys are fired as keypress and not keydown events - if (useragent.isMac && useragent.isOpera) { - addListener(el, "keypress", function(e) { - var keyId = e.keyIdentifier || e.keyCode; - if (lastDown !== keyId) { - return normalizeCommandKeys(callback, e, e.keyCode); - } else { - lastDown = null; - } - }); - } - } -}; - -}); -/*! @license -========================================================================== -SproutCore -- JavaScript Application Framework -copyright 2006-2009, Sprout Systems Inc., Apple Inc. and contributors. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -SproutCore and the SproutCore logo are trademarks of Sprout Systems, Inc. - -For more information about SproutCore, visit http://www.sproutcore.com - - -========================================================================== -@license */ - -// Most of the following code is taken from SproutCore with a few changes. - -define('pilot/keys', ['require', 'exports', 'module' , 'pilot/oop'], function(require, exports, module) { - -var oop = require("pilot/oop"); - -/** - * Helper functions and hashes for key handling. - */ -var Keys = (function() { - var ret = { - 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", - 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: '\"' - } - }; - - // A reverse map of FUNCTION_KEYS - for (i in ret.FUNCTION_KEYS) { - var name = ret.FUNCTION_KEYS[i].toUpperCase(); - ret[name] = parseInt(i, 10); - } - - // Add the MODIFIER_KEYS, FUNCTION_KEYS and PRINTABLE_KEYS to the KEY - // variables as well. - oop.mixin(ret, ret.MODIFIER_KEYS); - oop.mixin(ret, ret.PRINTABLE_KEYS); - oop.mixin(ret, ret.FUNCTION_KEYS); - - return ret; -})(); -oop.mixin(exports, Keys); - -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Mihai Sucan - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/dom', ['require', 'exports', 'module' ], function(require, exports, module) { - -var XHTML_NS = "http://www.w3.org/1999/xhtml"; - -exports.createElement = function(tag, ns) { - return document.createElementNS ? - document.createElementNS(ns || XHTML_NS, tag) : - document.createElement(tag); -}; - -exports.setText = function(elem, text) { - if (elem.innerText !== undefined) { - elem.innerText = text; - } - if (elem.textContent !== undefined) { - elem.textContent = text; - } -}; - -if (!document.documentElement.classList) { - exports.hasCssClass = function(el, name) { - var classes = el.className.split(/\s+/g); - return classes.indexOf(name) !== -1; - }; - - /** - * Add a CSS class to the list of classes on the given node - */ - exports.addCssClass = function(el, name) { - if (!exports.hasCssClass(el, name)) { - el.className += " " + name; - } - }; - - /** - * Remove a CSS class from the list of classes on the given node - */ - exports.removeCssClass = function(el, name) { - var classes = el.className.split(/\s+/g); - while (true) { - var index = classes.indexOf(name); - if (index == -1) { - break; - } - classes.splice(index, 1); - } - el.className = classes.join(" "); - }; - - exports.toggleCssClass = function(el, name) { - var classes = el.className.split(/\s+/g), add = true; - while (true) { - var index = classes.indexOf(name); - if (index == -1) { - break; - } - add = false; - classes.splice(index, 1); - } - if(add) - classes.push(name); - - el.className = classes.join(" "); - return add; - }; -} else { - exports.hasCssClass = function(el, name) { - return el.classList.contains(name); - }; - - exports.addCssClass = function(el, name) { - el.classList.add(name); - }; - - exports.removeCssClass = function(el, name) { - el.classList.remove(name); - }; - - exports.toggleCssClass = function(el, name) { - return el.classList.toggle(name); - }; -} - -/** - * Add or remove a CSS class from the list of classes on the given node - * depending on the value of include - */ -exports.setCssClass = function(node, className, include) { - if (include) { - exports.addCssClass(node, className); - } else { - exports.removeCssClass(node, className); - } -}; - -exports.importCssString = function(cssText, doc){ - doc = doc || document; - - if (doc.createStyleSheet) { - var sheet = doc.createStyleSheet(); - sheet.cssText = cssText; - } - else { - var style = doc.createElementNS ? - doc.createElementNS(XHTML_NS, "style") : - doc.createElement("style"); - - style.appendChild(doc.createTextNode(cssText)); - - var head = doc.getElementsByTagName("head")[0] || doc.documentElement; - head.appendChild(style); - } -}; - -exports.getInnerWidth = function(element) { - return (parseInt(exports.computedStyle(element, "paddingLeft")) - + parseInt(exports.computedStyle(element, "paddingRight")) + element.clientWidth); -}; - -exports.getInnerHeight = function(element) { - return (parseInt(exports.computedStyle(element, "paddingTop")) - + parseInt(exports.computedStyle(element, "paddingBottom")) + element.clientHeight); -}; - -if (window.pageYOffset !== undefined) { - exports.getPageScrollTop = function() { - return window.pageYOffset; - }; - - exports.getPageScrollLeft = function() { - return window.pageXOffset; - }; -} -else { - exports.getPageScrollTop = function() { - return document.body.scrollTop; - }; - - exports.getPageScrollLeft = function() { - return document.body.scrollLeft; - }; -} - -exports.computedStyle = function(element, style) { - if (window.getComputedStyle) { - return (window.getComputedStyle(element, "") || {})[style] || ""; - } - else { - return element.currentStyle[style]; - } -}; - -exports.scrollbarWidth = function() { - - var inner = exports.createElement("p"); - inner.style.width = "100%"; - inner.style.height = "200px"; - - var outer = exports.createElement("div"); - var style = outer.style; - - style.position = "absolute"; - style.left = "-10000px"; - style.overflow = "hidden"; - style.width = "200px"; - style.height = "150px"; - - outer.appendChild(inner); - - var body = document.body || document.documentElement; - body.appendChild(outer); - - var noScrollbar = inner.offsetWidth; - - style.overflow = "scroll"; - var withScrollbar = inner.offsetWidth; - - if (noScrollbar == withScrollbar) { - withScrollbar = outer.clientWidth; - } - - body.removeChild(outer); - - return noScrollbar-withScrollbar; -}; - -/** - * Optimized set innerHTML. This is faster than plain innerHTML if the element - * already contains a lot of child elements. - * - * See http://blog.stevenlevithan.com/archives/faster-than-innerhtml for details - */ -exports.setInnerHtml = function(el, innerHtml) { - var element = el.cloneNode(false);//document.createElement("div"); - element.innerHTML = innerHtml; - el.parentNode.replaceChild(element, el); - return element; -}; - -exports.setInnerText = function(el, innerText) { - if (document.body && "textContent" in document.body) - el.textContent = innerText; - else - el.innerText = innerText; - -}; - -exports.getInnerText = function(el) { - if (document.body && "textContent" in document.body) - return el.textContent; - else - return el.innerText || el.textContent; -}; - -exports.getParentWindow = function(document) { - return document.defaultView || document.parentWindow; -}; - -exports.getSelectionStart = function(textarea) { - // TODO IE - var start; - try { - start = textarea.selectionStart || 0; - } catch (e) { - start = 0; - } - return start; -}; - -exports.setSelectionStart = function(textarea, start) { - // TODO IE - return textarea.selectionStart = start; -}; - -exports.getSelectionEnd = function(textarea) { - // TODO IE - var end; - try { - end = textarea.selectionEnd || 0; - } catch (e) { - end = 0; - } - return end; -}; - -exports.setSelectionEnd = function(textarea, end) { - // TODO IE - return textarea.selectionEnd = end; -}; - -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/keyboard/textinput', ['require', 'exports', 'module' , 'pilot/event', 'pilot/useragent', 'pilot/dom'], function(require, exports, module) { - -var event = require("pilot/event"); -var useragent = require("pilot/useragent"); -var dom = require("pilot/dom"); - -var TextInput = function(parentNode, host) { - - var text = dom.createElement("textarea"); - text.style.left = "-10000px"; - parentNode.appendChild(text); - - var PLACEHOLDER = String.fromCharCode(0); - sendText(); - - var inCompostion = false; - var copied = false; - var tempStyle = ''; - - function sendText(valueToSend) { - 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); - } else - host.onTextInput(value); - } - } - copied = false; - - // Safari doesn't fire copy events if no text is selected - text.value = PLACEHOLDER; - text.select(); - } - - var onTextInput = function(e) { - if (useragent.isIE && text.value.charCodeAt(0) > 128) return; - setTimeout(function() { - if (!inCompostion) - sendText(); - }, 0); - }; - - var onCompositionStart = function(e) { - inCompostion = true; - if (!useragent.isIE) { - sendText(); - text.value = ""; - }; - host.onCompositionStart(); - if (!useragent.isGecko) setTimeout(onCompositionUpdate, 0); - }; - - var onCompositionUpdate = function() { - if (!inCompostion) return; - host.onCompositionUpdate(text.value); - }; - - var onCompositionEnd = function() { - inCompostion = false; - host.onCompositionEnd(); - setTimeout(function () { - sendText(); - }, 0); - }; - - var onCopy = function(e) { - copied = true; - var copyText = host.getCopyText(); - if(copyText) - text.value = copyText; - else - e.preventDefault(); - text.select(); - setTimeout(function () { - sendText(); - }, 0); - }; - - var onCut = function(e) { - copied = true; - var copyText = host.getCopyText(); - if(copyText) { - text.value = copyText; - host.onCut(); - } else - e.preventDefault(); - text.select(); - setTimeout(function () { - sendText(); - }, 0); - }; - - event.addCommandKeyListener(text, host.onCommandKey.bind(host)); - event.addListener(text, "keypress", onTextInput); - if (useragent.isIE) { - var keytable = { 13:1, 27:1 }; - event.addListener(text, "keyup", function (e) { - if (inCompostion && (!text.value || keytable[e.keyCode])) - setTimeout(onCompositionEnd, 0); - if ((text.value.charCodeAt(0)|0) < 129) { - return; - }; - inCompostion ? onCompositionUpdate() : onCompositionStart(); - }); - }; - event.addListener(text, "textInput", onTextInput); - event.addListener(text, "paste", function(e) { - // Some browsers support the event.clipboardData API. Use this to get - // the pasted content which increases speed if pasting a lot of lines. - if (e.clipboardData && e.clipboardData.getData) { - sendText(e.clipboardData.getData("text/plain")); - e.preventDefault(); - } else - // If a browser doesn't support any of the things above, use the regular - // method to detect the pasted input. - { - onTextInput(); - } - }); - if (!useragent.isIE) { - event.addListener(text, "propertychange", onTextInput); - }; - - if (useragent.isIE) { - event.addListener(text, "beforecopy", function(e) { - var copyText = host.getCopyText(); - if(copyText) - clipboardData.setData("Text", copyText); - else - e.preventDefault(); - }); - event.addListener(parentNode, "keydown", function(e) { - if (e.ctrlKey && e.keyCode == 88) { - var copyText = host.getCopyText(); - if (copyText) { - clipboardData.setData("Text", copyText); - host.onCut(); - } - event.preventDefault(e) - } - }); - } - else { - event.addListener(text, "copy", onCopy); - event.addListener(text, "cut", onCut); - } - - event.addListener(text, "compositionstart", onCompositionStart); - if (useragent.isGecko) { - event.addListener(text, "text", onCompositionUpdate); - }; - if (useragent.isWebKit) { - event.addListener(text, "keyup", onCompositionUpdate); - }; - event.addListener(text, "compositionend", onCompositionEnd); - - event.addListener(text, "blur", function() { - host.onBlur(); - }); - - event.addListener(text, "focus", function() { - host.onFocus(); - text.select(); - }); - - this.focus = function() { - host.onFocus(); - text.select(); - text.focus(); - }; - - this.blur = function() { - text.blur(); - }; - - this.getElement = function() { - return text; - }; - - this.onContextMenu = function(mousePos, isEmpty){ - if (mousePos) { - if(!tempStyle) - tempStyle = text.style.cssText; - text.style.cssText = 'position:fixed; z-index:1000;' + - 'left:' + (mousePos.x - 2) + 'px; top:' + (mousePos.y - 2) + 'px;' - - } - if (isEmpty) - text.value=''; - } - - this.onContextMenuClose = function(){ - setTimeout(function () { - if (tempStyle) { - text.style.cssText = tempStyle; - tempStyle = ''; - } - sendText(); - }, 0); - } -}; - -exports.TextInput = TextInput; -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Mihai Sucan - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/mouse_handler', ['require', 'exports', 'module' , 'pilot/event', 'pilot/dom'], function(require, exports, module) { - -var event = require("pilot/event"); -var dom = require("pilot/dom"); - -var STATE_UNKNOWN = 0; -var STATE_SELECT = 1; -var STATE_DRAG = 2; - -var DRAG_TIMER = 250; // milliseconds -var DRAG_OFFSET = 5; // pixels - -var MouseHandler = function(editor) { - this.editor = editor; - event.addListener(editor.container, "mousedown", function(e) { - editor.focus(); - return event.preventDefault(e); - }); - event.addListener(editor.container, "selectstart", function(e) { - return event.preventDefault(e); - }); - - var mouseTarget = editor.renderer.getMouseEventTarget(); - event.addListener(mouseTarget, "mousedown", this.onMouseDown.bind(this)); - event.addMultiMouseDownListener(mouseTarget, 0, 2, 500, this.onMouseDoubleClick.bind(this)); - event.addMultiMouseDownListener(mouseTarget, 0, 3, 600, this.onMouseTripleClick.bind(this)); - event.addMultiMouseDownListener(mouseTarget, 0, 4, 600, this.onMouseQuadClick.bind(this)); - event.addMouseWheelListener(mouseTarget, this.onMouseWheel.bind(this)); -}; - -(function() { - - this.$scrollSpeed = 1; - this.setScrollSpeed = function(speed) { - this.$scrollSpeed = speed; - }; - - this.getScrollSpeed = function() { - return this.$scrollSpeed; - }; - - this.$getEventPosition = function(e) { - var pageX = event.getDocumentX(e); - var pageY = event.getDocumentY(e); - var pos = this.editor.renderer.screenToTextCoordinates(pageX, pageY); - pos.row = Math.max(0, Math.min(pos.row, this.editor.session.getLength()-1)); - return pos; - }; - - this.$distance = function(ax, ay, bx, by) { - return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2)); - }; - - this.onMouseDown = function(e) { - var pageX = event.getDocumentX(e); - var pageY = event.getDocumentY(e); - var pos = this.$getEventPosition(e); - var editor = this.editor; - var self = this; - var selectionRange = editor.getSelectionRange(); - var selectionEmpty = selectionRange.isEmpty(); - var state = STATE_UNKNOWN; - var inSelection = false; - - var button = event.getButton(e) - if (button != 0) { - if (selectionEmpty) { - editor.moveCursorToPosition(pos); - } - if(button == 2) { - editor.textInput.onContextMenu({x: pageX, y: pageY}, selectionEmpty); - event.capture(editor.container, function(){}, editor.textInput.onContextMenuClose); - } - return; - } else - inSelection = !editor.getReadOnly() && - !selectionEmpty && - selectionRange.contains(pos.row, pos.column); - - if (!inSelection) { - // Directly pick STATE_SELECT, since the user is not clicking inside - // a selection. - onStartSelect(pos); - } - - editor.renderer.scrollCursorIntoView(); - - var mousePageX, mousePageY; - var overwrite = editor.getOverwrite(); - var dragCursor = null; - var mousedownTime = (new Date()).getTime(); - - var onMouseSelection = function(e) { - mousePageX = event.getDocumentX(e); - mousePageY = event.getDocumentY(e); - }; - - var onMouseSelectionEnd = function() { - clearInterval(timerId); - if (state == STATE_UNKNOWN) - onStartSelect(pos); - else if (state == STATE_DRAG) - onMouseDragSelectionEnd(); - - self.$clickSelection = null; - state = STATE_UNKNOWN; - }; - - var onMouseDragSelectionEnd = function() { - dom.removeCssClass(editor.container, "ace_dragging"); - - if (!self.$clickSelection) { - if (!dragCursor) { - editor.moveCursorToPosition(pos); - editor.selection.clearSelection(pos.row, pos.column); - } - } - - if (!dragCursor) - return; - - var selection = editor.getSelectionRange(); - if (selection.contains(dragCursor.row, dragCursor.column)) { - dragCursor = null; - return; - } - - editor.clearSelection(); - var newRange = editor.moveText(selection, dragCursor); - if (!newRange) { - dragCursor = null; - return; - } - - editor.selection.setSelectionRange(newRange); - }; - - var onSelectionInterval = function() { - if (mousePageX === undefined || mousePageY === undefined) - return; - - if (state == STATE_UNKNOWN) { - var distance = self.$distance(pageX, pageY, mousePageX, mousePageY); - var time = (new Date()).getTime(); - - - if (distance > DRAG_OFFSET) { - state = STATE_SELECT; - var cursor = editor.renderer.screenToTextCoordinates(mousePageX, mousePageY); - cursor.row = Math.max(0, Math.min(cursor.row, editor.session.getLength()-1)); - onStartSelect(cursor); - } else if ((time - mousedownTime) > DRAG_TIMER) { - state = STATE_DRAG; - dom.addCssClass(editor.container, "ace_dragging"); - } - - } - - if (state == STATE_DRAG) - onDragSelectionInterval(); - else if (state == STATE_SELECT) - onUpdateSelectionInterval(); - }; - - function onStartSelect(pos) { - if (e.shiftKey) - editor.selection.selectToPosition(pos) - else { - if (!self.$clickSelection) { - editor.moveCursorToPosition(pos); - editor.selection.clearSelection(pos.row, pos.column); - } - } - state = STATE_SELECT; - } - - var onUpdateSelectionInterval = function() { - var cursor = editor.renderer.screenToTextCoordinates(mousePageX, mousePageY); - cursor.row = Math.max(0, Math.min(cursor.row, editor.session.getLength()-1)); - - 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) { - var anchor = self.$clickSelection.end; - } else { - var 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); - dragCursor.row = Math.max(0, Math.min(dragCursor.row, - editor.session.getLength() - 1)); - - editor.renderer.updateCursor(dragCursor, overwrite); - editor.renderer.scrollCursorIntoView(); - }; - - event.capture(editor.container, onMouseSelection, onMouseSelectionEnd); - var timerId = setInterval(onSelectionInterval, 20); - - return event.preventDefault(e); - }; - - this.onMouseDoubleClick = function(e) { - var pos = this.$getEventPosition(e); - this.editor.moveCursorToPosition(pos); - this.editor.selection.selectWord(); - this.$clickSelection = this.editor.getSelectionRange(); - }; - - this.onMouseTripleClick = function(e) { - var pos = this.$getEventPosition(e); - this.editor.moveCursorToPosition(pos); - this.editor.selection.selectLine(); - this.$clickSelection = this.editor.getSelectionRange(); - }; - - this.onMouseQuadClick = function(e) { - this.editor.selectAll(); - this.$clickSelection = this.editor.getSelectionRange(); - }; - - this.onMouseWheel = function(e) { - var speed = this.$scrollSpeed * 2; - - this.editor.renderer.scrollBy(e.wheelX * speed, e.wheelY * speed); - return event.preventDefault(e); - }; - - -}).call(MouseHandler.prototype); - -exports.MouseHandler = MouseHandler; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/keyboard/keybinding', ['require', 'exports', 'module' , 'pilot/useragent', 'pilot/keys', 'pilot/event', 'pilot/settings', 'ace/keyboard/hash_handler', 'ace/keyboard/keybinding/default_mac', 'ace/keyboard/keybinding/default_win', 'pilot/canon', 'ace/commands/default_commands'], function(require, exports, module) { - -var useragent = require("pilot/useragent"); -var keyUtil = require("pilot/keys"); -var event = require("pilot/event"); -var settings = require("pilot/settings").settings; -var HashHandler = require("ace/keyboard/hash_handler").HashHandler; -var default_mac = require("ace/keyboard/keybinding/default_mac").bindings; -var default_win = require("ace/keyboard/keybinding/default_win").bindings; -var canon = require("pilot/canon"); -require("ace/commands/default_commands"); - -var KeyBinding = function(editor, config) { - this.$editor = editor; - this.$data = { }; - this.$keyboardHandler = null; - this.$defaulKeyboardHandler = new HashHandler(config || (useragent.isMac - ? default_mac - : default_win)); -}; - -(function() { - this.setKeyboardHandler = function(keyboardHandler) { - if (this.$keyboardHandler != keyboardHandler) { - this.$data = { }; - this.$keyboardHandler = keyboardHandler; - } - }; - - this.getKeyboardHandler = function() { - return this.$keyboardHandler; - }; - - this.$callKeyboardHandler = function (e, hashId, keyOrText, keyCode) { - var toExecute; - if (this.$keyboardHandler) { - toExecute = - this.$keyboardHandler.handleKeyboard(this.$data, hashId, keyOrText, keyCode, e); - } - - // If there is nothing to execute yet, then use the default keymapping. - if (!toExecute || !toExecute.command) { - toExecute = this.$defaulKeyboardHandler. - handleKeyboard(this.$data, hashId, keyOrText, keyCode, e); - } - - if (toExecute) { - var success = canon.exec(toExecute.command, - {editor: this.$editor}, toExecute.args); - if (success) { - return event.stopEvent(e); - } - } - }; - - this.onCommandKey = function(e, hashId, keyCode) { - key = (keyUtil[keyCode] || - String.fromCharCode(keyCode)).toLowerCase(); - - this.$callKeyboardHandler(e, hashId, key, keyCode); - }; - - this.onTextInput = function(text) { - this.$callKeyboardHandler({}, 0, text, 0); - } - -}).call(KeyBinding.prototype); - -exports.KeyBinding = KeyBinding; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck (julian.viereck@gmail.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/keyboard/hash_handler', ['require', 'exports', 'module' , 'pilot/keys'], function(require, exports, module) { - -var keyUtil = require("pilot/keys"); - -function HashHandler(config) { - this.setConfig(config); -} - -(function() { - function splitSafe(s, separator, limit, bLowerCase) { - return (bLowerCase && s.toLowerCase() || s) - .replace(/(?:^\s+|\n|\s+$)/g, "") - .split(new RegExp("[\\s ]*" + separator + "[\\s ]*", "g"), limit || 999); - } - - function parseKeys(keys, val, ret) { - var key, - hashId = 0, - parts = splitSafe(keys, "\\-", null, true), - i = 0, - l = parts.length; - - for (; i < l; ++i) { - if (keyUtil.KEY_MODS[parts[i]]) - hashId = hashId | keyUtil.KEY_MODS[parts[i]]; - else - key = parts[i] || "-"; //when empty, the splitSafe removed a '-' - } - - (ret[hashId] || (ret[hashId] = {}))[key] = val; - return ret; - } - - function objectReverse(obj, keySplit) { - var i, j, l, key, - ret = {}; - for (i in obj) { - key = obj[i]; - if (keySplit && typeof key == "string") { - key = key.split(keySplit); - for (j = 0, l = key.length; j < l; ++j) - parseKeys.call(this, key[j], i, ret); - } - else { - parseKeys.call(this, key, i, ret); - } - } - return ret; - } - - this.setConfig = function(config) { - this.$config = config; - if (typeof this.$config.reverse == "undefined") - this.$config.reverse = objectReverse.call(this, this.$config, "|"); - }; - - /** - * This function is called by keyBinding. - */ - this.handleKeyboard = function(data, hashId, textOrKey, keyCode) { - // Figure out if a commandKey was pressed or just some text was insert. - if (hashId != 0 || keyCode != 0) { - return { - command: (this.$config.reverse[hashId] || {})[textOrKey] - } - } else { - return { - command: "inserttext", - args: { - text: textOrKey - } - } - } - } -}).call(HashHandler.prototype) - -exports.HashHandler = HashHandler; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/keyboard/keybinding/default_mac', ['require', 'exports', 'module' ], function(require, exports, module) { - -exports.bindings = { - "selectall": "Command-A", - "removeline": "Command-D", - "gotoline": "Command-L", - "togglecomment": "Command-7", - "findnext": "Command-G", - "findprevious": "Command-Shift-G", - "find": "Command-F", - "replace": "Alt-Command-R", - "undo": "Command-Z", - "redo": "Command-Shift-Z|Command-Y", - "overwrite": "Insert", - "copylinesup": "Command-Option-Up", - "movelinesup": "Option-Up", - "selecttostart": "Command-Shift-Up", - "gotostart": "Command-Home|Command-Up", - "selectup": "Shift-Up", - "golineup": "Up|Ctrl-P", - "copylinesdown": "Command-Option-Down", - "movelinesdown": "Option-Down", - "selecttoend": "Command-Shift-Down", - "gotoend": "Command-End|Command-Down", - "selectdown": "Shift-Down", - "golinedown": "Down|Ctrl-N", - "selectwordleft": "Option-Shift-Left", - "gotowordleft": "Option-Left", - "selecttolinestart": "Command-Shift-Left", - "gotolinestart": "Command-Left|Home|Ctrl-A", - "selectleft": "Shift-Left", - "gotoleft": "Left|Ctrl-B", - "selectwordright": "Option-Shift-Right", - "gotowordright": "Option-Right", - "selecttolineend": "Command-Shift-Right", - "gotolineend": "Command-Right|End|Ctrl-E", - "selectright": "Shift-Right", - "gotoright": "Right|Ctrl-F", - "selectpagedown": "Shift-PageDown", - "pagedown": "PageDown", - "gotopagedown": "Option-PageDown|Ctrl-V", - "selectpageup": "Shift-PageUp", - "pageup": "PageUp", - "gotopageup": "Option-PageUp", - "selectlinestart": "Shift-Home", - "selectlineend": "Shift-End", - "del": "Delete|Ctrl-D", - "backspace": "Ctrl-Backspace|Command-Backspace|Shift-Backspace|Backspace|Ctrl-H", - "removetolineend": "Ctrl-K", - "removetolinestart": "Option-Backspace", - "removewordleft": "Alt-Backspace|Ctrl-Alt-Backspace", - "removewordright": "Alt-Delete", - "outdent": "Shift-Tab", - "indent": "Tab", - "transposeletters": "Ctrl-T", - "splitline": "Ctrl-O", - "centerselection": "Ctrl-L" -}; - -});/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/keyboard/keybinding/default_win', ['require', 'exports', 'module' ], function(require, exports, module) { - -exports.bindings = { - "selectall": "Ctrl-A", - "removeline": "Ctrl-D", - "gotoline": "Ctrl-L", - "togglecomment": "Ctrl-7", - "findnext": "Ctrl-K", - "findprevious": "Ctrl-Shift-K", - "find": "Ctrl-F", - "replace": "Alt-Ctrl-R", - "undo": "Ctrl-Z", - "redo": "Ctrl-Shift-Z|Ctrl-Y", - "overwrite": "Insert", - "copylinesup": "Ctrl-Alt-Up", - "movelinesup": "Alt-Up", - "selecttostart": "Alt-Shift-Up", - "gotostart": "Ctrl-Home|Ctrl-Up", - "selectup": "Shift-Up", - "golineup": "Up", - "copylinesdown": "Ctrl-Alt-Down", - "movelinesdown": "Alt-Down", - "selecttoend": "Alt-Shift-Down", - "gotoend": "Ctrl-End|Ctrl-Down", - "selectdown": "Shift-Down", - "golinedown": "Down", - "selectwordleft": "Ctrl-Shift-Left", - "gotowordleft": "Ctrl-Left", - "selecttolinestart": "Alt-Shift-Left", - "gotolinestart": "Alt-Left|Home", - "selectleft": "Shift-Left", - "gotoleft": "Left", - "selectwordright": "Ctrl-Shift-Right", - "gotowordright": "Ctrl-Right", - "selecttolineend": "Alt-Shift-Right", - "gotolineend": "Alt-Right|End", - "selectright": "Shift-Right", - "gotoright": "Right", - "selectpagedown": "Shift-PageDown", - "gotopagedown": "PageDown", - "selectpageup": "Shift-PageUp", - "gotopageup": "PageUp", - "selectlinestart": "Shift-Home", - "selectlineend": "Shift-End", - "del": "Delete", - "backspace": "Ctrl-Backspace|Command-Backspace|Option-Backspace|Shift-Backspace|Backspace", - "outdent": "Shift-Tab", - "indent": "Tab" -}; - -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * Mihai Sucan - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/commands/default_commands', ['require', 'exports', 'module' , 'pilot/lang', 'pilot/canon'], function(require, exports, module) { - -var lang = require("pilot/lang"); -var canon = require("pilot/canon"); - -canon.addCommand({ - name: "null", - exec: function(env, args, request) { } -}); - -canon.addCommand({ - name: "selectall", - exec: function(env, args, request) { env.editor.selectAll(); } -}); -canon.addCommand({ - name: "removeline", - exec: function(env, args, request) { env.editor.removeLines(); } -}); -canon.addCommand({ - name: "gotoline", - exec: function(env, args, request) { - var line = parseInt(prompt("Enter line number:")); - if (!isNaN(line)) { - env.editor.gotoLine(line); - } - } -}); -canon.addCommand({ - name: "togglecomment", - exec: function(env, args, request) { env.editor.toggleCommentLines(); } -}); -canon.addCommand({ - name: "findnext", - exec: function(env, args, request) { env.editor.findNext(); } -}); -canon.addCommand({ - name: "findprevious", - exec: function(env, args, request) { env.editor.findPrevious(); } -}); -canon.addCommand({ - name: "find", - exec: function(env, args, request) { - var needle = prompt("Find:"); - env.editor.find(needle); - } -}); -canon.addCommand({ - name: "replace", - exec: function(env, args, request) { - var needle = prompt("Find:"); - if (!needle) - return; - var replacement = prompt("Replacement:"); - if (!replacement) - return; - env.editor.replace(replacement, {needle: needle}); - } -}); -canon.addCommand({ - name: "replaceall", - exec: function(env, args, request) { - var needle = prompt("Find:"); - if (!needle) - return; - var replacement = prompt("Replacement:"); - if (!replacement) - return; - env.editor.replaceAll(replacement, {needle: needle}); - } -}); -canon.addCommand({ - name: "undo", - exec: function(env, args, request) { env.editor.undo(); } -}); -canon.addCommand({ - name: "redo", - exec: function(env, args, request) { env.editor.redo(); } -}); -canon.addCommand({ - name: "redo", - exec: function(env, args, request) { env.editor.redo(); } -}); -canon.addCommand({ - name: "overwrite", - exec: function(env, args, request) { env.editor.toggleOverwrite(); } -}); -canon.addCommand({ - name: "copylinesup", - exec: function(env, args, request) { env.editor.copyLinesUp(); } -}); -canon.addCommand({ - name: "movelinesup", - exec: function(env, args, request) { env.editor.moveLinesUp(); } -}); -canon.addCommand({ - name: "selecttostart", - exec: function(env, args, request) { env.editor.getSelection().selectFileStart(); } -}); -canon.addCommand({ - name: "gotostart", - exec: function(env, args, request) { env.editor.navigateFileStart(); } -}); -canon.addCommand({ - name: "selectup", - exec: function(env, args, request) { env.editor.getSelection().selectUp(); } -}); -canon.addCommand({ - name: "golineup", - exec: function(env, args, request) { env.editor.navigateUp(args.times); } -}); -canon.addCommand({ - name: "copylinesdown", - exec: function(env, args, request) { env.editor.copyLinesDown(); } -}); -canon.addCommand({ - name: "movelinesdown", - exec: function(env, args, request) { env.editor.moveLinesDown(); } -}); -canon.addCommand({ - name: "selecttoend", - exec: function(env, args, request) { env.editor.getSelection().selectFileEnd(); } -}); -canon.addCommand({ - name: "gotoend", - exec: function(env, args, request) { env.editor.navigateFileEnd(); } -}); -canon.addCommand({ - name: "selectdown", - exec: function(env, args, request) { env.editor.getSelection().selectDown(); } -}); -canon.addCommand({ - name: "golinedown", - exec: function(env, args, request) { env.editor.navigateDown(args.times); } -}); -canon.addCommand({ - name: "selectwordleft", - exec: function(env, args, request) { env.editor.getSelection().selectWordLeft(); } -}); -canon.addCommand({ - name: "gotowordleft", - exec: function(env, args, request) { env.editor.navigateWordLeft(); } -}); -canon.addCommand({ - name: "selecttolinestart", - exec: function(env, args, request) { env.editor.getSelection().selectLineStart(); } -}); -canon.addCommand({ - name: "gotolinestart", - exec: function(env, args, request) { env.editor.navigateLineStart(); } -}); -canon.addCommand({ - name: "selectleft", - exec: function(env, args, request) { env.editor.getSelection().selectLeft(); } -}); -canon.addCommand({ - name: "gotoleft", - exec: function(env, args, request) { env.editor.navigateLeft(args.times); } -}); -canon.addCommand({ - name: "selectwordright", - exec: function(env, args, request) { env.editor.getSelection().selectWordRight(); } -}); -canon.addCommand({ - name: "gotowordright", - exec: function(env, args, request) { env.editor.navigateWordRight(); } -}); -canon.addCommand({ - name: "selecttolineend", - exec: function(env, args, request) { env.editor.getSelection().selectLineEnd(); } -}); -canon.addCommand({ - name: "gotolineend", - exec: function(env, args, request) { env.editor.navigateLineEnd(); } -}); -canon.addCommand({ - name: "selectright", - exec: function(env, args, request) { env.editor.getSelection().selectRight(); } -}); -canon.addCommand({ - name: "gotoright", - exec: function(env, args, request) { env.editor.navigateRight(args.times); } -}); -canon.addCommand({ - name: "selectpagedown", - exec: function(env, args, request) { env.editor.selectPageDown(); } -}); -canon.addCommand({ - name: "pagedown", - exec: function(env, args, request) { env.editor.scrollPageDown(); } -}); -canon.addCommand({ - name: "gotopagedown", - exec: function(env, args, request) { env.editor.gotoPageDown(); } -}); -canon.addCommand({ - name: "selectpageup", - exec: function(env, args, request) { env.editor.selectPageUp(); } -}); -canon.addCommand({ - name: "pageup", - exec: function(env, args, request) { env.editor.scrollPageUp(); } -}); -canon.addCommand({ - name: "gotopageup", - exec: function(env, args, request) { env.editor.gotoPageUp(); } -}); -canon.addCommand({ - name: "selectlinestart", - exec: function(env, args, request) { env.editor.getSelection().selectLineStart(); } -}); -canon.addCommand({ - name: "gotolinestart", - exec: function(env, args, request) { env.editor.navigateLineStart(); } -}); -canon.addCommand({ - name: "selectlineend", - exec: function(env, args, request) { env.editor.getSelection().selectLineEnd(); } -}); -canon.addCommand({ - name: "gotolineend", - exec: function(env, args, request) { env.editor.navigateLineEnd(); } -}); -canon.addCommand({ - name: "del", - exec: function(env, args, request) { env.editor.removeRight(); } -}); -canon.addCommand({ - name: "backspace", - exec: function(env, args, request) { env.editor.removeLeft(); } -}); -canon.addCommand({ - name: "removetolinestart", - exec: function(env, args, request) { env.editor.removeToLineStart(); } -}); -canon.addCommand({ - name: "removetolineend", - exec: function(env, args, request) { env.editor.removeToLineEnd(); } -}); -canon.addCommand({ - name: "removewordleft", - exec: function(env, args, request) { env.editor.removeWordLeft(); } -}); -canon.addCommand({ - name: "removewordright", - exec: function(env, args, request) { env.editor.removeWordRight(); } -}); -canon.addCommand({ - name: "outdent", - exec: function(env, args, request) { env.editor.blockOutdent(); } -}); -canon.addCommand({ - name: "indent", - exec: function(env, args, request) { env.editor.indent(); } -}); -canon.addCommand({ - name: "inserttext", - exec: function(env, args, request) { - env.editor.insert(lang.stringRepeat(args.text || "", args.times || 1)); - } -}); -canon.addCommand({ - name: "centerselection", - exec: function(env, args, request) { env.editor.centerSelection(); } -}); -canon.addCommand({ - name: "splitline", - exec: function(env, args, request) { env.editor.splitLine(); } -}); -canon.addCommand({ - name: "transposeletters", - exec: function(env, args, request) { env.editor.transposeLetters(); } -}); - - -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Mihai Sucan - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/edit_session', ['require', 'exports', 'module' , 'pilot/oop', 'pilot/lang', 'pilot/event_emitter', 'ace/selection', 'ace/mode/text', 'ace/range', 'ace/document'], function(require, exports, module) { - -var oop = require("pilot/oop"); -var lang = require("pilot/lang"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; -var Selection = require("ace/selection").Selection; -var TextMode = require("ace/mode/text").Mode; -var Range = require("ace/range").Range; -var Document = require("ace/document").Document; - -var EditSession = function(text, mode) { - this.$modified = true; - this.$breakpoints = []; - this.$frontMarkers = {}; - this.$backMarkers = {}; - this.$markerId = 1; - this.$wrapData = []; - - if (text instanceof Document) { - this.setDocument(text); - } else { - this.setDocument(new Document(text)); - } - - this.selection = new Selection(this); - if (mode) - this.setMode(mode); -}; - - -(function() { - - oop.implement(this, EventEmitter); - - this.setDocument = function(doc) { - if (this.doc) - throw new Error("Document is already set"); - - this.doc = doc; - doc.on("change", this.onChange.bind(this)); - }; - - this.getDocument = function() { - return this.doc; - }; - - this.onChange = function(e) { - var delta = e.data; - this.$modified = true; - if (!this.$fromUndo && this.$undoManager && !delta.ignore) { - this.$deltas.push(delta); - this.$informUndoManager.schedule(); - } - - this.$updateWrapDataOnChange(e); - this._dispatchEvent("change", e); - }; - - this.setValue = function(text) { - this.doc.setValue(text); - this.$deltas = []; - this.getUndoManager().reset(); - }; - - this.getValue = - this.toString = function() { - return this.doc.getValue(); - }; - - this.getSelection = function() { - return this.selection; - }; - - this.setUndoManager = function(undoManager) { - this.$undoManager = undoManager; - this.$deltas = []; - - if (this.$informUndoManager) { - this.$informUndoManager.cancel(); - } - - if (undoManager) { - var self = this; - this.$informUndoManager = lang.deferredCall(function() { - if (self.$deltas.length > 0) - undoManager.execute({ - action : "aceupdate", - args : [self.$deltas, self] - }); - self.$deltas = []; - }); - } - }; - - this.$defaultUndoManager = { - undo: function() {}, - redo: function() {}, - reset: function() {} - }; - - this.getUndoManager = function() { - return this.$undoManager || this.$defaultUndoManager; - }, - - this.getTabString = function() { - if (this.getUseSoftTabs()) { - return lang.stringRepeat(" ", this.getTabSize()); - } else { - return "\t"; - } - }; - - this.$useSoftTabs = true; - this.setUseSoftTabs = function(useSoftTabs) { - if (this.$useSoftTabs === useSoftTabs) return; - - this.$useSoftTabs = useSoftTabs; - }; - - this.getUseSoftTabs = function() { - return this.$useSoftTabs; - }; - - this.$tabSize = 4; - this.setTabSize = function(tabSize) { - if (isNaN(tabSize) || this.$tabSize === tabSize) return; - - this.$modified = true; - this.$tabSize = tabSize; - this._dispatchEvent("changeTabSize"); - }; - - this.getTabSize = function() { - return this.$tabSize; - }; - - this.isTabStop = function(position) { - return this.$useSoftTabs && (position.column % this.$tabSize == 0); - }; - - this.$overwrite = false; - this.setOverwrite = function(overwrite) { - if (this.$overwrite == overwrite) return; - - this.$overwrite = overwrite; - this._dispatchEvent("changeOverwrite"); - }; - - this.getOverwrite = function() { - return this.$overwrite; - }; - - this.toggleOverwrite = function() { - this.setOverwrite(!this.$overwrite); - }; - - this.getBreakpoints = function() { - return this.$breakpoints; - }; - - this.setBreakpoints = function(rows) { - this.$breakpoints = []; - for (var i=0; i 0) { - inToken = !!line.charAt(column - 1).match(this.tokenRe); - } - - if (!inToken) { - inToken = !!line.charAt(column).match(this.tokenRe); - } - - var re = inToken ? this.tokenRe : this.nonTokenRe; - - var start = column; - if (start > 0) { - do { - start--; - } - while (start >= 0 && line.charAt(start).match(re)); - start++; - } - - var end = column; - while (end < line.length && line.charAt(end).match(re)) { - end++; - } - - return new Range(row, start, row, end); - }; - - this.setNewLineMode = function(newLineMode) { - this.doc.setNewLineMode(newLineMode); - }; - - this.getNewLineMode = function() { - return this.doc.getNewLineMode(); - }; - - this.$useWorker = true; - this.setUseWorker = function(useWorker) { - if (this.$useWorker == useWorker) - return; - - if (useWorker && !this.$worker && window.Worker) - this.$worker = mode.createWorker(this); - - if (!useWorker && this.$worker) { - this.$worker.terminate(); - this.$worker = null; - } - }; - - this.getUseWorker = function() { - return this.$useWorker; - }; - - this.$mode = null; - this.setMode = function(mode) { - if (this.$mode === mode) return; - - if (this.$worker) - this.$worker.terminate(); - - if (this.$useWorker && window.Worker && !require.noWorker) - this.$worker = mode.createWorker(this); - else - this.$worker = null; - - this.$mode = mode; - this._dispatchEvent("changeMode"); - }; - - this.getMode = function() { - if (!this.$mode) { - this.$mode = new TextMode(); - } - return this.$mode; - }; - - this.$scrollTop = 0; - this.setScrollTopRow = function(scrollTopRow) { - if (this.$scrollTop === scrollTopRow) return; - - this.$scrollTop = scrollTopRow; - this._dispatchEvent("changeScrollTop"); - }; - - this.getScrollTopRow = function() { - return this.$scrollTop; - }; - - this.getWidth = function() { - this.$computeWidth(); - return this.width; - }; - - this.getScreenWidth = function() { - this.$computeWidth(); - return this.screenWidth; - }; - - this.$computeWidth = function(force) { - if (this.$modified || force) { - this.$modified = false; - - var lines = this.doc.getAllLines(); - var longestLine = 0; - var longestScreenLine = 0; - var tabSize = this.getTabSize(); - - for ( var i = 0; i < lines.length; i++) { - var len = lines[i].length; - longestLine = Math.max(longestLine, len); - - lines[i].replace(/\t/g, function(m) { - len += tabSize-1; - return m; - }); - longestScreenLine = Math.max(longestScreenLine, len); - } - this.width = longestLine; - - if (this.$useWrapMode) { - this.screenWidth = this.$wrapLimit; - } else { - this.screenWidth = longestScreenLine; - } - } - }; - - /** - * Get a verbatim copy of the given line as it is in the document - */ - this.getLine = function(row) { - return this.doc.getLine(row); - }; - - /** - * Get a line as it is displayed on screen. Tabs are replaced by spaces. - */ - this.getDisplayLine = function(row) { - var tab = new Array(this.getTabSize()+1).join(" "); - return this.doc.getLine(row).replace(/\t/g, tab); - }; - - this.getLines = function(firstRow, lastRow) { - return this.doc.getLines(firstRow, lastRow); - }; - - this.getLength = function() { - return this.doc.getLength(); - }; - - this.getTextRange = function(range) { - return this.doc.getTextRange(range); - }; - - this.findMatchingBracket = function(position) { - if (position.column == 0) return null; - - var charBeforeCursor = this.getLine(position.row).charAt(position.column-1); - if (charBeforeCursor == "") return null; - - var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/); - if (!match) { - return null; - } - - if (match[1]) { - return this.$findClosingBracket(match[1], position); - } else { - return this.$findOpeningBracket(match[2], position); - } - }; - - this.$brackets = { - ")": "(", - "(": ")", - "]": "[", - "[": "]", - "{": "}", - "}": "{" - }; - - this.$findOpeningBracket = function(bracket, position) { - var openBracket = this.$brackets[bracket]; - - var column = position.column - 2; - var row = position.row; - var depth = 1; - - var line = this.getLine(row); - - while (true) { - while(column >= 0) { - var ch = line.charAt(column); - if (ch == openBracket) { - depth -= 1; - if (depth == 0) { - return {row: row, column: column}; - } - } - else if (ch == bracket) { - depth +=1; - } - column -= 1; - } - row -=1; - if (row < 0) break; - - var line = this.getLine(row); - var column = line.length-1; - } - return null; - }; - - this.$findClosingBracket = function(bracket, position) { - var closingBracket = this.$brackets[bracket]; - - var column = position.column; - var row = position.row; - var depth = 1; - - var line = this.getLine(row); - var lineCount = this.getLength(); - - while (true) { - while(column < line.length) { - var ch = line.charAt(column); - if (ch == closingBracket) { - depth -= 1; - if (depth == 0) { - return {row: row, column: column}; - } - } - else if (ch == bracket) { - depth +=1; - } - column += 1; - } - row +=1; - if (row >= lineCount) break; - - var line = this.getLine(row); - var column = 0; - } - return null; - }; - - this.insert = function(position, text) { - return this.doc.insert(position, text); - }; - - this.remove = function(range) { - return this.doc.remove(range); - }; - - this.undoChanges = function(deltas) { - if (!deltas.length) - return; - - this.$fromUndo = true; - this.doc.revertDeltas(deltas); - this.$fromUndo = false; - - this.$setUndoSelection(deltas, true); - }, - - this.redoChanges = function(deltas) { - if (!deltas.length) - return; - - this.$fromUndo = true; - this.doc.applyDeltas(deltas); - this.$fromUndo = false; - - this.$setUndoSelection(deltas, false); - }, - - this.$setUndoSelection = function(deltas, isUndo) { - // invert deltas is they are an undo - if (isUndo) - deltas = deltas.map(function(delta) { - var d = { - range: delta.range - } - if (delta.action == "insertText" || delta.action == "insertLines") - d.action = "removeText" - else - d.action = "insertText" - return d; - }).reverse(); - - - var actions = [{}]; - - // collapse insert and remove operations - for (var i=0; i= this.doc.getLength()-1) return 0; - - var removed = this.doc.removeLines(firstRow, lastRow); - this.doc.insertLines(firstRow+1, removed); - return 1; - }; - - this.duplicateLines = function(firstRow, lastRow) { - var firstRow = this.$clipRowToDocument(firstRow); - var lastRow = this.$clipRowToDocument(lastRow); - - var lines = this.getLines(firstRow, lastRow); - this.doc.insertLines(firstRow, lines); - - var addedRows = lastRow - firstRow + 1; - return addedRows; - }; - - this.$clipRowToDocument = function(row) { - return Math.max(0, Math.min(row, this.doc.getLength()-1)); - }; - - // WRAPMODE - this.$wrapLimit = 80; - this.$useWrapMode = false; - this.$wrapLimitRange = { - min : null, - max : null - }; - - this.setUseWrapMode = function(useWrapMode) { - if (useWrapMode != this.$useWrapMode) { - this.$useWrapMode = useWrapMode; - this.$modified = true; - - // If wrapMode is activaed, the wrapData array has to be initialized. - if (useWrapMode) { - var len = this.getLength(); - this.$wrapData = []; - for (i = 0; i < len; i++) { - this.$wrapData.push([]); - } - this.$updateWrapData(0, len - 1); - } - - this._dispatchEvent("changeWrapMode"); - } - }; - - this.getUseWrapMode = function() { - return this.$useWrapMode; - }; - - // Allow the wrap limit to move freely between min and max. Either - // 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. - this.setWrapLimitRange = function(min, max) { - if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) { - this.$wrapLimitRange.min = min; - this.$wrapLimitRange.max = max; - this.$modified = true; - // This will force a recalculation of the wrap limit - this._dispatchEvent("changeWrapMode"); - } - }; - - // 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) { - this.$wrapLimit = wrapLimit; - this.$modified = true; - if (this.$useWrapMode) { - this.$updateWrapData(0, this.getLength() - 1); - this._dispatchEvent("changeWrapLimit"); - } - return true; - } - return false; - }; - - this.$constrainWrapLimit = function(wrapLimit) { - var min = this.$wrapLimitRange.min; - if (min) - wrapLimit = Math.max(min, wrapLimit); - - var max = this.$wrapLimitRange.max; - if (max) - wrapLimit = Math.min(max, wrapLimit); - - // What would a limit of 0 even mean? - return Math.max(1, wrapLimit); - }; - - this.getWrapLimit = function() { - return this.$wrapLimit; - }; - - this.getWrapLimitRange = function() { - // Avoid unexpected mutation by returning a copy - return { - min : this.$wrapLimitRange.min, - max : this.$wrapLimitRange.max - }; - }; - - this.$updateWrapDataOnChange = function(e) { - if (!this.$useWrapMode) { - return; - } - - var len; - var action = e.data.action; - var firstRow = e.data.range.start.row, - lastRow = e.data.range.end.row; - - if (action.indexOf("Lines") != -1) { - if (action == "insertLines") { - lastRow = firstRow + (e.data.lines.length); - } else { - lastRow = firstRow; - } - len = e.data.lines.length; - } else { - len = lastRow - firstRow; - } - - if (len != 0) { - if (action.indexOf("remove") != -1) { - this.$wrapData.splice(firstRow, len); - lastRow = firstRow; - } else { - var args = [firstRow, 0]; - for (var i = 0; i < len; i++) args.push([]); - this.$wrapData.splice.apply(this.$wrapData, args); - } - } - - if (this.$wrapData.length != this.doc.$lines.length) { - console.error("The length of doc.$lines and $wrapData have to be the same!"); - } - - this.$updateWrapData(firstRow, lastRow); - }; - - this.$updateWrapData = function(firstRow, lastRow) { - var lines = this.doc.getAllLines(); - var tabSize = this.getTabSize(); - var wrapData = this.$wrapData; - var wrapLimit = this.$wrapLimit; - - for (var row = firstRow; row <= lastRow; row++) { - wrapData[row] = - this.$computeWrapSplits(lines[row], wrapLimit, tabSize); - } - }; - - // "Tokens" - var CHAR = 1, - CHAR_EXT = 2, - SPACE = 3, - TAB = 4, - TAB_SPACE = 5; - - this.$computeWrapSplits = function(textLine, wrapLimit, tabSize) { - textLine = textLine.trimRight(); - if (textLine.length == 0) { - return []; - } - - var tabSize = this.getTabSize(); - var splits = []; - var tokens = this.$getDisplayTokens(textLine); - var displayLength = tokens.length; - var lastSplit = 0, lastDocSplit = 0; - - function addSplit(screenPos) { - var displayed = tokens.slice(lastSplit, screenPos); - - // The document size is the current size - the extra width for tabs - // and multipleWidth characters. - var len = displayed.length; - displayed.join(""). - // Get all the tabs. - replace(/4/g, function(m) { - len -= tabSize - 1; - }). - // Get all the multipleWidth characters. - replace(/2/g, function(m) { - len -= 1; - }); - - lastDocSplit += len; - splits.push(lastDocSplit); - lastSplit = screenPos; - } - - while (displayLength - lastSplit > wrapLimit) { - // This is, where the split should be. - var split = lastSplit + wrapLimit; - - // If there is a space or tab at this split position. - if (tokens[split] >= SPACE) { - // Include all following spaces + tabs in this split as well. - while (tokens[split] >= SPACE) { - split ++; - } - addSplit(split); - } else { - // Search for the first non space/tab token. - for (split; split != lastSplit - 1; split--) { - if (tokens[split] >= SPACE) { - split++; - break; - } - } - // If we found one, then add the split. - if (split > lastSplit) { - addSplit(split); - } - // No space or tab around? Well, force a split then. - else { - addSplit(lastSplit + wrapLimit); - } - } - } - return splits; - } - - this.$getDisplayTokens = function(str) { - var arr = []; - var tabSize = this.getTabSize(); - - for (var i = 0; i < str.length; i++) { - var c = str.charCodeAt(i); - // Tab - if (c == 9) { - arr.push(TAB); - for (var n = 1; n < tabSize; n++) { - arr.push(TAB_SPACE); - } - } - // Space - else if(c == 32) { - arr.push(SPACE); - } - // CJK characters - else if ( - c >= 0x3040 && c <= 0x309F || // Hiragana - c >= 0x30A0 && c <= 0x30FF || // Katakana - c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs - c >= 0xF900 && c <= 0xFAFF || - c >= 0x3400 && c <= 0x4DBF - ) { - arr.push(CHAR, CHAR_EXT); - } else { - arr.push(CHAR); - } - } - 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 int number of columns for str on screen. - */ - this.$getStringScreenWidth = function(str) { - var screenColumn = 0; - var tabSize = this.getTabSize(); - - for (var i=0; i= 0x3040 && c <= 0x309F || // Hiragana - c >= 0x30A0 && c <= 0x30FF || // Katakana - c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs - c >= 0xF900 && c <= 0xFAFF || - c >= 0x3400 && c <= 0x4DBF - ) { - screenColumn += 2; - } else { - screenColumn += 1; - } - } - - return screenColumn; - } - - this.getRowHeight = function(config, row) { - var rows; - if (!this.$useWrapMode || !this.$wrapData[row]) { - rows = 1; - } else { - rows = this.$wrapData[row].length + 1; - } - - return rows * config.lineHeight; - } - - this.getScreenLastRowColumn = function(screenRow, returnDocPosition) { - if (!this.$useWrapMode) { - return this.$getStringScreenWidth(this.getLine(screenRow)); - } - - var rowData = this.$screenToDocumentRow(screenRow); - var docRow = rowData[0], - row = rowData[1]; - - var start, end; - if (this.$wrapData[docRow][row]) { - start = (this.$wrapData[docRow][row - 1] || 0); - end = this.$wrapData[docRow][row]; - returnDocPosition && end--; - } else { - end = this.getLine(docRow).length; - start = (this.$wrapData[docRow][row - 1] || 0); - } - if (!returnDocPosition) { - return this.$getStringScreenWidth(this.getLine(docRow).substring(start, end)); - } else { - return end; - } - }; - - this.getDocumentLastRowColumn = function(docRow, docColumn) { - if (!this.$useWrapMode) { - return this.getLine(docRow).length; - } - - var screenRow = this.documentToScreenRow(docRow, docColumn); - return this.getScreenLastRowColumn(screenRow, true); - } - - this.getScreenFirstRowColumn = function(screenRow) { - if (!this.$useWrapMode) { - return 0; - } - - var rowData = this.$screenToDocumentRow(screenRow); - var docRow = rowData[0], - row = rowData[1]; - - return this.$wrapData[docRow][row - 1] || 0; - }; - - this.getRowSplitData = function(row) { - if (!this.$useWrapMode) { - return undefined; - } else { - return this.$wrapData[row]; - } - }; - - /** - * - * @returns array - * - array[0]: The documentRow equivalent. - * - array[1]: The screenRowOffset to the first documentRow on the screen. - */ - this.$screenToDocumentRow = function(row) { - if (!this.$useWrapMode) { - return [row, 0]; - } - - var wrapData = this.$wrapData, linesCount = this.getLength(); - var docRow = 0; - while (docRow < linesCount && row >= wrapData[docRow].length + 1) { - row -= wrapData[docRow].length + 1; - docRow ++; - } - - return [docRow, row]; - }; - - this.screenToDocumentRow = function(screenRow) { - return this.$screenToDocumentRow(screenRow)[0]; - }; - - this.screenToDocumentColumn = function(screenRow, screenColumn) { - return this.screenToDocumentPosition(screenRow, screenColumn).column; - }; - - this.screenToDocumentPosition = function(row, column) { - var line; - var docRow; - var docColumn; - var remaining = column; - var linesCount = this.getLength(); - if (!this.$useWrapMode) { - docRow = row >= linesCount? linesCount-1 : (row < 0 ? 0 : row); - row = 0; - docColumn = 0; - line = this.getLine(docRow); - } else { - var wrapData = this.$wrapData; - - var docRow = 0; - while (docRow < linesCount && row >= wrapData[docRow].length + 1) { - row -= wrapData[docRow].length + 1; - docRow ++; - } - - if (docRow >= linesCount) { - docRow = linesCount-1 - row = wrapData[docRow].length; - } - docColumn = wrapData[docRow][row - 1] || 0; - line = this.getLine(docRow).substring(docColumn); - } - - var tabSize = this.getTabSize(); - for(var i = 0; i < line.length; i++) { - var c = line.charCodeAt(i); - - if (remaining > 0) { - docColumn += 1; - // tab - if (c == 9) { - if (remaining >= tabSize) { - remaining -= tabSize; - } else { - remaining = 0; - docColumn -= 1; - } - } - // CJK characters - else if ( - c >= 0x3040 && c <= 0x309F || // Hiragana - c >= 0x30A0 && c <= 0x30FF || // Katakana - c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs - c >= 0xF900 && c <= 0xFAFF || - c >= 0x3400 && c <= 0x4DBF - ) { - if (remaining >= 2) { - remaining -= 2; - } else { - remaining = 0; - docColumn -= 1; - } - } else { - remaining -= 1; - } - } else { - break; - } - } - - // Clamp docColumn. - if (this.$useWrapMode) { - column = wrapData[docRow][row] - if (docColumn >= column) { - // We remove one character at the end such that the docColumn - // position returned is not associated to the next row on the - // screen. - docColumn = column - 1; - } - } else if (line) { - docColumn = Math.min(docColumn, line.length); - } - - return { - row: docRow, - column: docColumn - }; - }; - - this.documentToScreenColumn = function(row, docColumn) { - return this.documentToScreenPosition(row, docColumn).column; - }; - - /** - * - * @return array[2] - * - array[0]: The number of the row on the screen (aka screenRow) - * - array[1]: The number of rows from the first docRow on the screen - * (aka screenRowOffset); - */ - this.$documentToScreenRow = function(docRow, docColumn) { - if (!this.$useWrapMode) { - return [docRow, 0]; - } - - var wrapData = this.$wrapData; - var screenRow = 0; - - // Handle special case where the row is outside of the range of lines. - if (docRow > wrapData.length - 1) { - return [ - this.getScreenLength(), - wrapData.length == 0 ? 0 : (wrapData[wrapData.length - 1].length - 1) - ]; - } - - for (var i = 0; i < docRow; i++) { - screenRow += wrapData[i].length + 1; - } - - var screenRowOffset = 0; - while (docColumn >= wrapData[docRow][screenRowOffset]) { - screenRow ++; - screenRowOffset++; - } - - return [screenRow, screenRowOffset]; - } - - this.documentToScreenRow = function(docRow, docColumn) { - return this.$documentToScreenRow(docRow, docColumn)[0]; - } - - this.documentToScreenPosition = function(pos, column) { - var str; - var tabSize = this.getTabSize(); - - // Normalize the passed in arguments. - var row; - if (column != null) { - row = pos; - } else { - row = pos.row; - column = pos.column; - } - - if (!this.$useWrapMode) { - str = this.getLine(row).substring(0, column); - column = this.$getStringScreenWidth(str); - return { - row: row, - column: column - }; - } - - var rowData = this.$documentToScreenRow(row, column); - var screenRow = rowData[0]; - - if (row >= this.getLength()) { - return { - row: screenRow, - column: 0 - }; - } - - var split; - var wrapRowData = this.$wrapData[row]; - var screenColumn; - var screenRowOffset = rowData[1]; - - str = this.getLine(row).substring( - wrapRowData[screenRowOffset - 1] || 0, column); - screenColumn = this.$getStringScreenWidth(str); - - return { - row: screenRow, - column: screenColumn - }; - }; - - this.getScreenLength = function() { - if (!this.$useWrapMode) { - return this.getLength(); - } - - var screenRows = 0; - for (var row = 0; row < this.$wrapData.length; row++) { - screenRows += this.$wrapData[row].length + 1; - } - return screenRows; - } - -}).call(EditSession.prototype); - -exports.EditSession = EditSession; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/selection', ['require', 'exports', 'module' , 'pilot/oop', 'pilot/lang', 'pilot/event_emitter', 'ace/range'], function(require, exports, module) { - -var oop = require("pilot/oop"); -var lang = require("pilot/lang"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; -var Range = require("ace/range").Range; - -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); - - var _self = this; - this.selectionLead.on("change", function(e) { - _self._dispatchEvent("changeCursor"); - if (!_self.$isEmpty) - _self._dispatchEvent("changeSelection"); - if (e.old.row == e.value.row) - _self.$updateDesiredColumn(); - }); - - this.selectionAnchor.on("change", function() { - if (!_self.$isEmpty) - _self._dispatchEvent("changeSelection"); - }); -}; - -(function() { - - oop.implement(this, EventEmitter); - - this.isEmpty = function() { - return (this.$isEmpty || ( - this.selectionAnchor.row == this.selectionLead.row && - this.selectionAnchor.column == this.selectionLead.column - )); - }; - - this.isMultiLine = function() { - if (this.isEmpty()) { - return false; - } - - return this.getRange().isMultiLine(); - }; - - this.getCursor = function() { - return this.selectionLead.getPosition(); - }; - - this.setSelectionAnchor = function(row, column) { - this.selectionAnchor.setPosition(row, column); - - if (this.$isEmpty) { - this.$isEmpty = false; - this._dispatchEvent("changeSelection"); - } - }; - - this.getSelectionAnchor = function() { - if (this.$isEmpty) - return this.getSelectionLead() - else - return this.selectionAnchor.getPosition(); - }; - - this.getSelectionLead = function() { - return this.selectionLead.getPosition(); - }; - - this.shiftSelection = function(columns) { - if (this.$isEmpty) { - this.moveCursorTo(this.selectionLead.row, this.selectionLead.column + columns); - return; - }; - - var anchor = this.getSelectionAnchor(); - var lead = this.getSelectionLead(); - - var isBackwards = this.isBackwards(); - - if (!isBackwards || anchor.column !== 0) - this.setSelectionAnchor(anchor.row, anchor.column + columns); - - if (isBackwards || lead.column !== 0) { - this.$moveSelection(function() { - this.moveCursorTo(lead.row, lead.column + columns); - }); - } - }; - - this.isBackwards = function() { - var anchor = this.selectionAnchor; - var lead = this.selectionLead; - return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column)); - }; - - this.getRange = function() { - var anchor = this.selectionAnchor; - var lead = this.selectionLead; - - if (this.isEmpty()) - return Range.fromPoints(lead, lead); - - if (this.isBackwards()) { - return Range.fromPoints(lead, anchor); - } - else { - return Range.fromPoints(anchor, lead); - } - }; - - this.clearSelection = function() { - if (!this.$isEmpty) { - this.$isEmpty = true; - this._dispatchEvent("changeSelection"); - } - }; - - this.selectAll = function() { - var lastRow = this.doc.getLength() - 1; - this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length); - this.moveCursorTo(0, 0); - }; - - this.setSelectionRange = function(range, reverse) { - if (reverse) { - this.setSelectionAnchor(range.end.row, range.end.column); - this.selectTo(range.start.row, range.start.column); - } else { - this.setSelectionAnchor(range.start.row, range.start.column); - this.selectTo(range.end.row, range.end.column); - } - this.$updateDesiredColumn(); - }; - - this.$updateDesiredColumn = function() { - var cursor = this.getCursor(); - this.$desiredColumn = this.session.documentToScreenColumn(cursor.row, cursor.column); - }; - - this.$moveSelection = function(mover) { - var lead = this.selectionLead; - if (this.$isEmpty) - this.setSelectionAnchor(lead.row, lead.column); - - mover.call(this); - }; - - this.selectTo = function(row, column) { - this.$moveSelection(function() { - this.moveCursorTo(row, column); - }); - }; - - this.selectToPosition = function(pos) { - this.$moveSelection(function() { - this.moveCursorToPosition(pos); - }); - }; - - 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 cursor = this.getCursor(); - var range = this.session.getWordRange(cursor.row, cursor.column); - this.setSelectionRange(range); - }; - - this.selectLine = function() { - this.setSelectionAnchor(this.selectionLead.row, 0); - this.$moveSelection(function() { - this.moveCursorTo(this.selectionLead.row + 1, 0); - }); - }; - - this.moveCursorUp = function() { - this.moveCursorBy(-1, 0); - }; - - this.moveCursorDown = function() { - this.moveCursorBy(1, 0); - }; - - this.moveCursorLeft = function() { - var cursor = this.selectionLead.getPosition(); - if (cursor.column == 0) { - // cursor is a line (start - if (cursor.row > 0) { - this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length); - } - } - else { - var tabSize = this.session.getTabSize(); - if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column-tabSize, cursor.column).split(" ").length-1 == tabSize) - this.moveCursorBy(0, -tabSize); - else - this.moveCursorBy(0, -1); - } - }; - - this.moveCursorRight = function() { - 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 { - var tabSize = this.session.getTabSize(); - var cursor = this.selectionLead; - 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 - this.moveCursorBy(0, 1); - } - }; - - this.moveCursorLineStart = function() { - var row = this.selectionLead.row; - var column = this.selectionLead.column; - var screenRow = this.session.documentToScreenRow(row, column); - var firstRowColumn = this.session.getScreenFirstRowColumn(screenRow); - var beforeCursor = this.doc.getLine(row).slice(firstRowColumn, column); - var leadingSpace = beforeCursor.match(/^\s*/); - if (leadingSpace[0].length == 0) { - var lastRowColumn = this.session.getDocumentLastRowColumn(row, column); - leadingSpace = this.doc.getLine(row). - substring(firstRowColumn, lastRowColumn). - match(/^\s*/); - this.moveCursorTo(row, firstRowColumn + leadingSpace[0].length); - } else if (leadingSpace[0].length >= column) { - this.moveCursorTo(row, firstRowColumn); - } else { - this.moveCursorTo(row, firstRowColumn + leadingSpace[0].length); - } - }; - - this.moveCursorLineEnd = function() { - var lead = this.selectionLead; - this.moveCursorTo(lead.row, this.session.getDocumentLastRowColumn(lead.row, lead.column)); - }; - - this.moveCursorFileEnd = function() { - var row = this.doc.getLength() - 1; - var column = this.doc.getLine(row).length; - this.moveCursorTo(row, column); - }; - - this.moveCursorFileStart = function() { - this.moveCursorTo(0, 0); - }; - - this.moveCursorWordRight = function() { - var row = this.selectionLead.row; - var column = this.selectionLead.column; - var line = this.doc.getLine(row); - var rightOfCursor = line.substring(column); - - var match; - this.session.nonTokenRe.lastIndex = 0; - this.session.tokenRe.lastIndex = 0; - - if (column == line.length) { - this.moveCursorRight(); - return; - } - else if (match = this.session.nonTokenRe.exec(rightOfCursor)) { - column += this.session.nonTokenRe.lastIndex; - this.session.nonTokenRe.lastIndex = 0; - } - else if (match = this.session.tokenRe.exec(rightOfCursor)) { - column += this.session.tokenRe.lastIndex; - this.session.tokenRe.lastIndex = 0; - } - - this.moveCursorTo(row, column); - }; - - this.moveCursorWordLeft = function() { - var row = this.selectionLead.row; - var column = this.selectionLead.column; - var line = this.doc.getLine(row); - var leftOfCursor = lang.stringReverse(line.substring(0, column)); - - var match; - this.session.nonTokenRe.lastIndex = 0; - this.session.tokenRe.lastIndex = 0; - - if (column == 0) { - this.moveCursorLeft(); - return; - } - else if (match = this.session.nonTokenRe.exec(leftOfCursor)) { - column -= this.session.nonTokenRe.lastIndex; - this.session.nonTokenRe.lastIndex = 0; - } - else if (match = this.session.tokenRe.exec(leftOfCursor)) { - column -= this.session.tokenRe.lastIndex; - this.session.tokenRe.lastIndex = 0; - } - - this.moveCursorTo(row, column); - }; - - this.moveCursorBy = function(rows, chars) { - if (this.session.getUseWrapMode()) { - var screenPos = this.session.documentToScreenPosition( - this.selectionLead.row, - this.selectionLead.column - ); - var screenCol = (chars == 0 && this.$desiredColumn) || screenPos.column; - var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenCol); - - this.moveCursorTo(docPos.row, docPos.column + chars, chars == 0); - } else { - var docColumn = (chars == 0 && this.$desiredColumn) || this.selectionLead.column; - this.moveCursorTo(this.selectionLead.row + rows, docColumn + chars, chars == 0); - } - }; - - this.moveCursorToPosition = function(position) { - this.moveCursorTo(position.row, position.column); - }; - - this.moveCursorTo = function(row, column, preventUpdateDesiredColumn) { - this.selectionLead.setPosition(row, column); - if (!preventUpdateDesiredColumn) - this.$updateDesiredColumn(this.selectionLead.column); - }; - - this.moveCursorToScreen = function(row, column, preventUpdateDesiredColumn) { - if (this.session.getUseWrapMode()) { - var pos = this.session.screenToDocumentPosition(row, column); - row = pos.row; - column = pos.column; - } - this.moveCursorTo(row, column, preventUpdateDesiredColumn); - }; - -}).call(Selection.prototype); - -exports.Selection = Selection; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) { - -var Range = function(startRow, startColumn, endRow, endColumn) { - this.start = { - row: startRow, - column: startColumn - }; - - this.end = { - row: endRow, - column: endColumn - }; -}; - -(function() { - - this.toString = function() { - return ("Range: [" + this.start.row + "/" + this.start.column + - "] -> [" + this.end.row + "/" + this.end.column + "]"); - }; - - this.contains = function(row, column) { - return this.compare(row, column) == 0; - }; - - this.compare = function(row, column) { - if (!this.isMultiLine()) { - if (row === this.start.row) { - return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0); - }; - } - - if (row < this.start.row) - return -1; - - if (row > this.end.row) - return 1; - - if (this.start.row === row) - return column >= this.start.column ? 0 : -1; - - if (this.end.row === row) - return column <= this.end.column ? 0 : 1; - - return 0; - }; - - this.clipRows = function(firstRow, lastRow) { - if (this.end.row > lastRow) { - var end = { - row: lastRow+1, - column: 0 - }; - } - - if (this.start.row > lastRow) { - var start = { - row: lastRow+1, - column: 0 - }; - } - - if (this.start.row < firstRow) { - var start = { - row: firstRow, - column: 0 - }; - } - - if (this.end.row < firstRow) { - var end = { - row: firstRow, - column: 0 - }; - } - return Range.fromPoints(start || this.start, end || this.end); - }; - - this.extend = function(row, column) { - var cmp = this.compare(row, column); - - if (cmp == 0) - return this; - else if (cmp == -1) - var start = {row: row, column: column}; - else - var end = {row: row, column: column}; - - return Range.fromPoints(start || this.start, end || this.end); - }; - - this.isEmpty = function() { - return (this.start.row == this.end.row && this.start.column == this.end.column); - }; - - this.isMultiLine = function() { - return (this.start.row !== this.end.row); - }; - - this.clone = function() { - return Range.fromPoints(this.start, this.end); - }; - - 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) - else - return new Range(this.start.row, 0, this.end.row, 0) - }; - - this.toScreenRange = function(session) { - var screenPosStart = - session.documentToScreenPosition(this.start); - var screenPosEnd = - session.documentToScreenPosition(this.end); - return new Range( - screenPosStart.row, screenPosStart.column, - screenPosEnd.row, screenPosEnd.column - ); - }; - -}).call(Range.prototype); - - -Range.fromPoints = function(start, end) { - return new Range(start.row, start.column, end.row, end.column); -}; - -exports.Range = Range; -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Mihai Sucan - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/mode/text', ['require', 'exports', 'module' , 'ace/tokenizer', 'ace/mode/text_highlight_rules'], function(require, exports, module) { - -var Tokenizer = require("ace/tokenizer").Tokenizer; -var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; - -var Mode = function() { - this.$tokenizer = new Tokenizer(new TextHighlightRules().getRules()); -}; - -(function() { - - this.getTokenizer = function() { - return this.$tokenizer; - }; - - this.toggleCommentLines = function(state, doc, startRow, endRow) { - }; - - this.getNextLineIndent = function(state, line, tab) { - return ""; - }; - - this.checkOutdent = function(state, line, input) { - return false; - }; - - this.autoOutdent = function(state, doc, row) { - }; - - this.$getIndent = function(line) { - var match = line.match(/^(\s+)/); - if (match) { - return match[1]; - } - - return ""; - }; - - this.createWorker = function(session) { - return null; - }; - - this.highlightSelection = function(editor) { - var session = editor.session; - if (!session.$selectionOccurrences) - session.$selectionOccurrences = []; - - if (session.$selectionOccurrences.length) - this.clearSelectionHighlight(editor); - - var selection = editor.getSelectionRange(); - if (selection.isEmpty() || selection.isMultiLine()) - return; - - var startOuter = selection.start.column - 1; - var endOuter = selection.end.column + 1; - var line = session.getLine(selection.start.row); - var lineCols = line.length; - var needle = line.substring(Math.max(startOuter, 0), - Math.min(endOuter, lineCols)); - - // Make sure the outer characters are not part of the word. - if ((startOuter >= 0 && /^[\w\d]/.test(needle)) || - (endOuter <= lineCols && /[\w\d]$/.test(needle))) - return; - - needle = line.substring(selection.start.column, selection.end.column); - if (!/^[\w\d]+$/.test(needle)) - return; - - var cursor = editor.getCursorPosition(); - - var newOptions = { - wrap: true, - wholeWord: true, - caseSensitive: true, - needle: needle - }; - - var currentOptions = editor.$search.getOptions(); - editor.$search.set(newOptions); - - var ranges = editor.$search.findAll(session); - ranges.forEach(function(range) { - if (!range.contains(cursor.row, cursor.column)) { - var marker = session.addMarker(range, "ace_selected_word"); - session.$selectionOccurrences.push(marker); - } - }); - - editor.$search.set(currentOptions); - }; - - this.clearSelectionHighlight = function(editor) { - if (!editor.session.$selectionOccurrences) - return; - - editor.session.$selectionOccurrences.forEach(function(marker) { - editor.session.removeMarker(marker); - }); - - editor.session.$selectionOccurrences = []; - }; - -}).call(Mode.prototype); - -exports.Mode = Mode; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/tokenizer', ['require', 'exports', 'module' ], function(require, exports, module) { - -var Tokenizer = function(rules) { - this.rules = rules; - - this.regExps = {}; - for ( var key in this.rules) { - var rule = this.rules[key]; - var state = rule; - var ruleRegExps = []; - - for ( var i = 0; i < state.length; i++) - ruleRegExps.push(state[i].regex); - - this.regExps[key] = new RegExp("(?:(" + ruleRegExps.join(")|(") + ")|(.))", "g"); - - } -}; - -(function() { - - this.getLineTokens = function(line, startState) { - var currentState = startState; - var state = this.rules[currentState]; - var re = this.regExps[currentState]; - re.lastIndex = 0; - - var match, tokens = []; - - var lastIndex = 0; - - var token = { - type: null, - value: "" - }; - - while (match = re.exec(line)) { - var type = "text"; - var value = match[0]; - - for ( var i = 0; i < state.length; i++) { - if (match[i + 1]) { - var rule = state[i]; - - if (typeof rule.token == "function") - type = rule.token(match[0]); - else - type = rule.token; - - if (rule.next && rule.next !== currentState) { - currentState = rule.next; - state = this.rules[currentState]; - lastIndex = re.lastIndex; - - re = this.regExps[currentState]; - re.lastIndex = lastIndex; - } - break; - } - }; - - - if (token.type !== type) { - if (token.type) - tokens.push(token); - - token = { - type: type, - value: value - }; - } else { - token.value += value; - } - - if (lastIndex == line.length) - break; - - lastIndex = re.lastIndex; - }; - - if (token.type) - tokens.push(token); - - return { - tokens : tokens, - state : currentState - }; - }; - -}).call(Tokenizer.prototype); - -exports.Tokenizer = Tokenizer; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/mode/text_highlight_rules', ['require', 'exports', 'module' ], function(require, exports, module) { - -var TextHighlightRules = function() { - - // regexp must not have capturing parentheses - // regexps are ordered -> the first match is used - - this.$rules = { - "start" : [ { - token : "empty_line", - regex : '^$' - }, { - token : "text", - regex : ".+" - } ] - }; -}; - -(function() { - - this.addRules = function(rules, prefix) { - for (var key in rules) { - var state = rules[key]; - for (var i=0; i - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/document', ['require', 'exports', 'module' , 'pilot/oop', 'pilot/event_emitter', 'ace/range', 'ace/anchor'], function(require, exports, module) { - -var oop = require("pilot/oop"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; -var Range = require("ace/range").Range; -var Anchor = require("ace/anchor").Anchor; - -var Document = function(text) { - this.$lines = []; - - if (Array.isArray(text)) { - this.insertLines(0, text); - } - // There has to be one line at least in the document. If you pass an empty - // string to the insert function, nothing will happen. Workaround. - else if (text.length == 0) { - this.$lines = [""]; - } else { - this.insert({row: 0, column:0}, text); - } -}; - -(function() { - - oop.implement(this, EventEmitter); - - 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); - }; - - this.getValue = function() { - return this.getAllLines().join(this.getNewLineCharacter()); - }; - - this.createAnchor = function(row, column) { - return new Anchor(this, row, column); - }; - - // check for IE split bug - if ("aaa".split(/a/).length == 0) - this.$split = function(text) { - return text.replace(/\r\n|\r/g, "\n").split("\n"); - } - else - this.$split = function(text) { - return text.split(/\r\n|\r|\n/); - }; - - - this.$detectNewLine = function(text) { - var match = text.match(/^.*?(\r?\n)/m); - if (match) { - this.$autoNewLine = match[1]; - } else { - this.$autoNewLine = "\n"; - } - }; - - this.getNewLineCharacter = function() { - switch (this.$newLineMode) { - case "windows": - return "\r\n"; - - case "unix": - return "\n"; - - case "auto": - return this.$autoNewLine; - } - }, - - this.$autoNewLine = "\n"; - this.$newLineMode = "auto"; - this.setNewLineMode = function(newLineMode) { - if (this.$newLineMode === newLineMode) return; - - this.$newLineMode = newLineMode; - }; - - this.getNewLineMode = function() { - return this.$newLineMode; - }; - - 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 - */ - this.getLine = function(row) { - return this.getLines(row, row + 1)[0] || ""; - }; - - 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! - */ - this.getAllLines = function() { - return this.getLines(0, this.getLength()); - }; - - this.getLength = function() { - return this.$lines.length; - }; - - 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)); - return lines.join(this.getNewLineCharacter()); - } - }; - - this.$clipPosition = function(position) { - var length = this.getLength(); - if (position.row >= length) { - position.row = Math.max(0, length - 1); - position.column = this.getLine(length-1).length; - } - return position; - } - - this.insert = function(position, text) { - if (text.length == 0) - return position; - - position = this.$clipPosition(position); - - if (this.getLength() <= 1) - this.$detectNewLine(text); - - var lines = this.$split(text); - var firstLine = lines.splice(0, 1)[0]; - var lastLine = lines.length == 0 ? null : lines.splice(lines.length - 1, 1)[0]; - - position = this.insertInLine(position, firstLine); - if (lastLine !== null) { - position = this.insertNewLine(position); // terminate first line - position = this.insertLines(position.row, lines); - position = this.insertInLine(position, lastLine || ""); - } - return position; - }; - - this.insertLines = function(row, lines) { - if (lines.length == 0) - return {row: row, column: 0}; - - var args = [row, 0]; - args.push.apply(args, lines); - this.$lines.splice.apply(this.$lines, args); - - var range = new Range(row, 0, row + lines.length, 0); - var delta = { - action: "insertLines", - range: range, - lines: lines - }; - this._dispatchEvent("change", { data: delta }); - return range.end; - }, - - this.insertNewLine = function(position) { - position = this.$clipPosition(position); - var line = this.$lines[position.row] || ""; - this.$lines[position.row] = line.substring(0, position.column); - this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length)); - - var end = { - row : position.row + 1, - column : 0 - }; - - var delta = { - action: "insertText", - range: Range.fromPoints(position, end), - text: this.getNewLineCharacter() - }; - this._dispatchEvent("change", { data: delta }); - - return end; - }; - - this.insertInLine = function(position, text) { - if (text.length == 0) - return position; - - var line = this.$lines[position.row] || ""; - this.$lines[position.row] = line.substring(0, position.column) + text - + line.substring(position.column); - - var end = { - row : position.row, - column : position.column + text.length - }; - - var delta = { - action: "insertText", - range: Range.fromPoints(position, end), - text: text - }; - this._dispatchEvent("change", { data: delta }); - - return end; - }; - - this.remove = function(range) { - // clip to document - range.start = this.$clipPosition(range.start); - range.end = this.$clipPosition(range.end); - - if (range.isEmpty()) - return range.start; - - var firstRow = range.start.row; - var lastRow = range.end.row; - - if (range.isMultiLine()) { - var firstFullRow = range.start.column == 0 ? firstRow : firstRow + 1; - var lastFullRow = lastRow - 1; - - if (range.end.column > 0) - this.removeInLine(lastRow, 0, range.end.column); - - if (lastFullRow >= firstFullRow) - this.removeLines(firstFullRow, lastFullRow); - - if (firstFullRow != firstRow) { - this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length); - this.removeNewLine(range.start.row); - } - } - else { - this.removeInLine(firstRow, range.start.column, range.end.column); - } - return range.start; - }; - - this.removeInLine = function(row, startColumn, endColumn) { - if (startColumn == endColumn) - return; - - var range = new Range(row, startColumn, row, endColumn); - var line = this.getLine(row); - var removed = line.substring(startColumn, endColumn); - var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length); - this.$lines.splice(row, 1, newLine); - - var delta = { - action: "removeText", - range: range, - text: removed - }; - this._dispatchEvent("change", { data: delta }); - return range.start; - }; - - /** - * 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 - */ - this.removeLines = function(firstRow, lastRow) { - var range = new Range(firstRow, 0, lastRow + 1, 0); - var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1); - - var delta = { - action: "removeLines", - range: range, - nl: this.getNewLineCharacter(), - lines: removed - }; - this._dispatchEvent("change", { data: delta }); - return removed; - }; - - this.removeNewLine = function(row) { - var firstLine = this.getLine(row); - var secondLine = this.getLine(row+1); - - var range = new Range(row, firstLine.length, row+1, 0); - var line = firstLine + secondLine; - - this.$lines.splice(row, 2, line); - - var delta = { - action: "removeText", - range: range, - text: this.getNewLineCharacter() - }; - this._dispatchEvent("change", { data: delta }); - }; - - this.replace = function(range, text) { - if (text.length == 0 && range.isEmpty()) - return range.start; - - // Shortcut: If the text we want to insert is the same as it is already - // in the document, we don't have to replace anything. - if (text == this.getTextRange(range)) - return range.end; - - this.remove(range); - if (text) { - var end = this.insert(range.start, text); - } - else { - end = range.start; - } - - return end; - }; - - this.applyDeltas = function(deltas) { - for (var i=0; i=0; i--) { - var delta = deltas[i]; - var range = Range.fromPoints(delta.range.start, delta.range.end); - - if (delta.action == "insertLines") - this.removeLines(range.start.row, range.end.row - 1) - else if (delta.action == "insertText") - this.remove(range) - else if (delta.action == "removeLines") - this.insertLines(range.start.row, delta.lines) - else if (delta.action == "removeText") - this.insert(range.start, delta.text) - } - }; - -}).call(Document.prototype); - -exports.Document = Document; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/anchor', ['require', 'exports', 'module' , 'pilot/oop', 'pilot/event_emitter'], function(require, exports, module) { - -var oop = require("pilot/oop"); -var EventEmitter = require("pilot/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 - */ -var Anchor = exports.Anchor = function(doc, row, column) { - this.document = doc; - - if (typeof column == "undefined") - this.setPosition(row.row, row.column); - else - this.setPosition(row, column); - - this.$onChange = this.onChange.bind(this); - doc.on("change", this.$onChange); -}; - -(function() { - - oop.implement(this, EventEmitter); - - this.getPosition = function() { - return this.$clipPositionToDocument(this.row, this.column); - }; - - this.getDocument = function() { - return this.document; - }; - - this.onChange = function(e) { - var delta = e.data; - var range = delta.range; - - if (range.start.row == range.end.row && range.start.row != this.row) - return; - - if (range.start.row > this.row) - return; - - if (range.start.row == this.row && range.start.column > this.column) - return; - - var row = this.row; - var column = this.column; - - if (delta.action === "insertText") { - if (range.start.row === row && range.start.column <= column) { - if (range.start.row === range.end.row) { - column += range.end.column - range.start.column; - } - else { - column -= range.start.column; - row += range.end.row - range.start.row; - } - } - else if (range.start.row !== range.end.row && range.start.row < row) { - row += range.end.row - range.start.row; - } - } else if (delta.action === "insertLines") { - if (range.start.row <= row) { - row += range.end.row - range.start.row; - } - } - else if (delta.action == "removeText") { - if (range.start.row == row && range.start.column < column) { - if (range.end.column >= column) - column = range.start.column; - else - column = Math.max(0, column - (range.end.column - range.start.column)); - - } else if (range.start.row !== range.end.row && range.start.row < row) { - if (range.end.row == row) { - column = Math.max(0, column - range.end.column) + range.start.column; - } - row -= (range.end.row - range.start.row); - } - else if (range.end.row == row) { - row -= range.end.row - range.start.row; - column = Math.max(0, column - range.end.column) + range.start.column; - } - } else if (delta.action == "removeLines") { - if (range.start.row <= row) { - if (range.end.row <= row) - row -= range.end.row - range.start.row; - else { - row = range.start.row; - column = 0; - } - } - } - - this.setPosition(row, column, true); - }; - - this.setPosition = function(row, column, noClip) { - if (noClip) { - pos = { - row: row, - column: column - }; - } - else { - pos = this.$clipPositionToDocument(row, column); - } - - if (this.row == pos.row && this.column == pos.column) - return; - - var old = { - row: this.row, - column: this.column - }; - - this.row = pos.row; - this.column = pos.column; - this._dispatchEvent("change", { - old: old, - value: pos - }); - }; - - this.detach = function() { - this.document.removeEventListener("change", this.$onChange); - }; - - this.$clipPositionToDocument = function(row, column) { - var pos = {}; - - if (row >= this.document.getLength()) { - pos.row = Math.max(0, this.document.getLength() - 1); - pos.column = this.document.getLine(pos.row).length; - } - else if (row < 0) { - pos.row = 0; - pos.column = 0; - } - else { - pos.row = row; - pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column)); - } - - if (column < 0) - pos.column = 0; - - return pos; - }; - -}).call(Anchor.prototype); - -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Mihai Sucan - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/search', ['require', 'exports', 'module' , 'pilot/lang', 'pilot/oop', 'ace/range'], function(require, exports, module) { - -var lang = require("pilot/lang"); -var oop = require("pilot/oop"); -var Range = require("ace/range").Range; - -var Search = function() { - this.$options = { - needle: "", - backwards: false, - wrap: false, - caseSensitive: false, - wholeWord: false, - scope: Search.ALL, - regExp: false - }; -}; - -Search.ALL = 1; -Search.SELECTION = 2; - -(function() { - - this.set = function(options) { - oop.mixin(this.$options, options); - return this; - }; - - this.getOptions = function() { - return lang.copyObject(this.$options); - }; - - this.find = function(session) { - if (!this.$options.needle) - return null; - - if (this.$options.backwards) { - var iterator = this.$backwardMatchIterator(session); - } else { - iterator = this.$forwardMatchIterator(session); - } - - var firstRange = null; - iterator.forEach(function(range) { - firstRange = range; - return true; - }); - - return firstRange; - }; - - this.findAll = function(session) { - if (!this.$options.needle) - return []; - - if (this.$options.backwards) { - var iterator = this.$backwardMatchIterator(session); - } else { - iterator = this.$forwardMatchIterator(session); - } - - var ranges = []; - iterator.forEach(function(range) { - ranges.push(range); - }); - - return ranges; - }; - - this.replace = function(input, replacement) { - var re = this.$assembleRegExp(); - var match = re.exec(input); - if (match && match[0].length == input.length) { - if (this.$options.regExp) { - return input.replace(re, replacement); - } else { - return replacement; - } - } else { - return null; - } - }; - - this.$forwardMatchIterator = function(session) { - var re = this.$assembleRegExp(); - var self = this; - - return { - forEach: function(callback) { - self.$forwardLineIterator(session).forEach(function(line, startIndex, row) { - if (startIndex) { - line = line.substring(startIndex); - } - - var matches = []; - - line.replace(re, function(str) { - var offset = arguments[arguments.length-2]; - matches.push({ - str: str, - offset: startIndex + offset - }); - return str; - }); - - for (var i=0; i= 0; i--) { - var match = matches[i]; - var range = self.$rangeFromMatch(row, match.offset, match.str.length); - if (callback(range)) - return true; - } - }); - } - }; - }; - - this.$rangeFromMatch = function(row, column, length) { - return new Range(row, column, row, column+length); - }; - - this.$assembleRegExp = function() { - if (this.$options.regExp) { - var needle = this.$options.needle; - } else { - needle = lang.escapeRegExp(this.$options.needle); - } - - if (this.$options.wholeWord) { - needle = "\\b" + needle + "\\b"; - } - - var modifier = "g"; - if (!this.$options.caseSensitive) { - modifier += "i"; - } - - var re = new RegExp(needle, modifier); - return re; - }; - - this.$forwardLineIterator = function(session) { - var searchSelection = this.$options.scope == Search.SELECTION; - - var range = session.getSelection().getRange(); - var start = session.getSelection().getCursor(); - - var firstRow = searchSelection ? range.start.row : 0; - var firstColumn = searchSelection ? range.start.column : 0; - var lastRow = searchSelection ? range.end.row : session.getLength() - 1; - - var wrap = this.$options.wrap; - var inWrap = false; - - function getLine(row) { - var line = session.getLine(row); - if (searchSelection && row == range.end.row) { - line = line.substring(0, range.end.column); - } - if (inWrap && row == start.row) { - line = line.substring(0, start.column); - } - return line; - } - - return { - forEach: function(callback) { - var row = start.row; - - var line = getLine(row); - var startIndex = start.column; - - var stop = false; - inWrap = false; - - while (!callback(line, startIndex, row)) { - - if (stop) { - return; - } - - row++; - startIndex = 0; - - if (row > lastRow) { - if (wrap) { - row = firstRow; - startIndex = firstColumn; - inWrap = true; - } else { - return; - } - } - - if (row == start.row) - stop = true; - - line = getLine(row); - } - } - }; - }; - - this.$backwardLineIterator = function(session) { - var searchSelection = this.$options.scope == Search.SELECTION; - - var range = session.getSelection().getRange(); - var start = searchSelection ? range.end : range.start; - - var firstRow = searchSelection ? range.start.row : 0; - var firstColumn = searchSelection ? range.start.column : 0; - var lastRow = searchSelection ? range.end.row : session.getLength() - 1; - - var wrap = this.$options.wrap; - - return { - forEach : function(callback) { - var row = start.row; - - var line = session.getLine(row).substring(0, start.column); - var startIndex = 0; - var stop = false; - var inWrap = false; - - while (!callback(line, startIndex, row)) { - - if (stop) - return; - - row--; - startIndex = 0; - - if (row < firstRow) { - if (wrap) { - row = lastRow; - inWrap = true; - } else { - return; - } - } - - if (row == start.row) - stop = true; - - line = session.getLine(row); - if (searchSelection) { - if (row == firstRow) - startIndex = firstColumn; - else if (row == lastRow) - line = line.substring(0, range.end.column); - } - - if (inWrap && row == start.row) - startIndex = start.column; - } - } - }; - }; - -}).call(Search.prototype); - -exports.Search = Search; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/background_tokenizer', ['require', 'exports', 'module' , 'pilot/oop', 'pilot/event_emitter'], function(require, exports, module) { - -var oop = require("pilot/oop"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; - -var BackgroundTokenizer = function(tokenizer, editor) { - this.running = false; - this.lines = []; - this.currentLine = 0; - this.tokenizer = tokenizer; - - var self = this; - - this.$worker = function() { - if (!self.running) { return; } - - var workerStart = new Date(); - var startLine = self.currentLine; - var doc = self.doc; - - var processedLines = 0; - var lastVisibleRow = editor.getLastVisibleRow(); - - var len = doc.getLength(); - while (self.currentLine < len) { - self.lines[self.currentLine] = self.$tokenizeRows(self.currentLine, self.currentLine)[0]; - self.currentLine++; - - // only check every 5 lines - processedLines += 1; - if ((processedLines % 5 == 0) && (new Date() - workerStart) > 20) { - self.fireUpdateEvent(startLine, self.currentLine-1); - - var timeout = self.currentLine < lastVisibleRow ? 20 : 100; - self.running = setTimeout(self.$worker, timeout); - return; - } - } - - self.running = false; - - self.fireUpdateEvent(startLine, len - 1); - }; -}; - -(function(){ - - oop.implement(this, EventEmitter); - - this.setTokenizer = function(tokenizer) { - this.tokenizer = tokenizer; - this.lines = []; - - this.start(0); - }; - - this.setDocument = function(doc) { - this.doc = doc; - this.lines = []; - - this.stop(); - }; - - this.fireUpdateEvent = function(firstRow, lastRow) { - var data = { - first: firstRow, - last: lastRow - }; - this._dispatchEvent("update", {data: data}); - }; - - this.start = function(startRow) { - this.currentLine = Math.min(startRow || 0, this.currentLine, - this.doc.getLength()); - - // remove all cached items below this line - this.lines.splice(this.currentLine, this.lines.length); - - this.stop(); - // pretty long delay to prevent the tokenizer from interfering with the user - this.running = setTimeout(this.$worker, 700); - }; - - this.stop = function() { - if (this.running) - clearTimeout(this.running); - this.running = false; - }; - - this.getTokens = function(firstRow, lastRow) { - return this.$tokenizeRows(firstRow, lastRow); - }; - - this.getState = function(row) { - return this.$tokenizeRows(row, row)[0].state; - }; - - this.$tokenizeRows = function(firstRow, lastRow) { - if (!this.doc) - return []; - - var rows = []; - - // determine start state - var state = "start"; - var doCache = false; - if (firstRow > 0 && this.lines[firstRow - 1]) { - state = this.lines[firstRow - 1].state; - doCache = true; - } - - var lines = this.doc.getLines(firstRow, lastRow); - for (var row=firstRow; row<=lastRow; row++) { - if (!this.lines[row]) { - var tokens = this.tokenizer.getLineTokens(lines[row-firstRow] || "", state); - var state = tokens.state; - rows.push(tokens); - - if (doCache) { - this.lines[row] = tokens; - } - } - else { - var tokens = this.lines[row]; - state = tokens.state; - rows.push(tokens); - } - } - return rows; - }; - -}).call(BackgroundTokenizer.prototype); - -exports.BackgroundTokenizer = BackgroundTokenizer; -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Mihai Sucan - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/undomanager', ['require', 'exports', 'module' ], function(require, exports, module) { - -var UndoManager = function() { - this.reset(); -}; - -(function() { - - this.execute = function(options) { - var deltas = options.args[0]; - this.$doc = options.args[1]; - this.$undoStack.push(deltas); - }; - - this.undo = function() { - var deltas = this.$undoStack.pop(); - if (deltas) { - this.$doc.undoChanges(deltas); - this.$redoStack.push(deltas); - } - }; - - this.redo = function() { - var deltas = this.$redoStack.pop(); - if (deltas) { - this.$doc.redoChanges(deltas); - this.$undoStack.push(deltas); - } - }; - - this.reset = function() { - this.$undoStack = []; - this.$redoStack = []; - }; - - this.hasUndo = function() { - return this.$undoStack.length > 0; - }; - - this.hasRedo = function() { - return this.$redoStack.length > 0; - }; - -}).call(UndoManager.prototype); - -exports.UndoManager = UndoManager; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/theme/textmate', ['require', 'exports', 'module' , 'pilot/dom'], function(require, exports, module) { - - var dom = require("pilot/dom"); - - var cssText = ".ace-tm .ace_editor {\ - border: 2px solid rgb(159, 159, 159);\ -}\ -\ -.ace-tm .ace_editor.ace_focus {\ - border: 2px solid #327fbd;\ -}\ -\ -.ace-tm .ace_gutter {\ - width: 50px;\ - background: #e8e8e8;\ - color: #333;\ - overflow : hidden;\ -}\ -\ -.ace-tm .ace_gutter-layer {\ - width: 100%;\ - text-align: right;\ -}\ -\ -.ace-tm .ace_gutter-layer .ace_gutter-cell {\ - padding-right: 6px;\ -}\ -\ -.ace-tm .ace_print_margin {\ - width: 1px;\ - background: #e8e8e8;\ -}\ -\ -.ace-tm .ace_text-layer {\ - cursor: text;\ -}\ -\ -.ace-tm .ace_cursor {\ - border-left: 2px solid black;\ -}\ -\ -.ace-tm .ace_cursor.ace_overwrite {\ - border-left: 0px;\ - border-bottom: 1px solid black;\ -}\ - \ -.ace-tm .ace_line .ace_invisible {\ - color: rgb(191, 191, 191);\ -}\ -\ -.ace-tm .ace_line .ace_keyword {\ - color: blue;\ -}\ -\ -.ace-tm .ace_line .ace_constant.ace_buildin {\ - color: rgb(88, 72, 246);\ -}\ -\ -.ace-tm .ace_line .ace_constant.ace_language {\ - color: rgb(88, 92, 246);\ -}\ -\ -.ace-tm .ace_line .ace_constant.ace_library {\ - color: rgb(6, 150, 14);\ -}\ -\ -.ace-tm .ace_line .ace_invalid {\ - background-color: rgb(153, 0, 0);\ - color: white;\ -}\ -\ -.ace-tm .ace_line .ace_support.ace_function {\ - color: rgb(60, 76, 114);\ -}\ -\ -.ace-tm .ace_line .ace_support.ace_constant {\ - color: rgb(6, 150, 14);\ -}\ -\ -.ace-tm .ace_line .ace_support.ace_type,\ -.ace-tm .ace_line .ace_support.ace_class {\ - color: rgb(109, 121, 222);\ -}\ -\ -.ace-tm .ace_line .ace_keyword.ace_operator {\ - color: rgb(104, 118, 135);\ -}\ -\ -.ace-tm .ace_line .ace_string {\ - color: rgb(3, 106, 7);\ -}\ -\ -.ace-tm .ace_line .ace_comment {\ - color: rgb(76, 136, 107);\ -}\ -\ -.ace-tm .ace_line .ace_comment.ace_doc {\ - color: rgb(0, 102, 255);\ -}\ -\ -.ace-tm .ace_line .ace_comment.ace_doc.ace_tag {\ - color: rgb(128, 159, 191);\ -}\ -\ -.ace-tm .ace_line .ace_constant.ace_numeric {\ - color: rgb(0, 0, 205);\ -}\ -\ -.ace-tm .ace_line .ace_variable {\ - color: rgb(49, 132, 149);\ -}\ -\ -.ace-tm .ace_line .ace_xml_pe {\ - color: rgb(104, 104, 91);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_selection {\ - background: rgb(181, 213, 255);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_step {\ - background: rgb(252, 255, 0);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_stack {\ - background: rgb(164, 229, 101);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_bracket {\ - margin: -1px 0 0 -1px;\ - border: 1px solid rgb(192, 192, 192);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_active_line {\ - background: rgb(232, 242, 254);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_selected_word {\ - background: rgb(250, 250, 255);\ - border: 1px solid rgb(200, 200, 250);\ -}\ -\ -.ace-tm .ace_string.ace_regex {\ - color: rgb(255, 0, 0)\ -}"; - - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "ace-tm"; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/mode/matching_brace_outdent', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) { - -var Range = require("ace/range").Range; - -var MatchingBraceOutdent = function() {}; - -(function() { - - this.checkOutdent = function(line, input) { - if (! /^\s+$/.test(line)) - return false; - - return /^\s*\}/.test(input); - }; - - this.autoOutdent = function(doc, row) { - var line = doc.getLine(row); - var match = line.match(/^(\s*\})/); - - if (!match) return 0; - - var column = match[1].length; - var openBracePos = doc.findMatchingBracket({row: row, column: column}); - - if (!openBracePos || openBracePos.row == row) return 0; - - var indent = this.$getIndent(doc.getLine(openBracePos.row)); - doc.replace(new Range(row, 0, row, column-1), indent); - }; - - this.$getIndent = function(line) { - var match = line.match(/^(\s+)/); - if (match) { - return match[1]; - } - - return ""; - }; - -}).call(MatchingBraceOutdent.prototype); - -exports.MatchingBraceOutdent = MatchingBraceOutdent; -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Irakli Gozalishvili (http://jeditoolkit.com) - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/virtual_renderer', ['require', 'exports', 'module' , 'pilot/oop', 'pilot/dom', 'pilot/event', 'pilot/useragent', 'ace/layer/gutter', 'ace/layer/marker', 'ace/layer/text', 'ace/layer/cursor', 'ace/scrollbar', 'ace/renderloop', 'pilot/event_emitter', 'text!ace/css/editor.css'], function(require, exports, module) { - -var oop = require("pilot/oop"); -var dom = require("pilot/dom"); -var event = require("pilot/event"); -var useragent = require("pilot/useragent"); -var GutterLayer = require("ace/layer/gutter").Gutter; -var MarkerLayer = require("ace/layer/marker").Marker; -var TextLayer = require("ace/layer/text").Text; -var CursorLayer = require("ace/layer/cursor").Cursor; -var ScrollBar = require("ace/scrollbar").ScrollBar; -var RenderLoop = require("ace/renderloop").RenderLoop; -var EventEmitter = require("pilot/event_emitter").EventEmitter; -var editorCss = require("text!ace/css/editor.css"); - -// import CSS once -dom.importCssString(editorCss); - -var VirtualRenderer = function(container, theme) { - this.container = container; - dom.addCssClass(this.container, "ace_editor"); - - this.setTheme(theme); - - this.$gutter = dom.createElement("div"); - this.$gutter.className = "ace_gutter"; - this.container.appendChild(this.$gutter); - - this.scroller = dom.createElement("div"); - this.scroller.className = "ace_scroller"; - this.container.appendChild(this.scroller); - - this.content = dom.createElement("div"); - this.content.className = "ace_content"; - this.scroller.appendChild(this.content); - - this.$gutterLayer = new GutterLayer(this.$gutter); - this.$markerBack = new MarkerLayer(this.content); - - var textLayer = this.$textLayer = new TextLayer(this.content); - this.canvas = textLayer.element; - - this.$markerFront = new MarkerLayer(this.content); - - this.characterWidth = textLayer.getCharacterWidth(); - this.lineHeight = textLayer.getLineHeight(); - - this.$cursorLayer = new CursorLayer(this.content); - this.$cursorPadding = 8; - - // Indicates whether the horizontal scrollbar is visible - this.$horizScroll = true; - this.$horizScrollAlwaysVisible = true; - - this.scrollBar = new ScrollBar(container); - this.scrollBar.addEventListener("scroll", this.onScroll.bind(this)); - - this.scrollTop = 0; - - this.cursorPos = { - row : 0, - column : 0 - }; - - var _self = this; - this.$textLayer.addEventListener("changeCharaterSize", function() { - _self.characterWidth = textLayer.getCharacterWidth(); - _self.lineHeight = textLayer.getLineHeight(); - _self.$updatePrintMargin(); - _self.onResize(true); - - _self.$loop.schedule(_self.CHANGE_FULL); - }); - event.addListener(this.$gutter, "click", this.$onGutterClick.bind(this)); - event.addListener(this.$gutter, "dblclick", this.$onGutterClick.bind(this)); - - this.$size = { - width: 0, - height: 0, - scrollerHeight: 0, - scrollerWidth: 0 - }; - - this.$loop = new RenderLoop(this.$renderChanges.bind(this)); - this.$loop.schedule(this.CHANGE_FULL); - - this.setPadding(4); - this.$updatePrintMargin(); -}; - -(function() { - this.showGutter = true; - - 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; - - oop.implement(this, EventEmitter); - - this.setSession = function(session) { - this.session = session; - 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 - */ - this.updateLines = function(firstRow, lastRow) { - if (lastRow === undefined) - lastRow = Infinity; - - if (!this.$changedLines) { - this.$changedLines = { - firstRow: firstRow, - lastRow: lastRow - }; - } - else { - if (this.$changedLines.firstRow > firstRow) - this.$changedLines.firstRow = firstRow; - - if (this.$changedLines.lastRow < lastRow) - this.$changedLines.lastRow = lastRow; - } - - this.$loop.schedule(this.CHANGE_LINES); - }; - - /** - * Triggers full update of the text layer - */ - this.updateText = function() { - this.$loop.schedule(this.CHANGE_TEXT); - }; - - /** - * Triggers a full update of all layers - */ - this.updateFull = function() { - this.$loop.schedule(this.CHANGE_FULL); - }; - - /** - * Triggers resize of the editor - */ - this.onResize = function(force) { - var changes = this.CHANGE_SIZE; - - var height = dom.getInnerHeight(this.container); - if (force || this.$size.height != height) { - this.$size.height = height; - - this.scroller.style.height = height + "px"; - this.scrollBar.setHeight(this.scroller.clientHeight); - - if (this.session) { - this.scrollToY(this.getScrollTop()); - changes = changes | this.CHANGE_FULL; - } - } - - var width = dom.getInnerWidth(this.container); - if (force || this.$size.width != width) { - this.$size.width = width; - - var gutterWidth = this.showGutter ? this.$gutter.offsetWidth : 0; - this.scroller.style.left = gutterWidth + "px"; - this.scroller.style.width = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()) + "px"; - - if (this.session.getUseWrapMode()) { - var availableWidth = this.scroller.clientWidth - this.$padding * 2; - var limit = Math.floor(availableWidth / this.characterWidth) - 1; - if (this.session.adjustWrapLimit(limit) || force) { - changes = changes | this.CHANGE_FULL; - } - } - } - - this.$size.scrollerWidth = this.scroller.clientWidth; - this.$size.scrollerHeight = this.scroller.clientHeight; - this.$loop.schedule(changes); - }; - - this.setTokenizer = function(tokenizer) { - this.$tokenizer = tokenizer; - this.$textLayer.setTokenizer(tokenizer); - this.$loop.schedule(this.CHANGE_TEXT); - }; - - this.$onGutterClick = function(e) { - var pageX = event.getDocumentX(e); - var pageY = event.getDocumentY(e); - - this._dispatchEvent("gutter" + e.type, { - row: this.screenToTextCoordinates(pageX, pageY).row, - htmlEvent: e - }); - }; - - this.setShowInvisibles = function(showInvisibles) { - if (this.$textLayer.setShowInvisibles(showInvisibles)) - this.$loop.schedule(this.CHANGE_TEXT); - }; - - this.getShowInvisibles = function() { - return this.$textLayer.showInvisibles; - }; - - this.$showPrintMargin = true; - this.setShowPrintMargin = function(showPrintMargin) { - this.$showPrintMargin = showPrintMargin; - this.$updatePrintMargin(); - }; - - this.getShowPrintMargin = function() { - return this.$showPrintMargin; - }; - - this.$printMarginColumn = 80; - this.setPrintMarginColumn = function(showPrintMargin) { - this.$printMarginColumn = showPrintMargin; - this.$updatePrintMargin(); - }; - - this.getPrintMarginColumn = function() { - return this.$printMarginColumn; - }; - - this.setShowGutter = function(show){ - if(this.showGutter === show) - return; - this.$gutter.style.display = show ? "block" : "none"; - this.showGutter = show; - this.onResize(true); - } - - this.$updatePrintMargin = function() { - var containerEl - - if (!this.$showPrintMargin && !this.$printMarginEl) - return; - - if (!this.$printMarginEl) { - containerEl = dom.createElement("div"); - containerEl.className = "ace_print_margin_layer"; - this.$printMarginEl = dom.createElement("div") - this.$printMarginEl.className = "ace_print_margin"; - containerEl.appendChild(this.$printMarginEl); - this.content.insertBefore(containerEl, this.$textLayer.element); - } - - var style = this.$printMarginEl.style; - style.left = ((this.characterWidth * this.$printMarginColumn) + this.$padding * 2) + "px"; - style.visibility = this.$showPrintMargin ? "visible" : "hidden"; - }; - - this.getContainerElement = function() { - return this.container; - }; - - this.getMouseEventTarget = function() { - return this.content; - }; - - this.getTextAreaContainer = function() { - return this.container; - }; - - this.moveTextAreaToCursor = function(textarea) { - // in IE the native cursor always shines through - if (useragent.isIE) - return; - - var pos = this.$cursorLayer.getPixelPosition(); - if (!pos) - return; - - var bounds = this.content.getBoundingClientRect(); - var offset = (this.layerConfig && this.layerConfig.offset) || 0; - - textarea.style.left = (bounds.left + pos.left + this.$padding) + "px"; - textarea.style.top = (bounds.top + pos.top - this.scrollTop + offset) + "px"; - }; - - this.getFirstVisibleRow = function() { - return (this.layerConfig || {}).firstRow || 0; - }; - - this.getFirstFullyVisibleRow = function(){ - if (!this.layerConfig) - return 0; - - return this.layerConfig.firstRow + (this.layerConfig.offset == 0 ? 0 : 1); - } - - this.getLastFullyVisibleRow = function() { - if (!this.layerConfig) - return 0; - - var flint = Math.floor((this.layerConfig.height + this.layerConfig.offset) / this.layerConfig.lineHeight); - return this.layerConfig.firstRow - 1 + flint; - } - - this.getLastVisibleRow = function() { - return (this.layerConfig || {}).lastRow || 0; - }; - - this.$padding = null; - this.setPadding = function(padding) { - this.$padding = padding; - this.content.style.padding = "0 " + padding + "px"; - this.$loop.schedule(this.CHANGE_FULL); - this.$updatePrintMargin(); - }; - - this.setHScrollBarAlwaysVisible = function(alwaysVisible) { - if (this.$horizScrollAlwaysVisible != alwaysVisible) { - this.$horizScrollAlwaysVisible = alwaysVisible; - if (!this.$horizScrollAlwaysVisible || !this.$horizScroll) - this.$loop.schedule(this.CHANGE_SCROLL); - } - } - - this.onScroll = function(e) { - this.scrollToY(e.data); - }; - - this.$updateScrollBar = function() { - this.scrollBar.setInnerHeight(this.session.getScreenLength() * this.lineHeight); - this.scrollBar.setScrollTop(this.scrollTop); - }; - - this.$renderChanges = function(changes) { - if (!changes || !this.session || !this.$tokenizer) - return; - - // text, scrolling and resize changes can cause the view port size to change - if (!this.layerConfig || - changes & this.CHANGE_FULL || - changes & this.CHANGE_SIZE || - changes & this.CHANGE_TEXT || - changes & this.CHANGE_LINES || - changes & this.CHANGE_SCROLL - ) - this.$computeLayerConfig(); - - // full - if (changes & this.CHANGE_FULL) { - 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.$updateScrollBar(); - this.scrollCursorIntoView(); - return; - } - - // scrolling - if (changes & this.CHANGE_SCROLL) { - if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES) - this.$textLayer.update(this.layerConfig); - else - 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.$updateScrollBar(); - return; - } - - if (changes & this.CHANGE_TEXT) { - this.$textLayer.update(this.layerConfig); - this.showGutter && this.$gutterLayer.update(this.layerConfig); - } - else if (changes & this.CHANGE_LINES) { - this.$updateLines(); - this.$updateScrollBar(); - this.showGutter && this.$gutterLayer.update(this.layerConfig); - } else if (changes & this.CHANGE_GUTTER) { - this.showGutter && this.$gutterLayer.update(this.layerConfig); - } - - if (changes & this.CHANGE_CURSOR) - this.$cursorLayer.update(this.layerConfig); - - if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) { - this.$markerFront.update(this.layerConfig); - } - - if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) { - this.$markerBack.update(this.layerConfig); - } - - if (changes & this.CHANGE_SIZE) - this.$updateScrollBar(); - }; - - this.$computeLayerConfig = function() { - var session = this.session; - - var offset = this.scrollTop % this.lineHeight; - var minHeight = this.$size.scrollerHeight + this.lineHeight; - - var longestLine = this.$getLongestLine(); - var widthChanged = !this.layerConfig ? true : (this.layerConfig.width != longestLine); - - var horizScroll = this.$horizScrollAlwaysVisible || this.$size.scrollerWidth - longestLine < 0; - var horizScrollChanged = this.$horizScroll !== horizScroll; - this.$horizScroll = horizScroll; - if (horizScrollChanged) - this.scroller.style.overflowX = horizScroll ? "scroll" : "hidden"; - - var lineCount = Math.ceil(minHeight / this.lineHeight) - 1; - var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight)); - var lastRow = firstRow + lineCount; - - // Map lines on the screen to lines in the document. - var firstRowScreen, firstRowHeight; - var lineHeight = { lineHeight: this.lineHeight }; - firstRow = session.screenToDocumentRow(firstRow); - firstRowScreen = session.documentToScreenRow(firstRow); - firstRowHeight = session.getRowHeight(lineHeight, firstRow); - - lastRow = Math.min(session.screenToDocumentRow(lastRow), session.getLength() - 1); - minHeight = this.$size.scrollerHeight + session.getRowHeight(lineHeight, lastRow)+ - firstRowHeight; - - offset = this.scrollTop - firstRowScreen * this.lineHeight; - - var layerConfig = this.layerConfig = { - width : longestLine, - padding : this.$padding, - firstRow : firstRow, - firstRowScreen: firstRowScreen, - lastRow : lastRow, - lineHeight : this.lineHeight, - characterWidth : this.characterWidth, - minHeight : minHeight, - offset : offset, - height : this.$size.scrollerHeight - }; - - this.$gutterLayer.element.style.marginTop = (-offset) + "px"; - this.content.style.marginTop = (-offset) + "px"; - this.content.style.width = longestLine + "px"; - this.content.style.height = minHeight + "px"; - - // Horizontal scrollbar visibility may have changed, which changes - // the client height of the scroller - if (horizScrollChanged) - this.onResize(true); - }; - - this.$updateLines = function() { - var firstRow = this.$changedLines.firstRow; - var lastRow = this.$changedLines.lastRow; - this.$changedLines = null; - - var layerConfig = this.layerConfig; - - // if the update changes the width of the document do a full redraw - if (layerConfig.width != this.$getLongestLine()) - return this.$textLayer.update(layerConfig); - - if (firstRow > layerConfig.lastRow + 1) { return; } - if (lastRow < layerConfig.firstRow) { return; } - - // if the last row is unknown -> redraw everything - if (lastRow === Infinity) { - this.showGutter && this.$gutterLayer.update(layerConfig); - this.$textLayer.update(layerConfig); - return; - } - - // else update only the changed rows - this.$textLayer.updateLines(layerConfig, firstRow, lastRow); - }; - - this.$getLongestLine = function() { - var charCount = this.session.getScreenWidth() + 1; - if (this.$textLayer.showInvisibles) - charCount += 1; - - return Math.max(this.$size.scrollerWidth - this.$padding * 2, Math.round(charCount * this.characterWidth)); - }; - - this.updateFrontMarkers = function() { - this.$markerFront.setMarkers(this.session.getMarkers(true)); - this.$loop.schedule(this.CHANGE_MARKER_FRONT); - }; - - this.updateBackMarkers = function() { - this.$markerBack.setMarkers(this.session.getMarkers()); - this.$loop.schedule(this.CHANGE_MARKER_BACK); - }; - - this.addGutterDecoration = function(row, className){ - this.$gutterLayer.addGutterDecoration(row, className); - this.$loop.schedule(this.CHANGE_GUTTER); - } - - this.removeGutterDecoration = function(row, className){ - this.$gutterLayer.removeGutterDecoration(row, className); - this.$loop.schedule(this.CHANGE_GUTTER); - } - - this.setBreakpoints = function(rows) { - this.$gutterLayer.setBreakpoints(rows); - this.$loop.schedule(this.CHANGE_GUTTER); - }; - - this.setAnnotations = function(annotations) { - this.$gutterLayer.setAnnotations(annotations); - this.$loop.schedule(this.CHANGE_GUTTER); - }; - - this.updateCursor = function() { - this.$loop.schedule(this.CHANGE_CURSOR); - }; - - this.hideCursor = function() { - this.$cursorLayer.hideCursor(); - }; - - this.showCursor = function() { - this.$cursorLayer.showCursor(); - }; - - this.scrollCursorIntoView = function() { - // the editor is not visible - if (this.$size.scrollerHeight === 0) - return; - - var pos = this.$cursorLayer.getPixelPosition(); - - var left = pos.left + this.$padding; - var top = pos.top; - - if (this.getScrollTop() > top) { - this.scrollToY(top); - } - - if (this.getScrollTop() + this.$size.scrollerHeight < top - + this.lineHeight) { - this.scrollToY(top + this.lineHeight - this.$size.scrollerHeight); - } - - if (this.scroller.scrollLeft > left) { - this.scrollToX(left); - } - - if (this.scroller.scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) { - - if (left + this.characterWidth > this.scroller.scrollWidth) - this.$renderChanges(this.CHANGE_SIZE); - - this.scrollToX(Math.round(left + this.characterWidth - this.$size.scrollerWidth)); - } - }, - - this.getScrollTop = function() { - return this.scrollTop; - }; - - this.getScrollLeft = function() { - return this.scroller.scrollLeft; - }; - - this.getScrollTopRow = function() { - return this.scrollTop / this.lineHeight; - }; - - this.getScrollBottomRow = function() { - return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1); - } - - this.scrollToRow = function(row) { - this.scrollToY(row * this.lineHeight); - }; - - this.scrollToLine = function(line, center) { - var lineHeight = { lineHeight: this.lineHeight }; - var offset = 0; - for (var l = 1; l < line; l++) { - offset += this.session.getRowHeight(lineHeight, l-1); - } - - if (center) { - offset -= this.$size.scrollerHeight / 2; - } - this.scrollToY(offset); - }; - - this.scrollToY = function(scrollTop) { - var maxHeight = this.session.getScreenLength() * this.lineHeight - this.$size.scrollerHeight; - var scrollTop = Math.max(0, Math.min(maxHeight, scrollTop)); - - if (this.scrollTop !== scrollTop) { - this.scrollTop = scrollTop; - this.$loop.schedule(this.CHANGE_SCROLL); - } - }; - - this.scrollToX = function(scrollLeft) { - if (scrollLeft <= this.$padding) - scrollLeft = 0; - - this.scroller.scrollLeft = scrollLeft; - }; - - this.scrollBy = function(deltaX, deltaY) { - deltaY && this.scrollToY(this.scrollTop + deltaY); - deltaX && this.scrollToX(this.scroller.scrollLeft + deltaX); - }; - - this.screenToTextCoordinates = function(pageX, pageY) { - var canvasPos = this.scroller.getBoundingClientRect(); - - var col = Math.round((pageX + this.scroller.scrollLeft - canvasPos.left - this.$padding - dom.getPageScrollLeft()) - / this.characterWidth); - var row = Math.floor((pageY + this.scrollTop - canvasPos.top - dom.getPageScrollTop()) - / this.lineHeight); - - return this.session.screenToDocumentPosition(row, Math.max(col, 0)); - }; - - this.textToScreenCoordinates = function(row, column) { - var canvasPos = this.scroller.getBoundingClientRect(); - var pos = this.session.documentToScreenPosition(row, column); - - var x = this.$padding + Math.round(pos.column * this.characterWidth); - var y = pos.row * this.lineHeight; - - return { - pageX: canvasPos.left + x - this.getScrollLeft(), - pageY: canvasPos.top + y - this.getScrollTop() - } - }; - - this.visualizeFocus = function() { - dom.addCssClass(this.container, "ace_focus"); - }; - - this.visualizeBlur = function() { - dom.removeCssClass(this.container, "ace_focus"); - }; - - this.showComposition = function(position) { - if (!this.$composition) { - this.$composition = dom.createElement("div"); - this.$composition.className = "ace_composition"; - this.content.appendChild(this.$composition); - } - - this.$composition.innerHTML = " "; - - var pos = this.$cursorLayer.getPixelPosition(); - var style = this.$composition.style; - style.top = pos.top + "px"; - style.left = (pos.left + this.$padding) + "px"; - style.height = this.lineHeight + "px"; - - this.hideCursor(); - }; - - this.setCompositionText = function(text) { - dom.setInnerText(this.$composition, text); - }; - - this.hideComposition = function() { - this.showCursor(); - - if (!this.$composition) - return; - - var style = this.$composition.style; - style.top = "-10000px"; - style.left = "-10000px"; - }; - - this.setTheme = function(theme) { - var _self = this; - if (!theme || typeof theme == "string") { - theme = theme || "ace/theme/textmate"; - require([theme], function(theme) { - afterLoad(theme); - }); - } else { - afterLoad(theme); - } - - var _self = this; - function afterLoad(theme) { - if (_self.$theme) - dom.removeCssClass(_self.container, _self.$theme); - - _self.$theme = theme ? theme.cssClass : null; - - if (_self.$theme) - dom.addCssClass(_self.container, _self.$theme); - - // force re-measure of the gutter width - if (_self.$size) { - _self.$size.width = 0; - _self.onResize(); - } - } - }; - - // Methods allows to add / remove CSS classnames to the editor element. - // This feature can be used by plug-ins to provide a visual indication of - // a certain mode that editor is in. - - this.setStyle = function setStyle(style) { - dom.addCssClass(this.container, style) - }; - - this.unsetStyle = function unsetStyle(style) { - dom.removeCssClass(this.container, style) - }; - -}).call(VirtualRenderer.prototype); - -exports.VirtualRenderer = VirtualRenderer; -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/layer/gutter', ['require', 'exports', 'module' , 'pilot/dom'], function(require, exports, module) { - -var dom = require("pilot/dom"); - -var Gutter = function(parentEl) { - this.element = dom.createElement("div"); - this.element.className = "ace_layer ace_gutter-layer"; - parentEl.appendChild(this.element); - - this.$breakpoints = []; - this.$annotations = []; - this.$decorations = []; -}; - -(function() { - - this.setSession = function(session) { - this.session = session; - }; - - this.addGutterDecoration = function(row, className){ - if (!this.$decorations[row]) - this.$decorations[row] = ""; - this.$decorations[row] += " ace_" + className; - } - - this.removeGutterDecoration = function(row, className){ - this.$decorations[row] = this.$decorations[row].replace(" ace_" + className, ""); - }; - - this.setBreakpoints = function(rows) { - this.$breakpoints = rows.concat(); - }; - - this.setAnnotations = function(annotations) { - // iterate over sparse array - this.$annotations = []; - for (var row in annotations) if (annotations.hasOwnProperty(row)) { - var rowAnnotations = annotations[row]; - if (!rowAnnotations) - continue; - - var rowInfo = this.$annotations[row] = { - text: [] - }; - for (var i=0; i", (i+1), ""); - } - this.element = dom.setInnerHtml(this.element, html.join("")); - this.element.style.height = config.minHeight + "px"; - }; - -}).call(Gutter.prototype); - -exports.Gutter = Gutter; - -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/layer/marker', ['require', 'exports', 'module' , 'ace/range', 'pilot/dom'], function(require, exports, module) { - -var Range = require("ace/range").Range; -var dom = require("pilot/dom"); - -var Marker = function(parentEl) { - this.element = dom.createElement("div"); - this.element.className = "ace_layer ace_marker-layer"; - parentEl.appendChild(this.element); -}; - -(function() { - - this.setSession = function(session) { - this.session = session; - }; - - this.setMarkers = function(markers) { - this.markers = markers; - }; - - this.update = function(config) { - var config = config || this.config; - if (!config) - return; - - this.config = config; - - var html = []; - for ( var key in this.markers) { - var marker = this.markers[key]; - - var range = marker.range.clipRows(config.firstRow, config.lastRow); - if (range.isEmpty()) continue; - - range = range.toScreenRange(this.session); - - if (marker.renderer) { - var top = this.$getTop(range.start.row, config); - var left = Math.round(range.start.column * config.characterWidth); - marker.renderer(html, range, left, top, config); - } - else if (range.isMultiLine()) { - if (marker.type == "text") { - this.drawTextMarker(html, range, marker.clazz, config); - } else { - this.drawMultiLineMarker(html, range, marker.clazz, config); - } - } - else { - this.drawSingleLineMarker(html, range, marker.clazz, config); - } - } - this.element = dom.setInnerHtml(this.element, html.join("")); - }; - - this.$getTop = function(row, layerConfig) { - return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight; - }; - - this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) { - // selection start - var row = range.start.row; - - var lineRange = new Range(row, range.start.column, - row, this.session.getScreenLastRowColumn(row)); - this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1); - - // selection end - var row = range.end.row; - var lineRange = new Range(row, 0, row, range.end.column); - this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig); - - for (var row = range.start.row + 1; row < range.end.row; row++) { - lineRange.start.row = row; - lineRange.end.row = row; - lineRange.end.column = this.session.getScreenLastRowColumn(row); - this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1); - } - }; - - this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig) { - // from selection start to the end of the line - var height = layerConfig.lineHeight; - var width = Math.round(layerConfig.width - (range.start.column * layerConfig.characterWidth)); - var top = this.$getTop(range.start.row, layerConfig); - var left = Math.round(range.start.column * layerConfig.characterWidth); - - stringBuilder.push( - "
" - ); - - // from start of the last line to the selection end - var top = this.$getTop(range.end.row, layerConfig); - var width = Math.round(range.end.column * layerConfig.characterWidth); - - stringBuilder.push( - "
" - ); - - // all the complete lines - var height = (range.end.row - range.start.row - 1) * layerConfig.lineHeight; - if (height < 0) - return; - var top = this.$getTop(range.start.row + 1, layerConfig); - - stringBuilder.push( - "
" - ); - }; - - this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig, extraLength) { - var height = layerConfig.lineHeight; - var width = Math.round((range.end.column + (extraLength || 0) - range.start.column) * layerConfig.characterWidth); - var top = this.$getTop(range.start.row, layerConfig); - var left = Math.round(range.start.column * layerConfig.characterWidth); - - stringBuilder.push( - "
" - ); - }; - -}).call(Marker.prototype); - -exports.Marker = Marker; - -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * Mihai Sucan - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/layer/text', ['require', 'exports', 'module' , 'pilot/oop', 'pilot/dom', 'pilot/lang', 'pilot/event_emitter'], function(require, exports, module) { - -var oop = require("pilot/oop"); -var dom = require("pilot/dom"); -var lang = require("pilot/lang"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; - -var Text = function(parentEl) { - this.element = dom.createElement("div"); - this.element.className = "ace_layer ace_text-layer"; - parentEl.appendChild(this.element); - - this.$characterSize = this.$measureSizes(); - this.$pollSizeChanges(); -}; - -(function() { - - oop.implement(this, EventEmitter); - - this.EOF_CHAR = "¶"; - this.EOL_CHAR = "¬"; - this.TAB_CHAR = "→"; - this.SPACE_CHAR = "·"; - - this.setTokenizer = function(tokenizer) { - this.tokenizer = tokenizer; - }; - - this.getLineHeight = function() { - return this.$characterSize.height || 1; - }; - - this.getCharacterWidth = function() { - return this.$characterSize.width || 1; - }; - - this.$pollSizeChanges = function() { - var self = this; - setInterval(function() { - var size = self.$measureSizes(); - if (self.$characterSize.width !== size.width || self.$characterSize.height !== size.height) { - self.$characterSize = size; - self._dispatchEvent("changeCharaterSize", {data: size}); - } - }, 500); - }; - - this.$fontStyles = { - fontFamily : 1, - fontSize : 1, - fontWeight : 1, - fontStyle : 1, - lineHeight : 1 - }, - - this.$measureSizes = function() { - var n = 1000; - if (!this.$measureNode) { - var measureNode = this.$measureNode = dom.createElement("div"); - var style = measureNode.style; - - style.width = style.height = "auto"; - style.left = style.top = (-n * 40) + "px"; - - style.visibility = "hidden"; - style.position = "absolute"; - style.overflow = "visible"; - style.whiteSpace = "nowrap"; - - // in FF 3.6 monospace fonts can have a fixed sub pixel width. - // that's why we have to measure many characters - // Note: characterWidth can be a float! - measureNode.innerHTML = lang.stringRepeat("Xy", n); - - var container = this.element.parentNode; - while (!dom.hasCssClass(container, "ace_editor")) - container = container.parentNode; - - container.appendChild(measureNode); - } - - var style = this.$measureNode.style; - for (var prop in this.$fontStyles) { - var value = dom.computedStyle(this.element, prop); - style[prop] = value; - } - - var size = { - height: this.$measureNode.offsetHeight, - width: this.$measureNode.offsetWidth / (n * 2) - }; - return size; - }; - - this.setSession = function(session) { - this.session = session; - }; - - this.showInvisibles = false; - this.setShowInvisibles = function(showInvisibles) { - if (this.showInvisibles == showInvisibles) - return false; - - this.showInvisibles = showInvisibles; - return true; - }; - - this.$computeTabString = function() { - var tabSize = this.session.getTabSize(); - if (this.showInvisibles) { - var halfTab = (tabSize) / 2; - this.$tabString = "" - + new Array(Math.floor(halfTab)).join(" ") - + this.TAB_CHAR - + new Array(Math.ceil(halfTab)+1).join(" ") - + ""; - } else { - this.$tabString = new Array(tabSize+1).join(" "); - } - }; - - this.updateLines = function(config, firstRow, lastRow) { - this.$computeTabString(); - // Due to wrap line changes there can be new lines if e.g. - // the line to updated wrapped in the meantime. - if (this.config.lastRow != config.lastRow || - this.config.firstRow != config.firstRow) { - this.scrollLines(config); - } - this.config = config; - - var first = Math.max(firstRow, config.firstRow); - var last = Math.min(lastRow, config.lastRow); - - var lineElements = this.element.childNodes; - var tokens = this.tokenizer.getTokens(first, last); - for (var i=first; i<=last; i++) { - var lineElement = lineElements[i - config.firstRow]; - if (!lineElement) - continue; - - var html = []; - this.$renderLine(html, i, tokens[i-first].tokens); - lineElement = dom.setInnerHtml(lineElement, html.join("")); - lineElement.style.height = - this.session.getRowHeight(config, i) + "px"; - } - }; - - this.scrollLines = function(config) { - this.$computeTabString(); - var oldConfig = this.config; - this.config = config; - - if (!oldConfig || oldConfig.lastRow < config.firstRow) - return this.update(config); - - if (config.lastRow < oldConfig.firstRow) - return this.update(config); - - var el = this.element; - - if (oldConfig.firstRow < config.firstRow) - for (var row=oldConfig.firstRow; row config.lastRow) - for (var row=config.lastRow+1; row<=oldConfig.lastRow; row++) - el.removeChild(el.lastChild); - - if (config.firstRow < oldConfig.firstRow) { - var fragment = this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1); - if (el.firstChild) - el.insertBefore(fragment, el.firstChild); - else - el.appendChild(fragment); - } - - if (config.lastRow > oldConfig.lastRow) { - var fragment = this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow); - el.appendChild(fragment); - } - }; - - this.$renderLinesFragment = function(config, firstRow, lastRow) { - var fragment = document.createDocumentFragment(); - var tokens = this.tokenizer.getTokens(firstRow, lastRow); - for (var row=firstRow; row<=lastRow; row++) { - var lineEl = dom.createElement("div"); - lineEl.className = "ace_line"; - var style = lineEl.style; - style.height = this.session.getRowHeight(config, row) + "px"; - style.width = config.width + "px"; - - var html = []; - if (tokens.length > row-firstRow) - this.$renderLine(html, row, tokens[row-firstRow].tokens); - // don't use setInnerHtml since we are working with an empty DIV - lineEl.innerHTML = html.join(""); - fragment.appendChild(lineEl); - } - return fragment; - }; - - this.update = function(config) { - this.$computeTabString(); - this.config = config; - - var html = []; - var tokens = this.tokenizer.getTokens(config.firstRow, config.lastRow) - var fragment = this.$renderLinesFragment(config, config.firstRow, config.lastRow); - - // Clear the current content of the element and add the rendered fragment. - this.element.innerHTML = ""; - this.element.appendChild(fragment); - }; - - this.$textToken = { - "text": true, - "rparen": true, - "lparen": true - }; - - this.$renderLine = function(stringBuilder, row, tokens) { - if (this.showInvisibles) { - var self = this; - var spaceRe = /( +)|([\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000])/g; - var spaceReplace = function(space) { - if (space.charCodeAt(0) == 32) - return new Array(space.length+1).join(" "); - else { - var space = new Array(space.length+1).join(self.SPACE_CHAR); - return "" + space + ""; - } - - }; - } - else { - var spaceRe = /[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/g; - var spaceReplace = " "; - } - - var _self = this; - var characterWidth = this.config.characterWidth; - function addToken(token, value) { - var output = value - .replace(/&/g, "&") - .replace(/" + c + "" - }); - - if (!_self.$textToken[token.type]) { - var classes = "ace_" + token.type.replace(/\./g, " ace_"); - stringBuilder.push("", output, ""); - } - else { - stringBuilder.push(output); - } - } - - var splits = this.session.getRowSplitData(row); - var chars = 0, split = 0, splitChars; - - if (!splits || splits.length == 0) { - splitChars = Number.MAX_VALUE; - } else { - splitChars = splits[0]; - } - - stringBuilder.push("
"); - for (var i = 0; i < tokens.length; i++) { - var token = tokens[i]; - var value = token.value; - - if (chars + value.length < splitChars) { - addToken(token, value); - chars += value.length; - } else { - while (chars + value.length >= splitChars) { - addToken(token, value.substring(0, splitChars - chars)); - value = value.substring(splitChars - chars); - chars = splitChars; - stringBuilder.push("
", - "
"); - split ++; - splitChars = splits[split] || Number.MAX_VALUE; - } - if (value.length != 0) { - chars += value.length; - addToken(token, value); - } - } - }; - - if (this.showInvisibles) { - if (row !== this.session.getLength() - 1) { - stringBuilder.push("" + this.EOL_CHAR + ""); - } else { - stringBuilder.push("" + this.EOF_CHAR + ""); - } - } - stringBuilder.push("
"); - }; - -}).call(Text.prototype); - -exports.Text = Text; - -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/layer/cursor', ['require', 'exports', 'module' , 'pilot/dom'], function(require, exports, module) { - -var dom = require("pilot/dom"); - -var Cursor = function(parentEl) { - this.element = dom.createElement("div"); - this.element.className = "ace_layer ace_cursor-layer"; - parentEl.appendChild(this.element); - - this.cursor = dom.createElement("div"); - this.cursor.className = "ace_cursor"; - - this.isVisible = false; -}; - -(function() { - - this.setSession = function(session) { - this.session = session; - }; - - this.hideCursor = function() { - this.isVisible = false; - if (this.cursor.parentNode) { - this.cursor.parentNode.removeChild(this.cursor); - } - clearInterval(this.blinkId); - }; - - this.showCursor = function() { - this.isVisible = true; - this.element.appendChild(this.cursor); - - var cursor = this.cursor; - cursor.style.visibility = "visible"; - this.restartTimer(); - }; - - this.restartTimer = function() { - clearInterval(this.blinkId); - if (!this.isVisible) { - return; - } - - var cursor = this.cursor; - this.blinkId = setInterval(function() { - cursor.style.visibility = "hidden"; - setTimeout(function() { - cursor.style.visibility = "visible"; - }, 400); - }, 1000); - }; - - this.getPixelPosition = function(onScreen) { - if (!this.config || !this.session) { - return { - left : 0, - top : 0 - }; - } - - var position = this.session.selection.getCursor(); - var pos = this.session.documentToScreenPosition(position); - var cursorLeft = Math.round(pos.column * this.config.characterWidth); - var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) * - this.config.lineHeight; - - return { - left : cursorLeft, - top : cursorTop - }; - }; - - this.update = function(config) { - this.config = config; - - this.pixelPos = this.getPixelPosition(true); - - this.cursor.style.left = this.pixelPos.left + "px"; - this.cursor.style.top = this.pixelPos.top + "px"; - this.cursor.style.width = config.characterWidth + "px"; - this.cursor.style.height = config.lineHeight + "px"; - - if (this.isVisible) { - this.element.appendChild(this.cursor); - } - - if (this.session.getOverwrite()) { - dom.addCssClass(this.cursor, "ace_overwrite"); - } else { - dom.removeCssClass(this.cursor, "ace_overwrite"); - } - - this.restartTimer(); - }; - -}).call(Cursor.prototype); - -exports.Cursor = Cursor; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/scrollbar', ['require', 'exports', 'module' , 'pilot/oop', 'pilot/dom', 'pilot/event', 'pilot/event_emitter'], function(require, exports, module) { - -var oop = require("pilot/oop"); -var dom = require("pilot/dom"); -var event = require("pilot/event"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; - -var ScrollBar = function(parent) { - this.element = dom.createElement("div"); - this.element.className = "ace_sb"; - - this.inner = dom.createElement("div"); - this.element.appendChild(this.inner); - - parent.appendChild(this.element); - - this.width = dom.scrollbarWidth(); - this.element.style.width = this.width + "px"; - - event.addListener(this.element, "scroll", this.onScroll.bind(this)); -}; - -(function() { - oop.implement(this, EventEmitter); - - this.onScroll = function() { - this._dispatchEvent("scroll", {data: this.element.scrollTop}); - }; - - this.getWidth = function() { - return this.width; - }; - - this.setHeight = function(height) { - this.element.style.height = height + "px"; - }; - - this.setInnerHeight = function(height) { - this.inner.style.height = height + "px"; - }; - - this.setScrollTop = function(scrollTop) { - this.element.scrollTop = scrollTop; - }; - -}).call(ScrollBar.prototype); - -exports.ScrollBar = ScrollBar; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('ace/renderloop', ['require', 'exports', 'module' , 'pilot/event'], function(require, exports, module) { - -var event = require("pilot/event"); - -var RenderLoop = function(onRender) { - this.onRender = onRender; - this.pending = false; - this.changes = 0; -}; - -(function() { - - this.schedule = function(change) { - //this.onRender(change); - //return; - this.changes = this.changes | change; - if (!this.pending) { - this.pending = true; - var _self = this; - this.setTimeoutZero(function() { - _self.pending = false; - var changes = _self.changes; - _self.changes = 0; - _self.onRender(changes); - }) - } - }; - - if (window.postMessage) { - - this.messageName = "zero-timeout-message"; - - this.setTimeoutZero = function(callback) { - if (!this.attached) { - var _self = this; - event.addListener(window, "message", function(e) { - if (_self.callback && e.data == _self.messageName) { - event.stopPropagation(e); - _self.callback(); - } - }); - this.attached = true; - } - this.callback = callback; - window.postMessage(this.messageName, "*"); - } - - } else { - - this.setTimeoutZero = function(callback) { - setTimeout(callback, 0); - } - } - -}).call(RenderLoop.prototype); - -exports.RenderLoop = RenderLoop; -}); -define("text!ace/css/editor.css", [], ".ace_editor {" + - " position: absolute;" + - " overflow: hidden;" + - "" + - " font-family: \"Menlo\", \"Monaco\", \"Courier New\", monospace;" + - " font-size: 12px; " + - "}" + - "" + - ".ace_scroller {" + - " position: absolute;" + - " overflow-x: scroll;" + - " overflow-y: hidden; " + - "}" + - "" + - ".ace_content {" + - " position: absolute;" + - " box-sizing: border-box;" + - " -moz-box-sizing: border-box;" + - " -webkit-box-sizing: border-box;" + - "}" + - "" + - ".ace_composition {" + - " position: absolute;" + - " background: #555;" + - " color: #DDD;" + - " z-index: 4;" + - "}" + - "" + - ".ace_gutter {" + - " position: absolute;" + - " overflow-x: hidden;" + - " overflow-y: hidden;" + - " height: 100%;" + - "}" + - "" + - ".ace_gutter-cell.ace_error {" + - " 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\");" + - " background-repeat: no-repeat;" + - " background-position: 4px center;" + - "}" + - "" + - ".ace_gutter-cell.ace_warning {" + - " 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\");" + - " background-repeat: no-repeat;" + - " background-position: 4px center;" + - "}" + - "" + - ".ace_editor .ace_sb {" + - " position: absolute;" + - " overflow-x: hidden;" + - " overflow-y: scroll;" + - " right: 0;" + - "}" + - "" + - ".ace_editor .ace_sb div {" + - " position: absolute;" + - " width: 1px;" + - " left: 0;" + - "}" + - "" + - ".ace_editor .ace_print_margin_layer {" + - " z-index: 0;" + - " position: absolute;" + - " overflow: hidden;" + - " margin: 0;" + - " left: 0;" + - " height: 100%;" + - " width: 100%;" + - "}" + - "" + - ".ace_editor .ace_print_margin {" + - " position: absolute;" + - " height: 100%;" + - "}" + - "" + - ".ace_editor textarea {" + - " position: fixed;" + - " z-index: -1;" + - " width: 10px;" + - " height: 30px;" + - " opacity: 0;" + - " background: transparent;" + - " appearance: none;" + - " border: none;" + - " resize: none;" + - " outline: none;" + - " overflow: hidden;" + - "}" + - "" + - ".ace_layer {" + - " z-index: 1;" + - " position: absolute;" + - " overflow: hidden; " + - " white-space: nowrap;" + - " height: 100%;" + - " width: 100%;" + - "}" + - "" + - ".ace_text-layer {" + - " font-family: Monaco, \"Courier New\", monospace;" + - " color: black;" + - "}" + - "" + - ".ace_cjk {" + - " display: inline-block;" + - " text-align: center;" + - "}" + - "" + - ".ace_cursor-layer {" + - " z-index: 4;" + - " cursor: text;" + - " pointer-events: none;" + - "}" + - "" + - ".ace_cursor {" + - " z-index: 4;" + - " position: absolute;" + - "}" + - "" + - ".ace_line {" + - " white-space: nowrap;" + - "}" + - "" + - ".ace_marker-layer {" + - " cursor: text;" + - "}" + - "" + - ".ace_marker-layer .ace_step {" + - " position: absolute;" + - " z-index: 3;" + - "}" + - "" + - ".ace_marker-layer .ace_selection {" + - " position: absolute;" + - " z-index: 4;" + - "}" + - "" + - ".ace_marker-layer .ace_bracket {" + - " position: absolute;" + - " z-index: 5;" + - "}" + - "" + - ".ace_marker-layer .ace_active_line {" + - " position: absolute;" + - " z-index: 2;" + - "}" + - "" + - ".ace_marker-layer .ace_selected_word {" + - " position: absolute;" + - " z-index: 6;" + - " box-sizing: border-box;" + - " -moz-box-sizing: border-box;" + - " -webkit-box-sizing: border-box;" + - "}" + - "" + - ".ace_dragging .ace_marker-layer, .ace_dragging .ace_text-layer {" + - " cursor: move;" + - "}" + - ""); - -define("text!icons/epl.html", [], "" + - "" + - "" + - "" + - "Eclipse Public License - Version 1.0" + - "" + - "" + - "" + - "" + - "" + - "" + - "

Eclipse Public License - v 1.0

" + - "" + - "

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE" + - "PUBLIC LICENSE (\"AGREEMENT\"). ANY USE, REPRODUCTION OR" + - "DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS" + - "AGREEMENT.

" + - "" + - "

1. DEFINITIONS

" + - "" + - "

\"Contribution\" means:

" + - "" + - "

a) in the case of the initial Contributor, the initial" + - "code and documentation distributed under this Agreement, and

" + - "

b) in the case of each subsequent Contributor:

" + - "

i) changes to the Program, and

" + - "

ii) additions to the Program;

" + - "

where such changes and/or additions to the Program" + - "originate from and are distributed by that particular Contributor. A" + - "Contribution 'originates' from a Contributor if it was added to the" + - "Program by such Contributor itself or anyone acting on such" + - "Contributor's behalf. Contributions do not include additions to the" + - "Program which: (i) are separate modules of software distributed in" + - "conjunction with the Program under their own license agreement, and (ii)" + - "are not derivative works of the Program.

" + - "" + - "

\"Contributor\" means any person or entity that distributes" + - "the Program.

" + - "" + - "

\"Licensed Patents\" mean patent claims licensable by a" + - "Contributor which are necessarily infringed by the use or sale of its" + - "Contribution alone or when combined with the Program.

" + - "" + - "

\"Program\" means the Contributions distributed in accordance" + - "with this Agreement.

" + - "" + - "

\"Recipient\" means anyone who receives the Program under" + - "this Agreement, including all Contributors.

" + - "" + - "

2. GRANT OF RIGHTS

" + - "" + - "

a) Subject to the terms of this Agreement, each" + - "Contributor hereby grants Recipient a non-exclusive, worldwide," + - "royalty-free copyright license to reproduce, prepare derivative works" + - "of, publicly display, publicly perform, distribute and sublicense the" + - "Contribution of such Contributor, if any, and such derivative works, in" + - "source code and object code form.

" + - "" + - "

b) Subject to the terms of this Agreement, each" + - "Contributor hereby grants Recipient a non-exclusive, worldwide," + - "royalty-free patent license under Licensed Patents to make, use, sell," + - "offer to sell, import and otherwise transfer the Contribution of such" + - "Contributor, if any, in source code and object code form. This patent" + - "license shall apply to the combination of the Contribution and the" + - "Program if, at the time the Contribution is added by the Contributor," + - "such addition of the Contribution causes such combination to be covered" + - "by the Licensed Patents. The patent license shall not apply to any other" + - "combinations which include the Contribution. No hardware per se is" + - "licensed hereunder.

" + - "" + - "

c) Recipient understands that although each Contributor" + - "grants the licenses to its Contributions set forth herein, no assurances" + - "are provided by any Contributor that the Program does not infringe the" + - "patent or other intellectual property rights of any other entity. Each" + - "Contributor disclaims any liability to Recipient for claims brought by" + - "any other entity based on infringement of intellectual property rights" + - "or otherwise. As a condition to exercising the rights and licenses" + - "granted hereunder, each Recipient hereby assumes sole responsibility to" + - "secure any other intellectual property rights needed, if any. For" + - "example, if a third party patent license is required to allow Recipient" + - "to distribute the Program, it is Recipient's responsibility to acquire" + - "that license before distributing the Program.

" + - "" + - "

d) Each Contributor represents that to its knowledge it" + - "has sufficient copyright rights in its Contribution, if any, to grant" + - "the copyright license set forth in this Agreement.

" + - "" + - "

3. REQUIREMENTS

" + - "" + - "

A Contributor may choose to distribute the Program in object code" + - "form under its own license agreement, provided that:

" + - "" + - "

a) it complies with the terms and conditions of this" + - "Agreement; and

" + - "" + - "

b) its license agreement:

" + - "" + - "

i) effectively disclaims on behalf of all Contributors" + - "all warranties and conditions, express and implied, including warranties" + - "or conditions of title and non-infringement, and implied warranties or" + - "conditions of merchantability and fitness for a particular purpose;

" + - "" + - "

ii) effectively excludes on behalf of all Contributors" + - "all liability for damages, including direct, indirect, special," + - "incidental and consequential damages, such as lost profits;

" + - "" + - "

iii) states that any provisions which differ from this" + - "Agreement are offered by that Contributor alone and not by any other" + - "party; and

" + - "" + - "

iv) states that source code for the Program is available" + - "from such Contributor, and informs licensees how to obtain it in a" + - "reasonable manner on or through a medium customarily used for software" + - "exchange.

" + - "" + - "

When the Program is made available in source code form:

" + - "" + - "

a) it must be made available under this Agreement; and

" + - "" + - "

b) a copy of this Agreement must be included with each" + - "copy of the Program.

" + - "" + - "

Contributors may not remove or alter any copyright notices contained" + - "within the Program.

" + - "" + - "

Each Contributor must identify itself as the originator of its" + - "Contribution, if any, in a manner that reasonably allows subsequent" + - "Recipients to identify the originator of the Contribution.

" + - "" + - "

4. COMMERCIAL DISTRIBUTION

" + - "" + - "

Commercial distributors of software may accept certain" + - "responsibilities with respect to end users, business partners and the" + - "like. While this license is intended to facilitate the commercial use of" + - "the Program, the Contributor who includes the Program in a commercial" + - "product offering should do so in a manner which does not create" + - "potential liability for other Contributors. Therefore, if a Contributor" + - "includes the Program in a commercial product offering, such Contributor" + - "(\"Commercial Contributor\") hereby agrees to defend and" + - "indemnify every other Contributor (\"Indemnified Contributor\")" + - "against any losses, damages and costs (collectively \"Losses\")" + - "arising from claims, lawsuits and other legal actions brought by a third" + - "party against the Indemnified Contributor to the extent caused by the" + - "acts or omissions of such Commercial Contributor in connection with its" + - "distribution of the Program in a commercial product offering. The" + - "obligations in this section do not apply to any claims or Losses" + - "relating to any actual or alleged intellectual property infringement. In" + - "order to qualify, an Indemnified Contributor must: a) promptly notify" + - "the Commercial Contributor in writing of such claim, and b) allow the" + - "Commercial Contributor to control, and cooperate with the Commercial" + - "Contributor in, the defense and any related settlement negotiations. The" + - "Indemnified Contributor may participate in any such claim at its own" + - "expense.

" + - "" + - "

For example, a Contributor might include the Program in a commercial" + - "product offering, Product X. That Contributor is then a Commercial" + - "Contributor. If that Commercial Contributor then makes performance" + - "claims, or offers warranties related to Product X, those performance" + - "claims and warranties are such Commercial Contributor's responsibility" + - "alone. Under this section, the Commercial Contributor would have to" + - "defend claims against the other Contributors related to those" + - "performance claims and warranties, and if a court requires any other" + - "Contributor to pay any damages as a result, the Commercial Contributor" + - "must pay those damages.

" + - "" + - "

5. NO WARRANTY

" + - "" + - "

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS" + - "PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS" + - "OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION," + - "ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY" + - "OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely" + - "responsible for determining the appropriateness of using and" + - "distributing the Program and assumes all risks associated with its" + - "exercise of rights under this Agreement , including but not limited to" + - "the risks and costs of program errors, compliance with applicable laws," + - "damage to or loss of data, programs or equipment, and unavailability or" + - "interruption of operations.

" + - "" + - "

6. DISCLAIMER OF LIABILITY

" + - "" + - "

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT" + - "NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT," + - "INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING" + - "WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF" + - "LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING" + - "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR" + - "DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED" + - "HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

" + - "" + - "

7. GENERAL

" + - "" + - "

If any provision of this Agreement is invalid or unenforceable under" + - "applicable law, it shall not affect the validity or enforceability of" + - "the remainder of the terms of this Agreement, and without further action" + - "by the parties hereto, such provision shall be reformed to the minimum" + - "extent necessary to make such provision valid and enforceable.

" + - "" + - "

If Recipient institutes patent litigation against any entity" + - "(including a cross-claim or counterclaim in a lawsuit) alleging that the" + - "Program itself (excluding combinations of the Program with other" + - "software or hardware) infringes such Recipient's patent(s), then such" + - "Recipient's rights granted under Section 2(b) shall terminate as of the" + - "date such litigation is filed.

" + - "" + - "

All Recipient's rights under this Agreement shall terminate if it" + - "fails to comply with any of the material terms or conditions of this" + - "Agreement and does not cure such failure in a reasonable period of time" + - "after becoming aware of such noncompliance. If all Recipient's rights" + - "under this Agreement terminate, Recipient agrees to cease use and" + - "distribution of the Program as soon as reasonably practicable. However," + - "Recipient's obligations under this Agreement and any licenses granted by" + - "Recipient relating to the Program shall continue and survive.

" + - "" + - "

Everyone is permitted to copy and distribute copies of this" + - "Agreement, but in order to avoid inconsistency the Agreement is" + - "copyrighted and may only be modified in the following manner. The" + - "Agreement Steward reserves the right to publish new versions (including" + - "revisions) of this Agreement from time to time. No one other than the" + - "Agreement Steward has the right to modify this Agreement. The Eclipse" + - "Foundation is the initial Agreement Steward. The Eclipse Foundation may" + - "assign the responsibility to serve as the Agreement Steward to a" + - "suitable separate entity. Each new version of the Agreement will be" + - "given a distinguishing version number. The Program (including" + - "Contributions) may always be distributed subject to the version of the" + - "Agreement under which it was received. In addition, after a new version" + - "of the Agreement is published, Contributor may elect to distribute the" + - "Program (including its Contributions) under the new version. Except as" + - "expressly stated in Sections 2(a) and 2(b) above, Recipient receives no" + - "rights or licenses to the intellectual property of any Contributor under" + - "this Agreement, whether expressly, by implication, estoppel or" + - "otherwise. All rights in the Program not expressly granted under this" + - "Agreement are reserved.

" + - "" + - "

This Agreement is governed by the laws of the State of New York and" + - "the intellectual property laws of the United States of America. No party" + - "to this Agreement will bring a legal action under this Agreement more" + - "than one year after the cause of action arose. Each party waives its" + - "rights to a jury trial in any resulting litigation.

" + - "" + - "" + - "" + - "" + - ""); - -define("text!styles.css", [], "html {" + - " height: 100%;" + - " overflow: hidden;" + - "}" + - "" + - "body {" + - " overflow: hidden;" + - " margin: 0;" + - " padding: 0;" + - " height: 100%;" + - " width: 100%;" + - " font-family: Arial, Helvetica, sans-serif, Tahoma, Verdana, sans-serif;" + - " font-size: 12px;" + - " background: rgb(14, 98, 165);" + - " color: white;" + - "}" + - "" + - "#editor {" + - " position: absolute;" + - " top: 60px;" + - " left: 0px;" + - " background: white;" + - "}" + - "" + - "#controls {" + - " width: 100%;" + - "}" + - "" + - "#cockpitInput {" + - " position: absolute;" + - " width: 100%;" + - " bottom: 0;" + - "" + - " border: none; outline: none;" + - " font-family: consolas, courier, monospace;" + - " font-size: 120%;" + - "}" + - "" + - "#cockpitOutput {" + - " padding: 10px;" + - " margin: 0 15px;" + - " border: 1px solid #AAA;" + - " -moz-border-radius-topleft: 10px;" + - " -moz-border-radius-topright: 10px;" + - " border-top-left-radius: 4px; border-top-right-radius: 4px;" + - " background: #DDD; color: #000;" + - "}"); - -define("text!icons/error_obj.gif", [], "data:image/gif;base64,R0lGODlhEAAQANUAAPVvcvWHiPVucvRuc+ttcfV6f91KVN5LU99PV/FZY/JhaM4oN84pONE4Rd1ATfJLWutVYPRgbdxpcsgWKMgZKs4lNfE/UvE/U+artcpdSc5uXveimslHPuBhW/eJhfV5efaCgO2CgP+/v+PExP///////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACUALAAAAAAQABAAAAZwwJJwSCwaj8jSSJPhZDQj5IjTCW1CHU60OPWQQGCSR1uUID4i0ock+iAkxQZBACCxBwJCoziJWC52F4IRE3EQD2kkD4sQe0QSDmkJkgkOcEQYFSQKnGkFDBhGGAsHBAEEBqBIGBINFA0SoUmztLVJQQA7"); - -define("text!icons/warning_obj.gif", [], "data:image/gif;base64,R0lGODlhEAAQANUAAP/bcv/egf/ijf/ij//klv/jl//lnf/mnv/uwf/IWv/Na//Qc//Ugf/Vgv/Vg//cl//enf/nuP/MbHtRE4BVFYJXFoFVFolbGIdbGIxeGpRkHcWDLcmHL8aELsaFLs2LMsmHMcuKM82LNdyYP9+bQuCcQ+GlVcuHMc+LNdGNNtuXQN+aQt2ZQuOwcOfMrv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAC8ALAAAAAAQABAAAAZhwJdwSCwaj0ihq1RyJYcrBIL0fLlYkQjLmRwhJhOEKmlKOSgVR8qEFAEalwwDgDqaPoGEPhEIsYsgAhIPGBoPCgMnRhwECxAWGBALBRxGHS0GB5qaLR5HG6ChoFWkpaZCQQA7"); - -define("text!logo.png", [], "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIkAAAAyCAYAAABoKfh/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAANBxJREFUeNrsfXd0XcW97jczu519qrrVZcuyXHHBDRsXMM2AjSkmEMAQqoEQyg1JIAkBQgiBJHAvKZQklEAwgdCLTTWmGeNecLdlWVavp+42M++PfSRLxgbue/e9++5azFp7aemcXWbPfPOr328OkVLCXPQ4jtgkQAj+040QwHE8uEnHGFyRc9bJY8vnTRxaUFuaa+ZpClOlBCGA5FKKnrSd2tUUb1xf17Hh/c2Nb7S2Jd9mQVVqCgP5Tz6c+F0e0DwuwIX/qZASkYCGyvwghDh4JqUErXELXSkHjJJDhwCOyzGkIARDUyCl7HtHTwD72pOQ8gid6dfsjANBCAyVIagpcDyOtO0hGtSRcTm4yxEJabBdgbTjQUq/v7qm+IMFIKSp0FTq38/jiCcdCCGgKRSuKxA0NXhSQkoJISVcVwBSglICBsCTEtGgjkTGgaEweELCdjkkgJywAV2lAAjiaQfJJy8BACj4v9SEBFxXVP/b2eP//tNzJhyTE9K/7pJhAGbXtyWvv/el9e/8cdkX1whGd7L/HYR+2/5LG/0mEoFRApldUd/0yKSdnCtOGP7Sby855pickH74lXao0JJARUEIf7ji2BNuPWvcUtvmFd9O0X9/U77JxIUDKnrSLsQ3mWkAXEjEQtplP14wdnTvPQgBPI/jxY+2Y93eNvDsvSiA6SNKcPoxw9D/3F8sPHrIa2v23bWlMb5IU9k3exsJREwVCcvFN+zqt+2/AiQCEgGVgQUJWuMZUErxdQrA8TgmVuXPqy6KHrQTpMQ1f3oHjy7dugWa+glALAASUpr41/oT/rg4WXXNvAmQ0geKpjKcOr58/sa6DSVQWePXqzeJsKEiGtDQk3HxrZL6fwiS3tWdY2qwXI6E5X69McllpDRmDumbKQJs3deBJz+q+0zLi52kUBLvf3radmsefX/Hp1fMHZunKqxPCgwriUZByCgCNH4dQAyFoTCs9xmo37b/hzZJr3VPAAyKGAgb6gCv4AhXhIM6C/YCDADq25OwBf6lEMT7xEX2YJTutD1sVxXaZwcBQK5v7BZ+le3DpYSmMJTEAlAZ/VbN/HdJkl6ggPhAAYCE5YIeWaIwknUAJSQICDx/8jp77Zr+1yqUoCPldC/+wztgREJI/7Pd7RlomhInXyVBVIaSqA8Q8S1C/ntB0mdU4iBQkrb3Fbrf/0YICcqILx2khMsFCABKAIX5BqnCCOIO/8nD7+1eBcczoLIieHwfMfU209De6S8e+sMgL6Qjx9RAiA+Yb73l/0Z18yWJAqAgrIOSLweuDhcvOdLnXEg/YCQAgGwCyB0Ljx9R+O4vz5hZXJJTL7n8k+vxjMsFeg8h/CARFxIhXfX78K0A+f8LJAPQ8g0m5+tUgJASXEpYScs8Y3LVK49dM/PS40eXVL9884l/K44aNzpJC47Hs4eAlwVJ77Xf4uP/Z5D0YuRrQCCPGKQ7qBuclG3Onzp4yT9unDPP0FVkXI5JQwvxyq1zf1+cH7oBttdPgX3b/keBBN9MmBz+wVmQ2CnbnD+lask/bpgzz8jmMwAg43JMrC7Ay7eecn9xfrAPKN+2/2Eg6U2mSSm/eSJOAoxSEEJgp+zA/ClVz/QCxMoCpLdlXI5J1YV4+Sen3F+cF7pefguU/5mSpLe5jgfBxdd6GL25IMt2Q/N8gMw3dAUSfryjv2QyVAbLE5g0tBAv3XLyAyUFoR/wQ4D0P7VJmc1OOx4ytoeM48FxeV+G+auuE9kMrxzwuQR3/ayyy8VhJX7f8xwPruPBO+S8/vf+T7nAEkDSciH7GYwEvmfChe8TSynhpB3kxAKIhAykkvZXqhnb5ZhQlfvnf9180hkKo5AADrT2IJ6yUVtZAI8LMEKw6osGjK8tgeUJTB5aiGdunPPvp9z1Rosr8SyBRCLjwvEIpCRZAEo4rt/Pr8sep2wPrsf7LB1KCVJfIam4yD6Py35UAQmFZdP48pujw7JcqJTklOSHxuaEA8NiISMn43Crsztd355Ib0zZ1m4hJCj98hqmFFGF0RIA0uViP4CUcDwIQx00ckjBjLLCSGVdS8+Ofa3xV+HnZSFcDgB6SWF4fEl+eExO2MjpSTnJjp701j1NPZ9LjyeJykApChVG8wDCCcE+APbXgkQCkEKOunT2sF8PLgznuNx3VikhxPWE+9vXNv6tuSfztEL90JntcmI5ngZPZo5gZboAEDW1wLb6jqK/vbkBV50+Hh3daZzzy5dw3YKJGD24EB4HNIXi/pfXYlDOdjyweA4ytos/v7oWnpDFTKXQGD3uurmjfpwT1IJcSAEAjBLak3JSv3ll470Zj7/XCxSCg1Fc4gfqFl5z0ohrAprKeDZ8rDLKVu1q3fu393bcbAbU5v6d9rhANKDOu/G0Md8Pm5rJhT8OhqawldtbOp5YsfNaVWENX6eahctBVFYxd2r19fOPqV5Ynhcq11UFMhsncIVEe4+V+GhLw/LnP9rxQGdn6j1oB5ObjuXlz5s5/J0Ljh8xzPMEHnp93cqX3t166qjaQVdef/bEn1QPihQXhE08/+E23Llk1URG6RqRcciomsIrLjph9DWjqvLHGgrrQ7TtCmze17H9r0s33LNzb9ua6y485vWpI0oKuCvEHU9//AqA8/tAcqQ1Z9keJg/Ju/eeCyaferjvW3vSR9/9wrr3mKE1wXJzLj519DMjynKKfvDHD+7yuPiyOMm4uWdMH/rw3PHlx1758Ie/X/yXjyJJ253y9sYGfL6re3coZFT3Pz0QDmX+/cUNbdGgUbGruRtLPt33mBkxH0pnHHX+1MF/uPXMcSMP168NdR1VSz7eM9Y0VVsCoIyifx65O2GNam3rmX3P92YMuO7yOcOn721O5Lz/RdN8M6CK3oXiZtwRv7xg0lPXnTom0v/8RMrCn15dCwA/IwQNRzLoCQDL8VCQGzz7ZxdOe3BMRW5xR3cSqUQaNqN9UUpPCDAhw2dMqpg3c1TJab//15rfrd3edAt0hVNCICFLqBRjmefCcz2oRE6rrS56/neLjz8tk0xjz/52uPlheJ4HSBnilhM996TRf7/ilNHzUokMOju6oasKVEZBiT8u46uitb/53vTH7nx6ZQPhssxOZWBqDJDi6AHq5kiiUrp83OVzhp8EAGmXDwCTrjBcPHtY9I/LvjgvnvEeXXzm+JcfvPzYGYwSdKfsp7bta2P9b5vMuJgzsfLOv10zKxwyVJiacufVf/n4th8+taaO6spKhM1uSDw2UDUhgVDwzDtf3nwDoaTFjAZ/IqXkjJD5V544YmSvcTsAWCrDVScOr31+5d7ThMQL9DArQDPU3/3mpY3HlecHZ147bwIyWWZWQGX405XHnjb9Zy//oMfmDxgqRTrlqGdMqXr02rmjI7YnwKWEQgkEFzjnntexrr7nJjMU2HToIPZ/rONy5AaNC+67ctYTQcrZll0NyA0b2LG/E6t3NqM7YcM0VIwdXICxQwtR15iArqn0loXjbr7rnyK6ob7zKlNXAELSibSdau6MB7sSaTBI/XunjDkt3tUNx/VAuIfueArxlAXYXvDsE0cvufzEEads39UAVWXQGMUnW/djZ1MPhJAYUhjBpBEliIUNXHx8TVnC5tjd0IrCWBCW4yUG2iSHGUjHExhcHF181tQhisclCACFUTDq2xSOxzGsJIZ5Eyq+8/T722NnTqqYwSiB5QncevYE44v6DthZI9PlvvE556iysKmrAIDTJ5SX3JMbuDZuuRM0lSGTcS47DE51CNFgho1Fffrc8TBtWOG1s0aVwPZ8w0tVGAh8ioLtCRw7ohjTawuvWbG99YWArhxO9Ce0sHnhzU9+9tHw8ryKOeMqkXE5LJdjeGkM91045a7L/vTBB5ZQ1pXnB3/+4GXTpwMEQvq2ksYobvzLcry1qeVxMxq8/6sMEj+HKcdev2D8w5qXYbubu1CUE8JT72zBsg2NWwRVnieM7pNCFLy9qemMqdV50y47eRS6ehKwLQuLT6q98tYla1elbO+vAPFcjwvbsdHa0YORZVHkByRS6TRe+ng3Vu1s9dKu6LEl3TF8WPHlF8wYesrGrXUwdAXxhIM/v7EJe9oyb4GxFQDh4E1TX/587/zr5h1FCmMmEskUeiyOmKlCCOkO8G4I+fLBHa/0opnV5+aGdHApoDKK1q4kNu5uhsZon46/6qQRk5jKIuf/dmnTO2v3wlAouJQYXZXfl6PhUqKyKIKcsAFKgI54Gqfe/iLW13e+ph/UubSfBOmV2RKQatYE8G0kV0y8Yk7tHJVRABIao6hr7MTuAx3Qsp8pjOLyOcNnS49PFRiYNe5bHZTst5m26NIH37XrmrsRUBko8QF96ZzhwfOOrX6QJzLnPHDJtJ+U54fgcg5KCHSF4tE31+OBN7euNCLmtYcC5JAENyzHI8eMKP316JJQcO+BdhTEAnhzzT68uaH5KT0Ummaaxu0BXX3MDOj3mpHQrJV7u+9+dsVO5EVMdMYzCGvA3LGltzsuj4DClj55Fa7HoVIBBQIPvbEZL69pfKTDUyZbTBtpCXLDd46tmdvd1QkhOBihePC1Tek9Pd55ZiR4shnQf2UGtHvMSHBBUwbzH3xtc9xyPDDIPrUiAT5wYg7Jv3tcIiesL/recbU5WYMQCiV4ZeVu3PGPT7P/+1nXacMH0ZmjS4Z2ZnD+wvuWdb+7di80RiGEBKMEjFIolEJmPY7OeBpn/epVrNjZea9pGrf1n7lebLBDrPpejojjCgwtjSw+a8oQJgEo1Jdsj7y5EX96bUNfvySABZMHs9qy2NWOe2SXOaArH9R3uzcsuv8tpC0HPvHa/+7XF0ye/utLpz131tTBau+76ArFx5v348bHVzapQfNCCqS/QWBx4injK05OJNKIBANIWxJvbGhcpwcDVxDI+ICrpPQCQeOny7e3v9nUmUFBNIh42sX02qKykKHMh5ApQojQVRUBXUNhLITVO9vw2Z7uh8yweZXCyDrORevgwvB5R5XHjHjSQXFeFMs3N6G+2/lp0FCfHQBqKRHQlNca495tK7e3oSQ/ClPXoClK1sTvB5JDV5pjucEFEysvqyqMQEp/MiCBF1bVuUs3tyYb2uJglICAgBKCq+YMPw0K7YxDPeOc+5Yl3ltX5wOEUDBCwIg/eV2JDM66+zWs2NF5rxk2f3wkMd3rlch+IXwCgNtuxaIZNeeETS0blCPI2C5eXNtgvby+IZO2XJ/pLoFQQMUls2rOFI5XRXo9nC+pAgkzZDz04fb2P9/06HKQLEClBKoKI/jJ2RP6nq9QiobWOBb9+7tuhigXq4zsPqIbkz24lCiIBuYNL4lSx5Mozo1iY30Xkrb4PSOwjnS5B/Kb1bs7RFFuFIQqKM0NoiIvdDo8oVJKYQYMxEJBxIJBfLqzrYtq6l1ZsQvP48aYyvy5QZUhYOhQFQ2r9nTsVnX1kSNpRaLQp3e0JFtj4RAioSBMXRswVvSQ94KQEprKFlx14ogBnsamujZ8srPtDcsWtz//8a4BD5k3qZKMKo/9hBCyIi7Vc86+d2ni3XV7+8oACAE642mc+atX8MGOjvvMyJEBcqRmc4G8mHHJxbOHRft//t7G/djdmvxrXVv64bfX7xtwzUWzhoULc8xLXS6/Mm4RiJg3PvzuzuUPvrKmb3BkdtX0cm4tx8Ol//EW9nTaPzJ09e3DJSoFH3i4roeS3ODkqKlDUVSYAR3bm+LdhNF3v+pdGaOrdrUm9mqaBkPXEdB1lOcFR4OLGCOEG5qOcNAEB0Fz3FqjUHqgTxJLVA4dFBssCUU4GETc8tAat95nlKa/BOSDi7DLE+RAwDBgGgY0TR/wPT1Uj1q2R48bOeiaiTVFSLkCyay4/seHO5C2+DPU0B575pNdibTDkeYSCZcjoKu4ZPawBdx2qwOG8lZcqgvPuXdZ4p21e0EJ0N6Txtl3v4oPtnfeZ4bNHx0JIBK+Ikx6vI8N1xvo8iwvfPaUwZdWFISRzPZLAPj78u1SEvYYKHvs7x/sEFxKJD2BhCtQmhfCOVOqLnEtNyaPYJtkx8zWwsGLbnp85falq/dAEr8PCY8j5Qm4QuLGR9/H25taHjJDxgOH6z8lBIwNPACixky9vMsWaM0ItGcEOpL2PkZJ21eGwSnJdKedna0ZgQ4baLcEAoaaB8g8V0J02AIdjkSXzeFy2UgGTDjKdEPVm5Iuul2gOWHD4XIL/ZpIuCSQXY5EmyXQZYsBr0izJ/QdRMoZFx0//JhuT6A146LL4djXncbzK/fWQ1VepZR0rtnT+fL7XzQgJSQ6Mh4OpF2cPnWIWZwXvNx2OAydLYtDXXj+/W8nnluxFYvuX4rlOzrvMyNHBgghgCOBLlegPe2hhwOcHFzVAYOdff6s2soWi6M94yLuSWzc34llGxs/IwpdQxW28Z1NjZ+sr+9EwhPoyLhosTjOm1VbHjSUc6SUOJLaAQDu8YZwOPg6DehoyXjoyB7tGRfdrkAsFuZQ1EelEIelUR7hnQxPiuDmlm6sOdCJrW09cLhIEkK9rwu8cUm6dnUmseZABza1dMHyOAOlatLx5KaWbqw90Im6rhQA4vY3mimh4c6Mg7WNnVh7oBON8QwoIT3ya3IzLpfY2taDtQc6sL09PoArTHu9CUoA1+U4qirvmpljSkh3MgPuudAY8M6aOuxuSnzCKMmVUlYKLj969oMdgODwPBfpjI3CnADOmjp4kWd5uRQEjJBl7d3eaef+5u0P31x14GemGfiRoVA4nA+oqBswUVLC9Vx4nguPe1nKJBG242H2qJLFo6pykUhn4HkuVAa8+MlOdCecFQyooJAVPQlnxUsf7YRKAddzkUhnMKIyB8cfVbrYsj3lq0LuVMgT/nDVzCsm1BQhmbb8PmSPeNrCDxdOZBfNrvlDJm5FyCEqOku6g2V7sGyvDzaEEG7ZLleEDYWnQYUNQ1M0IQT5KpAJCQR0JajCBfPS0KWDjOVwgLgEkjBuQeEZMOEeojYACem6tgVd2oCbQkCRYIyGvip7n6V8SOpaoDwDekgcVOl/BXe92gtm1swLGiqcpAUKAtvxMKa6CMt+tWABo/S03vsplCBluaDwQ/IZ28P5M2tKnnh/x1mW4y05a3LV/cNLY0WuRIpATlIIefWv729/pDslXwUloJCghIAf0lsK0ndkW5pIeeyi42qnSKDv84zl4qSJQzDjqMrvU0KuztoFLKBSpDIOWDZxIYTEouNqj359Tf0cCSwjh5kQO2XX3HnhlCdOnVwV7ohnQIkfe9FVBWnLgZASqYyLuy8+5pjdLfGHP9necn7Q1L4kFGW2vDKoG8g4HJSQTHfCatcoHaJrGiglKM41SzfVd0UBdMNPe8C2XGiG4hvNADjnSnFeaAhjFKqiwNBUdMStTlB0ERCqKgyqqoAxehgSF5o74xlZWRIh3SkbkaCOmKmNbE856EufpB0QAii6CkhACEFNQ9UpY2CUQWVsAPgUABAAXE+gND90+RlTBgdSlgtK/JgD5xKDck2UF4QMKWH0IlYICdvjWZfRD7CNrMjDiUeVXvTi8h1dZ02tuvzsY6qRcP34ghASz32yK3RAyFcVBkQNFSqjiNseuJ/RJJrqUwj8IxsncQUdX1N47awxpUjbveUcEpwLVBSEoTBi9k4WIb5UcFy/XwQEadvDsaNKMLE6/9rVdR3LDE3p5zYBVsqOXjSn9pnvzzuqpDtpgRJA11QcaInjheVbcNN3pyNpufCEgKmrePia2eeddufr2+o703eYAeUwy1ICErAdD5RR2dKT2WY5fHIkZCDtCgyvyC15b2Pj0QR4FwBc14PkAp7DQXU/SCUlRo0dOmhY2vEQChrgHGjsSH0BxrooAVMUBaqigLIvF60pjO7Z09jdPGNseTFjCqiqYFRl3py31+03iK5YLCv2hPCNa6ZQSCFLaysLKm0uQBkDY+zL3g0lALfd/IVTh1xUnBfyxW+WqJwbCSAaNGDqGoKGf5i6hlBAR37EhKGpfvqfEAgpcfGc4VNBcXZHwpIJlyOestGdsuF6HGFDDUICQU2BoTAwQhDVFTguh6kpJVWFUXAuwajfsbTjJeGJCRfNGna6aah9xeuaoiA/aiJi6l/qVzigIz9qQlOVLFCAgK7gotnDThYOP0r2A0g66ZAZI4sfue9704/O2H5BF2MUpqrgrn98inueWdP9yofbkR8OgBICy/FQVhDCo9fOuj2o0vMPTclLT4AxWl5aEDktFNDG246HhOW9uX1fB4rzosi4EmVFUYyuyP1BOuNCiKyBmM2kux5HJpHBiIr8G2oq87V42kVpfhR7DnShK+0sIwQOIZQoigJFVcEY+5KuUhTWtasp/lEiZSM/FkR3xsWxY8tq8qPGNXbaznJ//BXFhUAmnsGQkpzvj6stCXcmLVBFheLHSQZKEi4kwkHt/O/OqimyXA+MUt+j8Dh+9uh76Mk4oIeax9LPal51xtGorSyA5XjIOBzHjizRRlYXnrdxTxsuOXFU9joCVWVYfMro0esefP+URNpZKjyB3tgezzijrz5r/AVDS2NIZFwwRsG5wN6mnpaCkug586cMDqVtv18KY+iKp/Dzv74H7zA7HkgJKJC46dxjkJ8TgutxpCwXp08erP3+lY1X1ndmvq+rFJbtoaowdMfD184+lykUti1AKEV+2MAfX/gcr6xuWKIW5v761r+vfO/omqK8suIcZGwP8YyD6aNKcf+l0x6+8qEVO6mhrmaEwOMChbnmuT++eMYfSnLDBYlkxv3Ti6sfWL+n7Y4VGxvqp44pr4iGAuiyPJw9e/j81s41NzW2J38PSgAhISAgLBeFBZHLLzl9wqKuRBrhoIGQyvDO2n1tiqq84HrCAAEYU6Aoh1c3lAAZTzz6/pq6hefPHYdtjV2AynDl6eN/9eTSTcmGjsTjsBwHAoCmmLVV+d+/auHUGxzXgScpVJX44DvUJrEznn7GtKorR1bmoTvtgBKCiKnhjU934o+vbVkBXX8d5Eu0Ag8pa5hhGpc9+P0TYGcTgIam4OpTRpG7l3yG2y+YCl1T4bocacvDWdOHBioLwy+v2dO+QQIZAFAICQwvi42YOrw4lPb1OExDRV1jJ9bvbs+5fsH4M4vzguhM2KCEIGqq+PuyXXhs6faXEDQ+AaB+iY6QykytKS8464ZzJqEzISAkUJRj4rzp1ef9+l/rfuVAaQowev5frzvu52UFYcTTDhghCJka1mw7gDufW1OvhQI3qYw0tabEDTc+vPzvL/ziTKgKA+cC3WkbF80ZHt5+oHvJ715cPzMQMhpd2y1eMPeoPxXlmHmrdx5ARUFYXTir9uat9Z0vHei2fv7aim1PfOfU8djVEgdUhuvPP+Z3b322d8yGHU1PJDJ2fSiglYwdVnzB6bNGLnZcG64QGFocwz+Xrkd9Z+bXZkDvdF1RSrLZW0oZSNYkOLQZuvr2R1ubXxpRuX/BuNGV2NXcg2hIN266YNrDuxq6r2lo6V5PCSFDKvImjq0pGik8Fxu2NMIMBCAJQJXD2CSaSk+98uTRoykl0FUFIIBOCZas2MkRNG8yDW3N4TrjBnTyxrqGY3/WkayNxfxV6wiJ78wahnueX41fPP4hHrzuRKQVhoztIuV4mFBTpE0dWTypvy53ufTtDQCGoSKoUtz77CromlJ92Ykj4UlA1xRfurkcz32yu4fmhBcbKms5LMVBU/Of+2T38VfPGx8LZCsOXQEsmjMi75F3ti7sTjjL/3jd7EdmjyxGh82hawoUhcJO2/jBQ8tFUiqLTUqapATMoP7U8q1tx/3u2ZWX3n7xsei2/bhR2pW466Kp1fXtySef+2TPXMJITTSg5rX3ZJB2BTpTDnICKjSFnEiYdse7mw6cHgooC0+bPRptKRu2x7Hg+OGXzJtZe4nliXTAUE1dpejsSUJhBIPzQ3j5nQ14e33DcwEz8B+9Y0UJgaExGLqCIxXSEwCKpl37+LLNwy6RcuTEsYPRnrSRsCwMrYiOHTOsYKymMKgUUMHx0fo9eH/tPpx3xmT0pDJ9tdsDQDK+KvcHVbkBNDR1+zkWSrCpNY73v2herevquiNFAlRKZGO3teS5D7b94pwZNXBcX0ebGsPC6UPxwHOrG5Npu+RHCydhaGUhVEYgsoZy/2SNphAYigYhgabWbtz8zKdY8sHuFfNn1tSEFFnc1NSV1bcUn29vwvr67qW6obccGvEk2RC6rrL2jQ09r73+6Y4Lp40shZvNFpsqw5TqgtsipnbLnFGDQruauvu4HColuPvZVVhfH/+tGTHf7HNdpIQeCtx03+ubjzlqSP6IicOK4XFfVeoqw0/PPGrOhrqOX+040P3XtV/slxNHFBFJYiiKBLDi891I2W6boWvQA8b3XvxsH/a3xheeMWsECgti8CQHo0A4QExID8IFcgMqDjR24KkV27CxIf5UwDSuIpA8O1hEoYRV5IUQ0hgI55BHII4xShq5qp/26Jubn9q4u2X6cROHoKggAoUC0nFgWRzN3Sl8tG4flq2t3za0sjAa1NXiRNqClBK2e9APJlJK5H3v8dcM6c7urfElALEESaahXMUoeelr2HjlTLhvhJkc3M8mJELRDsQ9LMikrAsjqlw8uTo/Z9zgfJQXRRHWVTB6sMbY5RIt8TQ27mrFB9ta7OaE97gRMm8PKfJZlbtHy360yRQnHQ5VFlJCVg3gFGgKhJBwPJ5NL2CiJtzng0zmy35xBJdpKY0SXbqO0v++QkJ0uHhH0/TvAvJLeRVPyMkKd56OqaRY9HN5NVVBhqhvpRxxruc6z5wwpuSco2uLsbepC69+VrfHJmwaI6SlN3CSsZxrDPAbh5fFqmsr8lCQE4SqMFi2i+aOJLbta8fO5sQmzpTfGbr2RH8/mwsZKQip66vyAoOlEHAEwbbm5C89idvIkdmFum27VzDhXVwY0UflhPQAIQQ9acdt7cnstQR9hlD24MRhRa9dcOq4qc2dceQHNNz3zKf/an500Tl9IDEvetzwhCzv9fMJIZRREmeUNPUFm7JuqcwScHtLIrLvEHKFKIGEzBq4lBB0MELaCSFwuahwLGc2hJgAISoBGe3LQPserQuQJijKBs3Q3lIY3QQ/Ix4RUg7qn+ujhHRQgo6DkUnf5Z0zsRod8QzW72iEoSm9MYNcIWX+Ide3Syk1CUQwwBmGxyjZSw6WPfcF/HqNdiERFVIWHWoIMIJGQkhKAhHLcm4k3JsmCN1uBPQHKCF7DjNxMcfxTuCedyyFrCFAQABxCfKFoqorVJWtINkMc2/uqJdH67h8BOdiAggIISSta8rbBEh8iXYqJUzVL1Hx6RKEcSGGcS5KfLIebWOM7qAE6VTaipw1c+TO6RMqCruTGTDPw73PfPb71FOX/dtB+iKBZah0Z0BXoSjM9wgyTt9D86Im0paDjOUiZOrgXKAnnkbJoBiklOjoTifDAW2HwiiS2UBNH/q5gKkp9bGQ8WQybT/pSw9y+M3NINEfeQQyzgiJ9w5Q//uqjMEMaOhMpCGye4IRAgjOwQX1PTSCTkpIZ98te6vY/Rs1H67QjEsJSig8IVBaEIHHBVq7UsjGoXoUSnoGXnNQbRIgHjC0OwDdD/L0k1SyX3SXUdKta8rz0NTnj1TJ5BOhCRRG/YkWEmFTQ044sLUrkdn6dXVQfX+F8EecSE6BrYrKtkL6QTzBOTwJaAqbM662pLAnmUHE1LBjZwfSNl87IE7iOB40TcHEkWU46ZgajK8tQWlBFLbjG2nja0ugqwyOx2HoKgKGCsmFH5XUVNi2g8qSHEyoLYHtetkaX9/vt2wHg/LDmDyyDLbDUV4YhaZQCC7ABYeUAkIICPnlpJKmKFCYT0fo3Zai1/4ImfqAnQl664qRDQx6nhhgyKmKz2s5EomeEQJDU1FVnAtNYXBcjpxIAKUFEeRFAogEDagK6xf+zvJsFJ8O0ftszkX2nSRUhYFm3ePeSoO8qNmvRknC49xf55AQQoBz4e/YFNRRFAth5JAi3/B2OUxDw5TR5X0gkv2ivIfjs1CKAOfCcBwPCiWw0g6stI1M2oFtObAzDtxEJjJ/xojbYlEDadtFWGNYs70pyRj7aABIPI9DSGiUkhpdU8dqqjK0N1ZxsCMH9XC/eo2olDIKIWEo9MyQqd4khVA9zkGQnVguoDJ6UthUb+FC6MGAVghAtS0Xg0tyETF1FOWGkBcxEcjaFZbtwVAVDK8qRHlRDgpyghg1tAiu66+oLCUwK10IIKQSDqjXGxo7FyK7raMQ/nsJCV1lGF5ViLKiKAqzsZPeHRKElLAyLkrywigtiKKsKNbn/Qkhs5OtIC9sYlhFAWzbg+N4COkqKgflYmhpPopyQ7AsBx4XGFqej2gwgMpBORhbU4KQocF2PHDu32t0dRHyYyZsx4OqUIyoKvTtMo+jtDCCyuIcCClQVhSDoavQVeaDwHcoJkWC2s+lRJ7LBQblR2CoCqyEBdfxBoDGttzwCZOGvPvzS2evHlNddJOuKiPBhSksF9J2ITgPF+YGT1x01uSlx0+pHtfQ1oXSvDD21rdhU13nq5rG9g3M3XgCZXnBnx87uvjGuv3twRFlYVQXRz5oaO66whVy56GrLj9moq25OzBjTOkHEpB1u1smx4LqjRX5wRnS5c9IKZtyckIwDR07Ey0I6nRxRUHwTF2le+dPr37opQ/cP2/oSt4yKD8MK+MgFNTh2Byex+GkOHrpijQb1CPEF7tC+qjmQkJRWIQQGAqlrYSLaFm++YDrOmvhyX8ePaYM+xo70NKZBFMYiKGAUV8i6aqSXe29EkhAcgFKfWnAD1fYlC1YYtRPL3CHQ49RKIz6FAFC/HOERGFOCGnLRW40AE1hh1UHhBBwz48JDcqPYPu+dji2i2g4gIDGUNfUmb2fL5GkxwGPw1DJd6oHhf9NCLHCUJQPIqaOdDLjF2Z5Aop6UFvrGjt++piKYwblBnDV2RN/15Ny7u7syTQk0k4rABkLB0qKC8JVUgocaO1ESW4YImPhyaWbEmDKneRwCT5TV4b0JDLBh15cc4ui0JwfXjD9R8dNrHrgjU93nda/0osLiYqiHOxr6rbfX717KwEENEUIKW0uZAYAkdwXjzRI1KrKAk9ImRZSekLK+D/eXLelLe7sUwM6pPAzp6YpiSREtR3eZwjZjgdCiAYQz3a54NlMoJQSmkK12ePK3mvvSbdv209P2W873OMiZTs8UVSSi9xoUN+5r7XPhbNdDkKISiklactxeierF4wQAo7LETH0gMdlxs0SuIWUcD0B1xNQg0rA8URGcgEQX6UJCSgKC1guz/SKJtfjsB3Pd7sNYtguH+Apid6itl4pZnt9gHVcnt2tyX+uqioBLmSm93wp4Tkuh64xq7wgR3FdIRxXCMBn70NKEOqnR4K6egJxbdi2goxtg1HoxflmdSkLVZOsWsxYGaiMoDIvhF17mvHkW5uttoy4TFeVbYet4JNSeo4nEIyE/ig9kUw7fHEmY+erjI0dXpHz4OZdTb+RXLxuqPSsYWWxG977nF89rKqslVJo+w/s4H1mpZRcCtDxtcU/nTKq5HupjGPHU3bAcbkNSdJTx1UnPlq/r6OnscsszTefM7VBLbUVeUfnRs3wO5/v/cuKtXV3A1KZNq7y9qmjShb1pKxEfUtiMyWggvNLhCCpaaNL/zahtujoVMZ1K4oiqx95ueNml4uu8qJIzdDy3JWVg2LFnuc89c6nO3/OPSEnjS/90cTaoqsoocqWuo7H9h7ovJNRn+gruUBOTmjsyVOrfxkNKtMIVeoSqfRvN2w5sCQ3rN9bmBOsHlmVi+qS2Ky0Kzbtb+76cXtT16rigvCCOZMqbmNEljd2Rt94tj1+I3e8nsKY8VQsNMiuKIrUlBWGKzUmn3nz0523+hpF5JblB19IpjJL99e33xMJ6qcdXVv4wzVb919rc/nF4EGRRxzXYxT0tqmjSu6JGuwUpqn1ze09t+3d2/Y6JAQIwfETqu4eNTi/hqlK50vLt/+mqz3xDGEUnseh6b7UTDv83Z89+v53jx5akDtqSBGK8sNgAR1g1I9VcQ4rZWFnUxc+39qIzfu71xBV+6GuqctxpDJPjwsxKC+MRaeM+VdpYbS0qaUz/O7qul/FwmZJSa45gxH5JqR8XVPIuOK8wAwhxMjSPHMuYzQEIa72Y2QS4CI9bmzlDSdMrLzzkX+tXN+TctoumTfhRC7RIaWsqC2Lnrx+m7JVeuK94lxzbmVhkDzxypoPy4qi4fPmjv/Vhl3Nq4aV50+ePbbkp39+/rNPHI9bi8+afG5rj5WQnhcyQmZq3daG1nHV+byxLZ5a/vneBiGkRUB4eWGo7LGXVx+IhQ3r0gWTb928u2VNbsQsmDSs8J4nXl3zNCVEv/zMSbftauhs3rav/c+EAAqjpVecOeH1+obWomde3bGkdkjh7AtPHvtMQ3NPO6Q4ava4ipMff/nz5mUrNn+84LiR8xedetQ/nnx1/c2nHjPkny+9v+XThub4kotOG/v9E6cMwRtvb74qFtLmDC2JFTz8r89WmwG166pzpv5wx/6O3XsOdD0kATseTw0fX1M47LNVe343vCL3quFlkdkVRZFzvkhYDx41JP+KF5ZvfW3+zGF/ScQTM59/Y+dDwwbnn3L+iaOevffJj2tczq3i/DBWb6mf+tCST5ZOHFN2/IWnjHr67tbufT0p5xNBCTzuq0VKyUsZoax974vWs9/f3HiSqbKRIV3J0zWqSwlpu9xOWF5TxpXrqKq+qAUCLxMgc1jW3cEIHZWpjIUVK7cNfeODjYWxsEGmHlVZ43hcZtWNmxV5Tu//HheWx0Wmn77lICRvyojixZ9t2d+8syk5qzXhnfThhv3LKSWmX6khIKR0skxF79PNBz5r7HJnrtvTeXk8aaEoxzxn0ohBV36wft+O+jZrVnOXM2fV1qYvCJHcdwA4etLeT9OOSCRsvqE16S2AlFtUheas3ta0tb41M3ljXfd3WzuTGJQXnDe2puAyTyBz8qyxXxw3bdR2VVVQUxb7LmwX0hMoHxQ7Jy+slb62su7fklS/6LNtrWc2t8XlmJrCK7iQ1s797XzVjrZTO1x2xosf7b47FlSrp40re1JVmDJu1OANC+YevYeqWlttee4CEFJGCcms3t60b19LeurWhsS5jW1xlBaETpBcgDKa2ri79fmCmFlsxMzjqgZFj/5g9R6MGlIwMy8veLqUEk2dqV2jBuefEjDNrecumFpXWVG0tSBqBPNyzBMJiN3RncL76xuu6ZbK2e+sbfheOm2ToaU535W261MO+hXUM0rqA4Z2vxEMzuWKPqbTo2MbU3Jyc1pO7vbYUVIzxgVC5nd0TVlCsrm0wzWlH6uJpS0PWxoSJ2NPVxtV1LdPmFR95+bdzbfA54NwCAmPC/criHcCjMZ0jRWnLL4GIHG4Hlwh9kNi2mGMOCokmiEFFKZ2ZCkKhZpC8tOOeA9CeKAEAugESDmIn7sBFwGaZdBnXR0FAJUg7RACRGVdfphe5gd0JS+ZytBd2xt/yDSm7K9vbNrXlq7TggYcy4ahkiqPSzieWJ2liW21PJHUFFJqcZKybJ4BF7uYIpBx+SrOJcKGGnIcl+/dvf+7TFM0AqQ7EvY2aAqXUjJJSCsI4RAinTUn9F43+0Bb8jXLdq89enjxHYQg/O66/SsWzhk1edKwQYP2NfcccFyxV1cYmls6hiaS1l1MZXzJ/pbGeNqOR0ytzPU4uMAXhAh4Qq53uIRCSRGk73pLCXgegdp/hwafHhBXCIl/ibz5DQjpykDqGxAJG15+NJipqSz0OrtTipV2BAFQXZZflbZBasrzhxu62rcnSa/PTwjxCWdc9uxp6GicMLx05GebG0tyo8H2cTUlIwghnsxGL0k/8nB2X3yfJM4IpETH9rr2xmljyo+ua4qXg1Bv1JDCwamM7fa9k7+bATE01YhFTcSTFicEhPpp0ewiIgBIT31jd2LU0EFdq/d2H69paqOhKWYqY3dQRqDoGpo6UrsURjFuWPEJO+o7PwnlBKcPLo6FX/9w+9by4py8ipJYoKIsfzgo+by6JDrH4xxrtzW211YVxPZ22JcnrNS7kZARsGw3CS4opVTp1w+ajVTL3jG2bL5yd0NX09ypQ6YuX1O3rrkt+WPLdj+ePrZs1PPvbX06Y7kfdyUy4FR9c01dy7WGpkDXFMWyvFYp5eSivBCGluVOyNjiczPAjs8JG9jX3L2d6TooI32T+V+5TVhfmadte/qg3CAuOW3sS2FTy0+nMiXPvPPFX7gk/3z/8923nTGj9gdTRpee0NXZM7KtIwHGqOF6XlBKGgQBuMdNx/VC0FjH8nX7/1BdHP2PH3xn8ufxtJ1MxpPD4inhUkp023bBpdQBAsf1GOcy0Duxtu1BYTT57ud77y7JDz52yaljtrZ0Jjw7Y0W5IE2QEpRRSE1JbNzRVL9wzugp0XDgvcdeXf8jx/FUj/NgNp5LHdeDwqi3Yt2+B6tLon+5ZdG0ZSmbbxUer3j8jQ03d8UzrxkBHUmbP/fPtzZef8bsEXe0jCg5IS+sTXzvs53JusaePw4pz7tNco+dOaP6Ld0wdkQMOvkfyzau2FrfdefqLfWvXrdw4lPdKfdjQ1OKXlz+xXNdzV33uK4X9jye6KXGOa4HzkWgd2UwlXVvq2//ZOa48rO37ut4F5Su3NXQuX1ISWzE7sbut6nC1jz/7pa3L5p71HkTR5QOAZDZ29hpLFm6eTZjVN3f2IHZY0sfCoWCl+aE1MlvfLStrbXbflw3tN6dJr7RNmX/qc2KpJQILHocKsF5OSa7WNdYNG257W099htQ1L8pCnNc25ldEtNv1VQW3N+eWhoy1GFpD3cZCs4DYKRd3GIw/EChGJ10cZ2Q0qacX19ZFDzPcnh3S7f1aSiglqRd+R9BFT+zPDzjCrwZ0vCoy7HK5vLPFCgKauTfbQ/POly+6DruqTFTWdAdz7QuPHnsJYwS+vTSTTW6oaWYwuB53oySqP4Lyihr7LavCKrkOi5xwPJwLyGIhVT8weF4y+J4UrjuJeX55sUBTcnvSli7uiz+C4BuJNk6VNv2hsQM+tOSPHNSR9za2Rx3fisk+fSUSVXvVA6KHLtk2cY3ygpDgxs70p8lHHmnpiqNtuXMLopqN+aE9epk2m3uSHkPepK8HFTxgJBotzzcJSHDIY38weX4xBZ42C9nk4CUs4IquTrhyttByDYF8gJdwakpF9dTStsdl8cCTNxSlh86QQgp2+LWh2mX3KwpOJVKMZ8L2VVREDqhM2HtbU24d+u6uvqwRcj/hy2V/SkTIqVE8OIn/OovV0BC9DHT+oePXdcPnauK/3svjNEBQS+ZDcVT2otnAsdxQRmFojAILvoYZ70qp3/isDcGI4REfjRw4txpw07bdaBrRX40MG5iTf7PH3lp7VONXdZFSrbeF8S/v8+H8SO1IKQvGce58O+djRtwT/h9UBgY7bexH+ndb1bAdTiYyvzKQMvFacdUf1hbkTvp9//4rIiqrEdTlYMMvew2oY7rEYUpUlV8Bl52q5SDHOHed+x3neyXm+lj+fXlnw7uf+u6HkAIVEXpJyX8zZC564+nopDD/yDRfyFIlAFEFUZ8PvphHqowAil9rnrvy/XPnfiZSvKlfElviWbvDw31/8GhQ398iGWzaGnLGbS/ofnqyrzw9Rnbwp+fX/VmU9z5iaYOJB4r/eh79HD3OuTdJKHZyTp8cZWq+N9LCaiqgm11bQ1NbT0lqqYQxggOZXAySqApVPZ/9qG7ZLPDVEX1jkd/CgM7xI7wGfv+DxTRfglOkk0XUoX+p38w6n+3/a8BAGOtxmE+9d9lAAAAAElFTkSuQmCC"); - -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kevin Dangoor (kdangoor@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -var deps = [ - "pilot/fixoldbrowsers", - "pilot/index", - "pilot/plugin_manager", - "pilot/environment", - "ace/editor", - "ace/edit_session", - "ace/virtual_renderer", - "ace/undomanager", - "ace/theme/textmate" -]; - -require(deps, function() { - var catalog = require("pilot/plugin_manager").catalog; - catalog.registerPlugins([ "pilot/index" ]); - - var Dom = require("pilot/dom"); - var Event = require("pilot/event"); - - var Editor = require("ace/editor").Editor; - var EditSession = require("ace/edit_session").EditSession; - var UndoManager = require("ace/undomanager").UndoManager; - var Renderer = require("ace/virtual_renderer").VirtualRenderer; - - window.ace = { - edit: function(el) { - if (typeof(el) == "string") { - el = document.getElementById(el); - } - - var doc = new EditSession(Dom.getInnerText(el)); - doc.setUndoManager(new UndoManager()); - el.innerHTML = ''; - - var editor = new Editor(new Renderer(el, "ace/theme/textmate")); - editor.setSession(doc); - - var env = require("pilot/environment").create(); - catalog.startupPlugins({ env: env }).then(function() { - env.document = doc; - env.editor = editor; - editor.resize(); - Event.addListener(window, "resize", function() { - editor.resize(); - }); - el.env = env; - }); - // Store env on editor such that it can be accessed later on from - // the returned object. - editor.env = env; - return editor; - } - }; -}); diff --git a/build/src/ace.js b/build/src/ace.js deleted file mode 100644 index ca2d9cc2..00000000 --- a/build/src/ace.js +++ /dev/null @@ -1 +0,0 @@ -(function(){if(window.require)require.packaged=!0;else{var a=function(b,c,d){typeof b!=="string"?a.original?a.original.apply(window,arguments):(console.error("dropping module because define wasn't a string."),console.trace()):(define.modules||(define.modules={}),define.modules[b]=d)};window.define&&(a.original=window.define),window.define=a;var b=function(a,d){if(Object.prototype.toString.call(a)==="[object Array]"){var e=[];for(var f=0,g=a.length;f>>0;if(c===0)return-1;var d=0,e=d;arguments.length>0&&(d=Number(arguments[1]),d!==d?d=0:d!==0&&d!==1/e&&d!==-(1/e)&&(d=(d>0||-1)*Math.floor(Math.abs(d))));if(d>=c)return-1;var f=d>=0?d:Math.max(c-Math.abs(d),0);for(;f>>0;if(c===0)return-1;var d=c,e=!1|0;arguments.length>0&&(d=Number(arguments[1]),d!==d?d=0:d!==0&&d!==1/e&&d!==-(1/e)&&(d=(d>0||-1)*Math.floor(Math.abs(d))));var f=d>=0?Math.min(d,c-1):c-Math.abs(d);while(f>=0)if(f in b&&b[f]===a)return f;return-1}),Array.prototype.map||(Array.prototype.map=function(a){if(this===void 0||this===null)throw new TypeError;var b=Object(this),c=b.length>>>0;if(typeof a!=="function")throw new TypeError;res=Array(c);var d=arguments[1];for(var e=0;e>>0;if(typeof a!=="function")throw new TypeError;var d=arguments[1];for(var e=0;e>>0;if(typeof a!="function")throw new TypeError;if(b==0&&arguments.length==1)throw new TypeError;var c=0;if(arguments.length<2){do{if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}while(!0)}else var d=arguments[1];for(;c>>0;if(typeof a!="function")throw new TypeError;if(b==0&&arguments.length==1)throw new TypeError;var c=b-1;if(arguments.length<2){do{if(c in this){d=this[c--];break}if(--c<0)throw new TypeError}while(!0)}else var d=arguments[1];for(;c>=0;c--)c in this&&(d=a.call(null,d,this[c],c,this));return d}),Object.keys||(Object.keys=function m(a){var b,c=[];for(b in a)f(a,b)&&c.push(b);return c}),Object.getOwnPropertyNames||(Object.getOwnPropertyNames=Object.keys);var n="Object.getOwnPropertyDescriptor called on a non-object";Object.getOwnPropertyDescriptor||(Object.getOwnPropertyDescriptor=function o(a,b){var c,d,e;if(typeof a!=="object"&&typeof a!=="function"||a===null)throw new TypeError(n);f(a,b)&&(c={configurable:!0,enumerable:!0},d=c.get=g(a,b),e=c.set=h(a,b),!d&&!e&&(c.writeable=!0,c.value=a[b]));return c}),Object.getPrototypeOf||(Object.getPrototypeOf=function p(a){return a.__proto__||a.constructor.prototype}),Object.create||(Object.create=function q(a,b){var c;if(a===null)c={"__proto__":null};else{if(typeof a!=="object")throw new TypeError(a+" is not an object or null");d.prototype=a,c=new d}typeof b!=="undefined"&&Object.defineProperties(c,b);return c}),Object.defineProperty||(Object.defineProperty=function r(a,b,c){var d,e,f;if("object"!==typeof a&&"function"!==typeof a)throw new TypeError(a+"is not an object");if(c&&"object"!==typeof c)throw new TypeError("Property descriptor map must be an object");if("value"in c){if("get"in c||"set"in c)throw new TypeError('Invalid property. "value" present on property with getter or setter.');if(d=a.__proto__)a.__proto__=Object.prototype;delete a[b],a[b]=c.value,d&&(a.__proto__=d)}else(f=c.get)&&i(a,f),(e=c.set)&&j(a,e);return a}),Object.defineProperties||(Object.defineProperties=function s(a,b){Object.getOwnPropertyNames(b).forEach(function(c){Object.defineProperty(a,c,b[c])});return a});var t=function(a){return a};Object.seal||(Object.seal=t),Object.freeze||(Object.freeze=t),Object.preventExtensions||(Object.preventExtension=t);var u=function(){return!1},v=function(){return!0};Object.isSealed||(Object.isSealed=u),Object.isFrozen||(Object.isFrozen=u),Object.isExtensible||(Object.isExtensible=v),String.prototype.trim||(String.prototype.trim=function(){return this.trimLeft().trimRight()}),String.prototype.trimRight||(String.prototype.trimRight=function(){return this.replace(/[\t\v\f\s\u00a0\ufeff]+$/,"")}),String.prototype.trimLeft||(String.prototype.trimLeft=function(){return this.replace(/^[\t\v\f\s\u00a0\ufeff]+/,"")}),b.globalsLoaded=!0}),define("pilot/index",["require","exports","module","pilot/fixoldbrowsers","pilot/types/basic","pilot/types/command","pilot/types/settings","pilot/commands/settings","pilot/commands/basic","pilot/settings/canon","pilot/canon"],function(a,b,c){b.startup=function(b,c){a("pilot/fixoldbrowsers"),a("pilot/types/basic").startup(b,c),a("pilot/types/command").startup(b,c),a("pilot/types/settings").startup(b,c),a("pilot/commands/settings").startup(b,c),a("pilot/commands/basic").startup(b,c),a("pilot/settings/canon").startup(b,c),a("pilot/canon").startup(b,c)},b.shutdown=function(b,c){a("pilot/types/basic").shutdown(b,c),a("pilot/types/command").shutdown(b,c),a("pilot/types/settings").shutdown(b,c),a("pilot/commands/settings").shutdown(b,c),a("pilot/commands/basic").shutdown(b,c),a("pilot/settings/canon").shutdown(b,c),a("pilot/canon").shutdown(b,c)}}),define("pilot/types/basic",["require","exports","module","pilot/types"],function(a,b,c){function m(a){if(a instanceof e)this.subtype=a;else{if(typeof a!=="string")throw new Error("Can' handle array subtype");this.subtype=d.getType(a);if(this.subtype==null)throw new Error("Unknown array subtype: "+a)}}function l(a){if(typeof a.defer!=="function")throw new Error("Instances of DeferredType need typeSpec.defer to be a function that returns a type");Object.keys(a).forEach(function(b){this[b]=a[b]},this)}function j(a){if(!Array.isArray(a.data)&&typeof a.data!=="function")throw new Error("instances of SelectionType need typeSpec.data to be an array or function that returns an array:"+JSON.stringify(a));Object.keys(a).forEach(function(b){this[b]=a[b]},this)}var d=a("pilot/types"),e=d.Type,f=d.Conversion,g=d.Status,h=new e;h.stringify=function(a){return a},h.parse=function(a){if(typeof a!="string")throw new Error("non-string passed to text.parse()");return new f(a)},h.name="text";var i=new e;i.stringify=function(a){if(!a)return null;return""+a},i.parse=function(a){if(typeof a!="string")throw new Error("non-string passed to number.parse()");if(a.replace(/\s/g,"").length===0)return new f(null,g.INCOMPLETE,"");var b=new f(parseInt(a,10));isNaN(b.value)&&(b.status=g.INVALID,b.message="Can't convert \""+a+'" to a number.');return b},i.decrement=function(a){return a-1},i.increment=function(a){return a+1},i.name="number",j.prototype=new e,j.prototype.stringify=function(a){return a},j.prototype.parse=function(a){if(typeof a!="string")throw new Error("non-string passed to parse()");if(!this.data)throw new Error("Missing data on selection type extension.");var b=typeof this.data==="function"?this.data():this.data,c=!1,d,e=[];b.forEach(function(b){a==b?(d=this.fromString(b),c=!0):b.indexOf(a)===0&&e.push(this.fromString(b))},this);if(c)return new f(d);this.noMatch&&this.noMatch();if(e.length>0){var h="Possibilities"+(a.length===0?"":" for '"+a+"'");return new f(null,g.INCOMPLETE,h,e)}var h="Can't use '"+a+"'.";return new f(null,g.INVALID,h,e)},j.prototype.fromString=function(a){return a},j.prototype.decrement=function(a){var b=typeof this.data==="function"?this.data():this.data,c;if(a==null)c=b.length-1;else{var d=this.stringify(a),c=b.indexOf(d);c=c===0?b.length-1:c-1}return this.fromString(b[c])},j.prototype.increment=function(a){var b=typeof this.data==="function"?this.data():this.data,c;if(a==null)c=0;else{var d=this.stringify(a),c=b.indexOf(d);c=c===b.length-1?0:c+1}return this.fromString(b[c])},j.prototype.name="selection",b.SelectionType=j;var k=new j({name:"bool",data:["true","false"],stringify:function(a){return""+a},fromString:function(a){return a==="true"?!0:!1}});l.prototype=new e,l.prototype.stringify=function(a){return this.defer().stringify(a)},l.prototype.parse=function(a){return this.defer().parse(a)},l.prototype.decrement=function(a){var b=this.defer();return b.decrement?b.decrement(a):undefined},l.prototype.increment=function(a){var b=this.defer();return b.increment?b.increment(a):undefined},l.prototype.name="deferred",b.DeferredType=l,m.prototype=new e,m.prototype.stringify=function(a){return a.join(" ")},m.prototype.parse=function(a){return this.defer().parse(a)},m.prototype.name="array",b.startup=function(){d.registerType(h),d.registerType(i),d.registerType(k),d.registerType(j),d.registerType(l),d.registerType(m)},b.shutdown=function(){d.unregisterType(h),d.unregisterType(i),d.unregisterType(k),d.unregisterType(j),d.unregisterType(l),d.unregisterType(m)}}),define("pilot/types",["require","exports","module"],function(a,b,c){function i(a,b){if(a.substr(-2)==="[]"){var c=a.slice(0,-2);return new g.array(c)}var d=g[a];typeof d==="function"&&(d=new d(b));return d}function f(){}function e(a,b,c,e){this.value=a,this.status=b||d.VALID,this.message=c,this.predictions=e||[]}var d={VALID:{toString:function(){return"VALID"},valueOf:function(){return 0}},INCOMPLETE:{toString:function(){return"INCOMPLETE"},valueOf:function(){return 1}},INVALID:{toString:function(){return"INVALID"},valueOf:function(){return 2}},combine:function(a){var b=d.VALID;for(var c=0;cb&&(b=arguments[c]);return b}};b.Status=d,b.Conversion=e,f.prototype={stringify:function(a){throw new Error("not implemented")},parse:function(a){throw new Error("not implemented")},name:undefined,increment:function(a){return undefined},decrement:function(a){return undefined},getDefault:function(){return this.parse("")}},b.Type=f;var g={};b.registerType=function(a){if(typeof a==="object"){if(!(a instanceof f))throw new Error("Can't registerType using: "+a);if(!a.name)throw new Error("All registered types must have a name");g[a.name]=a}else{if(typeof a!=="function")throw new Error("Unknown type: "+a);if(!a.prototype.name)throw new Error("All registered types must have a name");g[a.prototype.name]=a}},b.registerTypes=function h(a){Object.keys(a).forEach(function(c){var d=a[c];d.name=c,b.registerType(d)})},b.deregisterType=function(a){delete g[a.name]},b.getType=function(a){if(typeof a==="string")return i(a);if(typeof a==="object"){if(!a.name)throw new Error("Missing 'name' member to typeSpec");return i(a.name,a)}throw new Error("Can't extract type from "+a)}}),define("pilot/types/command",["require","exports","module","pilot/canon","pilot/types/basic","pilot/types"],function(a,b,c){var d=a("pilot/canon"),e=a("pilot/types/basic").SelectionType,f=a("pilot/types"),g=new e({name:"command",data:function(){return d.getCommandNames()},stringify:function(a){return a.name},fromString:function(a){return d.getCommand(a)}});b.startup=function(){f.registerType(g)},b.shutdown=function(){f.unregisterType(g)}}),define("pilot/canon",["require","exports","module","pilot/console","pilot/stacktrace","pilot/oop","pilot/event_emitter","pilot/catalog","pilot/types","pilot/lang"],function(a,b,c){function x(a){a=a||{},this.command=a.command,this.args=a.args,this.typed=a.typed,this._begunOutput=!1,this.start=new Date,this.end=null,this.completed=!1,this.error=!1}function u(a,b,c,d){typeof a==="string"&&(a=n[a]);if(!a)return!1;var e=new x({command:a,args:c,typed:d});a.exec(b,c||{},e);return!0}function t(){return o}function s(a){return n[a]}function r(a){var b=typeof a==="string"?a:a.name;delete n[b],k.arrayRemove(o,b)}function q(a,b){var c=b.type;b.type=j.getType(c);if(b.type==null)throw new Error("In "+a+"/"+b.name+": can't find type for: "+JSON.stringify(c))}function p(a){if(!a.name)throw new Error("All registered commands must have a name");a.params==null&&(a.params=[]);if(!Array.isArray(a.params))throw new Error("command.params must be an array in "+a.name);a.params.forEach(function(b){if(!b.name)throw new Error("In "+a.name+": all params must have a name");q(a.name,b)},this),n[a.name]=a,o.push(a.name),o.sort()}var d=a("pilot/console"),e=a("pilot/stacktrace").Trace,f=a("pilot/oop"),g=a("pilot/event_emitter").EventEmitter,h=a("pilot/catalog"),i=a("pilot/types").Status,j=a("pilot/types"),k=a("pilot/lang"),l={name:"command",description:"A command is a bit of functionality with optional typed arguments which can do something small like moving the cursor around the screen, or large like cloning a project from VCS.",indexOn:"name"};b.startup=function(a,b){h.addExtensionSpec(l)},b.shutdown=function(a,b){h.removeExtensionSpec(l)};var m={name:"thing",description:"thing is an example command",params:[{name:"param1",description:"an example parameter",type:"text",defaultValue:null}],exec:function(a,b,c){thing()}},n={},o=[];b.removeCommand=r,b.addCommand=p,b.getCommand=s,b.getCommandNames=t,b.exec=u,b.upgradeType=q,f.implement(b,g);var v=[],w=100;f.implement(x.prototype,g),x.prototype._beginOutput=function(){this._begunOutput=!0,this.outputs=[],v.push(this);while(v.length>w)v.shiftObject();b._dispatchEvent("output",{requests:v,request:this})},x.prototype.doneWithError=function(a){this.error=!0,this.done(a)},x.prototype.async=function(){this._begunOutput||this._beginOutput()},x.prototype.output=function(a){this._begunOutput||this._beginOutput(),typeof a!=="string"&&!(a instanceof Node)&&(a=a.toString()),this.outputs.push(a),this._dispatchEvent("output",{});return this},x.prototype.done=function(a){this.completed=!0,this.end=new Date,this.duration=this.end.getTime()-this.start.getTime(),a&&this.output(a),this._dispatchEvent("output",{})},b.Request=x}),define("pilot/console",["require","exports","module"],function(a,b,c){var d=function(){},e=["assert","count","debug","dir","dirxml","error","group","groupEnd","info","log","profile","profileEnd","time","timeEnd","trace","warn"];typeof window==="undefined"?e.forEach(function(a){b[a]=function(){var b=Array.prototype.slice.call(arguments),c={op:"log",method:a,args:b};postMessage(JSON.stringify(c))}}):e.forEach(function(a){window.console&&window.console[a]?b[a]=Function.prototype.bind.call(window.console[a],window.console):b[a]=d})}),define("pilot/stacktrace",["require","exports","module","pilot/useragent","pilot/console"],function(a,b,c){function i(){}function g(a){for(var b=0;b\s*\(/gm,"{anonymous}()@").split("\n")},firefox:function(a){var b=a.stack;if(!b){e.log(a);return[]}b=b.replace(/(?:\n@:0)?\s+$/m,""),b=b.replace(/^\(/gm,"{anonymous}(");return b.split("\n")},opera:function(a){var b=a.message.split("\n"),c="{anonymous}",d=/Line\s+(\d+).*?script\s+(http\S+)(?:.*?in\s+function\s+(\S+))?/i,e,f,g;for(e=4,f=0,g=b.length;e=0,b.isIPad=e.indexOf("iPad")>=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("pilot/oop",["require","exports","module"],function(a,b,c){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("pilot/event_emitter",["require","exports","module"],function(a,b,c){var d={};d._emit=d._dispatchEvent=function(a,b){this._eventRegistry=this._eventRegistry||{};var c=this._eventRegistry[a];if(c&&c.length){var b=b||{};b.type=a;for(var d=0;d"+setting.name+" = "+setting.get():(b.setting.set(b.value),d="Setting: "+b.setting.name+" = "+b.setting.get());else{var e=a.settings.getSettingNames();d="",e.sort(function(a,b){return a.localeCompare(b)}),e.forEach(function(b){var c=a.settings.getSetting(b),e="https://wiki.mozilla.org/Labs/Skywriter/Settings#"+c.name;d+=''+c.name+" = "+c.value+"
"})}c.done(d)}},e={name:"unset",params:[{name:"setting",type:"setting",description:"The name of the setting to return to defaults"}],description:"unset a setting entirely",exec:function(a,b,c){var d=a.settings.get(b.setting);d?(d.reset(),c.done("Reset "+d.name+" to default: "+a.settings.get(b.setting))):c.doneWithError("No setting with the name "+b.setting+".")}},f=a("pilot/canon");b.startup=function(a,b){f.addCommand(d),f.addCommand(e)},b.shutdown=function(a,b){f.removeCommand(d),f.removeCommand(e)}}),define("pilot/commands/basic",["require","exports","module","pilot/typecheck","pilot/canon"],function(require,exports,module){var checks=require("pilot/typecheck"),canon=require("pilot/canon"),helpMessages={plainPrefix:'

Welcome to Skywriter - Code in the Cloud

',plainSuffix:'For more information, see the Skywriter Wiki.'},helpCommandSpec={name:"help",params:[{name:"search",type:"text",description:"Search string to narrow the output.",defaultValue:null}],description:"Get help on the available commands.",exec:function(a,b,c){var d=[],e=canon.getCommand(b.search);if(e&&e.exec)d.push(e.description?e.description:"No description for "+b.search);else{var f=!1;!b.search&&helpMessages.plainPrefix&&d.push(helpMessages.plainPrefix),e?(d.push("

Sub-Commands of "+e.name+"

"),d.push("

"+e.description+"

")):b.search?(b.search=="hidden"&&(b.search="",f=!0),d.push("

Commands starting with '"+b.search+"':

")):d.push("

Available Commands:

");var g=canon.getCommandNames();g.sort(),d.push("");for(var h=0;h"),d.push('"),d.push(""),d.push("")}d.push("
'+e.name+""+e.description+"
"),!b.search&&helpMessages.plainSuffix&&d.push(helpMessages.plainSuffix)}c.done(d.join(""))}},evalCommandSpec={name:"eval",params:[{name:"javascript",type:"text",description:"The JavaScript to evaluate"}],description:"evals given js code and show the result",hidden:!0,exec:function(env,args,request){var result,javascript=args.javascript;try{result=eval(javascript)}catch(e){result="Error: "+e.message+""}var msg="",type="",x;if(checks.isFunction(result))msg=(result+"").replace(/\n/g,"
").replace(/ /g," "),type="function";else if(checks.isObject(result)){Array.isArray(result)?type="array":type="object";var items=[],value;for(x in result)result.hasOwnProperty(x)&&(checks.isFunction(result[x])?value="[function]":checks.isObject(result[x])?value="[object]":value=result[x],items.push({name:x,value:value}));items.sort(function(a,b){return a.name.toLowerCase()"+items[x].name+": "+items[x].value+"
"}else msg=result,type=typeof result;request.done("Result for eval '"+javascript+"' (type: "+type+"):

"+msg)}},versionCommandSpec={name:"version",description:"show the Skywriter version",hidden:!0,exec:function(a,b,c){var d="Skywriter "+skywriter.versionNumber+" ("+skywriter.versionCodename+")";c.done(d)}},skywriterCommandSpec={name:"skywriter",hidden:!0,exec:function(a,b,c){var d=Math.floor(Math.random()*messages.length);c.done("Skywriter "+messages[d])}},messages=["really wants you to trick it out in some way.","is your Web editor.","would love to be like Emacs on the Web.","is written on the Web platform, so you can tweak it."],canon=require("pilot/canon");exports.startup=function(a,b){canon.addCommand(helpCommandSpec),canon.addCommand(evalCommandSpec),canon.addCommand(skywriterCommandSpec)},exports.shutdown=function(a,b){canon.removeCommand(helpCommandSpec),canon.removeCommand(evalCommandSpec),canon.removeCommand(skywriterCommandSpec)}}),define("pilot/typecheck",["require","exports","module"],function(a,b,c){var d=Object.prototype.toString;b.isString=function(a){return a&&d.call(a)==="[object String]"},b.isBoolean=function(a){return a&&d.call(a)==="[object Boolean]"},b.isNumber=function(a){return a&&d.call(a)==="[object Number]"&&isFinite(a)},b.isObject=function(a){return a!==undefined&&(a===null||typeof a=="object"||Array.isArray(a)||b.isFunction(a))},b.isFunction=function(a){return a&&d.call(a)==="[object Function]"}}),define("pilot/settings/canon",["require","exports","module"],function(a,b,c){var d={name:"historyLength",description:"How many typed commands do we recall for reference?",type:"number",defaultValue:50};b.startup=function(a,b){a.env.settings.addSetting(d)},b.shutdown=function(a,b){a.env.settings.removeSetting(d)}}),define("pilot/plugin_manager",["require","exports","module","pilot/promise"],function(a,b,c){var d=a("pilot/promise").Promise;b.REASONS={APP_STARTUP:1,APP_SHUTDOWN:2,PLUGIN_ENABLE:3,PLUGIN_DISABLE:4,PLUGIN_INSTALL:5,PLUGIN_UNINSTALL:6,PLUGIN_UPGRADE:7,PLUGIN_DOWNGRADE:8},b.Plugin=function(a){this.name=a,this.status=this.INSTALLED},b.Plugin.prototype={NEW:0,INSTALLED:1,REGISTERED:2,STARTED:3,UNREGISTERED:4,SHUTDOWN:5,install:function(b,c){var e=new d;if(this.status>this.NEW){e.resolve(this);return e}a([this.name],function(a){a.install&&a.install(b,c),this.status=this.INSTALLED,e.resolve(this)}.bind(this));return e},register:function(b,c){var e=new d;if(this.status!=this.INSTALLED){e.resolve(this);return e}a([this.name],function(a){a.register&&a.register(b,c),this.status=this.REGISTERED,e.resolve(this)}.bind(this));return e},startup:function(c,e){e=e||b.REASONS.APP_STARTUP;var f=new d;if(this.status!=this.REGISTERED){f.resolve(this);return f}a([this.name],function(a){a.startup&&a.startup(c,e),this.status=this.STARTED,f.resolve(this)}.bind(this));return f},shutdown:function(b,c){this.status==this.STARTED&&(pluginModule=a(this.name),pluginModule.shutdown&&pluginModule.shutdown(b,c))}},b.PluginCatalog=function(){this.plugins={}},b.PluginCatalog.prototype={registerPlugins:function(a,c,e){var f=[];a.forEach(function(a){var d=this.plugins[a];d===undefined&&(d=new b.Plugin(a),this.plugins[a]=d,f.push(d.register(c,e)))}.bind(this));return d.group(f)},startupPlugins:function(a,b){var c=[];for(var e in this.plugins){var f=this.plugins[e];c.push(f.startup(a,b))}return d.group(c)}},b.catalog=new b.PluginCatalog}),define("pilot/promise",["require","exports","module","pilot/console","pilot/stacktrace"],function(a,b,c){var d=a("pilot/console"),e=a("pilot/stacktrace").Trace,f=-1,g=0,h=1,i=0,j=!1,k=[],l=[];Promise=function(){this._status=g,this._value=undefined,this._onSuccessHandlers=[],this._onErrorHandlers=[],this._id=i++,k[this._id]=this},Promise.prototype.isPromise=!0,Promise.prototype.isComplete=function(){return this._status!=g},Promise.prototype.isResolved=function(){return this._status==h},Promise.prototype.isRejected=function(){return this._status==f},Promise.prototype.then=function(a,b){typeof a==="function"&&(this._status===h?a.call(null,this._value):this._status===g&&this._onSuccessHandlers.push(a)),typeof b==="function"&&(this._status===f?b.call(null,this._value):this._status===g&&this._onErrorHandlers.push(b));return this},Promise.prototype.chainPromise=function(a){var b=new Promise;b._chainedFrom=this,this.then(function(c){try{b.resolve(a(c))}catch(d){b.reject(d)}},function(a){b.reject(a)});return b},Promise.prototype.resolve=function(a){return this._complete(this._onSuccessHandlers,h,a,"resolve")},Promise.prototype.reject=function(a){return this._complete(this._onErrorHandlers,f,a,"reject")},Promise.prototype._complete=function(a,b,c,f){if(this._status!=g){d.group("Promise already closed"),d.error("Attempted "+f+"() with ",c),d.error("Previous status = ",this._status,", previous value = ",this._value),d.trace(),this._completeTrace&&(d.error("Trace of previous completion:"),this._completeTrace.log(5)),d.groupEnd();return this}j&&(this._completeTrace=new e(new Error)),this._status=b,this._value=c,a.forEach(function(a){a.call(null,this._value)},this),this._onSuccessHandlers.length=0,this._onErrorHandlers.length=0,delete k[this._id],l.push(this);while(l.length>20)l.shift();return this},Promise.group=function(a){a instanceof Array||(a=Array.prototype.slice.call(arguments));if(a.length===0)return(new Promise).resolve([]);var b=new Promise,c=[],d=0,e=function(e){return function(g){c[e]=g,d++,b._status!==f&&(d===a.length&&b.resolve(c))}};a.forEach(function(a,c){var d=e(c),f=b.reject.bind(b);a.then(d,f)});return b},b.Promise=Promise,b._outstanding=k,b._recent=l}),define("pilot/environment",["require","exports","module","pilot/settings"],function(a,b,c){function e(){return{settings:d}}var d=a("pilot/settings").settings;b.create=e}),define("ace/editor",["require","exports","module","pilot/fixoldbrowsers","pilot/oop","pilot/event","pilot/lang","pilot/useragent","ace/keyboard/textinput","ace/mouse_handler","ace/keyboard/keybinding","ace/edit_session","ace/search","ace/background_tokenizer","ace/range","pilot/event_emitter"],function(a,b,c){a("pilot/fixoldbrowsers");var d=a("pilot/oop"),e=a("pilot/event"),f=a("pilot/lang"),g=a("pilot/useragent"),h=a("ace/keyboard/textinput").TextInput,i=a("ace/mouse_handler").MouseHandler,j=a("ace/keyboard/keybinding").KeyBinding,k=a("ace/edit_session").EditSession,l=a("ace/search").Search,m=a("ace/background_tokenizer").BackgroundTokenizer,n=a("ace/range").Range,o=a("pilot/event_emitter").EventEmitter,p=function(a,b){var c=a.getContainerElement();this.container=c,this.renderer=a,this.textInput=new h(a.getTextAreaContainer(),this),this.keyBinding=new j(this),g.isIPad||(this.$mouseHandler=new i(this)),this.$blockScrolling=0,this.$search=(new l).set({wrap:!0}),this.setSession(b||new k(""))};(function(){d.implement(this,o),this.$forwardEvents={gutterclick:1,gutterdblclick:1},this.$originalAddEventListener=this.addEventListener,this.$originalRemoveEventListener=this.removeEventListener,this.addEventListener=function(a,b){return this.$forwardEvents[a]?this.renderer.addEventListener(a,b):this.$originalAddEventListener(a,b)},this.removeEventListener=function(a,b){return this.$forwardEvents[a]?this.renderer.removeEventListener(a,b):this.$originalRemoveEventListener(a,b)},this.setKeyboardHandler=function(a){this.keyBinding.setKeyboardHandler(a)},this.getKeyboardHandler=function(){return this.keyBinding.getKeyboardHandler()},this.setSession=function(a){if(this.session!=a){if(this.session){var b=this.session;this.session.removeEventListener("change",this.$onDocumentChange),this.session.removeEventListener("changeMode",this.$onChangeMode),this.session.removeEventListener("changeTabSize",this.$onChangeTabSize),this.session.removeEventListener("changeWrapLimit",this.$onChangeWrapLimit),this.session.removeEventListener("changeWrapMode",this.$onChangeWrapMode),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);var c=this.session.getSelection();c.removeEventListener("changeCursor",this.$onCursorChange),c.removeEventListener("changeSelection",this.$onSelectionChange),this.session.setScrollTopRow(this.renderer.getScrollTopRow())}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.$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.$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.selection=a.getSelection(),this.selection.addEventListener("changeCursor",this.$onCursorChange),this.$onSelectionChange=this.onSelectionChange.bind(this),this.selection.addEventListener("changeSelection",this.$onSelectionChange),this.onChangeMode(),this.bgTokenizer.setDocument(a.getDocument()),this.bgTokenizer.start(0),this.onCursorChange(),this.onSelectionChange(),this.onChangeFrontMarker(),this.onChangeBackMarker(),this.onChangeBreakpoint(),this.onChangeAnnotation(),this.renderer.scrollToRow(a.getScrollTopRow()),this.renderer.updateFull(),this._dispatchEvent("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.setStyle=function(a){this.renderer.setStyle(a)},this.unsetStyle=function(a){this.renderer.unsetStyle(a)},this.$highlightBrackets=function(){this.session.$bracketHighlight&&(this.session.removeMarker(this.session.$bracketHighlight),this.session.$bracketHighlight=null);if(!this.$highlightPending){var a=this;this.$highlightPending=!0,setTimeout(function(){a.$highlightPending=!1;var b=a.session.findMatchingBracket(a.getCursorPosition());if(b){var c=new n(b.row,b.column,b.row,b.column+1);a.session.$bracketHighlight=a.session.addMarker(c,"ace_bracket")}},10)}},this.focus=function(){var a=this;setTimeout(function(){a.textInput.focus()}),this.textInput.focus()},this.blur=function(){this.textInput.blur()},this.onFocus=function(){this.renderer.showCursor(),this.renderer.visualizeFocus(),this._dispatchEvent("focus")},this.onBlur=function(){this.renderer.hideCursor(),this.renderer.visualizeBlur(),this._dispatchEvent("blur")},this.onDocumentChange=function(a){var b=a.data,c=b.range;this.bgTokenizer.start(c.start.row);if(c.start.row==c.end.row&&b.action!="insertLines"&&b.action!="removeLines")var d=c.end.row;else d=Infinity;this.renderer.updateLines(c.start.row,d),this.renderer.updateCursor()},this.onTokenizerUpdate=function(a){var b=a.data;this.renderer.updateLines(b.first,b.last)},this.onCursorChange=function(a){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),a.$highlightLineMarker=null;if(this.getHighlightActiveLine()&&(this.getSelectionStyle()!="line"||!this.selection.isMultiLine())){var b=this.getCursorPosition(),c=new n(b.row,0,b.row+1,0);a.$highlightLineMarker=a.addMarker(c,"ace_active_line","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)}this.onCursorChange(a),this.$highlightSelectedWord&&this.mode.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(){var a=this.session.getMode();if(this.mode!=a){this.mode=a;var b=a.getTokenizer();if(this.bgTokenizer)this.bgTokenizer.setTokenizer(b);else{var c=this.onTokenizerUpdate.bind(this);this.bgTokenizer=new m(b,this),this.bgTokenizer.addEventListener("update",c)}this.renderer.setTokenizer(this.bgTokenizer)}},this.onChangeWrapLimit=function(){this.renderer.updateFull()},this.onChangeWrapMode=function(){this.renderer.onResize(!0)},this.getCopyText=function(){return this.selection.isEmpty()?"":this.session.getTextRange(this.getSelectionRange())},this.onCut=function(){this.$readOnly||(this.selection.isEmpty()||(this.session.remove(this.getSelectionRange()),this.clearSelection()))},this.insert=function(a){if(!this.$readOnly){var b=this.getCursorPosition();a=a.replace("\t",this.session.getTabString());if(this.selection.isEmpty()){if(this.session.getOverwrite()){var c=new n.fromPoints(b,b);c.end.column+=a.length,this.session.remove(c)}}else{var b=this.session.remove(this.getSelectionRange());this.clearSelection()}this.clearSelection();var d=this.bgTokenizer.getState(b.row),e=this.mode.checkOutdent(d,this.session.getLine(b.row),a),f=this.session.getLine(b.row),g=this.mode.getNextLineIndent(d,f.slice(0,b.column),this.session.getTabString()),h=this.session.insert(b,a),d=this.bgTokenizer.getState(b.row);if(this.session.getDocument().isNewLine(a)){this.moveCursorTo(b.row+1,0);var i=this.session.getTabSize(),j=Number.MAX_VALUE;for(var k=b.row+1;k<=h.row;++k){var l=0;f=this.session.getLine(k);for(var m=0;m0;++m)f.charAt(m)=="\t"?o-=i:f.charAt(m)==" "&&(o-=1);this.session.remove(new n(k,0,k,m))}this.session.indentRows(b.row+1,h.row,g)}else e&&this.mode.autoOutdent(d,this.session,b.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()},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.$selectionStyle="line",this.setSelectionStyle=function(a){this.$selectionStyle!=a&&(this.$selectionStyle=a,this.onSelectionChange(),this._dispatchEvent("changeSelectionStyle",{data:a}))},this.getSelectionStyle=function(){return this.$selectionStyle},this.$highlightActiveLine=!0,this.setHighlightActiveLine=function(a){this.$highlightActiveLine!=a&&(this.$highlightActiveLine=a,this.$updateHighlightActiveLine())},this.getHighlightActiveLine=function(){return this.$highlightActiveLine},this.$highlightSelectedWord=!0,this.setHighlightSelectedWord=function(a){this.$highlightSelectedWord!=a&&(this.$highlightSelectedWord=a,a?this.mode.highlightSelection(this):this.mode.clearSelectionHighlight(this))},this.getHighlightSelectedWord=function(){return this.$highlightSelectedWord},this.setShowInvisibles=function(a){this.getShowInvisibles()!=a&&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.removeRight=function(){this.$readOnly||(this.selection.isEmpty()&&this.selection.selectRight(),this.session.remove(this.getSelectionRange()),this.clearSelection())},this.removeLeft=function(){this.$readOnly||(this.selection.isEmpty()&&this.selection.selectLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection())},this.removeWordRight=function(){this.$readOnly||(this.selection.isEmpty()&&this.selection.selectWordRight(),this.session.remove(this.getSelectionRange()),this.clearSelection())},this.removeWordLeft=function(){this.$readOnly||(this.selection.isEmpty()&&this.selection.selectWordLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection())},this.removeToLineStart=function(){this.$readOnly||(this.selection.isEmpty()&&this.selection.selectLineStart(),this.session.remove(this.getSelectionRange()),this.clearSelection())},this.removeToLineEnd=function(){this.$readOnly||(this.selection.isEmpty()&&this.selection.selectLineEnd(),this.session.remove(this.getSelectionRange()),this.clearSelection())},this.splitLine=function(){if(!this.$readOnly){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.$readOnly){if(!this.selection.isEmpty())return;var a=this.getCursorPosition(),b=a.column;if(b==0)return;var c=this.session.getLine(a.row);if(b=b.end.row&&b.start.column>=b.end.column){var d;if(this.session.getUseSoftTabs()){var e=a.getTabSize(),g=this.getCursorPosition(),h=a.documentToScreenColumn(g.row,g.column),i=e-h%e;d=f.stringRepeat(" ",i)}else d="\t";return this.onTextInput(d)}var c=this.$getSelectedRows();a.indentRows(c.first,c.last,"\t")}},this.blockOutdent=function(){if(!this.$readOnly){var a=this.session.getSelection();this.session.outdentRows(a.getRange())}},this.toggleCommentLines=function(){if(!this.$readOnly){var a=this.bgTokenizer.getState(this.getCursorPosition().row),b=this.$getSelectedRows();this.mode.toggleCommentLines(a,this.session,b.first,b.last)}},this.removeLines=function(){if(!this.$readOnly){var a=this.$getSelectedRows();this.session.remove(new n(a.first,0,a.last+1,0)),this.clearSelection()}},this.moveLinesDown=function(){this.$readOnly||this.$moveLines(function(a,b){return this.session.moveLinesDown(a,b)})},this.moveLinesUp=function(){this.$readOnly||this.$moveLines(function(a,b){return this.session.moveLinesUp(a,b)})},this.moveText=function(a,b){if(this.$readOnly)return null;return this.session.moveText(a,b)},this.copyLinesUp=function(){this.$readOnly||this.$moveLines(function(a,b){this.session.duplicateLines(a,b);return 0})},this.copyLinesDown=function(){this.$readOnly||this.$moveLines(function(a,b){return this.session.duplicateLines(a,b)})},this.$moveLines=function(a){var b=this.$getSelectedRows(),c=a.call(this,b.first,b.last),d=this.selection;d.setSelectionAnchor(b.last+c+1,0),d.$moveSelection(function(){d.moveCursorTo(b.first+c,0)})},this.$getSelectedRows=function(){var a=this.getSelectionRange().collapseRows();return{first:a.start.row,last:a.end.row}},this.onCompositionStart=function(a){this.renderer.showComposition(this.getCursorPosition())},this.onCompositionUpdate=function(a){this.renderer.setCompositionText(a)},this.onCompositionEnd=function(){this.renderer.hideComposition()},this.getFirstVisibleRow=function(){return this.renderer.getFirstVisibleRow()},this.getLastVisibleRow=function(){return this.renderer.getLastVisibleRow()},this.isRowVisible=function(a){return a>=this.getFirstVisibleRow()&&a<=this.getLastVisibleRow()},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.gotoLine=function(a,b){this.selection.clearSelection(),this.$blockScrolling+=1,this.moveCursorTo(a-1,b||0),this.$blockScrolling-=1,this.isRowVisible(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()){a=a||1;while(a--)this.selection.moveCursorLeft()}else{var b=this.getSelectionRange().start;this.moveCursorToPosition(b)}this.clearSelection()},this.navigateRight=function(a){if(this.selection.isEmpty()){a=a||1;while(a--)this.selection.moveCursorRight()}else{var b=this.getSelectionRange().end;this.moveCursorToPosition(b)}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);this.$tryReplace(c,a),c!==null&&this.selection.setSelectionRange(c)},this.replaceAll=function(a,b){b&&this.$search.set(b);var c=this.$search.findAll(this.session);if(c.length){var d=this.getSelectionRange();this.clearSelection(),this.selection.moveCursorTo(0,0),this.$blockScrolling+=1;for(var e=c.length-1;e>=0;--e)this.$tryReplace(c[e],a);this.selection.setSelectionRange(d),this.$blockScrolling-=1}},this.$tryReplace=function(a,b){var c=this.session.getTextRange(a),b=this.$search.replace(c,b);if(b!==null){a.end=this.session.replace(a,b);return a}return 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);b&&(this.gotoLine(b.end.row+1,b.end.column),this.selection.setSelectionRange(b))},this.undo=function(){this.session.getUndoManager().undo()},this.redo=function(){this.session.getUndoManager().redo()}}).call(p.prototype),b.Editor=p}),define("pilot/event",["require","exports","module","pilot/keys","pilot/useragent","pilot/dom"],function(a,b,c){function g(a,b,c){var f=0;e.isOpera&&e.isMac?f=0|(b.metaKey?1:0)|(b.altKey?2:0)|(b.shiftKey?4:0)|(b.ctrlKey?8:0):f=0|(b.ctrlKey?1:0)|(b.altKey?2:0)|(b.shiftKey?4:0)|(b.metaKey?8:0);if(c in d.MODIFIER_KEYS){switch(d.MODIFIER_KEYS[c]){case"Alt":f=2;break;case"Shift":f=4;break;case"Ctrl":f=1;break;default:f=8}c=0}f&8&&(c==91||c==93)&&(c=0);if(f==0&&!(c in d.FUNCTION_KEYS))return!1;return a(b,f,c)}var d=a("pilot/keys"),e=a("pilot/useragent"),f=a("pilot/dom");b.addListener=function(a,b,c){if(a.addEventListener)return a.addEventListener(b,c,!1);if(a.attachEvent){var d=function(){c(window.event)};c._wrapper=d,a.attachEvent("on"+b,d)}},b.removeListener=function(a,b,c){if(a.removeEventListener)return a.removeEventListener(b,c,!1);a.detachEvent&&a.detachEvent("on"+b,c._wrapper||c)},b.stopEvent=function(a){b.stopPropagation(a),b.preventDefault(a);return!1},b.stopPropagation=function(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0},b.preventDefault=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1},b.getDocumentX=function(a){return a.clientX?a.clientX+f.getPageScrollLeft():a.pageX},b.getDocumentY=function(a){return a.clientY?a.clientY+f.getPageScrollTop():a.pageY},b.getButton=function(a){if(a.type=="dblclick")return 0;if(a.type=="contextmenu")return 2;return a.preventDefault?a.button:({1:0,2:2,4:1})[a.button]},document.documentElement.setCapture?b.capture=function(a,c,d){function f(e){c&&c(e),d&&d(),b.removeListener(a,"mousemove",c),b.removeListener(a,"mouseup",f),b.removeListener(a,"losecapture",f),a.releaseCapture()}function e(a){c(a);return b.stopPropagation(a)}b.addListener(a,"mousemove",c),b.addListener(a,"mouseup",f),b.addListener(a,"losecapture",f),a.setCapture()}:b.capture=function(a,b,c){function e(a){b&&b(a),c&&c(),document.removeEventListener("mousemove",d,!0),document.removeEventListener("mouseup",e,!0),a.stopPropagation()}function d(a){b(a),a.stopPropagation()}document.addEventListener("mousemove",d,!0),document.addEventListener("mouseup",e,!0)},b.addMouseWheelListener=function(a,c){var d=function(a){a.wheelDelta!==undefined?a.wheelDeltaX!==undefined?(a.wheelX=-a.wheelDeltaX/8,a.wheelY=-a.wheelDeltaY/8):(a.wheelX=0,a.wheelY=-a.wheelDelta/8):a.axis&&a.axis==a.HORIZONTAL_AXIS?(a.wheelX=(a.detail||0)*5,a.wheelY=0):(a.wheelX=0,a.wheelY=(a.detail||0)*5),c(a)};b.addListener(a,"DOMMouseScroll",d),b.addListener(a,"mousewheel",d)},b.addMultiMouseDownListener=function(a,c,d,f,g){var h=0,i,j,k=function(a){h+=1,h==1&&(i=a.clientX,j=a.clientY,setTimeout(function(){h=0},f||600));if(b.getButton(a)!=c||Math.abs(a.clientX-i)>5||Math.abs(a.clientY-j)>5)h=0;h==d&&(h=0,g(a));return b.preventDefault(a)};b.addListener(a,"mousedown",k),e.isIE&&b.addListener(a,"dblclick",k)},b.addCommandKeyListener=function(a,c){var d=b.addListener;if(e.isOldGecko){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){h=a.keyIdentifier||a.keyCode;return g(c,a,a.keyCode)}),e.isMac&&e.isOpera&&d(a,"keypress",function(a){var b=a.keyIdentifier||a.keyCode;if(h!==b)return g(c,a,a.keyCode);h=null})}}}),define("pilot/keys",["require","exports","module","pilot/oop"],function(a,b,c){var d=a("pilot/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",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(i in a.FUNCTION_KEYS){var b=a.FUNCTION_KEYS[i].toUpperCase();a[b]=parseInt(i,10)}d.mixin(a,a.MODIFIER_KEYS),d.mixin(a,a.PRINTABLE_KEYS),d.mixin(a,a.FUNCTION_KEYS);return a}();d.mixin(b,e)}),define("pilot/dom",["require","exports","module"],function(a,b,c){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)},document.documentElement.classList?(b.hasCssClass=function(a,b){return a.classList.contains(b)},b.addCssClass=function(a,b){a.classList.add(b)},b.removeCssClass=function(a,b){a.classList.remove(b)},b.toggleCssClass=function(a,b){return a.classList.toggle(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);while(!0){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;while(!0){var e=c.indexOf(b);if(e==-1)break;d=!1,c.splice(e,1)}d&&c.push(b),a.className=c.join(" ");return d}),b.setCssClass=function(a,c,d){d?b.addCssClass(a,c):b.removeCssClass(a,c)},b.importCssString=function(a,b){b=b||document;if(b.createStyleSheet){var c=b.createStyleSheet();c.cssText=a}else{var e=b.createElementNS?b.createElementNS(d,"style"):b.createElement("style");e.appendChild(b.createTextNode(a));var f=b.getElementsByTagName("head")[0]||b.documentElement;f.appendChild(e)}},b.getInnerWidth=function(a){return parseInt(b.computedStyle(a,"paddingLeft"))+parseInt(b.computedStyle(a,"paddingRight"))+a.clientWidth},b.getInnerHeight=function(a){return parseInt(b.computedStyle(a,"paddingTop"))+parseInt(b.computedStyle(a,"paddingBottom"))+a.clientHeight},window.pageYOffset!==undefined?(b.getPageScrollTop=function(){return window.pageYOffset},b.getPageScrollLeft=function(){return window.pageXOffset}):(b.getPageScrollTop=function(){return document.body.scrollTop},b.getPageScrollLeft=function(){return document.body.scrollLeft}),b.computedStyle=function(a,b){return window.getComputedStyle?(window.getComputedStyle(a,"")||{})[b]||"":a.currentStyle[b]},b.scrollbarWidth=function(){var a=b.createElement("p");a.style.width="100%",a.style.height="200px";var c=b.createElement("div"),d=c.style;d.position="absolute",d.left="-10000px",d.overflow="hidden",d.width="200px",d.height="150px",c.appendChild(a);var e=document.body||document.documentElement;e.appendChild(c);var f=a.offsetWidth;d.overflow="scroll";var g=a.offsetWidth;f==g&&(g=c.clientWidth),e.removeChild(c);return f-g},b.setInnerHtml=function(a,b){var c=a.cloneNode(!1);c.innerHTML=b,a.parentNode.replaceChild(c,a);return c},b.setInnerText=function(a,b){document.body&&"textContent"in document.body?a.textContent=b:a.innerText=b},b.getInnerText=function(a){return document.body&&"textContent"in document.body?a.textContent:a.innerText||a.textContent},b.getParentWindow=function(a){return a.defaultView||a.parentWindow},b.getSelectionStart=function(a){var b;try{b=a.selectionStart||0}catch(c){b=0}return b},b.setSelectionStart=function(a,b){return a.selectionStart=b},b.getSelectionEnd=function(a){var b;try{b=a.selectionEnd||0}catch(c){b=0}return b},b.setSelectionEnd=function(a,b){return a.selectionEnd=b}}),define("ace/keyboard/textinput",["require","exports","module","pilot/event","pilot/useragent","pilot/dom"],function(a,b,c){var d=a("pilot/event"),e=a("pilot/useragent"),f=a("pilot/dom"),g=function(a,b){function k(a){if(!i){var d=a||c.value;d&&(d.charCodeAt(d.length-1)==g.charCodeAt(0)?(d=d.slice(0,-1),d&&b.onTextInput(d)):b.onTextInput(d))}i=!1,c.value=g,c.select()}var c=f.createElement("textarea");c.style.left="-10000px",a.appendChild(c);var g=String.fromCharCode(0);k();var h=!1,i=!1,j="",l=function(a){(!e.isIE||c.value.charCodeAt(0)<=128)&&setTimeout(function(){h||k()},0)},m=function(a){h=!0,e.isIE||(k(),c.value=""),b.onCompositionStart(),e.isGecko||setTimeout(n,0)},n=function(){h&&b.onCompositionUpdate(c.value)},o=function(){h=!1,b.onCompositionEnd(),setTimeout(function(){k()},0)},p=function(a){i=!0;var d=b.getCopyText();d?c.value=d:a.preventDefault(),c.select(),setTimeout(function(){k()},0)},q=function(a){i=!0;var d=b.getCopyText();d?(c.value=d,b.onCut()):a.preventDefault(),c.select(),setTimeout(function(){k()},0)};d.addCommandKeyListener(c,b.onCommandKey.bind(b)),d.addListener(c,"keypress",l);if(e.isIE){var r={13:1,27:1};d.addListener(c,"keyup",function(a){h&&(!c.value||r[a.keyCode])&&setTimeout(o,0);(c.value.charCodeAt(0)|0)>=129&&(h?n():m())})}d.addListener(c,"textInput",l),d.addListener(c,"paste",function(a){a.clipboardData&&a.clipboardData.getData?(k(a.clipboardData.getData("text/plain")),a.preventDefault()):l()}),e.isIE||d.addListener(c,"propertychange",l),e.isIE?(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",p),d.addListener(c,"cut",q)),d.addListener(c,"compositionstart",m),e.isGecko&&d.addListener(c,"text",n),e.isWebKit&&d.addListener(c,"keyup",n),d.addListener(c,"compositionend",o),d.addListener(c,"blur",function(){b.onBlur()}),d.addListener(c,"focus",function(){b.onFocus(),c.select()}),this.focus=function(){b.onFocus(),c.select(),c.focus()},this.blur=function(){c.blur()},this.getElement=function(){return c},this.onContextMenu=function(a,b){a&&(j||(j=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(){j&&(c.style.cssText=j,j=""),k()},0)}};b.TextInput=g}),define("ace/mouse_handler",["require","exports","module","pilot/event","pilot/dom"],function(a,b,c){var d=a("pilot/event"),e=a("pilot/dom"),f=0,g=1,h=2,i=250,j=5,k=function(a){this.editor=a,d.addListener(a.container,"mousedown",function(b){a.focus();return d.preventDefault(b)}),d.addListener(a.container,"selectstart",function(a){return d.preventDefault(a)});var b=a.renderer.getMouseEventTarget();d.addListener(b,"mousedown",this.onMouseDown.bind(this)),d.addMultiMouseDownListener(b,0,2,500,this.onMouseDoubleClick.bind(this)),d.addMultiMouseDownListener(b,0,3,600,this.onMouseTripleClick.bind(this)),d.addMultiMouseDownListener(b,0,4,600,this.onMouseQuadClick.bind(this)),d.addMouseWheelListener(b,this.onMouseWheel.bind(this))};(function(){this.$scrollSpeed=1,this.setScrollSpeed=function(a){this.$scrollSpeed=a},this.getScrollSpeed=function(){return this.$scrollSpeed},this.$getEventPosition=function(a){var b=d.getDocumentX(a),c=d.getDocumentY(a),e=this.editor.renderer.screenToTextCoordinates(b,c);e.row=Math.max(0,Math.min(e.row,this.editor.session.getLength()-1));return e},this.$distance=function(a,b,c,d){return Math.sqrt(Math.pow(c-a,2)+Math.pow(d-b,2))},this.onMouseDown=function(a){function B(b){a.shiftKey?l.selection.selectToPosition(b):m.$clickSelection||(l.moveCursorToPosition(b),l.selection.clearSelection(b.row,b.column)),p=g}var b=d.getDocumentX(a),c=d.getDocumentY(a),k=this.$getEventPosition(a),l=this.editor,m=this,n=l.getSelectionRange(),o=n.isEmpty(),p=f,q=!1,r=d.getButton(a);if(r!=0)o&&l.moveCursorToPosition(k),r==2&&(l.textInput.onContextMenu({x:b,y:c},o),d.capture(l.container,function(){},l.textInput.onContextMenuClose));else{q=!l.getReadOnly()&&!o&&n.contains(k.row,k.column),q||B(k),l.renderer.scrollCursorIntoView();var s,t,u=l.getOverwrite(),v=null,w=(new Date).getTime(),x=function(a){s=d.getDocumentX(a),t=d.getDocumentY(a)},y=function(){clearInterval(E),p==f?B(k):p==h&&z(),m.$clickSelection=null,p=f},z=function(){e.removeCssClass(l.container,"ace_dragging"),m.$clickSelection||(v||(l.moveCursorToPosition(k),l.selection.clearSelection(k.row,k.column)));if(v){var a=l.getSelectionRange();if(a.contains(v.row,v.column)){v=null;return}l.clearSelection();var b=l.moveText(a,v);if(!b){v=null;return}l.selection.setSelectionRange(b)}},A=function(){if(s!==undefined&&t!==undefined){if(p==f){var a=m.$distance(b,c,s,t),d=(new Date).getTime();if(a>j){p=g;var k=l.renderer.screenToTextCoordinates(s,t);k.row=Math.max(0,Math.min(k.row,l.session.getLength()-1)),B(k)}else d-w>i&&(p=h,e.addCssClass(l.container,"ace_dragging"))}p==h?D():p==g&&C()}},C=function(){var a=l.renderer.screenToTextCoordinates(s,t);a.row=Math.max(0,Math.min(a.row,l.session.getLength()-1));if(m.$clickSelection)if(m.$clickSelection.contains(a.row,a.column))l.selection.setSelectionRange(m.$clickSelection);else{if(m.$clickSelection.compare(a.row,a.column)==-1)var b=m.$clickSelection.end;else var b=m.$clickSelection.start;l.selection.setSelectionAnchor(b.row,b.column),l.selection.selectToPosition(a)}else l.selection.selectToPosition(a);l.renderer.scrollCursorIntoView()},D=function(){v=l.renderer.screenToTextCoordinates(s,t),v.row=Math.max(0,Math.min(v.row,l.session.getLength()-1)),l.renderer.updateCursor(v,u),l.renderer.scrollCursorIntoView()};d.capture(l.container,x,y);var E=setInterval(A,20);return d.preventDefault(a)}},this.onMouseDoubleClick=function(a){var b=this.$getEventPosition(a);this.editor.moveCursorToPosition(b),this.editor.selection.selectWord(),this.$clickSelection=this.editor.getSelectionRange()},this.onMouseTripleClick=function(a){var b=this.$getEventPosition(a);this.editor.moveCursorToPosition(b),this.editor.selection.selectLine(),this.$clickSelection=this.editor.getSelectionRange()},this.onMouseQuadClick=function(a){this.editor.selectAll(),this.$clickSelection=this.editor.getSelectionRange()},this.onMouseWheel=function(a){var b=this.$scrollSpeed*2;this.editor.renderer.scrollBy(a.wheelX*b,a.wheelY*b);return d.preventDefault(a)}}).call(k.prototype),b.MouseHandler=k}),define("ace/keyboard/keybinding",["require","exports","module","pilot/useragent","pilot/keys","pilot/event","pilot/settings","ace/keyboard/hash_handler","ace/keyboard/keybinding/default_mac","ace/keyboard/keybinding/default_win","pilot/canon","ace/commands/default_commands"],function(a,b,c){var d=a("pilot/useragent"),e=a("pilot/keys"),f=a("pilot/event"),g=a("pilot/settings").settings,h=a("ace/keyboard/hash_handler").HashHandler,i=a("ace/keyboard/keybinding/default_mac").bindings,j=a("ace/keyboard/keybinding/default_win").bindings,k=a("pilot/canon");a("ace/commands/default_commands");var l=function(a,b){this.$editor=a,this.$data={},this.$keyboardHandler=null,this.$defaulKeyboardHandler=new h(b||(d.isMac?i:j))};(function(){this.setKeyboardHandler=function(a){this.$keyboardHandler!=a&&(this.$data={},this.$keyboardHandler=a)},this.getKeyboardHandler=function(){return this.$keyboardHandler},this.$callKeyboardHandler=function(a,b,c,d){var e;this.$keyboardHandler&&(e=this.$keyboardHandler.handleKeyboard(this.$data,b,c,d,a));if(!e||!e.command)e=this.$defaulKeyboardHandler.handleKeyboard(this.$data,b,c,d,a);if(e){var g=k.exec(e.command,{editor:this.$editor},e.args);if(g)return f.stopEvent(a)}},this.onCommandKey=function(a,b,c){key=(e[c]||String.fromCharCode(c)).toLowerCase(),this.$callKeyboardHandler(a,b,key,c)},this.onTextInput=function(a){this.$callKeyboardHandler({},0,a,0)}}).call(l.prototype),b.KeyBinding=l}),define("ace/keyboard/hash_handler",["require","exports","module","pilot/keys"],function(a,b,c){function e(a){this.setConfig(a)}var d=a("pilot/keys");(function(){function c(a,c){var d,e,f,g,h={};for(d in a){g=a[d];if(c&&typeof g=="string"){g=g.split(c);for(e=0,f=g.length;e0&&a.execute({action:"aceupdate",args:[b.$deltas,b]}),b.$deltas=[]})}},this.$defaultUndoManager={undo:function(){},redo:function(){},reset:function(){}},this.getUndoManager=function(){return this.$undoManager||this.$defaultUndoManager},this.getTabString=function(){return this.getUseSoftTabs()?e.stringRepeat(" ",this.getTabSize()):"\t"},this.$useSoftTabs=!0,this.setUseSoftTabs=function(a){this.$useSoftTabs!==a&&(this.$useSoftTabs=a)},this.getUseSoftTabs=function(){return this.$useSoftTabs},this.$tabSize=4,this.setTabSize=function(a){!isNaN(a)&&this.$tabSize!==a&&(this.$modified=!0,this.$tabSize=a,this._dispatchEvent("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){this.$overwrite!=a&&(this.$overwrite=a,this._dispatchEvent("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=0){var h=g.charAt(d);if(h==c){f-=1;if(f==0)return{row:e,column:d}}else h==a&&(f+=1);d-=1}e-=1;if(e<0)break;var g=this.getLine(e),d=g.length-1}return null},this.$findClosingBracket=function(a,b){var c=this.$brackets[a],d=b.column,e=b.row,f=1,g=this.getLine(e),h=this.getLength();while(!0){while(d=h)break;var g=this.getLine(e),d=0}return null},this.insert=function(a,b){return this.doc.insert(a,b)},this.remove=function(a){return this.doc.remove(a)},this.undoChanges=function(a){a.length&&(this.$fromUndo=!0,this.doc.revertDeltas(a),this.$fromUndo=!1,this.$setUndoSelection(a,!0))},this.redoChanges=function(a){a.length&&(this.$fromUndo=!0,this.doc.applyDeltas(a),this.$fromUndo=!1,this.$setUndoSelection(a,!1))},this.$setUndoSelection=function(a,b){b&&(a=a.map(function(a){var b={range:a.range};a.action=="insertText"||a.action=="insertLines"?b.action="removeText":b.action="insertText";return b}).reverse());var c=[{}];for(var d=0;d=this.doc.getLength()-1)return 0;var c=this.doc.removeLines(a,b);this.doc.insertLines(a+1,c);return 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.$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;if(a){var b=this.getLength();this.$wrapData=[];for(i=0;i0){this.$wrapLimit=b,this.$modified=!0,this.$useWrapMode&&(this.$updateWrapData(0,this.getLength()-1),this._dispatchEvent("changeWrapLimit"));return!0}return!1},this.$constrainWrapLimit=function(a){var b=this.$wrapLimitRange.min;b&&(a=Math.max(b,a));var c=this.$wrapLimitRange.max;c&&(a=Math.min(c,a));return Math.max(1,a)},this.getWrapLimit=function(){return this.$wrapLimit},this.getWrapLimitRange=function(){return{min:this.$wrapLimitRange.min,max:this.$wrapLimitRange.max}},this.$updateWrapDataOnChange=function(a){if(this.$useWrapMode){var b,c=a.data.action,d=a.data.range.start.row,e=a.data.range.end.row;c.indexOf("Lines")!=-1?(c=="insertLines"?e=d+a.data.lines.length:e=d,b=a.data.lines.length):b=e-d;if(b!=0)if(c.indexOf("remove")!=-1)this.$wrapData.splice(d,b),e=d;else{var f=[d,0];for(var g=0;gb){var k=h+b;if(e[k]=g){k++;break}k>h?j(k):j(h+b)}else{while(e[k]>=g)k++;j(k)}}return d},this.$getDisplayTokens=function(a){var d=[],e=this.getTabSize();for(var f=0;f=12352&&h<=12447||h>=12448&&h<=12543||h>=19968&&h<=40959||h>=63744&&h<=64255||h>=13312&&h<=19903?d.push(b,c):d.push(b)}return d},this.$getStringScreenWidth=function(a){var b=0,c=this.getTabSize();for(var d=0;d=12352&&e<=12447||e>=12448&&e<=12543||e>=19968&&e<=40959||e>=63744&&e<=64255||e>=13312&&e<=19903?b+=2:b+=1}return b},this.getRowHeight=function(a,b){var c;this.$useWrapMode&&this.$wrapData[b]?c=this.$wrapData[b].length+1:c=1;return c*a.lineHeight},this.getScreenLastRowColumn=function(a,b){if(!this.$useWrapMode)return this.$getStringScreenWidth(this.getLine(a));var c=this.$screenToDocumentRow(a),d=c[0],e=c[1],f,g;this.$wrapData[d][e]?(f=this.$wrapData[d][e-1]||0,g=this.$wrapData[d][e],b&&g--):(g=this.getLine(d).length,f=this.$wrapData[d][e-1]||0);return b?g:this.$getStringScreenWidth(this.getLine(d).substring(f,g))},this.getDocumentLastRowColumn=function(a,b){if(!this.$useWrapMode)return this.getLine(a).length;var c=this.documentToScreenRow(a,b);return this.getScreenLastRowColumn(c,!0)},this.getScreenFirstRowColumn=function(a){if(!this.$useWrapMode)return 0;var b=this.$screenToDocumentRow(a),c=b[0],d=b[1];return this.$wrapData[c][d-1]||0},this.getRowSplitData=function(a){return this.$useWrapMode?this.$wrapData[a]:undefined},this.$screenToDocumentRow=function(a){if(!this.$useWrapMode)return[a,0];var b=this.$wrapData,c=this.getLength(),d=0;while(d=b[d].length+1)a-=b[d].length+1,d++;return[d,a]},this.screenToDocumentRow=function(a){return this.$screenToDocumentRow(a)[0]},this.screenToDocumentColumn=function(a,b){return this.screenToDocumentPosition(a,b).column},this.screenToDocumentPosition=function(a,b){var c,d,e,f=b,g=this.getLength();if(this.$useWrapMode){var h=this.$wrapData,d=0;while(d=h[d].length+1)a-=h[d].length+1,d++;d>=g&&(d=g-1,a=h[d].length),e=h[d][a-1]||0,c=this.getLine(d).substring(e)}else d=a>=g?g-1:a<0?0:a,a=0,e=0,c=this.getLine(d);var i=this.getTabSize();for(var j=0;j0)e+=1,k==9?f=12352&&k<=12447||k>=12448&&k<=12543||k>=19968&&k<=40959||k>=63744&&k<=64255||k>=13312&&k<=19903?f<2?(f=0,e-=1):f-=2:f-=1;else break}this.$useWrapMode?(b=h[d][a],e>=b&&(e=b-1)):c&&(e=Math.min(e,c.length));return{row:d,column:e}},this.documentToScreenColumn=function(a,b){return this.documentToScreenPosition(a,b).column},this.$documentToScreenRow=function(a,b){if(!this.$useWrapMode)return[a,0];var c=this.$wrapData,d=0;if(a>c.length-1)return[this.getScreenLength(),c.length==0?0:c[c.length-1].length-1];for(var e=0;e=c[a][f])d++,f++;return[d,f]},this.documentToScreenRow=function(a,b){return this.$documentToScreenRow(a,b)[0]},this.documentToScreenPosition=function(a,b){var c,d=this.getTabSize(),e;b!=null?e=a:(e=a.row,b=a.column);if(!this.$useWrapMode){c=this.getLine(e).substring(0,b),b=this.$getStringScreenWidth(c);return{row:e,column:b}}var f=this.$documentToScreenRow(e,b),g=f[0];if(e>=this.getLength())return{row:g,column:0};var h,i=this.$wrapData[e],j,k=f[1];c=this.getLine(e).substring(i[k-1]||0,b),j=this.$getStringScreenWidth(c);return{row:g,column:j}},this.getScreenLength=function(){if(!this.$useWrapMode)return this.getLength();var a=0;for(var b=0;bb.row||a.row==b.row&&a.column>b.column},this.getRange=function(){var a=this.selectionAnchor,b=this.selectionLead;if(this.isEmpty())return g.fromPoints(b,b);return this.isBackwards()?g.fromPoints(b,a):g.fromPoints(a,b)},this.clearSelection=function(){this.$isEmpty||(this.$isEmpty=!0,this._dispatchEvent("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.$updateDesiredColumn()},this.$updateDesiredColumn=function(){var a=this.getCursor();this.$desiredColumn=this.session.documentToScreenColumn(a.row,a.column)},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.selectLine=function(){this.setSelectionAnchor(this.selectionLead.row,0),this.$moveSelection(function(){this.moveCursorTo(this.selectionLead.row+1,0)})},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.moveCursorLeft=function(){var a=this.selectionLead.getPosition();if(a.column==0)a.row>0&&this.moveCursorTo(a.row-1,this.doc.getLine(a.row-1).length);else{var b=this.session.getTabSize();this.session.isTabStop(a)&&this.doc.getLine(a.row).slice(a.column-b,a.column).split(" ").length-1==b?this.moveCursorBy(0,-b):this.moveCursorBy(0,-1)}},this.moveCursorRight=function(){if(this.selectionLead.column==this.doc.getLine(this.selectionLead.row).length)this.selectionLead.row ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(a,b){return this.compare(a,b)==0},this.compare=function(a,b){if(!this.isMultiLine())if(a===this.start.row)return bthis.end.column?1:0;if(athis.end.row)return 1;if(this.start.row===a)return b>=this.start.column?0:-1;if(this.end.row===a)return b<=this.end.column?0:1;return 0},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");b.$selectionOccurrences.push(c)}}),a.$search.set(k)}},this.clearSelectionHighlight=function(a){a.session.$selectionOccurrences&&(a.session.$selectionOccurrences.forEach(function(b){a.session.removeMarker(b)}),a.session.$selectionOccurrences=[])}}).call(f.prototype),b.Mode=f}),define("ace/tokenizer",["require","exports","module"],function(a,b,c){var d=function(a){this.rules=a,this.regExps={};for(var b in this.rules){var c=this.rules[b],d=c,e=[];for(var f=0;f=b&&(a.row=Math.max(0,b-1),a.column=this.getLine(b-1).length);return a},this.insert=function(a,b){if(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];a=this.insertInLine(a,d),e!==null&&(a=this.insertNewLine(a),a=this.insertLines(a.row,c),a=this.insertInLine(a,e||""));return 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};this._dispatchEvent("change",{data:e});return 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()};this._dispatchEvent("change",{data:d});return 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};this._dispatchEvent("change",{data:e});return 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){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};this._dispatchEvent("change",{data:i});return 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};this._dispatchEvent("change",{data:e});return 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._dispatchEvent("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","pilot/oop","pilot/event_emitter"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/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){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&&c.start.rowd?(d=c.start.row,e=0):d-=c.end.row-c.start.row)),this.setPosition(d,e,!0)}},this.setPosition=function(a,b,c){c?pos={row:a,column:b}:pos=this.$clipPositionToDocument(a,b);if(this.row!=pos.row||this.column!=pos.column){var d={row:this.row,column:this.column};this.row=pos.row,this.column=pos.column,this._dispatchEvent("change",{old:d,value:pos})}},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.$clipPositionToDocument=function(a,b){var c={};a=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);b&&e==c.end.row&&(f=f.substring(0,c.end.column)),j&&e==d.row&&(f=f.substring(0,d.column));return f}var b=this.$options.scope==g.SELECTION,c=a.getSelection().getRange(),d=a.getSelection().getCursor(),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)b=e,g=f,j=!0;else return;b==d.row&&(l=!0),c=k(b)}}}},this.$backwardLineIterator=function(a){var b=this.$options.scope==g.SELECTION,c=a.getSelection().getRange(),d=b?c.end:c.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(j20){c.fireUpdateEvent(d,c.currentLine-1);var i=c.currentLine0&&this.lines[a-1]&&(d=this.lines[a-1].state,e=!0);var f=this.doc.getLines(a,b);for(var g=a;g<=b;g++)if(this.lines[g]){var h=this.lines[g];d=h.state,c.push(h)}else{var h=this.tokenizer.getLineTokens(f[g-a]||"",d),d=h.state;c.push(h),e&&(this.lines[g]=h)}return c}}).call(f.prototype),b.BackgroundTokenizer=f}),define("ace/undomanager",["require","exports","module"],function(a,b,c){var d=function(){this.reset()};(function(){this.execute=function(a){var b=a.args[0];this.$doc=a.args[1],this.$undoStack.push(b)},this.undo=function(){var a=this.$undoStack.pop();a&&(this.$doc.undoChanges(a),this.$redoStack.push(a))},this.redo=function(){var a=this.$redoStack.pop();a&&(this.$doc.redoChanges(a),this.$undoStack.push(a))},this.reset=function(){this.$undoStack=[],this.$redoStack=[]},this.hasUndo=function(){return this.$undoStack.length>0},this.hasRedo=function(){return this.$redoStack.length>0}}).call(d.prototype),b.UndoManager=d}),define("ace/theme/textmate",["require","exports","module","pilot/dom"],function(a,b,c){var d=a("pilot/dom"),e=".ace-tm .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-tm .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-tm .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-tm .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-tm .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-tm .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-tm .ace_text-layer {\n cursor: text;\n}\n\n.ace-tm .ace_cursor {\n border-left: 2px solid black;\n}\n\n.ace-tm .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid black;\n}\n \n.ace-tm .ace_line .ace_invisible {\n color: rgb(191, 191, 191);\n}\n\n.ace-tm .ace_line .ace_keyword {\n color: blue;\n}\n\n.ace-tm .ace_line .ace_constant.ace_buildin {\n color: rgb(88, 72, 246);\n}\n\n.ace-tm .ace_line .ace_constant.ace_language {\n color: rgb(88, 92, 246);\n}\n\n.ace-tm .ace_line .ace_constant.ace_library {\n color: rgb(6, 150, 14);\n}\n\n.ace-tm .ace_line .ace_invalid {\n background-color: rgb(153, 0, 0);\n color: white;\n}\n\n.ace-tm .ace_line .ace_support.ace_function {\n color: rgb(60, 76, 114);\n}\n\n.ace-tm .ace_line .ace_support.ace_constant {\n color: rgb(6, 150, 14);\n}\n\n.ace-tm .ace_line .ace_support.ace_type,\n.ace-tm .ace_line .ace_support.ace_class {\n color: rgb(109, 121, 222);\n}\n\n.ace-tm .ace_line .ace_keyword.ace_operator {\n color: rgb(104, 118, 135);\n}\n\n.ace-tm .ace_line .ace_string {\n color: rgb(3, 106, 7);\n}\n\n.ace-tm .ace_line .ace_comment {\n color: rgb(76, 136, 107);\n}\n\n.ace-tm .ace_line .ace_comment.ace_doc {\n color: rgb(0, 102, 255);\n}\n\n.ace-tm .ace_line .ace_comment.ace_doc.ace_tag {\n color: rgb(128, 159, 191);\n}\n\n.ace-tm .ace_line .ace_constant.ace_numeric {\n color: rgb(0, 0, 205);\n}\n\n.ace-tm .ace_line .ace_variable {\n color: rgb(49, 132, 149);\n}\n\n.ace-tm .ace_line .ace_xml_pe {\n color: rgb(104, 104, 91);\n}\n\n.ace-tm .ace_marker-layer .ace_selection {\n background: rgb(181, 213, 255);\n}\n\n.ace-tm .ace_marker-layer .ace_step {\n background: rgb(252, 255, 0);\n}\n\n.ace-tm .ace_marker-layer .ace_stack {\n background: rgb(164, 229, 101);\n}\n\n.ace-tm .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-tm .ace_marker-layer .ace_active_line {\n background: rgb(232, 242, 254);\n}\n\n.ace-tm .ace_marker-layer .ace_selected_word {\n background: rgb(250, 250, 255);\n border: 1px solid rgb(200, 200, 250);\n}\n\n.ace-tm .ace_string.ace_regex {\n color: rgb(255, 0, 0)\n}";d.importCssString(e),b.cssClass="ace-tm"}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(a,b,c){var d=a("ace/range").Range,e=function(){};(function(){this.checkOutdent=function(a,b){if(!/^\s+$/.test(a))return!1;return/^\s*\}/.test(b)},this.autoOutdent=function(a,b){var c=a.getLine(b),e=c.match(/^(\s*\})/);if(!e)return 0;var f=e[1].length,g=a.findMatchingBracket({row:b,column:f});if(!g||g.row==b)return 0;var h=this.$getIndent(a.getLine(g.row));a.replace(new d(b,0,b,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);if(b)return b[1];return""}}).call(e.prototype),b.MatchingBraceOutdent=e}),define("ace/virtual_renderer",["require","exports","module","pilot/oop","pilot/dom","pilot/event","pilot/useragent","ace/layer/gutter","ace/layer/marker","ace/layer/text","ace/layer/cursor","ace/scrollbar","ace/renderloop","pilot/event_emitter","text!ace/css/editor.css"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/dom"),f=a("pilot/event"),g=a("pilot/useragent"),h=a("ace/layer/gutter").Gutter,i=a("ace/layer/marker").Marker,j=a("ace/layer/text").Text,k=a("ace/layer/cursor").Cursor,l=a("ace/scrollbar").ScrollBar,m=a("ace/renderloop").RenderLoop,n=a("pilot/event_emitter").EventEmitter,o=a("text!ace/css/editor.css");e.importCssString(o);var p=function(a,b){this.container=a,e.addCssClass(this.container,"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 h(this.$gutter),this.$markerBack=new i(this.content);var c=this.$textLayer=new j(this.content);this.canvas=c.element,this.$markerFront=new i(this.content),this.characterWidth=c.getCharacterWidth(),this.lineHeight=c.getLineHeight(),this.$cursorLayer=new k(this.content),this.$cursorPadding=8,this.$horizScroll=!0,this.$horizScrollAlwaysVisible=!0,this.scrollBar=new l(a),this.scrollBar.addEventListener("scroll",this.onScroll.bind(this)),this.scrollTop=0,this.cursorPos={row:0,column:0};var d=this;this.$textLayer.addEventListener("changeCharaterSize",function(){d.characterWidth=c.getCharacterWidth(),d.lineHeight=c.getLineHeight(),d.$updatePrintMargin(),d.onResize(!0),d.$loop.schedule(d.CHANGE_FULL)}),f.addListener(this.$gutter,"click",this.$onGutterClick.bind(this)),f.addListener(this.$gutter,"dblclick",this.$onGutterClick.bind(this)),this.$size={width:0,height:0,scrollerHeight:0,scrollerWidth:0},this.$loop=new m(this.$renderChanges.bind(this)),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,d.implement(this,n),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&&this.scrollToY(c),this.getScrollTop()+this.$size.scrollerHeightb&&this.scrollToX(b),this.scroller.scrollLeft+this.$size.scrollerWidththis.scroller.scrollWidth&&this.$renderChanges(this.CHANGE_SIZE),this.scrollToX(Math.round(b+this.characterWidth-this.$size.scrollerWidth)))}},this.getScrollTop=function(){return this.scrollTop},this.getScrollLeft=function(){return this.scroller.scrollLeft},this.getScrollTopRow=function(){return this.scrollTop/this.lineHeight},this.getScrollBottomRow=function(){return Math.max(0,Math.floor((this.scrollTop+this.$size.scrollerHeight)/this.lineHeight)-1)},this.scrollToRow=function(a){this.scrollToY(a*this.lineHeight)},this.scrollToLine=function(a,b){var c={lineHeight:this.lineHeight},d=0;for(var e=1;e",c+1,"")}this.element=d.setInnerHtml(this.element,b.join("")),this.element.style.height=a.minHeight+"px"}}).call(e.prototype),b.Gutter=e}),define("ace/layer/marker",["require","exports","module","ace/range","pilot/dom"],function(a,b,c){var d=a("ace/range").Range,e=a("pilot/dom"),f=function(a){this.element=e.createElement("div"),this.element.className="ace_layer ace_marker-layer",a.appendChild(this.element)};(function(){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){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(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):this.drawSingleLineMarker(b,f,d.clazz,a)}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,e,1);var f=b.end.row,g=new d(f,0,f,b.end.column);this.drawSingleLineMarker(a,g,c,e);for(var f=b.start.row+1;f");var g=this.$getTop(b.end.row,d),f=Math.round(b.end.column*d.characterWidth);a.push("
");var e=(b.end.row-b.start.row-1)*d.lineHeight;if(e>=0){var g=this.$getTop(b.start.row+1,d);a.push("
")}},this.drawSingleLineMarker=function(a,b,c,d,e){var f=d.lineHeight,g=Math.round((b.end.column+(e||0)-b.start.column)*d.characterWidth),h=this.$getTop(b.start.row,d),i=Math.round(b.start.column*d.characterWidth);a.push("
")}}).call(f.prototype),b.Marker=f}),define("ace/layer/text",["require","exports","module","pilot/oop","pilot/dom","pilot/lang","pilot/event_emitter"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/dom"),f=a("pilot/lang"),g=a("pilot/event_emitter").EventEmitter,h=function(a){this.element=e.createElement("div"),this.element.className="ace_layer ace_text-layer",a.appendChild(this.element),this.$characterSize=this.$measureSizes(),this.$pollSizeChanges()};(function(){d.implement(this,g),this.EOF_CHAR="¶",this.EOL_CHAR="¬",this.TAB_CHAR="→",this.SPACE_CHAR="·",this.setTokenizer=function(a){this.tokenizer=a},this.getLineHeight=function(){return this.$characterSize.height||1},this.getCharacterWidth=function(){return this.$characterSize.width||1},this.$pollSizeChanges=function(){var a=this;setInterval(function(){var b=a.$measureSizes();if(a.$characterSize.width!==b.width||a.$characterSize.height!==b.height)a.$characterSize=b,a._dispatchEvent("changeCharaterSize",{data:b})},500)},this.$fontStyles={fontFamily:1,fontSize:1,fontWeight:1,fontStyle:1,lineHeight:1},this.$measureSizes=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="absolute",c.overflow="visible",c.whiteSpace="nowrap",b.innerHTML=f.stringRepeat("Xy",a);var d=this.element.parentNode;while(!e.hasCssClass(d,"ace_editor"))d=d.parentNode;d.appendChild(b)}var c=this.$measureNode.style;for(var g in this.$fontStyles){var h=e.computedStyle(this.element,g);c[g]=h}var i={height:this.$measureNode.offsetHeight,width:this.$measureNode.offsetWidth/(a*2)};return i},this.setSession=function(a){this.session=a},this.showInvisibles=!1,this.setShowInvisibles=function(a){if(this.showInvisibles==a)return!1;this.showInvisibles=a;return!0},this.$computeTabString=function(){var a=this.session.getTabSize();if(this.showInvisibles){var b=a/2;this.$tabString=""+Array(Math.floor(b)).join(" ")+this.TAB_CHAR+Array(Math.ceil(b)+1).join(" ")+""}else this.$tabString=Array(a+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=this.tokenizer.getTokens(d,f);for(var i=d;i<=f;i++){var j=g[i-a.firstRow];if(!j)continue;var k=[];this.$renderLine(k,i,h[i-d].tokens),j=e.setInnerHtml(j,k.join("")),j.style.height=this.session.getRowHeight(a,i)+"px"}},this.scrollLines=function(a){this.$computeTabString();var b=this.config;this.config=a;if(!b||b.lastRowa.lastRow)for(var d=a.lastRow+1;d<=b.lastRow;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=document.createDocumentFragment(),f=this.tokenizer.getTokens(b,c);for(var g=b;g<=c;g++){var h=e.createElement("div");h.className="ace_line";var i=h.style;i.height=this.session.getRowHeight(a,g)+"px",i.width=a.width+"px";var j=[];f.length>g-b&&this.$renderLine(j,g,f[g-b].tokens),h.innerHTML=j.join(""),d.appendChild(h)}return d},this.update=function(a){this.$computeTabString(),this.config=a;var b=[],c=this.tokenizer.getTokens(a.firstRow,a.lastRow),d=this.$renderLinesFragment(a,a.firstRow,a.lastRow);this.element.innerHTML="",this.element.appendChild(d)},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderLine=function(a,b,c){function i(b,c){var d=c.replace(/&/g,"&").replace(/"+a+""});if(g.$textToken[b.type])a.push(d);else{var i="ace_"+b.type.replace(/\./g," ace_");a.push("",d,"")}}if(this.showInvisibles)var d=this,e=/( +)|([\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000])/g,f=function(a){if(a.charCodeAt(0)==32)return Array(a.length+1).join(" ");var a=Array(a.length+1).join(d.SPACE_CHAR);return""+a+""};else var e=/[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/g,f=" ";var g=this,h=this.config.characterWidth,j=this.session.getRowSplitData(b),k=0,l=0,m;j&&j.length!=0?m=j[0]:m=Number.MAX_VALUE,a.push("
");for(var n=0;n=m)i(o,p.substring(0,m-k)),p=p.substring(m-k),k=m,a.push("
","
"),l++,m=j[l]||Number.MAX_VALUE;p.length!=0&&(k+=p.length,i(o,p))}}this.showInvisibles&&(b!==this.session.getLength()-1?a.push(""+this.EOL_CHAR+""):a.push(""+this.EOF_CHAR+"")),a.push("
")}}).call(h.prototype),b.Text=h}),define("ace/layer/cursor",["require","exports","module","pilot/dom"],function(a,b,c){var d=a("pilot/dom"),e=function(a){this.element=d.createElement("div"),this.element.className="ace_layer ace_cursor-layer",a.appendChild(this.element),this.cursor=d.createElement("div"),this.cursor.className="ace_cursor",this.isVisible=!1};(function(){this.setSession=function(a){this.session=a},this.hideCursor=function(){this.isVisible=!1,this.cursor.parentNode&&this.cursor.parentNode.removeChild(this.cursor),clearInterval(this.blinkId)},this.showCursor=function(){this.isVisible=!0,this.element.appendChild(this.cursor);var a=this.cursor;a.style.visibility="visible",this.restartTimer()},this.restartTimer=function(){clearInterval(this.blinkId);if(this.isVisible){var a=this.cursor;this.blinkId=setInterval(function(){a.style.visibility="hidden",setTimeout(function(){a.style.visibility="visible"},400)},1e3)}},this.getPixelPosition=function(a){if(!this.config||!this.session)return{left:0,top:0};var b=this.session.selection.getCursor(),c=this.session.documentToScreenPosition(b),d=Math.round(c.column*this.config.characterWidth),e=(c.row-(a?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:d,top:e}},this.update=function(a){this.config=a,this.pixelPos=this.getPixelPosition(!0),this.cursor.style.left=this.pixelPos.left+"px",this.cursor.style.top=this.pixelPos.top+"px",this.cursor.style.width=a.characterWidth+"px",this.cursor.style.height=a.lineHeight+"px",this.isVisible&&this.element.appendChild(this.cursor),this.session.getOverwrite()?d.addCssClass(this.cursor,"ace_overwrite"):d.removeCssClass(this.cursor,"ace_overwrite"),this.restartTimer()}}).call(e.prototype),b.Cursor=e}),define("ace/scrollbar",["require","exports","module","pilot/oop","pilot/dom","pilot/event","pilot/event_emitter"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/dom"),f=a("pilot/event"),g=a("pilot/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(),this.element.style.width=this.width+"px",f.addListener(this.element,"scroll",this.onScroll.bind(this))};(function(){d.implement(this,g),this.onScroll=function(){this._dispatchEvent("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","pilot/event"],function(a,b,c){var d=a("pilot/event"),e=function(a){this.onRender=a,this.pending=!1,this.changes=0};(function(){this.schedule=function(a){this.changes=this.changes|a;if(!this.pending){this.pending=!0;var b=this;this.setTimeoutZero(function(){b.pending=!1;var a=b.changes;b.changes=0,b.onRender(a)})}},window.postMessage?(this.messageName="zero-timeout-message",this.setTimeoutZero=function(a){if(!this.attached){var b=this;d.addListener(window,"message",function(a){b.callback&&a.data==b.messageName&&(d.stopPropagation(a),b.callback())}),this.attached=!0}this.callback=a,window.postMessage(this.messageName,"*")}):this.setTimeoutZero=function(a){setTimeout(a,0)}}).call(e.prototype),b.RenderLoop=e}),define("text!ace/css/editor.css",[],'.ace_editor { position: absolute; overflow: hidden; font-family: "Menlo", "Monaco", "Courier New", monospace; font-size: 12px; }.ace_scroller { position: absolute; overflow-x: scroll; overflow-y: hidden; }.ace_content { position: absolute; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;}.ace_composition { position: absolute; background: #555; color: #DDD; z-index: 4;}.ace_gutter { position: absolute; overflow-x: hidden; overflow-y: hidden; height: 100%;}.ace_gutter-cell.ace_error { 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"); background-repeat: no-repeat; background-position: 4px center;}.ace_gutter-cell.ace_warning { 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"); background-repeat: no-repeat; background-position: 4px center;}.ace_editor .ace_sb { position: absolute; overflow-x: hidden; overflow-y: scroll; right: 0;}.ace_editor .ace_sb div { position: absolute; width: 1px; left: 0;}.ace_editor .ace_print_margin_layer { z-index: 0; position: absolute; overflow: hidden; margin: 0; left: 0; height: 100%; width: 100%;}.ace_editor .ace_print_margin { position: absolute; height: 100%;}.ace_editor textarea { position: fixed; z-index: -1; width: 10px; height: 30px; opacity: 0; background: transparent; appearance: none; border: none; resize: none; outline: none; overflow: hidden;}.ace_layer { z-index: 1; position: absolute; overflow: hidden; white-space: nowrap; height: 100%; width: 100%;}.ace_text-layer { font-family: Monaco, "Courier New", monospace; color: black;}.ace_cjk { display: inline-block; text-align: center;}.ace_cursor-layer { z-index: 4; cursor: text; pointer-events: none;}.ace_cursor { z-index: 4; position: absolute;}.ace_line { white-space: nowrap;}.ace_marker-layer { cursor: text;}.ace_marker-layer .ace_step { position: absolute; z-index: 3;}.ace_marker-layer .ace_selection { position: absolute; z-index: 4;}.ace_marker-layer .ace_bracket { position: absolute; z-index: 5;}.ace_marker-layer .ace_active_line { position: absolute; z-index: 2;}.ace_marker-layer .ace_selected_word { position: absolute; z-index: 6; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;}.ace_dragging .ace_marker-layer, .ace_dragging .ace_text-layer { cursor: move;}'),define("text!icons/epl.html",[],'Eclipse Public License - Version 1.0

Eclipse Public License - v 1.0

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSEPUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION ORDISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT\'S ACCEPTANCE OF THISAGREEMENT.

1. DEFINITIONS

"Contribution" means:

a) in the case of the initial Contributor, the initialcode and documentation distributed under this Agreement, and

b) in the case of each subsequent Contributor:

i) changes to the Program, and

ii) additions to the Program;

where such changes and/or additions to the Programoriginate from and are distributed by that particular Contributor. AContribution \'originates\' from a Contributor if it was added to theProgram by such Contributor itself or anyone acting on suchContributor\'s behalf. Contributions do not include additions to theProgram which: (i) are separate modules of software distributed inconjunction with the Program under their own license agreement, and (ii)are not derivative works of the Program.

"Contributor" means any person or entity that distributesthe Program.

"Licensed Patents" mean patent claims licensable by aContributor which are necessarily infringed by the use or sale of itsContribution alone or when combined with the Program.

"Program" means the Contributions distributed in accordancewith this Agreement.

"Recipient" means anyone who receives the Program underthis Agreement, including all Contributors.

2. GRANT OF RIGHTS

a) Subject to the terms of this Agreement, eachContributor hereby grants Recipient a non-exclusive, worldwide,royalty-free copyright license to reproduce, prepare derivative worksof, publicly display, publicly perform, distribute and sublicense theContribution of such Contributor, if any, and such derivative works, insource code and object code form.

b) Subject to the terms of this Agreement, eachContributor hereby grants Recipient a non-exclusive, worldwide,royalty-free patent license under Licensed Patents to make, use, sell,offer to sell, import and otherwise transfer the Contribution of suchContributor, if any, in source code and object code form. This patentlicense shall apply to the combination of the Contribution and theProgram if, at the time the Contribution is added by the Contributor,such addition of the Contribution causes such combination to be coveredby the Licensed Patents. The patent license shall not apply to any othercombinations which include the Contribution. No hardware per se islicensed hereunder.

c) Recipient understands that although each Contributorgrants the licenses to its Contributions set forth herein, no assurancesare provided by any Contributor that the Program does not infringe thepatent or other intellectual property rights of any other entity. EachContributor disclaims any liability to Recipient for claims brought byany other entity based on infringement of intellectual property rightsor otherwise. As a condition to exercising the rights and licensesgranted hereunder, each Recipient hereby assumes sole responsibility tosecure any other intellectual property rights needed, if any. Forexample, if a third party patent license is required to allow Recipientto distribute the Program, it is Recipient\'s responsibility to acquirethat license before distributing the Program.

d) Each Contributor represents that to its knowledge ithas sufficient copyright rights in its Contribution, if any, to grantthe copyright license set forth in this Agreement.

3. REQUIREMENTS

A Contributor may choose to distribute the Program in object codeform under its own license agreement, provided that:

a) it complies with the terms and conditions of thisAgreement; and

b) its license agreement:

i) effectively disclaims on behalf of all Contributorsall warranties and conditions, express and implied, including warrantiesor conditions of title and non-infringement, and implied warranties orconditions of merchantability and fitness for a particular purpose;

ii) effectively excludes on behalf of all Contributorsall liability for damages, including direct, indirect, special,incidental and consequential damages, such as lost profits;

iii) states that any provisions which differ from thisAgreement are offered by that Contributor alone and not by any otherparty; and

iv) states that source code for the Program is availablefrom such Contributor, and informs licensees how to obtain it in areasonable manner on or through a medium customarily used for softwareexchange.

When the Program is made available in source code form:

a) it must be made available under this Agreement; and

b) a copy of this Agreement must be included with eachcopy of the Program.

Contributors may not remove or alter any copyright notices containedwithin the Program.

Each Contributor must identify itself as the originator of itsContribution, if any, in a manner that reasonably allows subsequentRecipients to identify the originator of the Contribution.

4. COMMERCIAL DISTRIBUTION

Commercial distributors of software may accept certainresponsibilities with respect to end users, business partners and thelike. While this license is intended to facilitate the commercial use ofthe Program, the Contributor who includes the Program in a commercialproduct offering should do so in a manner which does not createpotential liability for other Contributors. Therefore, if a Contributorincludes the Program in a commercial product offering, such Contributor("Commercial Contributor") hereby agrees to defend andindemnify every other Contributor ("Indemnified Contributor")against any losses, damages and costs (collectively "Losses")arising from claims, lawsuits and other legal actions brought by a thirdparty against the Indemnified Contributor to the extent caused by theacts or omissions of such Commercial Contributor in connection with itsdistribution of the Program in a commercial product offering. Theobligations in this section do not apply to any claims or Lossesrelating to any actual or alleged intellectual property infringement. Inorder to qualify, an Indemnified Contributor must: a) promptly notifythe Commercial Contributor in writing of such claim, and b) allow theCommercial Contributor to control, and cooperate with the CommercialContributor in, the defense and any related settlement negotiations. TheIndemnified Contributor may participate in any such claim at its ownexpense.

For example, a Contributor might include the Program in a commercialproduct offering, Product X. That Contributor is then a CommercialContributor. If that Commercial Contributor then makes performanceclaims, or offers warranties related to Product X, those performanceclaims and warranties are such Commercial Contributor\'s responsibilityalone. Under this section, the Commercial Contributor would have todefend claims against the other Contributors related to thoseperformance claims and warranties, and if a court requires any otherContributor to pay any damages as a result, the Commercial Contributormust pay those damages.

5. NO WARRANTY

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM ISPROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONSOF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITYOR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solelyresponsible for determining the appropriateness of using anddistributing the Program and assumes all risks associated with itsexercise of rights under this Agreement , including but not limited tothe risks and costs of program errors, compliance with applicable laws,damage to or loss of data, programs or equipment, and unavailability orinterruption of operations.

6. DISCLAIMER OF LIABILITY

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENTNOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDINGWITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ORDISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTEDHEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

7. GENERAL

If any provision of this Agreement is invalid or unenforceable underapplicable law, it shall not affect the validity or enforceability ofthe remainder of the terms of this Agreement, and without further actionby the parties hereto, such provision shall be reformed to the minimumextent necessary to make such provision valid and enforceable.

If Recipient institutes patent litigation against any entity(including a cross-claim or counterclaim in a lawsuit) alleging that theProgram itself (excluding combinations of the Program with othersoftware or hardware) infringes such Recipient\'s patent(s), then suchRecipient\'s rights granted under Section 2(b) shall terminate as of thedate such litigation is filed.

All Recipient\'s rights under this Agreement shall terminate if itfails to comply with any of the material terms or conditions of thisAgreement and does not cure such failure in a reasonable period of timeafter becoming aware of such noncompliance. If all Recipient\'s rightsunder this Agreement terminate, Recipient agrees to cease use anddistribution of the Program as soon as reasonably practicable. However,Recipient\'s obligations under this Agreement and any licenses granted byRecipient relating to the Program shall continue and survive.

Everyone is permitted to copy and distribute copies of thisAgreement, but in order to avoid inconsistency the Agreement iscopyrighted and may only be modified in the following manner. TheAgreement Steward reserves the right to publish new versions (includingrevisions) of this Agreement from time to time. No one other than theAgreement Steward has the right to modify this Agreement. The EclipseFoundation is the initial Agreement Steward. The Eclipse Foundation mayassign the responsibility to serve as the Agreement Steward to asuitable separate entity. Each new version of the Agreement will begiven a distinguishing version number. The Program (includingContributions) may always be distributed subject to the version of theAgreement under which it was received. In addition, after a new versionof the Agreement is published, Contributor may elect to distribute theProgram (including its Contributions) under the new version. Except asexpressly stated in Sections 2(a) and 2(b) above, Recipient receives norights or licenses to the intellectual property of any Contributor underthis Agreement, whether expressly, by implication, estoppel orotherwise. All rights in the Program not expressly granted under thisAgreement are reserved.

This Agreement is governed by the laws of the State of New York andthe intellectual property laws of the United States of America. No partyto this Agreement will bring a legal action under this Agreement morethan one year after the cause of action arose. Each party waives itsrights to a jury trial in any resulting litigation.

'),define("text!styles.css",[],"html { height: 100%; overflow: hidden;}body { overflow: hidden; margin: 0; padding: 0; height: 100%; width: 100%; font-family: Arial, Helvetica, sans-serif, Tahoma, Verdana, sans-serif; font-size: 12px; background: rgb(14, 98, 165); color: white;}#editor { position: absolute; top: 60px; left: 0px; background: white;}#controls { width: 100%;}#cockpitInput { position: absolute; width: 100%; bottom: 0; border: none; outline: none; font-family: consolas, courier, monospace; font-size: 120%;}#cockpitOutput { padding: 10px; margin: 0 15px; border: 1px solid #AAA; -moz-border-radius-topleft: 10px; -moz-border-radius-topright: 10px; border-top-left-radius: 4px; border-top-right-radius: 4px; background: #DDD; color: #000;}"),define("text!icons/error_obj.gif",[],"data:image/gif;base64,R0lGODlhEAAQANUAAPVvcvWHiPVucvRuc+ttcfV6f91KVN5LU99PV/FZY/JhaM4oN84pONE4Rd1ATfJLWutVYPRgbdxpcsgWKMgZKs4lNfE/UvE/U+artcpdSc5uXveimslHPuBhW/eJhfV5efaCgO2CgP+/v+PExP///////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACUALAAAAAAQABAAAAZwwJJwSCwaj8jSSJPhZDQj5IjTCW1CHU60OPWQQGCSR1uUID4i0ock+iAkxQZBACCxBwJCoziJWC52F4IRE3EQD2kkD4sQe0QSDmkJkgkOcEQYFSQKnGkFDBhGGAsHBAEEBqBIGBINFA0SoUmztLVJQQA7"),define("text!icons/warning_obj.gif",[],"data:image/gif;base64,R0lGODlhEAAQANUAAP/bcv/egf/ijf/ij//klv/jl//lnf/mnv/uwf/IWv/Na//Qc//Ugf/Vgv/Vg//cl//enf/nuP/MbHtRE4BVFYJXFoFVFolbGIdbGIxeGpRkHcWDLcmHL8aELsaFLs2LMsmHMcuKM82LNdyYP9+bQuCcQ+GlVcuHMc+LNdGNNtuXQN+aQt2ZQuOwcOfMrv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAC8ALAAAAAAQABAAAAZhwJdwSCwaj0ihq1RyJYcrBIL0fLlYkQjLmRwhJhOEKmlKOSgVR8qEFAEalwwDgDqaPoGEPhEIsYsgAhIPGBoPCgMnRhwECxAWGBALBRxGHS0GB5qaLR5HG6ChoFWkpaZCQQA7"),define("text!logo.png",[],"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIkAAAAyCAYAAABoKfh/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAANBxJREFUeNrsfXd0XcW97jczu519qrrVZcuyXHHBDRsXMM2AjSkmEMAQqoEQyg1JIAkBQgiBJHAvKZQklEAwgdCLTTWmGeNecLdlWVavp+42M++PfSRLxgbue/e9++5azFp7aemcXWbPfPOr328OkVLCXPQ4jtgkQAj+040QwHE8uEnHGFyRc9bJY8vnTRxaUFuaa+ZpClOlBCGA5FKKnrSd2tUUb1xf17Hh/c2Nb7S2Jd9mQVVqCgP5Tz6c+F0e0DwuwIX/qZASkYCGyvwghDh4JqUErXELXSkHjJJDhwCOyzGkIARDUyCl7HtHTwD72pOQ8gid6dfsjANBCAyVIagpcDyOtO0hGtSRcTm4yxEJabBdgbTjQUq/v7qm+IMFIKSp0FTq38/jiCcdCCGgKRSuKxA0NXhSQkoJISVcVwBSglICBsCTEtGgjkTGgaEweELCdjkkgJywAV2lAAjiaQfJJy8BACj4v9SEBFxXVP/b2eP//tNzJhyTE9K/7pJhAGbXtyWvv/el9e/8cdkX1whGd7L/HYR+2/5LG/0mEoFRApldUd/0yKSdnCtOGP7Sby855pickH74lXao0JJARUEIf7ji2BNuPWvcUtvmFd9O0X9/U77JxIUDKnrSLsQ3mWkAXEjEQtplP14wdnTvPQgBPI/jxY+2Y93eNvDsvSiA6SNKcPoxw9D/3F8sPHrIa2v23bWlMb5IU9k3exsJREwVCcvFN+zqt+2/AiQCEgGVgQUJWuMZUErxdQrA8TgmVuXPqy6KHrQTpMQ1f3oHjy7dugWa+glALAASUpr41/oT/rg4WXXNvAmQ0geKpjKcOr58/sa6DSVQWePXqzeJsKEiGtDQk3HxrZL6fwiS3tWdY2qwXI6E5X69McllpDRmDumbKQJs3deBJz+q+0zLi52kUBLvf3radmsefX/Hp1fMHZunKqxPCgwriUZByCgCNH4dQAyFoTCs9xmo37b/hzZJr3VPAAyKGAgb6gCv4AhXhIM6C/YCDADq25OwBf6lEMT7xEX2YJTutD1sVxXaZwcBQK5v7BZ+le3DpYSmMJTEAlAZ/VbN/HdJkl6ggPhAAYCE5YIeWaIwknUAJSQICDx/8jp77Zr+1yqUoCPldC/+wztgREJI/7Pd7RlomhInXyVBVIaSqA8Q8S1C/ntB0mdU4iBQkrb3Fbrf/0YICcqILx2khMsFCABKAIX5BqnCCOIO/8nD7+1eBcczoLIieHwfMfU209De6S8e+sMgL6Qjx9RAiA+Yb73l/0Z18yWJAqAgrIOSLweuDhcvOdLnXEg/YCQAgGwCyB0Ljx9R+O4vz5hZXJJTL7n8k+vxjMsFeg8h/CARFxIhXfX78K0A+f8LJAPQ8g0m5+tUgJASXEpYScs8Y3LVK49dM/PS40eXVL9884l/K44aNzpJC47Hs4eAlwVJ77Xf4uP/Z5D0YuRrQCCPGKQ7qBuclG3Onzp4yT9unDPP0FVkXI5JQwvxyq1zf1+cH7oBttdPgX3b/keBBN9MmBz+wVmQ2CnbnD+lask/bpgzz8jmMwAg43JMrC7Ay7eecn9xfrAPKN+2/2Eg6U2mSSm/eSJOAoxSEEJgp+zA/ClVz/QCxMoCpLdlXI5J1YV4+Sen3F+cF7pefguU/5mSpLe5jgfBxdd6GL25IMt2Q/N8gMw3dAUSfryjv2QyVAbLE5g0tBAv3XLyAyUFoR/wQ4D0P7VJmc1OOx4ytoeM48FxeV+G+auuE9kMrxzwuQR3/ayyy8VhJX7f8xwPruPBO+S8/vf+T7nAEkDSciH7GYwEvmfChe8TSynhpB3kxAKIhAykkvZXqhnb5ZhQlfvnf9180hkKo5AADrT2IJ6yUVtZAI8LMEKw6osGjK8tgeUJTB5aiGdunPPvp9z1Rosr8SyBRCLjwvEIpCRZAEo4rt/Pr8sep2wPrsf7LB1KCVJfIam4yD6Py35UAQmFZdP48pujw7JcqJTklOSHxuaEA8NiISMn43Crsztd355Ib0zZ1m4hJCj98hqmFFGF0RIA0uViP4CUcDwIQx00ckjBjLLCSGVdS8+Ofa3xV+HnZSFcDgB6SWF4fEl+eExO2MjpSTnJjp701j1NPZ9LjyeJykApChVG8wDCCcE+APbXgkQCkEKOunT2sF8PLgznuNx3VikhxPWE+9vXNv6tuSfztEL90JntcmI5ngZPZo5gZboAEDW1wLb6jqK/vbkBV50+Hh3daZzzy5dw3YKJGD24EB4HNIXi/pfXYlDOdjyweA4ytos/v7oWnpDFTKXQGD3uurmjfpwT1IJcSAEAjBLak3JSv3ll470Zj7/XCxSCg1Fc4gfqFl5z0ohrAprKeDZ8rDLKVu1q3fu393bcbAbU5v6d9rhANKDOu/G0Md8Pm5rJhT8OhqawldtbOp5YsfNaVWENX6eahctBVFYxd2r19fOPqV5Ynhcq11UFMhsncIVEe4+V+GhLw/LnP9rxQGdn6j1oB5ObjuXlz5s5/J0Ljh8xzPMEHnp93cqX3t166qjaQVdef/bEn1QPihQXhE08/+E23Llk1URG6RqRcciomsIrLjph9DWjqvLHGgrrQ7TtCmze17H9r0s33LNzb9ua6y485vWpI0oKuCvEHU9//AqA8/tAcqQ1Z9keJg/Ju/eeCyaferjvW3vSR9/9wrr3mKE1wXJzLj519DMjynKKfvDHD+7yuPiyOMm4uWdMH/rw3PHlx1758Ie/X/yXjyJJ253y9sYGfL6re3coZFT3Pz0QDmX+/cUNbdGgUbGruRtLPt33mBkxH0pnHHX+1MF/uPXMcSMP168NdR1VSz7eM9Y0VVsCoIyifx65O2GNam3rmX3P92YMuO7yOcOn721O5Lz/RdN8M6CK3oXiZtwRv7xg0lPXnTom0v/8RMrCn15dCwA/IwQNRzLoCQDL8VCQGzz7ZxdOe3BMRW5xR3cSqUQaNqN9UUpPCDAhw2dMqpg3c1TJab//15rfrd3edAt0hVNCICFLqBRjmefCcz2oRE6rrS56/neLjz8tk0xjz/52uPlheJ4HSBnilhM996TRf7/ilNHzUokMOju6oasKVEZBiT8u46uitb/53vTH7nx6ZQPhssxOZWBqDJDi6AHq5kiiUrp83OVzhp8EAGmXDwCTrjBcPHtY9I/LvjgvnvEeXXzm+JcfvPzYGYwSdKfsp7bta2P9b5vMuJgzsfLOv10zKxwyVJiacufVf/n4th8+taaO6spKhM1uSDw2UDUhgVDwzDtf3nwDoaTFjAZ/IqXkjJD5V544YmSvcTsAWCrDVScOr31+5d7ThMQL9DArQDPU3/3mpY3HlecHZ147bwIyWWZWQGX405XHnjb9Zy//oMfmDxgqRTrlqGdMqXr02rmjI7YnwKWEQgkEFzjnntexrr7nJjMU2HToIPZ/rONy5AaNC+67ctYTQcrZll0NyA0b2LG/E6t3NqM7YcM0VIwdXICxQwtR15iArqn0loXjbr7rnyK6ob7zKlNXAELSibSdau6MB7sSaTBI/XunjDkt3tUNx/VAuIfueArxlAXYXvDsE0cvufzEEads39UAVWXQGMUnW/djZ1MPhJAYUhjBpBEliIUNXHx8TVnC5tjd0IrCWBCW4yUG2iSHGUjHExhcHF181tQhisclCACFUTDq2xSOxzGsJIZ5Eyq+8/T722NnTqqYwSiB5QncevYE44v6DthZI9PlvvE556iysKmrAIDTJ5SX3JMbuDZuuRM0lSGTcS47DE51CNFgho1Fffrc8TBtWOG1s0aVwPZ8w0tVGAh8ioLtCRw7ohjTawuvWbG99YWArhxO9Ce0sHnhzU9+9tHw8ryKOeMqkXE5LJdjeGkM91045a7L/vTBB5ZQ1pXnB3/+4GXTpwMEQvq2ksYobvzLcry1qeVxMxq8/6sMEj+HKcdev2D8w5qXYbubu1CUE8JT72zBsg2NWwRVnieM7pNCFLy9qemMqdV50y47eRS6ehKwLQuLT6q98tYla1elbO+vAPFcjwvbsdHa0YORZVHkByRS6TRe+ng3Vu1s9dKu6LEl3TF8WPHlF8wYesrGrXUwdAXxhIM/v7EJe9oyb4GxFQDh4E1TX/587/zr5h1FCmMmEskUeiyOmKlCCOkO8G4I+fLBHa/0opnV5+aGdHApoDKK1q4kNu5uhsZon46/6qQRk5jKIuf/dmnTO2v3wlAouJQYXZXfl6PhUqKyKIKcsAFKgI54Gqfe/iLW13e+ph/UubSfBOmV2RKQatYE8G0kV0y8Yk7tHJVRABIao6hr7MTuAx3Qsp8pjOLyOcNnS49PFRiYNe5bHZTst5m26NIH37XrmrsRUBko8QF96ZzhwfOOrX6QJzLnPHDJtJ+U54fgcg5KCHSF4tE31+OBN7euNCLmtYcC5JAENyzHI8eMKP316JJQcO+BdhTEAnhzzT68uaH5KT0Ummaaxu0BXX3MDOj3mpHQrJV7u+9+dsVO5EVMdMYzCGvA3LGltzsuj4DClj55Fa7HoVIBBQIPvbEZL69pfKTDUyZbTBtpCXLDd46tmdvd1QkhOBihePC1Tek9Pd55ZiR4shnQf2UGtHvMSHBBUwbzH3xtc9xyPDDIPrUiAT5wYg7Jv3tcIiesL/recbU5WYMQCiV4ZeVu3PGPT7P/+1nXacMH0ZmjS4Z2ZnD+wvuWdb+7di80RiGEBKMEjFIolEJmPY7OeBpn/epVrNjZea9pGrf1n7lebLBDrPpejojjCgwtjSw+a8oQJgEo1Jdsj7y5EX96bUNfvySABZMHs9qy2NWOe2SXOaArH9R3uzcsuv8tpC0HPvHa/+7XF0ye/utLpz131tTBau+76ArFx5v348bHVzapQfNCCqS/QWBx4injK05OJNKIBANIWxJvbGhcpwcDVxDI+ICrpPQCQeOny7e3v9nUmUFBNIh42sX02qKykKHMh5ApQojQVRUBXUNhLITVO9vw2Z7uh8yweZXCyDrORevgwvB5R5XHjHjSQXFeFMs3N6G+2/lp0FCfHQBqKRHQlNca495tK7e3oSQ/ClPXoClK1sTvB5JDV5pjucEFEysvqyqMQEp/MiCBF1bVuUs3tyYb2uJglICAgBKCq+YMPw0K7YxDPeOc+5Yl3ltX5wOEUDBCwIg/eV2JDM66+zWs2NF5rxk2f3wkMd3rlch+IXwCgNtuxaIZNeeETS0blCPI2C5eXNtgvby+IZO2XJ/pLoFQQMUls2rOFI5XRXo9nC+pAgkzZDz04fb2P9/06HKQLEClBKoKI/jJ2RP6nq9QiobWOBb9+7tuhigXq4zsPqIbkz24lCiIBuYNL4lSx5Mozo1iY30Xkrb4PSOwjnS5B/Kb1bs7RFFuFIQqKM0NoiIvdDo8oVJKYQYMxEJBxIJBfLqzrYtq6l1ZsQvP48aYyvy5QZUhYOhQFQ2r9nTsVnX1kSNpRaLQp3e0JFtj4RAioSBMXRswVvSQ94KQEprKFlx14ogBnsamujZ8srPtDcsWtz//8a4BD5k3qZKMKo/9hBCyIi7Vc86+d2ni3XV7+8oACAE642mc+atX8MGOjvvMyJEBcqRmc4G8mHHJxbOHRft//t7G/djdmvxrXVv64bfX7xtwzUWzhoULc8xLXS6/Mm4RiJg3PvzuzuUPvrKmb3BkdtX0cm4tx8Ol//EW9nTaPzJ09e3DJSoFH3i4roeS3ODkqKlDUVSYAR3bm+LdhNF3v+pdGaOrdrUm9mqaBkPXEdB1lOcFR4OLGCOEG5qOcNAEB0Fz3FqjUHqgTxJLVA4dFBssCUU4GETc8tAat95nlKa/BOSDi7DLE+RAwDBgGgY0TR/wPT1Uj1q2R48bOeiaiTVFSLkCyay4/seHO5C2+DPU0B575pNdibTDkeYSCZcjoKu4ZPawBdx2qwOG8lZcqgvPuXdZ4p21e0EJ0N6Txtl3v4oPtnfeZ4bNHx0JIBK+Ikx6vI8N1xvo8iwvfPaUwZdWFISRzPZLAPj78u1SEvYYKHvs7x/sEFxKJD2BhCtQmhfCOVOqLnEtNyaPYJtkx8zWwsGLbnp85falq/dAEr8PCY8j5Qm4QuLGR9/H25taHjJDxgOH6z8lBIwNPACixky9vMsWaM0ItGcEOpL2PkZJ21eGwSnJdKedna0ZgQ4baLcEAoaaB8g8V0J02AIdjkSXzeFy2UgGTDjKdEPVm5Iuul2gOWHD4XIL/ZpIuCSQXY5EmyXQZYsBr0izJ/QdRMoZFx0//JhuT6A146LL4djXncbzK/fWQ1VepZR0rtnT+fL7XzQgJSQ6Mh4OpF2cPnWIWZwXvNx2OAydLYtDXXj+/W8nnluxFYvuX4rlOzrvMyNHBgghgCOBLlegPe2hhwOcHFzVAYOdff6s2soWi6M94yLuSWzc34llGxs/IwpdQxW28Z1NjZ+sr+9EwhPoyLhosTjOm1VbHjSUc6SUOJLaAQDu8YZwOPg6DehoyXjoyB7tGRfdrkAsFuZQ1EelEIelUR7hnQxPiuDmlm6sOdCJrW09cLhIEkK9rwu8cUm6dnUmseZABza1dMHyOAOlatLx5KaWbqw90Im6rhQA4vY3mimh4c6Mg7WNnVh7oBON8QwoIT3ya3IzLpfY2taDtQc6sL09PoArTHu9CUoA1+U4qirvmpljSkh3MgPuudAY8M6aOuxuSnzCKMmVUlYKLj969oMdgODwPBfpjI3CnADOmjp4kWd5uRQEjJBl7d3eaef+5u0P31x14GemGfiRoVA4nA+oqBswUVLC9Vx4nguPe1nKJBG242H2qJLFo6pykUhn4HkuVAa8+MlOdCecFQyooJAVPQlnxUsf7YRKAddzkUhnMKIyB8cfVbrYsj3lq0LuVMgT/nDVzCsm1BQhmbb8PmSPeNrCDxdOZBfNrvlDJm5FyCEqOku6g2V7sGyvDzaEEG7ZLleEDYWnQYUNQ1M0IQT5KpAJCQR0JajCBfPS0KWDjOVwgLgEkjBuQeEZMOEeojYACem6tgVd2oCbQkCRYIyGvip7n6V8SOpaoDwDekgcVOl/BXe92gtm1swLGiqcpAUKAtvxMKa6CMt+tWABo/S03vsplCBluaDwQ/IZ28P5M2tKnnh/x1mW4y05a3LV/cNLY0WuRIpATlIIefWv729/pDslXwUloJCghIAf0lsK0ndkW5pIeeyi42qnSKDv84zl4qSJQzDjqMrvU0KuztoFLKBSpDIOWDZxIYTEouNqj359Tf0cCSwjh5kQO2XX3HnhlCdOnVwV7ohnQIkfe9FVBWnLgZASqYyLuy8+5pjdLfGHP9necn7Q1L4kFGW2vDKoG8g4HJSQTHfCatcoHaJrGiglKM41SzfVd0UBdMNPe8C2XGiG4hvNADjnSnFeaAhjFKqiwNBUdMStTlB0ERCqKgyqqoAxehgSF5o74xlZWRIh3SkbkaCOmKmNbE856EufpB0QAii6CkhACEFNQ9UpY2CUQWVsAPgUABAAXE+gND90+RlTBgdSlgtK/JgD5xKDck2UF4QMKWH0IlYICdvjWZfRD7CNrMjDiUeVXvTi8h1dZ02tuvzsY6qRcP34ghASz32yK3RAyFcVBkQNFSqjiNseuJ/RJJrqUwj8IxsncQUdX1N47awxpUjbveUcEpwLVBSEoTBi9k4WIb5UcFy/XwQEadvDsaNKMLE6/9rVdR3LDE3p5zYBVsqOXjSn9pnvzzuqpDtpgRJA11QcaInjheVbcNN3pyNpufCEgKmrePia2eeddufr2+o703eYAeUwy1ICErAdD5RR2dKT2WY5fHIkZCDtCgyvyC15b2Pj0QR4FwBc14PkAp7DQXU/SCUlRo0dOmhY2vEQChrgHGjsSH0BxrooAVMUBaqigLIvF60pjO7Z09jdPGNseTFjCqiqYFRl3py31+03iK5YLCv2hPCNa6ZQSCFLaysLKm0uQBkDY+zL3g0lALfd/IVTh1xUnBfyxW+WqJwbCSAaNGDqGoKGf5i6hlBAR37EhKGpfvqfEAgpcfGc4VNBcXZHwpIJlyOestGdsuF6HGFDDUICQU2BoTAwQhDVFTguh6kpJVWFUXAuwajfsbTjJeGJCRfNGna6aah9xeuaoiA/aiJi6l/qVzigIz9qQlOVLFCAgK7gotnDThYOP0r2A0g66ZAZI4sfue9704/O2H5BF2MUpqrgrn98inueWdP9yofbkR8OgBICy/FQVhDCo9fOuj2o0vMPTclLT4AxWl5aEDktFNDG246HhOW9uX1fB4rzosi4EmVFUYyuyP1BOuNCiKyBmM2kux5HJpHBiIr8G2oq87V42kVpfhR7DnShK+0sIwQOIZQoigJFVcEY+5KuUhTWtasp/lEiZSM/FkR3xsWxY8tq8qPGNXbaznJ//BXFhUAmnsGQkpzvj6stCXcmLVBFheLHSQZKEi4kwkHt/O/OqimyXA+MUt+j8Dh+9uh76Mk4oIeax9LPal51xtGorSyA5XjIOBzHjizRRlYXnrdxTxsuOXFU9joCVWVYfMro0esefP+URNpZKjyB3tgezzijrz5r/AVDS2NIZFwwRsG5wN6mnpaCkug586cMDqVtv18KY+iKp/Dzv74H7zA7HkgJKJC46dxjkJ8TgutxpCwXp08erP3+lY1X1ndmvq+rFJbtoaowdMfD184+lykUti1AKEV+2MAfX/gcr6xuWKIW5v761r+vfO/omqK8suIcZGwP8YyD6aNKcf+l0x6+8qEVO6mhrmaEwOMChbnmuT++eMYfSnLDBYlkxv3Ti6sfWL+n7Y4VGxvqp44pr4iGAuiyPJw9e/j81s41NzW2J38PSgAhISAgLBeFBZHLLzl9wqKuRBrhoIGQyvDO2n1tiqq84HrCAAEYU6Aoh1c3lAAZTzz6/pq6hefPHYdtjV2AynDl6eN/9eTSTcmGjsTjsBwHAoCmmLVV+d+/auHUGxzXgScpVJX44DvUJrEznn7GtKorR1bmoTvtgBKCiKnhjU934o+vbVkBXX8d5Eu0Ag8pa5hhGpc9+P0TYGcTgIam4OpTRpG7l3yG2y+YCl1T4bocacvDWdOHBioLwy+v2dO+QQIZAFAICQwvi42YOrw4lPb1OExDRV1jJ9bvbs+5fsH4M4vzguhM2KCEIGqq+PuyXXhs6faXEDQ+AaB+iY6QykytKS8464ZzJqEzISAkUJRj4rzp1ef9+l/rfuVAaQowev5frzvu52UFYcTTDhghCJka1mw7gDufW1OvhQI3qYw0tabEDTc+vPzvL/ziTKgKA+cC3WkbF80ZHt5+oHvJ715cPzMQMhpd2y1eMPeoPxXlmHmrdx5ARUFYXTir9uat9Z0vHei2fv7aim1PfOfU8djVEgdUhuvPP+Z3b322d8yGHU1PJDJ2fSiglYwdVnzB6bNGLnZcG64QGFocwz+Xrkd9Z+bXZkDvdF1RSrLZW0oZSNYkOLQZuvr2R1ubXxpRuX/BuNGV2NXcg2hIN266YNrDuxq6r2lo6V5PCSFDKvImjq0pGik8Fxu2NMIMBCAJQJXD2CSaSk+98uTRoykl0FUFIIBOCZas2MkRNG8yDW3N4TrjBnTyxrqGY3/WkayNxfxV6wiJ78wahnueX41fPP4hHrzuRKQVhoztIuV4mFBTpE0dWTypvy53ufTtDQCGoSKoUtz77CromlJ92Ykj4UlA1xRfurkcz32yu4fmhBcbKms5LMVBU/Of+2T38VfPGx8LZCsOXQEsmjMi75F3ti7sTjjL/3jd7EdmjyxGh82hawoUhcJO2/jBQ8tFUiqLTUqapATMoP7U8q1tx/3u2ZWX3n7xsei2/bhR2pW466Kp1fXtySef+2TPXMJITTSg5rX3ZJB2BTpTDnICKjSFnEiYdse7mw6cHgooC0+bPRptKRu2x7Hg+OGXzJtZe4nliXTAUE1dpejsSUJhBIPzQ3j5nQ14e33DcwEz8B+9Y0UJgaExGLqCIxXSEwCKpl37+LLNwy6RcuTEsYPRnrSRsCwMrYiOHTOsYKymMKgUUMHx0fo9eH/tPpx3xmT0pDJ9tdsDQDK+KvcHVbkBNDR1+zkWSrCpNY73v2herevquiNFAlRKZGO3teS5D7b94pwZNXBcX0ebGsPC6UPxwHOrG5Npu+RHCydhaGUhVEYgsoZy/2SNphAYigYhgabWbtz8zKdY8sHuFfNn1tSEFFnc1NSV1bcUn29vwvr67qW6obccGvEk2RC6rrL2jQ09r73+6Y4Lp40shZvNFpsqw5TqgtsipnbLnFGDQruauvu4HColuPvZVVhfH/+tGTHf7HNdpIQeCtx03+ubjzlqSP6IicOK4XFfVeoqw0/PPGrOhrqOX+040P3XtV/slxNHFBFJYiiKBLDi891I2W6boWvQA8b3XvxsH/a3xheeMWsECgti8CQHo0A4QExID8IFcgMqDjR24KkV27CxIf5UwDSuIpA8O1hEoYRV5IUQ0hgI55BHII4xShq5qp/26Jubn9q4u2X6cROHoKggAoUC0nFgWRzN3Sl8tG4flq2t3za0sjAa1NXiRNqClBK2e9APJlJK5H3v8dcM6c7urfElALEESaahXMUoeelr2HjlTLhvhJkc3M8mJELRDsQ9LMikrAsjqlw8uTo/Z9zgfJQXRRHWVTB6sMbY5RIt8TQ27mrFB9ta7OaE97gRMm8PKfJZlbtHy360yRQnHQ5VFlJCVg3gFGgKhJBwPJ5NL2CiJtzng0zmy35xBJdpKY0SXbqO0v++QkJ0uHhH0/TvAvJLeRVPyMkKd56OqaRY9HN5NVVBhqhvpRxxruc6z5wwpuSco2uLsbepC69+VrfHJmwaI6SlN3CSsZxrDPAbh5fFqmsr8lCQE4SqMFi2i+aOJLbta8fO5sQmzpTfGbr2RH8/mwsZKQip66vyAoOlEHAEwbbm5C89idvIkdmFum27VzDhXVwY0UflhPQAIQQ9acdt7cnstQR9hlD24MRhRa9dcOq4qc2dceQHNNz3zKf/an500Tl9IDEvetzwhCzv9fMJIZRREmeUNPUFm7JuqcwScHtLIrLvEHKFKIGEzBq4lBB0MELaCSFwuahwLGc2hJgAISoBGe3LQPserQuQJijKBs3Q3lIY3QQ/Ix4RUg7qn+ujhHRQgo6DkUnf5Z0zsRod8QzW72iEoSm9MYNcIWX+Ide3Syk1CUQwwBmGxyjZSw6WPfcF/HqNdiERFVIWHWoIMIJGQkhKAhHLcm4k3JsmCN1uBPQHKCF7DjNxMcfxTuCedyyFrCFAQABxCfKFoqorVJWtINkMc2/uqJdH67h8BOdiAggIISSta8rbBEh8iXYqJUzVL1Hx6RKEcSGGcS5KfLIebWOM7qAE6VTaipw1c+TO6RMqCruTGTDPw73PfPb71FOX/dtB+iKBZah0Z0BXoSjM9wgyTt9D86Im0paDjOUiZOrgXKAnnkbJoBiklOjoTifDAW2HwiiS2UBNH/q5gKkp9bGQ8WQybT/pSw9y+M3NINEfeQQyzgiJ9w5Q//uqjMEMaOhMpCGye4IRAgjOwQX1PTSCTkpIZ98te6vY/Rs1H67QjEsJSig8IVBaEIHHBVq7UsjGoXoUSnoGXnNQbRIgHjC0OwDdD/L0k1SyX3SXUdKta8rz0NTnj1TJ5BOhCRRG/YkWEmFTQ044sLUrkdn6dXVQfX+F8EecSE6BrYrKtkL6QTzBOTwJaAqbM662pLAnmUHE1LBjZwfSNl87IE7iOB40TcHEkWU46ZgajK8tQWlBFLbjG2nja0ugqwyOx2HoKgKGCsmFH5XUVNi2g8qSHEyoLYHtetkaX9/vt2wHg/LDmDyyDLbDUV4YhaZQCC7ABYeUAkIICPnlpJKmKFCYT0fo3Zai1/4ImfqAnQl664qRDQx6nhhgyKmKz2s5EomeEQJDU1FVnAtNYXBcjpxIAKUFEeRFAogEDagK6xf+zvJsFJ8O0ftszkX2nSRUhYFm3ePeSoO8qNmvRknC49xf55AQQoBz4e/YFNRRFAth5JAi3/B2OUxDw5TR5X0gkv2ivIfjs1CKAOfCcBwPCiWw0g6stI1M2oFtObAzDtxEJjJ/xojbYlEDadtFWGNYs70pyRj7aABIPI9DSGiUkhpdU8dqqjK0N1ZxsCMH9XC/eo2olDIKIWEo9MyQqd4khVA9zkGQnVguoDJ6UthUb+FC6MGAVghAtS0Xg0tyETF1FOWGkBcxEcjaFZbtwVAVDK8qRHlRDgpyghg1tAiu66+oLCUwK10IIKQSDqjXGxo7FyK7raMQ/nsJCV1lGF5ViLKiKAqzsZPeHRKElLAyLkrywigtiKKsKNbn/Qkhs5OtIC9sYlhFAWzbg+N4COkqKgflYmhpPopyQ7AsBx4XGFqej2gwgMpBORhbU4KQocF2PHDu32t0dRHyYyZsx4OqUIyoKvTtMo+jtDCCyuIcCClQVhSDoavQVeaDwHcoJkWC2s+lRJ7LBQblR2CoCqyEBdfxBoDGttzwCZOGvPvzS2evHlNddJOuKiPBhSksF9J2ITgPF+YGT1x01uSlx0+pHtfQ1oXSvDD21rdhU13nq5rG9g3M3XgCZXnBnx87uvjGuv3twRFlYVQXRz5oaO66whVy56GrLj9moq25OzBjTOkHEpB1u1smx4LqjRX5wRnS5c9IKZtyckIwDR07Ey0I6nRxRUHwTF2le+dPr37opQ/cP2/oSt4yKD8MK+MgFNTh2Byex+GkOHrpijQb1CPEF7tC+qjmQkJRWIQQGAqlrYSLaFm++YDrOmvhyX8ePaYM+xo70NKZBFMYiKGAUV8i6aqSXe29EkhAcgFKfWnAD1fYlC1YYtRPL3CHQ49RKIz6FAFC/HOERGFOCGnLRW40AE1hh1UHhBBwz48JDcqPYPu+dji2i2g4gIDGUNfUmb2fL5GkxwGPw1DJd6oHhf9NCLHCUJQPIqaOdDLjF2Z5Aop6UFvrGjt++piKYwblBnDV2RN/15Ny7u7syTQk0k4rABkLB0qKC8JVUgocaO1ESW4YImPhyaWbEmDKneRwCT5TV4b0JDLBh15cc4ui0JwfXjD9R8dNrHrgjU93nda/0osLiYqiHOxr6rbfX717KwEENEUIKW0uZAYAkdwXjzRI1KrKAk9ImRZSekLK+D/eXLelLe7sUwM6pPAzp6YpiSREtR3eZwjZjgdCiAYQz3a54NlMoJQSmkK12ePK3mvvSbdv209P2W873OMiZTs8UVSSi9xoUN+5r7XPhbNdDkKISiklactxeierF4wQAo7LETH0gMdlxs0SuIWUcD0B1xNQg0rA8URGcgEQX6UJCSgKC1guz/SKJtfjsB3Pd7sNYtguH+Apid6itl4pZnt9gHVcnt2tyX+uqioBLmSm93wp4Tkuh64xq7wgR3FdIRxXCMBn70NKEOqnR4K6egJxbdi2goxtg1HoxflmdSkLVZOsWsxYGaiMoDIvhF17mvHkW5uttoy4TFeVbYet4JNSeo4nEIyE/ig9kUw7fHEmY+erjI0dXpHz4OZdTb+RXLxuqPSsYWWxG977nF89rKqslVJo+w/s4H1mpZRcCtDxtcU/nTKq5HupjGPHU3bAcbkNSdJTx1UnPlq/r6OnscsszTefM7VBLbUVeUfnRs3wO5/v/cuKtXV3A1KZNq7y9qmjShb1pKxEfUtiMyWggvNLhCCpaaNL/zahtujoVMZ1K4oiqx95ueNml4uu8qJIzdDy3JWVg2LFnuc89c6nO3/OPSEnjS/90cTaoqsoocqWuo7H9h7ovJNRn+gruUBOTmjsyVOrfxkNKtMIVeoSqfRvN2w5sCQ3rN9bmBOsHlmVi+qS2Ky0Kzbtb+76cXtT16rigvCCOZMqbmNEljd2Rt94tj1+I3e8nsKY8VQsNMiuKIrUlBWGKzUmn3nz0523+hpF5JblB19IpjJL99e33xMJ6qcdXVv4wzVb919rc/nF4EGRRxzXYxT0tqmjSu6JGuwUpqn1ze09t+3d2/Y6JAQIwfETqu4eNTi/hqlK50vLt/+mqz3xDGEUnseh6b7UTDv83Z89+v53jx5akDtqSBGK8sNgAR1g1I9VcQ4rZWFnUxc+39qIzfu71xBV+6GuqctxpDJPjwsxKC+MRaeM+VdpYbS0qaUz/O7qul/FwmZJSa45gxH5JqR8XVPIuOK8wAwhxMjSPHMuYzQEIa72Y2QS4CI9bmzlDSdMrLzzkX+tXN+TctoumTfhRC7RIaWsqC2Lnrx+m7JVeuK94lxzbmVhkDzxypoPy4qi4fPmjv/Vhl3Nq4aV50+ePbbkp39+/rNPHI9bi8+afG5rj5WQnhcyQmZq3daG1nHV+byxLZ5a/vneBiGkRUB4eWGo7LGXVx+IhQ3r0gWTb928u2VNbsQsmDSs8J4nXl3zNCVEv/zMSbftauhs3rav/c+EAAqjpVecOeH1+obWomde3bGkdkjh7AtPHvtMQ3NPO6Q4ava4ipMff/nz5mUrNn+84LiR8xedetQ/nnx1/c2nHjPkny+9v+XThub4kotOG/v9E6cMwRtvb74qFtLmDC2JFTz8r89WmwG166pzpv5wx/6O3XsOdD0kATseTw0fX1M47LNVe343vCL3quFlkdkVRZFzvkhYDx41JP+KF5ZvfW3+zGF/ScQTM59/Y+dDwwbnn3L+iaOevffJj2tczq3i/DBWb6mf+tCST5ZOHFN2/IWnjHr67tbufT0p5xNBCTzuq0VKyUsZoax974vWs9/f3HiSqbKRIV3J0zWqSwlpu9xOWF5TxpXrqKq+qAUCLxMgc1jW3cEIHZWpjIUVK7cNfeODjYWxsEGmHlVZ43hcZtWNmxV5Tu//HheWx0Wmn77lICRvyojixZ9t2d+8syk5qzXhnfThhv3LKSWmX6khIKR0skxF79PNBz5r7HJnrtvTeXk8aaEoxzxn0ohBV36wft+O+jZrVnOXM2fV1qYvCJHcdwA4etLeT9OOSCRsvqE16S2AlFtUheas3ta0tb41M3ljXfd3WzuTGJQXnDe2puAyTyBz8qyxXxw3bdR2VVVQUxb7LmwX0hMoHxQ7Jy+slb62su7fklS/6LNtrWc2t8XlmJrCK7iQ1s797XzVjrZTO1x2xosf7b47FlSrp40re1JVmDJu1OANC+YevYeqWlttee4CEFJGCcms3t60b19LeurWhsS5jW1xlBaETpBcgDKa2ri79fmCmFlsxMzjqgZFj/5g9R6MGlIwMy8veLqUEk2dqV2jBuefEjDNrecumFpXWVG0tSBqBPNyzBMJiN3RncL76xuu6ZbK2e+sbfheOm2ToaU535W261MO+hXUM0rqA4Z2vxEMzuWKPqbTo2MbU3Jyc1pO7vbYUVIzxgVC5nd0TVlCsrm0wzWlH6uJpS0PWxoSJ2NPVxtV1LdPmFR95+bdzbfA54NwCAmPC/criHcCjMZ0jRWnLL4GIHG4Hlwh9kNi2mGMOCokmiEFFKZ2ZCkKhZpC8tOOeA9CeKAEAugESDmIn7sBFwGaZdBnXR0FAJUg7RACRGVdfphe5gd0JS+ZytBd2xt/yDSm7K9vbNrXlq7TggYcy4ahkiqPSzieWJ2liW21PJHUFFJqcZKybJ4BF7uYIpBx+SrOJcKGGnIcl+/dvf+7TFM0AqQ7EvY2aAqXUjJJSCsI4RAinTUn9F43+0Bb8jXLdq89enjxHYQg/O66/SsWzhk1edKwQYP2NfcccFyxV1cYmls6hiaS1l1MZXzJ/pbGeNqOR0ytzPU4uMAXhAh4Qq53uIRCSRGk73pLCXgegdp/hwafHhBXCIl/ibz5DQjpykDqGxAJG15+NJipqSz0OrtTipV2BAFQXZZflbZBasrzhxu62rcnSa/PTwjxCWdc9uxp6GicMLx05GebG0tyo8H2cTUlIwghnsxGL0k/8nB2X3yfJM4IpETH9rr2xmljyo+ua4qXg1Bv1JDCwamM7fa9k7+bATE01YhFTcSTFicEhPpp0ewiIgBIT31jd2LU0EFdq/d2H69paqOhKWYqY3dQRqDoGpo6UrsURjFuWPEJO+o7PwnlBKcPLo6FX/9w+9by4py8ipJYoKIsfzgo+by6JDrH4xxrtzW211YVxPZ22JcnrNS7kZARsGw3CS4opVTp1w+ajVTL3jG2bL5yd0NX09ypQ6YuX1O3rrkt+WPLdj+ePrZs1PPvbX06Y7kfdyUy4FR9c01dy7WGpkDXFMWyvFYp5eSivBCGluVOyNjiczPAjs8JG9jX3L2d6TooI32T+V+5TVhfmadte/qg3CAuOW3sS2FTy0+nMiXPvPPFX7gk/3z/8923nTGj9gdTRpee0NXZM7KtIwHGqOF6XlBKGgQBuMdNx/VC0FjH8nX7/1BdHP2PH3xn8ufxtJ1MxpPD4inhUkp023bBpdQBAsf1GOcy0Duxtu1BYTT57ud77y7JDz52yaljtrZ0Jjw7Y0W5IE2QEpRRSE1JbNzRVL9wzugp0XDgvcdeXf8jx/FUj/NgNp5LHdeDwqi3Yt2+B6tLon+5ZdG0ZSmbbxUer3j8jQ03d8UzrxkBHUmbP/fPtzZef8bsEXe0jCg5IS+sTXzvs53JusaePw4pz7tNco+dOaP6Ld0wdkQMOvkfyzau2FrfdefqLfWvXrdw4lPdKfdjQ1OKXlz+xXNdzV33uK4X9jye6KXGOa4HzkWgd2UwlXVvq2//ZOa48rO37ut4F5Su3NXQuX1ISWzE7sbut6nC1jz/7pa3L5p71HkTR5QOAZDZ29hpLFm6eTZjVN3f2IHZY0sfCoWCl+aE1MlvfLStrbXbflw3tN6dJr7RNmX/qc2KpJQILHocKsF5OSa7WNdYNG257W099htQ1L8pCnNc25ldEtNv1VQW3N+eWhoy1GFpD3cZCs4DYKRd3GIw/EChGJ10cZ2Q0qacX19ZFDzPcnh3S7f1aSiglqRd+R9BFT+zPDzjCrwZ0vCoy7HK5vLPFCgKauTfbQ/POly+6DruqTFTWdAdz7QuPHnsJYwS+vTSTTW6oaWYwuB53oySqP4Lyihr7LavCKrkOi5xwPJwLyGIhVT8weF4y+J4UrjuJeX55sUBTcnvSli7uiz+C4BuJNk6VNv2hsQM+tOSPHNSR9za2Rx3fisk+fSUSVXvVA6KHLtk2cY3ygpDgxs70p8lHHmnpiqNtuXMLopqN+aE9epk2m3uSHkPepK8HFTxgJBotzzcJSHDIY38weX4xBZ42C9nk4CUs4IquTrhyttByDYF8gJdwakpF9dTStsdl8cCTNxSlh86QQgp2+LWh2mX3KwpOJVKMZ8L2VVREDqhM2HtbU24d+u6uvqwRcj/hy2V/SkTIqVE8OIn/OovV0BC9DHT+oePXdcPnauK/3svjNEBQS+ZDcVT2otnAsdxQRmFojAILvoYZ70qp3/isDcGI4REfjRw4txpw07bdaBrRX40MG5iTf7PH3lp7VONXdZFSrbeF8S/v8+H8SO1IKQvGce58O+djRtwT/h9UBgY7bexH+ndb1bAdTiYyvzKQMvFacdUf1hbkTvp9//4rIiqrEdTlYMMvew2oY7rEYUpUlV8Bl52q5SDHOHed+x3neyXm+lj+fXlnw7uf+u6HkAIVEXpJyX8zZC564+nopDD/yDRfyFIlAFEFUZ8PvphHqowAil9rnrvy/XPnfiZSvKlfElviWbvDw31/8GhQ398iGWzaGnLGbS/ofnqyrzw9Rnbwp+fX/VmU9z5iaYOJB4r/eh79HD3OuTdJKHZyTp8cZWq+N9LCaiqgm11bQ1NbT0lqqYQxggOZXAySqApVPZ/9qG7ZLPDVEX1jkd/CgM7xI7wGfv+DxTRfglOkk0XUoX+p38w6n+3/a8BAGOtxmE+9d9lAAAAAElFTkSuQmCC");var deps=["pilot/fixoldbrowsers","pilot/index","pilot/plugin_manager","pilot/environment","ace/editor","ace/edit_session","ace/virtual_renderer","ace/undomanager","ace/theme/textmate"];require(deps,function(){var a=require("pilot/plugin_manager").catalog;a.registerPlugins(["pilot/index"]);var b=require("pilot/dom"),c=require("pilot/event"),d=require("ace/editor").Editor,e=require("ace/edit_session").EditSession,f=require("ace/undomanager").UndoManager,g=require("ace/virtual_renderer").VirtualRenderer;window.ace={edit:function(h){typeof h=="string"&&(h=document.getElementById(h));var i=new e(b.getInnerText(h));i.setUndoManager(new f),h.innerHTML="";var j=new d(new g(h,"ace/theme/textmate"));j.setSession(i);var k=require("pilot/environment").create();a.startupPlugins({env:k}).then(function(){k.document=i,k.editor=j,j.resize(),c.addListener(window,"resize",function(){j.resize()}),h.env=k}),j.env=k;return j}}}) \ No newline at end of file diff --git a/build/src/cockpit-uncompressed.js b/build/src/cockpit-uncompressed.js deleted file mode 100644 index 54e6826f..00000000 --- a/build/src/cockpit-uncompressed.js +++ /dev/null @@ -1,2486 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kevin Dangoor (kdangoor@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('cockpit/index', ['require', 'exports', 'module' , 'pilot/index', 'cockpit/cli', 'cockpit/ui/settings', 'cockpit/ui/cli_view', 'cockpit/commands/basic'], function(require, exports, module) { - - -exports.startup = function(data, reason) { - require('pilot/index'); - require('cockpit/cli').startup(data, reason); - // window.testCli = require('cockpit/test/testCli'); - - require('cockpit/ui/settings').startup(data, reason); - require('cockpit/ui/cli_view').startup(data, reason); - require('cockpit/commands/basic').startup(data, reason); -}; - -/* -exports.shutdown(data, reason) { -}; -*/ - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('cockpit/cli', ['require', 'exports', 'module' , 'pilot/console', 'pilot/lang', 'pilot/oop', 'pilot/event_emitter', 'pilot/types', 'pilot/canon'], function(require, exports, module) { - - -var console = require('pilot/console'); -var lang = require('pilot/lang'); -var oop = require('pilot/oop'); -var EventEmitter = require('pilot/event_emitter').EventEmitter; - -//var keyboard = require('keyboard/keyboard'); -var types = require('pilot/types'); -var Status = require('pilot/types').Status; -var Conversion = require('pilot/types').Conversion; -var canon = require('pilot/canon'); - -/** - * Normally type upgrade is done when the owning command is registered, but - * out commandParam isn't part of a command, so it misses out. - */ -exports.startup = function(data, reason) { - canon.upgradeType('command', commandParam); -}; - -/** - * The information required to tell the user there is a problem with their - * input. - * TODO: There a several places where {start,end} crop up. Perhaps we should - * have a Cursor object. - */ -function Hint(status, message, start, end, predictions) { - this.status = status; - this.message = message; - - if (typeof start === 'number') { - this.start = start; - this.end = end; - this.predictions = predictions; - } - else { - var arg = start; - this.start = arg.start; - this.end = arg.end; - this.predictions = arg.predictions; - } -} -Hint.prototype = { -}; -/** - * Loop over the array of hints finding the one we should display. - * @param hints array of hints - */ -Hint.sort = function(hints, cursor) { - // Calculate 'distance from cursor' - if (cursor !== undefined) { - hints.forEach(function(hint) { - if (hint.start === Argument.AT_CURSOR) { - hint.distance = 0; - } - else if (cursor < hint.start) { - hint.distance = hint.start - cursor; - } - else if (cursor > hint.end) { - hint.distance = cursor - hint.end; - } - else { - hint.distance = 0; - } - }, this); - } - // Sort - hints.sort(function(hint1, hint2) { - // Compare first based on distance from cursor - if (cursor !== undefined) { - var diff = hint1.distance - hint2.distance; - if (diff != 0) { - return diff; - } - } - // otherwise go with hint severity - return hint2.status - hint1.status; - }); - // tidy-up - if (cursor !== undefined) { - hints.forEach(function(hint) { - delete hint.distance; - }, this); - } - return hints; -}; -exports.Hint = Hint; - -/** - * A Hint that arose as a result of a Conversion - */ -function ConversionHint(conversion, arg) { - this.status = conversion.status; - this.message = conversion.message; - if (arg) { - this.start = arg.start; - this.end = arg.end; - } - else { - this.start = 0; - this.end = 0; - } - this.predictions = conversion.predictions; -}; -oop.inherits(ConversionHint, Hint); - - -/** - * We record where in the input string an argument comes so we can report errors - * against those string positions. - * We publish a 'change' event when-ever the text changes - * @param emitter Arguments use something else to pass on change events. - * Currently this will be the creating Requisition. This prevents dependency - * loops and prevents us from needing to merge listener lists. - * @param text The string (trimmed) that contains the argument - * @param start The position of the text in the original input string - * @param end See start - * @param prefix Knowledge of quotation marks and whitespace used prior to the - * text in the input string allows us to re-generate the original input from - * the arguments. - * @param suffix Any quotation marks and whitespace used after the text. - * Whitespace is normally placed in the prefix to the succeeding argument, but - * can be used here when this is the last argument. - * @constructor - */ -function Argument(emitter, text, start, end, prefix, suffix) { - this.emitter = emitter; - this.setText(text); - this.start = start; - this.end = end; - this.prefix = prefix; - this.suffix = suffix; -} -Argument.prototype = { - /** - * Return the result of merging these arguments. - * TODO: What happens when we're merging arguments for the single string - * case and some of the arguments are in quotation marks? - */ - merge: function(following) { - if (following.emitter != this.emitter) { - throw new Error('Can\'t merge Arguments from different EventEmitters'); - } - return new Argument( - this.emitter, - this.text + this.suffix + following.prefix + following.text, - this.start, following.end, - this.prefix, - following.suffix); - }, - - /** - * See notes on events in Assignment. We might need to hook changes here - * into a CliRequisition so they appear of the command line. - */ - setText: function(text) { - if (text == null) { - throw new Error('Illegal text for Argument: ' + text); - } - var ev = { argument: this, oldText: this.text, text: text }; - this.text = text; - this.emitter._dispatchEvent('argumentChange', ev); - }, - - /** - * Helper when we're putting arguments back together - */ - toString: function() { - // TODO: There is a bug here - we should re-escape escaped characters - // But can we do that reliably? - return this.prefix + this.text + this.suffix; - } -}; - -/** - * Merge an array of arguments into a single argument. - * All Arguments in the array are expected to have the same emitter - */ -Argument.merge = function(argArray, start, end) { - start = (start === undefined) ? 0 : start; - end = (end === undefined) ? argArray.length : end; - - var joined; - for (var i = start; i < end; i++) { - var arg = argArray[i]; - if (!joined) { - joined = arg; - } - else { - joined = joined.merge(arg); - } - } - return joined; -}; - -/** - * We sometimes need a way to say 'this error occurs where ever the cursor is' - */ -Argument.AT_CURSOR = -1; - - -/** - * A link between a parameter and the data for that parameter. - * The data for the parameter is available as in the preferred type and as - * an Argument for the CLI. - *

We also record validity information where applicable. - *

For values, null and undefined have distinct definitions. null means - * that a value has been provided, undefined means that it has not. - * Thus, null is a valid default value, and common because it identifies an - * parameter that is optional. undefined means there is no value from - * the command line. - * @constructor - */ -function Assignment(param, requisition) { - this.param = param; - this.requisition = requisition; - this.setValue(param.defaultValue); -}; -Assignment.prototype = { - /** - * The parameter that we are assigning to - * @readonly - */ - param: undefined, - - /** - * Report on the status of the last parse() conversion. - * @see types.Conversion - */ - conversion: undefined, - - /** - * The current value in a type as specified by param.type - */ - value: undefined, - - /** - * The string version of the current value - */ - arg: undefined, - - /** - * The current value (i.e. not the string representation) - * Use setValue() to mutate - */ - value: undefined, - setValue: function(value) { - if (this.value === value) { - return; - } - - if (value === undefined) { - this.value = this.param.defaultValue; - this.conversion = this.param.getDefault ? - this.param.getDefault() : - this.param.type.getDefault(); - this.arg = undefined; - } else { - this.value = value; - this.conversion = undefined; - var text = (value == null) ? '' : this.param.type.stringify(value); - if (this.arg) { - this.arg.setText(text); - } - } - - this.requisition._assignmentChanged(this); - }, - - /** - * The textual representation of the current value - * Use setValue() to mutate - */ - arg: undefined, - setArgument: function(arg) { - if (this.arg === arg) { - return; - } - this.arg = arg; - this.conversion = this.param.type.parse(arg.text); - this.conversion.arg = arg; // TODO: make this automatic? - this.value = this.conversion.value; - this.requisition._assignmentChanged(this); - }, - - /** - * Create a list of the hints associated with this parameter assignment. - * Generally there will be only one hint generated because we're currently - * only displaying one hint at a time, ordering by distance from cursor - * and severity. Since distance from cursor will be the same for all hints - * from this assignment all but the most severe will ever be used. It might - * make sense with more experience to alter this to function to be getHint() - */ - getHint: function() { - // Allow the parameter to provide documentation - if (this.param.getCustomHint && this.value && this.arg) { - var hint = this.param.getCustomHint(this.value, this.arg); - if (hint) { - return hint; - } - } - - // If there is no argument, use the cursor position - var message = '' + this.param.name + ': '; - if (this.param.description) { - // TODO: This should be a short description - do we need to trim? - message += this.param.description.trim(); - - // Ensure the help text ends with '. ' - if (message.charAt(message.length - 1) !== '.') { - message += '.'; - } - if (message.charAt(message.length - 1) !== ' ') { - message += ' '; - } - } - var status = Status.VALID; - var start = this.arg ? this.arg.start : Argument.AT_CURSOR; - var end = this.arg ? this.arg.end : Argument.AT_CURSOR; - var predictions; - - // Non-valid conversions will have useful information to pass on - if (this.conversion) { - status = this.conversion.status; - if (this.conversion.message) { - message += this.conversion.message; - } - predictions = this.conversion.predictions; - } - - // Hint if the param is required, but not provided - var argProvided = this.arg && this.arg.text !== ''; - var dataProvided = this.value !== undefined || argProvided; - if (this.param.defaultValue === undefined && !dataProvided) { - status = Status.INVALID; - message += 'Required<\strong>'; - } - - return new Hint(status, message, start, end, predictions); - }, - - /** - * Basically setValue(conversion.predictions[0]) done in a safe - * way. - */ - complete: function() { - if (this.conversion && this.conversion.predictions && - this.conversion.predictions.length > 0) { - this.setValue(this.conversion.predictions[0]); - } - }, - - /** - * If the cursor is at 'position', do we have sufficient data to start - * displaying the next hint. This is both complex and important. - * For example, if the user has just typed:

    - *
  • 'set tabstop ' then they clearly want to know about the valid - * values for the tabstop setting, so the hint is based on the next - * parameter. - *
  • 'set tabstop' (without trailing space) - they will probably still - * want to know about the valid values for the tabstop setting because - * there is no confusion about the setting in question. - *
  • 'set tabsto' they've not finished typing a setting name so the hint - * should be based on the current parameter. - *
  • 'set tabstop' (when there is an additional tabstopstyle setting) we - * can't make assumptions about the setting - we're not finished. - *
- *

Note that the input for 2 and 4 is identical, only the configuration - * has changed, so hint display is environmental. - * - *

This function works out if the cursor is before the end of this - * assignment (assuming that we've asked the same thing of the previous - * assignment) and then attempts to work out if we should use the hint from - * the next assignment even though technically the cursor is still inside - * this one due to the rules above. - */ - isPositionCaptured: function(position) { - if (!this.arg) { - return false; - } - - // Note we don't check if position >= this.arg.start because that's - // implied by the fact that we're asking the assignments in turn, and - // we want to avoid thing falling between the cracks, but we do need - // to check that the argument does have a position - if (this.arg.start === -1) { - return false; - } - - // We're clearly done if the position is past the end of the text - if (position > this.arg.end) { - return false; - } - - // If we're AT the end, the position is captured if either the status - // is not valid or if there are other valid options including current - if (position === this.arg.end) { - return this.conversion.status !== Status.VALID || - this.conversion.predictions.length !== 0; - } - - // Otherwise we're clearly inside - return true; - }, - - /** - * Replace the current value with the lower value if such a concept - * exists. - */ - decrement: function() { - var replacement = this.param.type.decrement(this.value); - if (replacement != null) { - this.setValue(replacement); - } - }, - - /** - * Replace the current value with the higher value if such a concept - * exists. - */ - increment: function() { - var replacement = this.param.type.increment(this.value); - if (replacement != null) { - this.setValue(replacement); - } - }, - - /** - * Helper when we're rebuilding command lines. - */ - toString: function() { - return this.arg ? this.arg.toString() : ''; - } -}; -exports.Assignment = Assignment; - - -/** - * This is a special parameter to reflect the command itself. - */ -var commandParam = { - name: '__command', - type: 'command', - description: 'The command to execute', - - /** - * Provide some documentation for a command. - */ - getCustomHint: function(command, arg) { - var docs = []; - docs.push(' > '); - docs.push(command.name); - if (command.params && command.params.length > 0) { - command.params.forEach(function(param) { - if (param.defaultValue === undefined) { - docs.push(' [' + param.name + ']'); - } - else { - docs.push(' [' + param.name + ']'); - } - }, this); - } - docs.push('
'); - - docs.push(command.description ? command.description : '(No description)'); - docs.push('
'); - - if (command.params && command.params.length > 0) { - docs.push('

    '); - command.params.forEach(function(param) { - docs.push('
  • '); - docs.push('' + param.name + ': '); - docs.push(param.description ? param.description : '(No description)'); - if (param.defaultValue === undefined) { - docs.push(' [Required]'); - } - else if (param.defaultValue === null) { - docs.push(' [Optional]'); - } - else { - docs.push(' [Default: ' + param.defaultValue + ']'); - } - docs.push('
  • '); - }, this); - docs.push('
'); - } - - return new Hint(Status.VALID, docs.join(''), arg); - } -}; - -/** - * A Requisition collects the information needed to execute a command. - * There is no point in a requisition for parameter-less commands because there - * is no information to collect. A Requisition is a collection of assignments - * of values to parameters, each handled by an instance of Assignment. - * CliRequisition adds functions for parsing input from a command line to this - * class. - *

Events

- * We publish the following events:
    - *
  • argumentChange: The text of some argument has changed. It is likely that - * any UI component displaying this argument will need to be updated. (Note that - * this event is actually published by the Argument itself - see the docs for - * Argument for more details) - * The event object looks like: { argument: A, oldText: B, text: B } - *
  • commandChange: The command has changed. It is likely that a UI - * structure will need updating to match the parameters of the new command. - * The event object looks like { command: A } - * @constructor - */ -function Requisition(env) { - this.env = env; - this.commandAssignment = new Assignment(commandParam, this); -} - -Requisition.prototype = { - /** - * The command that we are about to execute. - * @see setCommandConversion() - * @readonly - */ - commandAssignment: undefined, - - /** - * The count of assignments. Excludes the commandAssignment - * @readonly - */ - assignmentCount: undefined, - - /** - * The object that stores of Assignment objects that we are filling out. - * The Assignment objects are stored under their param.name for named - * lookup. Note: We make use of the property of Javascript objects that - * they are not just hashmaps, but linked-list hashmaps which iterate in - * insertion order. - * Excludes the commandAssignment. - */ - _assignments: undefined, - - /** - * The store of hints generated by the assignments. We are trying to prevent - * the UI from needing to access this in broad form, but instead use - * methods that query part of this structure. - */ - _hints: undefined, - - /** - * When the command changes, we need to keep a bunch of stuff in sync - */ - _assignmentChanged: function(assignment) { - // This is all about re-creating Assignments - if (assignment.param.name !== '__command') { - return; - } - - this._assignments = {}; - - if (assignment.value) { - assignment.value.params.forEach(function(param) { - this._assignments[param.name] = new Assignment(param, this); - }, this); - } - - this.assignmentCount = Object.keys(this._assignments).length; - this._dispatchEvent('commandChange', { command: assignment.value }); - }, - - /** - * Assignments have an order, so we need to store them in an array. - * But we also need named access ... - */ - getAssignment: function(nameOrNumber) { - var name = (typeof nameOrNumber === 'string') ? - nameOrNumber : - Object.keys(this._assignments)[nameOrNumber]; - return this._assignments[name]; - }, - - /** - * Where parameter name == assignment names - they are the same. - */ - getParameterNames: function() { - return Object.keys(this._assignments); - }, - - /** - * A *shallow* clone of the assignments. - * This is useful for systems that wish to go over all the assignments - * finding values one way or another and wish to trim an array as they go. - */ - cloneAssignments: function() { - return Object.keys(this._assignments).map(function(name) { - return this._assignments[name]; - }, this); - }, - - /** - * Collect the statuses from the Assignments. - * The hints returned are sorted by severity - */ - _updateHints: function() { - // TODO: work out when to clear this out for the plain Requisition case - // this._hints = []; - this.getAssignments(true).forEach(function(assignment) { - this._hints.push(assignment.getHint()); - }, this); - Hint.sort(this._hints); - - // We would like to put some initial help here, but for anyone but - // a complete novice a 'type help' message is very annoying, so we - // need to find a way to only display this message once, or for - // until the user click a 'close' button or similar - // TODO: Add special case for '' input - }, - - /** - * Returns the most severe status - */ - getWorstHint: function() { - return this._hints[0]; - }, - - /** - * Extract the names and values of all the assignments, and return as - * an object. - */ - getArgsObject: function() { - var args = {}; - this.getAssignments().forEach(function(assignment) { - args[assignment.param.name] = assignment.value; - }, this); - return args; - }, - - /** - * Access the arguments as an array. - * @param includeCommand By default only the parameter arguments are - * returned unless (includeCommand === true), in which case the list is - * prepended with commandAssignment.arg - */ - getAssignments: function(includeCommand) { - var args = []; - if (includeCommand === true) { - args.push(this.commandAssignment); - } - Object.keys(this._assignments).forEach(function(name) { - args.push(this.getAssignment(name)); - }, this); - return args; - }, - - /** - * Reset all the assignments to their default values - */ - setDefaultValues: function() { - this.getAssignments().forEach(function(assignment) { - assignment.setValue(undefined); - }, this); - }, - - /** - * Helper to call canon.exec - */ - exec: function() { - canon.exec(this.commandAssignment.value, - this.env, - this.getArgsObject(), - this.toCanonicalString()); - }, - - /** - * Extract a canonical version of the input - */ - toCanonicalString: function() { - var line = []; - line.push(this.commandAssignment.value.name); - Object.keys(this._assignments).forEach(function(name) { - var assignment = this._assignments[name]; - var type = assignment.param.type; - // TODO: This will cause problems if there is a non-default value - // after a default value. Also we need to decide when to use - // named parameters in place of positional params. Both can wait. - if (assignment.value !== assignment.param.defaultValue) { - line.push(' '); - line.push(type.stringify(assignment.value)); - } - }, this); - return line.join(''); - } -}; -oop.implement(Requisition.prototype, EventEmitter); -exports.Requisition = Requisition; - - -/** - * An object used during command line parsing to hold the various intermediate - * data steps. - *

    The 'output' of the update is held in 2 objects: input.hints which is an - * array of hints to display to the user. In the future this will become a - * single value. - *

    The other output value is input.requisition which gives access to an - * args object for use in executing the final command. - * - *

    The majority of the functions in this class are called in sequence by the - * constructor. Their task is to add to hints fill out the requisition. - *

    The general sequence is:

      - *
    • _tokenize(): convert _typed into _parts - *
    • _split(): convert _parts into _command and _unparsedArgs - *
    • _assign(): convert _unparsedArgs into requisition - *
    - * - * @param typed {string} The instruction as typed by the user so far - * @param options {object} A list of optional named parameters. Can be any of: - * flags: Flags for us to check against the predicates specified with the - * commands. Defaulted to keyboard.buildFlags({ }); - * if not specified. - * @constructor - */ -function CliRequisition(env, options) { - Requisition.call(this, env); - - if (options && options.flags) { - /** - * TODO: We were using a default of keyboard.buildFlags({ }); - * This allowed us to have commands that only existed in certain contexts - * - i.e. Javascript specific commands. - */ - this.flags = options.flags; - } -} -oop.inherits(CliRequisition, Requisition); -(function() { - /** - * Called by the UI when ever the user interacts with a command line input - * @param input A structure that details the state of the input field. - * It should look something like: { typed:a, cursor: { start:b, end:c } } - * Where a is the contents of the input field, and b and c are the start - * and end of the cursor/selection respectively. - */ - CliRequisition.prototype.update = function(input) { - this.input = input; - this._hints = []; - - var args = this._tokenize(input.typed); - this._split(args); - - if (this.commandAssignment.value) { - this._assign(args); - } - - this._updateHints(); - }; - - /** - * Return an array of Status scores so we can create a marked up - * version of the command line input. - */ - CliRequisition.prototype.getInputStatusMarkup = function() { - // 'scores' is an array which tells us what chars are errors - // Initialize with everything VALID - var scores = this.toString().split('').map(function(ch) { - return Status.VALID; - }); - // For all chars in all hints, check and upgrade the score - this._hints.forEach(function(hint) { - for (var i = hint.start; i <= hint.end; i++) { - if (hint.status > scores[i]) { - scores[i] = hint.status; - } - } - }, this); - return scores; - }; - - /** - * Reconstitute the input from the args - */ - CliRequisition.prototype.toString = function() { - return this.getAssignments(true).map(function(assignment) { - return assignment.toString(); - }, this).join(''); - }; - - var superUpdateHints = CliRequisition.prototype._updateHints; - /** - * Marks up hints in a number of ways: - * - Makes INCOMPLETE hints that are not near the cursor INVALID since - * they can't be completed by typing - * - Finds the most severe hint, and annotates the array with it - * - Finds the hint to display, and also annotates the array with it - * TODO: I'm wondering if array annotation is evil and we should replace - * this with an object. Need to find out more. - */ - CliRequisition.prototype._updateHints = function() { - superUpdateHints.call(this); - - // Not knowing about cursor positioning, the requisition and assignments - // can't know this, but anything they mark as INCOMPLETE is actually - // INVALID unless the cursor is actually inside that argument. - var c = this.input.cursor; - this._hints.forEach(function(hint) { - var startInHint = c.start >= hint.start && c.start <= hint.end; - var endInHint = c.end >= hint.start && c.end <= hint.end; - var inHint = startInHint || endInHint; - if (!inHint && hint.status === Status.INCOMPLETE) { - hint.status = Status.INVALID; - } - }, this); - - Hint.sort(this._hints); - }; - - /** - * Accessor for the hints array. - * While we could just use the hints property, using getHints() is - * preferred for symmetry with Requisition where it needs a function due to - * lack of an atomic update system. - */ - CliRequisition.prototype.getHints = function() { - return this._hints; - }; - - /** - * Look through the arguments attached to our assignments for the assignment - * at the given position. - */ - CliRequisition.prototype.getAssignmentAt = function(position) { - var assignments = this.getAssignments(true); - for (var i = 0; i < assignments.length; i++) { - var assignment = assignments[i]; - if (!assignment.arg) { - // There is no argument in this assignment, we've fallen off - // the end of the obvious answers - it must be this one. - return assignment; - } - if (assignment.isPositionCaptured(position)) { - return assignment; - } - } - - return assignment; - }; - - /** - * Split up the input taking into account ' and " - */ - CliRequisition.prototype._tokenize = function(typed) { - // For blank input, place a dummy empty argument into the list - if (typed == null || typed.length === 0) { - return [ new Argument(this, '', 0, 0, '', '') ]; - } - - var OUTSIDE = 1; // The last character was whitespace - var IN_SIMPLE = 2; // The last character was part of a parameter - var IN_SINGLE_Q = 3; // We're inside a single quote: ' - var IN_DOUBLE_Q = 4; // We're inside double quotes: " - - var mode = OUTSIDE; - - // First we un-escape. This list was taken from: - // https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Unicode - // We are generally converting to their real values except for \', \" - // and '\ ' which we are converting to unicode private characters so we - // can distinguish them from ', " and ' ', which have special meaning. - // They need swapping back post-split - see unescape2() - typed = typed - .replace(/\\\\/g, '\\') - .replace(/\\b/g, '\b') - .replace(/\\f/g, '\f') - .replace(/\\n/g, '\n') - .replace(/\\r/g, '\r') - .replace(/\\t/g, '\t') - .replace(/\\v/g, '\v') - .replace(/\\n/g, '\n') - .replace(/\\r/g, '\r') - .replace(/\\ /g, '\uF000') - .replace(/\\'/g, '\uF001') - .replace(/\\"/g, '\uF002'); - - function unescape2(str) { - return str - .replace(/\uF000/g, ' ') - .replace(/\uF001/g, '\'') - .replace(/\uF002/g, '"'); - } - - var i = 0; - var start = 0; // Where did this section start? - var prefix = ''; - var args = []; - - while (true) { - if (i >= typed.length) { - // There is nothing else to read - tidy up - if (mode !== OUTSIDE) { - var str = unescape2(typed.substring(start, i)); - args.push(new Argument(this, str, start, i, prefix, '')); - } - else { - if (i !== start) { - // There's a bunch of whitespace at the end of the - // command add it to the last argument's suffix, - // creating an empty argument if needed. - var extra = typed.substring(start, i); - var lastArg = args[args.length - 1]; - if (!lastArg) { - lastArg = new Argument(this, '', i, i, extra, ''); - args.push(lastArg); - } - else { - lastArg.suffix += extra; - } - } - } - break; - } - - var c = typed[i]; - switch (mode) { - case OUTSIDE: - if (c === '\'') { - prefix = typed.substring(start, i + 1); - mode = IN_SINGLE_Q; - start = i + 1; - } - else if (c === '"') { - prefix = typed.substring(start, i + 1); - mode = IN_DOUBLE_Q; - start = i + 1; - } - else if (/ /.test(c)) { - // Still whitespace, do nothing - } - else { - prefix = typed.substring(start, i); - mode = IN_SIMPLE; - start = i; - } - break; - - case IN_SIMPLE: - // There is an edge case of xx'xx which we are assuming to - // be a single parameter (and same with ") - if (c === ' ') { - var str = unescape2(typed.substring(start, i)); - args.push(new Argument(this, str, - start, i, prefix, '')); - mode = OUTSIDE; - start = i; - prefix = ''; - } - break; - - case IN_SINGLE_Q: - if (c === '\'') { - var str = unescape2(typed.substring(start, i)); - args.push(new Argument(this, str, - start - 1, i + 1, prefix, c)); - mode = OUTSIDE; - start = i + 1; - prefix = ''; - } - break; - - case IN_DOUBLE_Q: - if (c === '"') { - var str = unescape2(typed.substring(start, i)); - args.push(new Argument(this, str, - start - 1, i + 1, prefix, c)); - mode = OUTSIDE; - start = i + 1; - prefix = ''; - } - break; - } - - i++; - } - - return args; - }; - - /** - * Looks in the canon for a command extension that matches what has been - * typed at the command line. - */ - CliRequisition.prototype._split = function(args) { - var argsUsed = 1; - var arg; - - while (argsUsed <= args.length) { - var arg = Argument.merge(args, 0, argsUsed); - this.commandAssignment.setArgument(arg); - - if (!this.commandAssignment.value) { - // Not found. break with value == null - break; - } - - /* - // Previously we needed a way to hide commands depending context. - // We have not resurrected that feature yet. - if (!keyboard.flagsMatch(command.predicates, this.flags)) { - // If the predicates say 'no match' then go LA LA LA - command = null; - break; - } - */ - - if (this.commandAssignment.value.exec) { - // Valid command, break with command valid - for (var i = 0; i < argsUsed; i++) { - args.shift(); - } - break; - } - - argsUsed++; - } - }; - - /** - * Work out which arguments are applicable to which parameters. - *

    This takes #_command.params and #_unparsedArgs and creates a map of - * param names to 'assignment' objects, which have the following properties: - *

      - *
    • param - The matching parameter. - *
    • index - Zero based index into where the match came from on the input - *
    • value - The matching input - *
    - */ - CliRequisition.prototype._assign = function(args) { - if (args.length === 0) { - this.setDefaultValues(); - return; - } - - // Create an error if the command does not take parameters, but we have - // been given them ... - if (this.assignmentCount === 0) { - // TODO: previously we were doing some extra work to avoid this if - // we determined that we had args that were all whitespace, but - // probably given our tighter tokenize() this won't be an issue? - this._hints.push(new Hint(Status.INVALID, - this.commandAssignment.value.name + - ' does not take any parameters', - Argument.merge(args))); - return; - } - - // Special case: if there is only 1 parameter, and that's of type - // text we put all the params into the first param - if (this.assignmentCount === 1) { - var assignment = this.getAssignment(0); - if (assignment.param.type.name === 'text') { - assignment.setArgument(Argument.merge(args)); - return; - } - } - - var assignments = this.cloneAssignments(); - var names = this.getParameterNames(); - - // Extract all the named parameters - var used = []; - assignments.forEach(function(assignment) { - var namedArgText = '--' + assignment.name; - - var i = 0; - while (true) { - var arg = args[i]; - if (namedArgText !== arg.text) { - i++; - if (i >= args.length) { - break; - } - continue; - } - - // boolean parameters don't have values, default to false - if (assignment.param.type.name === 'boolean') { - assignment.setValue(true); - } - else { - if (i + 1 < args.length) { - // Missing value portion of this named param - this._hints.push(new Hint(Status.INCOMPLETE, - 'Missing value for: ' + namedArgText, - args[i])); - } - else { - args.splice(i + 1, 1); - assignment.setArgument(args[i + 1]); - } - } - - lang.arrayRemove(names, assignment.name); - args.splice(i, 1); - // We don't need to i++ if we splice - } - }, this); - - // What's left are positional parameters assign in order - names.forEach(function(name) { - var assignment = this.getAssignment(name); - if (args.length === 0) { - // No more values - assignment.setValue(undefined); // i.e. default - } - else { - var arg = args[0]; - args.splice(0, 1); - assignment.setArgument(arg); - } - }, this); - - if (args.length > 0) { - var remaining = Argument.merge(args); - this._hints.push(new Hint(Status.INVALID, - 'Input \'' + remaining.text + '\' makes no sense.', - remaining)); - } - }; - -})(); -exports.CliRequisition = CliRequisition; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('cockpit/ui/settings', ['require', 'exports', 'module' , 'pilot/types', 'pilot/types/basic'], function(require, exports, module) { - - -var types = require("pilot/types"); -var SelectionType = require('pilot/types/basic').SelectionType; - -var direction = new SelectionType({ - name: 'direction', - data: [ 'above', 'below' ] -}); - -var hintDirectionSetting = { - name: "hintDirection", - description: "Are hints shown above or below the command line?", - type: "direction", - defaultValue: "above" -}; - -var outputDirectionSetting = { - name: "outputDirection", - description: "Is the output window shown above or below the command line?", - type: "direction", - defaultValue: "above" -}; - -var outputHeightSetting = { - name: "outputHeight", - description: "What height should the output panel be?", - type: "number", - defaultValue: 300 -}; - -exports.startup = function(data, reason) { - types.registerType(direction); - data.env.settings.addSetting(hintDirectionSetting); - data.env.settings.addSetting(outputDirectionSetting); - data.env.settings.addSetting(outputHeightSetting); -}; - -exports.shutdown = function(data, reason) { - types.unregisterType(direction); - data.env.settings.removeSetting(hintDirectionSetting); - data.env.settings.removeSetting(outputDirectionSetting); - data.env.settings.removeSetting(outputHeightSetting); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('cockpit/ui/cli_view', ['require', 'exports', 'module' , 'text!cockpit/ui/cli_view.css', 'pilot/event', 'pilot/dom', 'pilot/keys', 'pilot/canon', 'pilot/types', 'cockpit/cli', 'cockpit/ui/request_view'], function(require, exports, module) { - - -var editorCss = require("text!cockpit/ui/cli_view.css"); -var event = require("pilot/event"); -var dom = require("pilot/dom"); -dom.importCssString(editorCss); - -var event = require("pilot/event"); -var keys = require("pilot/keys"); -var canon = require("pilot/canon"); -var Status = require('pilot/types').Status; - -var CliRequisition = require('cockpit/cli').CliRequisition; -var Hint = require('cockpit/cli').Hint; -var RequestView = require('cockpit/ui/request_view').RequestView; - -var NO_HINT = new Hint(Status.VALID, '', 0, 0); - -/** - * On startup we need to: - * 1. Add 3 sets of elements to the DOM for: - * - command line output - * - input hints - * - completion - * 2. Attach a set of events so the command line works - */ -exports.startup = function(data, reason) { - var cli = new CliRequisition(data.env); - var cliView = new CliView(cli, data.env); -}; - -/** - * A class to handle the simplest UI implementation - */ -function CliView(cli, env) { - this.cli = cli; - this.doc = document; - this.win = dom.getParentWindow(this.doc); - - // TODO: we should have a better way to specify command lines??? - this.element = this.doc.getElementById('cockpitInput'); - if (!this.element) { - // console.log('No element with an id of cockpit. Bailing on cli'); - return; - } - - this.settings = env.settings; - this.hintDirection = this.settings.getSetting('hintDirection'); - this.outputDirection = this.settings.getSetting('outputDirection'); - this.outputHeight = this.settings.getSetting('outputHeight'); - - // If the requisition tells us something has changed, we use this to know - // if we should ignore it - this.isUpdating = false; - - this.createElements(); - this.update(); -} -CliView.prototype = { - /** - * Create divs for completion, hints and output - */ - createElements: function() { - var input = this.element; - - this.element.spellcheck = false; - - this.output = this.doc.getElementById('cockpitOutput'); - this.popupOutput = (this.output == null); - if (!this.output) { - this.output = this.doc.createElement('div'); - this.output.id = 'cockpitOutput'; - this.output.className = 'cptFocusPopup'; - input.parentNode.insertBefore(this.output, input.nextSibling); - - var setMaxOutputHeight = function() { - this.output.style.maxHeight = this.outputHeight.get() + 'px'; - }.bind(this); - this.outputHeight.addEventListener('change', setMaxOutputHeight); - setMaxOutputHeight(); - } - - this.completer = this.doc.createElement('div'); - this.completer.className = 'cptCompletion VALID'; - ; - this.completer.style.color = dom.computedStyle(input, "color"); - this.completer.style.fontSize = dom.computedStyle(input, "fontSize"); - this.completer.style.fontFamily = dom.computedStyle(input, "fontFamily"); - this.completer.style.fontWeight = dom.computedStyle(input, "fontWeight"); - this.completer.style.fontStyle = dom.computedStyle(input, "fontStyle"); - input.parentNode.insertBefore(this.completer, input.nextSibling); - - // Transfer background styling to the completer. - this.completer.style.backgroundColor = input.style.backgroundColor; - input.style.backgroundColor = 'transparent'; - - this.hinter = this.doc.createElement('div'); - this.hinter.className = 'cptHints cptFocusPopup'; - input.parentNode.insertBefore(this.hinter, input.nextSibling); - - var resizer = this.resizer.bind(this); - event.addListener(this.win, 'resize', resizer); - this.hintDirection.addEventListener('change', resizer); - this.outputDirection.addEventListener('change', resizer); - resizer(); - - canon.addEventListener('output', function(ev) { - new RequestView(ev.request, this); - }.bind(this)); - event.addCommandKeyListener(input, this.onCommandKey.bind(this)); - event.addListener(input, 'keyup', this.onKeyUp.bind(this)); - - // cursor position affects hint severity. TODO: shortcuts for speed - event.addListener(input, 'mouseup', function(ev) { - this.isUpdating = true; - this.update(); - this.isUpdating = false; - }.bind(this)); - - this.cli.addEventListener('argumentChange', this.onArgChange.bind(this)); - }, - - /** - * We need to see the output of the latest command entered - */ - scrollOutputToBottom: function() { - // Certain browsers have a bug such that scrollHeight is too small - // when content does not fill the client area of the element - var scrollHeight = Math.max(this.output.scrollHeight, this.output.clientHeight); - this.output.scrollTop = scrollHeight - this.output.clientHeight; - }, - - /** - * To be called on window resize or any time we want to align the elements - * with the input box. - */ - resizer: function() { - var rect = this.element.getClientRects()[0]; - - this.completer.style.top = rect.top + 'px'; - var height = rect.bottom - rect.top; - this.completer.style.height = height + 'px'; - this.completer.style.lineHeight = height + 'px'; - this.completer.style.left = rect.left + 'px'; - var width = rect.right - rect.left; - this.completer.style.width = width + 'px'; - - if (this.hintDirection.get() === 'below') { - this.hinter.style.top = rect.bottom + 'px'; - this.hinter.style.bottom = 'auto'; - } - else { - this.hinter.style.top = 'auto'; - this.hinter.style.bottom = (this.doc.documentElement.clientHeight - rect.top) + 'px'; - } - this.hinter.style.left = (rect.left + 30) + 'px'; - this.hinter.style.maxWidth = (width - 110) + 'px'; - - if (this.popupOutput) { - if (this.outputDirection.get() === 'below') { - this.output.style.top = rect.bottom + 'px'; - this.output.style.bottom = 'auto'; - } - else { - this.output.style.top = 'auto'; - this.output.style.bottom = (this.doc.documentElement.clientHeight - rect.top) + 'px'; - } - this.output.style.left = rect.left + 'px'; - this.output.style.width = (width - 80) + 'px'; - } - }, - - /** - * Ensure that TAB isn't handled by the browser - */ - onCommandKey: function(ev, hashId, keyCode) { - var handled; - // var handled = keyboardManager.processKeyEvent(ev, this, { - // isCommandLine: true, isKeyUp: false - // }); - if (keyCode === keys.TAB || - keyCode === keys.UP || - keyCode === keys.DOWN) { - event.stopEvent(ev); - } - return handled; - }, - - /** - * The main keyboard processing loop - */ - onKeyUp: function(ev) { - var handled; - /* - var handled = keyboardManager.processKeyEvent(ev, this, { - isCommandLine: true, isKeyUp: true - }); - */ - - // RETURN does a special exec/highlight thing - if (ev.keyCode === keys.RETURN) { - var worst = this.cli.getWorstHint(); - // Deny RETURN unless the command might work - if (worst.status === Status.VALID) { - this.cli.exec(); - this.element.value = ''; - } - else { - // If we've denied RETURN because the command was not VALID, - // select the part of the command line that is causing problems - // TODO: if there are 2 errors are we picking the right one? - dom.setSelectionStart(this.element, worst.start); - dom.setSelectionEnd(this.element, worst.end); - } - } - - this.update(); - - // Special actions which delegate to the assignment - var current = this.cli.getAssignmentAt(dom.getSelectionStart(this.element)); - if (current) { - // TAB does a special complete thing - if (ev.keyCode === keys.TAB) { - current.complete(); - this.update(); - } - - // UP/DOWN look for some history - if (ev.keyCode === keys.UP) { - current.increment(); - this.update(); - } - if (ev.keyCode === keys.DOWN) { - current.decrement(); - this.update(); - } - } - - return handled; - }, - - /** - * Actually parse the input and make sure we're all up to date - */ - update: function() { - this.isUpdating = true; - var input = { - typed: this.element.value, - cursor: { - start: dom.getSelectionStart(this.element), - end: dom.getSelectionEnd(this.element.selectionEnd) - } - }; - this.cli.update(input); - - var display = this.cli.getAssignmentAt(input.cursor.start).getHint(); - - // 1. Update the completer with prompt/error marker/TAB info - dom.removeCssClass(this.completer, Status.VALID.toString()); - dom.removeCssClass(this.completer, Status.INCOMPLETE.toString()); - dom.removeCssClass(this.completer, Status.INVALID.toString()); - - var completion = '> '; - if (this.element.value.length > 0) { - var scores = this.cli.getInputStatusMarkup(); - completion += this.markupStatusScore(scores); - } - - // Display the "-> prediction" at the end of the completer - if (this.element.value.length > 0 && - display.predictions && display.predictions.length > 0) { - var tab = display.predictions[0]; - completion += '  ⇥ ' + (tab.name ? tab.name : tab); - } - this.completer.innerHTML = completion; - dom.addCssClass(this.completer, this.cli.getWorstHint().status.toString()); - - // 2. Update the hint element - var hint = ''; - if (this.element.value.length !== 0) { - hint += display.message; - if (display.predictions && display.predictions.length > 0) { - hint += ': [ '; - display.predictions.forEach(function(prediction) { - hint += (prediction.name ? prediction.name : prediction); - hint += ' | '; - }, this); - hint = hint.replace(/\| $/, ']'); - } - } - - this.hinter.innerHTML = hint; - if (hint.length === 0) { - dom.addCssClass(this.hinter, 'cptNoPopup'); - } - else { - dom.removeCssClass(this.hinter, 'cptNoPopup'); - } - - this.isUpdating = false; - }, - - /** - * Markup an array of Status values with spans - */ - markupStatusScore: function(scores) { - var completion = ''; - // Create mark-up - var i = 0; - var lastStatus = -1; - while (true) { - if (lastStatus !== scores[i]) { - completion += ''; - lastStatus = scores[i]; - } - completion += this.element.value[i]; - i++; - if (i === this.element.value.length) { - completion += ''; - break; - } - if (lastStatus !== scores[i]) { - completion += ''; - } - } - - return completion; - }, - - /** - * Update the input element to reflect the changed argument - */ - onArgChange: function(ev) { - if (this.isUpdating) { - return; - } - - var prefix = this.element.value.substring(0, ev.argument.start); - var suffix = this.element.value.substring(ev.argument.end); - var insert = typeof ev.text === 'string' ? ev.text : ev.text.name; - this.element.value = prefix + insert + suffix; - // Fix the cursor. - var insertEnd = (prefix + insert).length; - this.element.selectionStart = insertEnd; - this.element.selectionEnd = insertEnd; - } -}; -exports.CliView = CliView; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('cockpit/ui/request_view', ['require', 'exports', 'module' , 'pilot/dom', 'pilot/event', 'text!cockpit/ui/request_view.html', 'pilot/domtemplate', 'text!cockpit/ui/request_view.css'], function(require, exports, module) { - -var dom = require("pilot/dom"); -var event = require("pilot/event"); -var requestViewHtml = require("text!cockpit/ui/request_view.html"); -var Templater = require("pilot/domtemplate").Templater; - -var requestViewCss = require("text!cockpit/ui/request_view.css"); -dom.importCssString(requestViewCss); - -/** - * Pull the HTML into the DOM, but don't add it to the document - */ -var templates = document.createElement('div'); -templates.innerHTML = requestViewHtml; -var row = templates.querySelector('.cptRow'); - -/** - * Work out the path for images. - * TODO: This should probably live in some utility area somewhere - */ -function imageUrl(path) { - var dataUrl = require('text!cockpit/ui/' + path); - if (dataUrl) { - return dataUrl; - } - - var filename = module.id.split('/').pop() + '.js'; - var imagePath; - - if (module.uri.substr(-filename.length) !== filename) { - console.error('Can\'t work out path from module.uri/module.id'); - return path; - } - - if (module.uri) { - var end = module.uri.length - filename.length - 1; - return module.uri.substr(0, end) + path; - } - - return filename + path; -} - - -/** - * Adds a row to the CLI output display - */ -function RequestView(request, cliView) { - this.request = request; - this.cliView = cliView; - this.imageUrl = imageUrl; - - // Elements attached to this by the templater. For info only - this.rowin = null; - this.rowout = null; - this.output = null; - this.hide = null; - this.show = null; - this.duration = null; - this.throb = null; - - new Templater().processNode(row.cloneNode(true), this); - - this.cliView.output.appendChild(this.rowin); - this.cliView.output.appendChild(this.rowout); - - this.request.addEventListener('output', this.onRequestChange.bind(this)); -}; - -RequestView.prototype = { - /** - * A single click on an invocation line in the console copies the command to - * the command line - */ - copyToInput: function() { - this.cliView.element.value = this.request.typed; - }, - - /** - * A double click on an invocation line in the console executes the command - */ - executeRequest: function(ev) { - this.cliView.cli.update({ - typed: this.request.typed, - cursor: { start:0, end:0 } - }); - this.cliView.cli.exec(); - }, - - hideOutput: function(ev) { - this.output.style.display = 'none'; - dom.addCssClass(this.hide, 'cmd_hidden'); - dom.removeCssClass(this.show, 'cmd_hidden'); - - event.stopPropagation(ev); - }, - - showOutput: function(ev) { - this.output.style.display = 'block'; - dom.removeCssClass(this.hide, 'cmd_hidden'); - dom.addCssClass(this.show, 'cmd_hidden'); - - event.stopPropagation(ev); - }, - - remove: function(ev) { - this.cliView.output.removeChild(this.rowin); - this.cliView.output.removeChild(this.rowout); - event.stopPropagation(ev); - }, - - onRequestChange: function(ev) { - this.duration.innerHTML = this.request.duration ? - 'completed in ' + (this.request.duration / 1000) + ' sec ' : - ''; - - this.output.innerHTML = ''; - this.request.outputs.forEach(function(output) { - var node; - if (typeof output == 'string') { - node = document.createElement('p'); - node.innerHTML = output; - } else { - node = output; - } - this.output.appendChild(node); - }, this); - this.cliView.scrollOutputToBottom(); - - dom.setCssClass(this.output, 'cmd_error', this.request.error); - - this.throb.style.display = this.request.completed ? 'none' : 'block'; - } -}; -exports.RequestView = RequestView; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is DomTemplate. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) (original author) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('pilot/domtemplate', ['require', 'exports', 'module' ], function(require, exports, module) { - - -// WARNING: do not 'use_strict' without reading the notes in envEval; - -/** - * A templater that allows one to quickly template DOM nodes. - */ -function Templater() { - this.scope = []; -}; - -/** - * Recursive function to walk the tree processing the attributes as it goes. - * @param node the node to process. If you pass a string in instead of a DOM - * element, it is assumed to be an id for use with document.getElementById() - * @param data the data to use for node processing. - */ -Templater.prototype.processNode = function(node, data) { - if (typeof node === 'string') { - node = document.getElementById(node); - } - if (data === null || data === undefined) { - data = {}; - } - this.scope.push(node.nodeName + (node.id ? '#' + node.id : '')); - try { - // Process attributes - if (node.attributes && node.attributes.length) { - // We need to handle 'foreach' and 'if' first because they might stop - // some types of processing from happening, and foreach must come first - // because it defines new data on which 'if' might depend. - if (node.hasAttribute('foreach')) { - this.processForEach(node, data); - return; - } - if (node.hasAttribute('if')) { - if (!this.processIf(node, data)) { - return; - } - } - // Only make the node available once we know it's not going away - data.__element = node; - // It's good to clean up the attributes when we've processed them, - // but if we do it straight away, we mess up the array index - var attrs = Array.prototype.slice.call(node.attributes); - for (var i = 0; i < attrs.length; i++) { - var value = attrs[i].value; - var name = attrs[i].name; - this.scope.push(name); - try { - if (name === 'save') { - // Save attributes are a setter using the node - value = this.stripBraces(value); - this.property(value, data, node); - node.removeAttribute('save'); - } else if (name.substring(0, 2) === 'on') { - // Event registration relies on property doing a bind - value = this.stripBraces(value); - var func = this.property(value, data); - if (typeof func !== 'function') { - this.handleError('Expected ' + value + - ' to resolve to a function, but got ' + typeof func); - } - node.removeAttribute(name); - var capture = node.hasAttribute('capture' + name.substring(2)); - node.addEventListener(name.substring(2), func, capture); - if (capture) { - node.removeAttribute('capture' + name.substring(2)); - } - } else { - // Replace references in all other attributes - var self = this; - var newValue = value.replace(/\$\{[^}]*\}/g, function(path) { - return self.envEval(path.slice(2, -1), data, value); - }); - // Remove '_' prefix of attribute names so the DOM won't try - // to use them before we've processed the template - if (name.charAt(0) === '_') { - node.removeAttribute(name); - node.setAttribute(name.substring(1), newValue); - } else if (value !== newValue) { - attrs[i].value = newValue; - } - } - } finally { - this.scope.pop(); - } - } - } - - // Loop through our children calling processNode. First clone them, so the - // set of nodes that we visit will be unaffected by additions or removals. - var childNodes = Array.prototype.slice.call(node.childNodes); - for (var j = 0; j < childNodes.length; j++) { - this.processNode(childNodes[j], data); - } - - if (node.nodeType === Node.TEXT_NODE) { - this.processTextNode(node, data); - } - } finally { - this.scope.pop(); - } -}; - -/** - * Handle - * @param node An element with an 'if' attribute - * @param data The data to use with envEval - * @returns true if processing should continue, false otherwise - */ -Templater.prototype.processIf = function(node, data) { - this.scope.push('if'); - try { - var originalValue = node.getAttribute('if'); - var value = this.stripBraces(originalValue); - var recurse = true; - try { - var reply = this.envEval(value, data, originalValue); - recurse = !!reply; - } catch (ex) { - this.handleError('Error with \'' + value + '\'', ex); - recurse = false; - } - if (!recurse) { - node.parentNode.removeChild(node); - } - node.removeAttribute('if'); - return recurse; - } finally { - this.scope.pop(); - } -}; - -/** - * Handle and the special case of - * - * @param node An element with a 'foreach' attribute - * @param data The data to use with envEval - */ -Templater.prototype.processForEach = function(node, data) { - this.scope.push('foreach'); - try { - var originalValue = node.getAttribute('foreach'); - var value = originalValue; - - var paramName = 'param'; - if (value.charAt(0) === '$') { - // No custom loop variable name. Use the default: 'param' - value = this.stripBraces(value); - } else { - // Extract the loop variable name from 'NAME in ${ARRAY}' - var nameArr = value.split(' in '); - paramName = nameArr[0].trim(); - value = this.stripBraces(nameArr[1].trim()); - } - node.removeAttribute('foreach'); - try { - var self = this; - // Process a single iteration of a loop - var processSingle = function(member, clone, ref) { - ref.parentNode.insertBefore(clone, ref); - data[paramName] = member; - self.processNode(clone, data); - delete data[paramName]; - }; - - // processSingle is no good for nodes where we want to work on - // the childNodes rather than the node itself - var processAll = function(scope, member) { - self.scope.push(scope); - try { - if (node.nodeName === 'LOOP') { - for (var i = 0; i < node.childNodes.length; i++) { - var clone = node.childNodes[i].cloneNode(true); - processSingle(member, clone, node); - } - } else { - var clone = node.cloneNode(true); - clone.removeAttribute('foreach'); - processSingle(member, clone, node); - } - } finally { - self.scope.pop(); - } - }; - - var reply = this.envEval(value, data, originalValue); - if (Array.isArray(reply)) { - reply.forEach(function(data, i) { - processAll('' + i, data); - }, this); - } else { - for (var param in reply) { - if (reply.hasOwnProperty(param)) { - processAll(param, param); - } - } - } - node.parentNode.removeChild(node); - } catch (ex) { - this.handleError('Error with \'' + value + '\'', ex); - } - } finally { - this.scope.pop(); - } -}; - -/** - * Take a text node and replace it with another text node with the ${...} - * sections parsed out. We replace the node by altering node.parentNode but - * we could probably use a DOM Text API to achieve the same thing. - * @param node The Text node to work on - * @param data The data to use in calls to envEval - */ -Templater.prototype.processTextNode = function(node, data) { - // Replace references in other attributes - var value = node.data; - // We can't use the string.replace() with function trick (see generic - // attribute processing in processNode()) because we need to support - // functions that return DOM nodes, so we can't have the conversion to a - // string. - // Instead we process the string as an array of parts. In order to split - // the string up, we first replace '${' with '\uF001$' and '}' with '\uF002' - // We can then split using \uF001 or \uF002 to get an array of strings - // where scripts are prefixed with $. - // \uF001 and \uF002 are just unicode chars reserved for private use. - value = value.replace(/\$\{([^}]*)\}/g, '\uF001$$$1\uF002'); - var parts = value.split(/\uF001|\uF002/); - if (parts.length > 1) { - parts.forEach(function(part) { - if (part === null || part === undefined || part === '') { - return; - } - if (part.charAt(0) === '$') { - part = this.envEval(part.slice(1), data, node.data); - } - // It looks like this was done a few lines above but see envEval - if (part === null) { - part = "null"; - } - if (part === undefined) { - part = "undefined"; - } - // if (isDOMElement(part)) { ... } - if (typeof part.cloneNode !== 'function') { - part = node.ownerDocument.createTextNode(part.toString()); - } - node.parentNode.insertBefore(part, node); - }, this); - node.parentNode.removeChild(node); - } -}; - -/** - * Warn of string does not begin '${' and end '}' - * @param str the string to check. - * @return The string stripped of ${ and }, or untouched if it does not match - */ -Templater.prototype.stripBraces = function(str) { - if (!str.match(/\$\{.*\}/g)) { - this.handleError('Expected ' + str + ' to match ${...}'); - return str; - } - return str.slice(2, -1); -}; - -/** - * Combined getter and setter that works with a path through some data set. - * For example: - *
      - *
    • property('a.b', { a: { b: 99 }}); // returns 99 - *
    • property('a', { a: { b: 99 }}); // returns { b: 99 } - *
    • property('a', { a: { b: 99 }}, 42); // returns 99 and alters the - * input data to be { a: { b: 42 }} - *
    - * @param path An array of strings indicating the path through the data, or - * a string to be cut into an array using split('.') - * @param data An object to look in for the path argument - * @param newValue (optional) If defined, this value will replace the - * original value for the data at the path specified. - * @return The value pointed to by path before any - * newValue is applied. - */ -Templater.prototype.property = function(path, data, newValue) { - this.scope.push(path); - try { - if (typeof path === 'string') { - path = path.split('.'); - } - var value = data[path[0]]; - if (path.length === 1) { - if (newValue !== undefined) { - data[path[0]] = newValue; - } - if (typeof value === 'function') { - return function() { - return value.apply(data, arguments); - }; - } - return value; - } - if (!value) { - this.handleError('Can\'t find path=' + path); - return null; - } - return this.property(path.slice(1), value, newValue); - } finally { - this.scope.pop(); - } -}; - -/** - * Like eval, but that creates a context of the variables in env in - * which the script is evaluated. - * WARNING: This script uses 'with' which is generally regarded to be evil. - * The alternative is to create a Function at runtime that takes X parameters - * according to the X keys in the env object, and then call that function using - * the values in the env object. This is likely to be slow, but workable. - * @param script The string to be evaluated. - * @param env The environment in which to eval the script. - * @param context Optional debugging string in case of failure - * @return The return value of the script, or the error message if the script - * execution failed. - */ -Templater.prototype.envEval = function(script, env, context) { - with (env) { - try { - this.scope.push(context); - return eval(script); - } catch (ex) { - this.handleError('Template error evaluating \'' + script + '\'', ex); - return script; - } finally { - this.scope.pop(); - } - } -}; - -/** - * A generic way of reporting errors, for easy overloading in different - * environments. - * @param message the error message to report. - * @param ex optional associated exception. - */ -Templater.prototype.handleError = function(message, ex) { - this.logError(message); - this.logError('In: ' + this.scope.join(' > ')); - if (ex) { - this.logError(ex); - } -}; - - -/** - * A generic way of reporting errors, for easy overloading in different - * environments. - * @param message the error message to report. - */ -Templater.prototype.logError = function(message) { - window.console && window.console.log && console.log(message); -}; - -exports.Templater = Templater; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Skywriter Team (skywriter@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define('cockpit/commands/basic', ['require', 'exports', 'module' , 'pilot/canon'], function(require, exports, module) { - - -var canon = require('pilot/canon'); - -/** - * '!' command - */ -var bangCommandSpec = { - name: 'sh', - description: 'Execute a system command (requires server support)', - params: [ - { - name: 'command', - type: 'text', - description: 'The string to send to the os shell.' - } - ], - exec: function(env, args, request) { - var req = new XMLHttpRequest(); - req.open('GET', '/exec?args=' + args.command, true); - req.onreadystatechange = function(ev) { - if (req.readyState == 4) { - if (req.status == 200) { - request.done('
    ' + req.responseText + '
    '); - } - } - }; - req.send(null); - } -}; - -var canon = require('pilot/canon'); - -exports.startup = function(data, reason) { - canon.addCommand(bangCommandSpec); -}; - -exports.shutdown = function(data, reason) { - canon.removeCommand(bangCommandSpec); -}; - - -}); -define("text!cockpit/ui/cli_view.css", [], "" + - "#cockpitInput { padding-left: 16px; }" + - "" + - "#cockpitOutput { overflow: auto; }" + - "#cockpitOutput.cptFocusPopup { position: absolute; z-index: 999; }" + - "" + - ".cptFocusPopup { display: none; }" + - "#cockpitInput:focus ~ .cptFocusPopup { display: block; }" + - "#cockpitInput:focus ~ .cptFocusPopup.cptNoPopup { display: none; }" + - "" + - ".cptCompletion { padding: 0; position: absolute; z-index: -1000; }" + - ".cptCompletion.VALID { background: #FFF; }" + - ".cptCompletion.INCOMPLETE { background: #DDD; }" + - ".cptCompletion.INVALID { background: #DDD; }" + - ".cptCompletion span { color: #FFF; }" + - ".cptCompletion span.INCOMPLETE { color: #DDD; border-bottom: 2px dotted #F80; }" + - ".cptCompletion span.INVALID { color: #DDD; border-bottom: 2px dotted #F00; }" + - "span.cptPrompt { color: #66F; font-weight: bold; }" + - "" + - "" + - ".cptHints {" + - " color: #000;" + - " position: absolute;" + - " border: 1px solid rgba(230, 230, 230, 0.8);" + - " background: rgba(250, 250, 250, 0.8);" + - " -moz-border-radius-topleft: 10px;" + - " -moz-border-radius-topright: 10px;" + - " border-top-left-radius: 10px; border-top-right-radius: 10px;" + - " z-index: 1000;" + - " padding: 8px;" + - " display: none;" + - "}" + - ".cptHints ul { margin: 0; padding: 0 15px; }" + - "" + - ".cptGt { font-weight: bold; font-size: 120%; }" + - ""); - -define("text!cockpit/ui/request_view.css", [], "" + - ".cptRowIn {" + - " display: box; display: -moz-box; display: -webkit-box;" + - " box-orient: horizontal; -moz-box-orient: horizontal; -webkit-box-orient: horizontal;" + - " box-align: center; -moz-box-align: center; -webkit-box-align: center;" + - " color: #333;" + - " background-color: #EEE;" + - " width: 100%;" + - " font-family: consolas, courier, monospace;" + - "}" + - ".cptRowIn > * { padding-left: 2px; padding-right: 2px; }" + - ".cptRowIn > img { cursor: pointer; }" + - ".cptHover { display: none; }" + - ".cptRowIn:hover > .cptHover { display: block; }" + - ".cptRowIn:hover > .cptHover.cptHidden { display: none; }" + - ".cptOutTyped {" + - " box-flex: 1; -moz-box-flex: 1; -webkit-box-flex: 1;" + - " font-weight: bold; color: #000; font-size: 120%;" + - "}" + - ".cptRowOutput { padding-left: 10px; line-height: 1.2em; }" + - ".cptRowOutput strong," + - ".cptRowOutput b," + - ".cptRowOutput th," + - ".cptRowOutput h1," + - ".cptRowOutput h2," + - ".cptRowOutput h3 { color: #000; }" + - ".cptRowOutput a { font-weight: bold; color: #666; text-decoration: none; }" + - ".cptRowOutput a: hover { text-decoration: underline; cursor: pointer; }" + - ".cptRowOutput input[type=password]," + - ".cptRowOutput input[type=text]," + - ".cptRowOutput textarea {" + - " color: #000; font-size: 120%;" + - " background: transparent; padding: 3px;" + - " border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px;" + - "}" + - ".cptRowOutput table," + - ".cptRowOutput td," + - ".cptRowOutput th { border: 0; padding: 0 2px; }" + - ".cptRowOutput .right { text-align: right; }" + - ""); - -define("text!cockpit/ui/request_view.html", [], "" + - "
    " + - " " + - "
    " + - "" + - " " + - "
    >
    " + - "
    ${request.typed}
    " + - "" + - " " + - "
    " + - " \"Hide" + - " \"Show" + - " \"Remove" + - "" + - "
    " + - "" + - " " + - "
    " + - "
    " + - " " + - "
    " + - "
    " + - ""); - -define("text!cockpit/ui/images/closer.png", [], "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAj9JREFUeNp0ks+LUlEUx7/vV1o8Z8wUx3IEHcQmiBiQlomjRNCiZpEuEqF/oEUwq/6EhvoHggmRcJUQBM1CRJAW0aLIaGQimZJxJsWxyV/P9/R1zzWlFl04vPvOPZ9z7rnnK5imidmKRCIq+zxgdoPZ1T/ut8xeM3tcKpW6s1hhBkaj0Qj7bDebTX+324WmadxvsVigqipcLleN/d4rFoulORiLxTZY8ItOp8MBCpYkiYPj8Xjus9vtlORWoVB4KcTjcQc732dLpSRXvCZaAws6Q4WDdqsO52kNH+oCRFGEz+f7ydwBKRgMPmTXi49GI1x2D/DsznesB06ws2eDbI7w9HYN6bVjvGss4KAjwDAMq81mM2SW5Wa/3weBbz42UL9uYnVpiO2Nr9ANHSGXib2Wgm9tCYIggGKJEVkvlwgi5/FQRmTLxO6hgJVzI1x0T/fJrBtHJxPeL6tI/fsZLA6ot8lkQi8HRVbw94gkWYI5MaHrOjcCGSNRxZosy9y5cErDzn0Dqx7gcwO8WtBp4PndI35GMYqiUMUvBL5yOBz8yRfFNpbPmqgcCFh/IuHa1nR/YXGM8+oUpFhihEQiwcdRLpfVRqOBtWXWq34Gra6AXq8Hp2piZcmKT4cKnE4nwuHwdByVSmWQz+d32WCTlHG/qaHHREN9kgi0sYQfv0R4PB4EAgESQDKXy72fSy6VSnHJVatVf71eR7vd5n66mtfrRSgU4pLLZrOlf7RKK51Ok8g3/yPyR5lMZi7y3wIMAME4EigHWgKnAAAAAElFTkSuQmCC"); - -define("text!cockpit/ui/images/dot_clear.gif", [], "data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAEBMgA7"); - -define("text!cockpit/ui/images/minus.png", [], "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAAZiS0dEANIA0gDS7KbF4AAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kFGw4xMrIJw5EAAAHcSURBVCjPhZIxSxtxGMZ/976XhJA/RA5EAyJcFksnp64hjUPBoXRyCYLQTyD0UxScu0nFwalCQSgFCVk7dXAwUAiBDA2RO4W7yN1x9+9gcyhU+pteHt4H3pfncay1LOl0OgY4BN4Ar/7KP4BvwNFwOIyWu87S2O12O8DxfD73oygiSRIAarUaxhhWV1fHwMFgMBiWxl6v9y6Koi+3t7ckSUKtVkNVAcjzvNRWVlYwxry9vLz86uzs7HjAZDKZGGstjUaDfxHHMSLC5ubmHdB2VfVwNpuZ5clxHPMcRVFwc3PTXFtbO3RFZHexWJCmabnweAaoVqvlv4vFAhHZdVX1ZZqmOI5DURR8fz/lxbp9Yrz+7bD72SfPcwBU1XdF5N5aWy2KgqIoeBzPEnWVLMseYnAcRERdVR27rrsdxzGqyutP6898+GBsNBqo6i9XVS88z9sOggAR4X94noeqXoiIHPm+H9XrdYIgIAxDwjAkTVPCMESzBy3LMprNJr7v34nIkV5dXd2fn59fG2P2siwjSRIqlQrWWlSVJFcqlQqtVot2u40xZu/s7OxnWbl+v98BjkejkT+dTgmCoDxtY2ODra2tMXBweno6fNJVgP39fQN8eKbkH09OTsqS/wHFRdHPfTSfjwAAAABJRU5ErkJggg=="); - -define("text!cockpit/ui/images/pinaction.png", [], "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAC7mlDQ1BJQ0MgUHJvZmlsZQAAeAGFVM9rE0EU/jZuqdAiCFprDrJ4kCJJWatoRdQ2/RFiawzbH7ZFkGQzSdZuNuvuJrWliOTi0SreRe2hB/+AHnrwZC9KhVpFKN6rKGKhFy3xzW5MtqXqwM5+8943731vdt8ADXLSNPWABOQNx1KiEWlsfEJq/IgAjqIJQTQlVdvsTiQGQYNz+Xvn2HoPgVtWw3v7d7J3rZrStpoHhP1A4Eea2Sqw7xdxClkSAog836Epx3QI3+PY8uyPOU55eMG1Dys9xFkifEA1Lc5/TbhTzSXTQINIOJT1cVI+nNeLlNcdB2luZsbIEL1PkKa7zO6rYqGcTvYOkL2d9H5Os94+wiHCCxmtP0a4jZ71jNU/4mHhpObEhj0cGDX0+GAVtxqp+DXCFF8QTSeiVHHZLg3xmK79VvJKgnCQOMpkYYBzWkhP10xu+LqHBX0m1xOv4ndWUeF5jxNn3tTd70XaAq8wDh0MGgyaDUhQEEUEYZiwUECGPBoxNLJyPyOrBhuTezJ1JGq7dGJEsUF7Ntw9t1Gk3Tz+KCJxlEO1CJL8Qf4qr8lP5Xn5y1yw2Fb3lK2bmrry4DvF5Zm5Gh7X08jjc01efJXUdpNXR5aseXq8muwaP+xXlzHmgjWPxHOw+/EtX5XMlymMFMXjVfPqS4R1WjE3359sfzs94i7PLrXWc62JizdWm5dn/WpI++6qvJPmVflPXvXx/GfNxGPiKTEmdornIYmXxS7xkthLqwviYG3HCJ2VhinSbZH6JNVgYJq89S9dP1t4vUZ/DPVRlBnM0lSJ93/CKmQ0nbkOb/qP28f8F+T3iuefKAIvbODImbptU3HvEKFlpW5zrgIXv9F98LZua6N+OPwEWDyrFq1SNZ8gvAEcdod6HugpmNOWls05Uocsn5O66cpiUsxQ20NSUtcl12VLFrOZVWLpdtiZ0x1uHKE5QvfEp0plk/qv8RGw/bBS+fmsUtl+ThrWgZf6b8C8/UXAeIuJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAClklEQVQ4EX1TXUhUQRQ+Z3Zmd+9uN1q2P3UpZaEwcikKekkqLKggKHJ96MHe9DmLkCDa9U198Id8kErICmIlRAN96UdE6QdBW/tBA5Uic7E0zN297L17p5mb1zYjD3eYc+d83zlnON8g5xzWNUSEdUBkHTJasRWySPP7fw3hfwkk2GoNsc0vOaJRHo1GV/GiMctkTIJRFlpZli8opK+htmf83gXeG63oteOtra0u25e7TYJIJELb26vYCACTgUe1lXV86BTn745l+MsyHqs53S/Aq4VEUa9Y6ko14eYY4u3AyM3HYwdKU35DZyblGR2+qq6W0X2Nnh07xynnVYpHORx/E1/GvvqaAZUayjMjdM2f/Lgr5E+fV93zR4u3zKCLughsZqKwAzAxaz6dPY6JgjLUF+eSP5OpjmAw2E8DvldHSvJMKPg08aRor1tc4BuALu6mOwGWdQC3mKIqRsC8mKd8wYfD78/earzSYzdMDW9QgKb0Is8CBY1mQXOiaXAHEpMDE5XTJqIq4EiyxUqKlpfkF0pyV1OTAoFAhmTmyCCoDsZNZvIkUjELQpipo0sQqYZAswZHwsEEE10M0pq2SSZY9HqNcDicJcNTpBvQJz40UbSOTh1B8bDpuY0w9Hb3kkn9lPAlBLfhfD39XTtX/blFJqiqrjbkTi63Hbofj2uL4GMsmzFgbDJ/vmMgv/lB4syJ0oXO7d3j++vio6GFsYmD6cHJreWc3/jRVVHhsOYvM8iZ36mtjPDBk/xDZE8CoHlbrlAssbTxDdDJvdb536L7I6S7Vy++6Gi4Xi9BsUthJRaLOYSPz4XALKI4j4iObd/e5UtDKUjZzYyYRyGAJv01Zj8kC5cbs5WY83hQnv0DzCXl+r8APElkq0RU6oMAAAAASUVORK5CYII="); - -define("text!cockpit/ui/images/pinin.png", [], "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAC7mlDQ1BJQ0MgUHJvZmlsZQAAeAGFVM9rE0EU/jZuqdAiCFprDrJ4kCJJWatoRdQ2/RFiawzbH7ZFkGQzSdZuNuvuJrWliOTi0SreRe2hB/+AHnrwZC9KhVpFKN6rKGKhFy3xzW5MtqXqwM5+8943731vdt8ADXLSNPWABOQNx1KiEWlsfEJq/IgAjqIJQTQlVdvsTiQGQYNz+Xvn2HoPgVtWw3v7d7J3rZrStpoHhP1A4Eea2Sqw7xdxClkSAog836Epx3QI3+PY8uyPOU55eMG1Dys9xFkifEA1Lc5/TbhTzSXTQINIOJT1cVI+nNeLlNcdB2luZsbIEL1PkKa7zO6rYqGcTvYOkL2d9H5Os94+wiHCCxmtP0a4jZ71jNU/4mHhpObEhj0cGDX0+GAVtxqp+DXCFF8QTSeiVHHZLg3xmK79VvJKgnCQOMpkYYBzWkhP10xu+LqHBX0m1xOv4ndWUeF5jxNn3tTd70XaAq8wDh0MGgyaDUhQEEUEYZiwUECGPBoxNLJyPyOrBhuTezJ1JGq7dGJEsUF7Ntw9t1Gk3Tz+KCJxlEO1CJL8Qf4qr8lP5Xn5y1yw2Fb3lK2bmrry4DvF5Zm5Gh7X08jjc01efJXUdpNXR5aseXq8muwaP+xXlzHmgjWPxHOw+/EtX5XMlymMFMXjVfPqS4R1WjE3359sfzs94i7PLrXWc62JizdWm5dn/WpI++6qvJPmVflPXvXx/GfNxGPiKTEmdornIYmXxS7xkthLqwviYG3HCJ2VhinSbZH6JNVgYJq89S9dP1t4vUZ/DPVRlBnM0lSJ93/CKmQ0nbkOb/qP28f8F+T3iuefKAIvbODImbptU3HvEKFlpW5zrgIXv9F98LZua6N+OPwEWDyrFq1SNZ8gvAEcdod6HugpmNOWls05Uocsn5O66cpiUsxQ20NSUtcl12VLFrOZVWLpdtiZ0x1uHKE5QvfEp0plk/qv8RGw/bBS+fmsUtl+ThrWgZf6b8C8/UXAeIuJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABZ0lEQVQ4Ea2TPUsDQRCGZ89Eo4FACkULEQs1CH4Uamfjn7GxEYJFIFXgChFsbPwzNnZioREkaiHBQtEiEEiMRm/dZ8OEGAxR4sBxx877Pju7M2estTJIxLrNuVwuMxQEx0ZkzcFHyRtjXt02559RtB2GYanTYzoryOfz+6l4Nbszf2niwffKmpGRo9sVW22mDgqFwp5C2gDMm+P32a3JB1N+n5JifUGeP9JeNxGryPLYjcwMP8rJ07Q9fZltQzyAstOJ2vVu5sKc1ZZkRBrOcKeb+HexPidvkpCN5JUcllZtpZFc5DgBWc5M2eysZuMuofMBSA4NWjx4PUCsXefMlI0QY3ewRg4NWi4ZTQsgrjYXema+e4VqtEMK6KXvu+4B9Bklt90vVKMeD2BI6DOt4rZ/Gk7WyKFBi4fNPIAJY0joM61SCCZ9tI1o0OIB8D+DBIkYaJRbCBH9mZgNt+bb++ufSSF/eX8BYcDeAzuQJVUAAAAASUVORK5CYII="); - -define("text!cockpit/ui/images/pinout.png", [], "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAC7mlDQ1BJQ0MgUHJvZmlsZQAAeAGFVM9rE0EU/jZuqdAiCFprDrJ4kCJJWatoRdQ2/RFiawzbH7ZFkGQzSdZuNuvuJrWliOTi0SreRe2hB/+AHnrwZC9KhVpFKN6rKGKhFy3xzW5MtqXqwM5+8943731vdt8ADXLSNPWABOQNx1KiEWlsfEJq/IgAjqIJQTQlVdvsTiQGQYNz+Xvn2HoPgVtWw3v7d7J3rZrStpoHhP1A4Eea2Sqw7xdxClkSAog836Epx3QI3+PY8uyPOU55eMG1Dys9xFkifEA1Lc5/TbhTzSXTQINIOJT1cVI+nNeLlNcdB2luZsbIEL1PkKa7zO6rYqGcTvYOkL2d9H5Os94+wiHCCxmtP0a4jZ71jNU/4mHhpObEhj0cGDX0+GAVtxqp+DXCFF8QTSeiVHHZLg3xmK79VvJKgnCQOMpkYYBzWkhP10xu+LqHBX0m1xOv4ndWUeF5jxNn3tTd70XaAq8wDh0MGgyaDUhQEEUEYZiwUECGPBoxNLJyPyOrBhuTezJ1JGq7dGJEsUF7Ntw9t1Gk3Tz+KCJxlEO1CJL8Qf4qr8lP5Xn5y1yw2Fb3lK2bmrry4DvF5Zm5Gh7X08jjc01efJXUdpNXR5aseXq8muwaP+xXlzHmgjWPxHOw+/EtX5XMlymMFMXjVfPqS4R1WjE3359sfzs94i7PLrXWc62JizdWm5dn/WpI++6qvJPmVflPXvXx/GfNxGPiKTEmdornIYmXxS7xkthLqwviYG3HCJ2VhinSbZH6JNVgYJq89S9dP1t4vUZ/DPVRlBnM0lSJ93/CKmQ0nbkOb/qP28f8F+T3iuefKAIvbODImbptU3HvEKFlpW5zrgIXv9F98LZua6N+OPwEWDyrFq1SNZ8gvAEcdod6HugpmNOWls05Uocsn5O66cpiUsxQ20NSUtcl12VLFrOZVWLpdtiZ0x1uHKE5QvfEp0plk/qv8RGw/bBS+fmsUtl+ThrWgZf6b8C8/UXAeIuJAAAACXBIWXMAAAsTAAALEwEAmpwYAAACyUlEQVQ4EW1TXUgUURQ+Z3ZmnVV3QV2xJbVSEIowQbAfLQx8McLoYX2qjB58MRSkP3vZppceYhGxgrZaIughlYpE7CHFWiiKyj9II0qxWmwlNh1Xtp2f27mz7GDlZX7uuXO+73zfuXeQMQYIgAyALppgyBtse32stsw86txkHhATn+FbfPfzxnPB+vR3RMJYuTwW6bbB4a6WS5O3Yu2VlXIesDiAamiQNKVlVXfx5I0GJ7DY7p0/+erU4dgeMJIA31WNxZmAgibOreXDqF55sY4SFUURqbi+nkjgwTyAbHhLX8yOLsSM2QRA3JRAAgd4RGPbVhkKEp8qeJ7PFyW3fw++YHtC7CkaD0amqyqihSwlMQQ0wa07IjPVI/vbexreIUrVaQV2D4RMQ/o7m12Mdfx4H3PfB9FNzTR1U2cO0Bi45aV6xNvFBNaoIAfbSiwLlqi9/hR/R3Nrhua+Oqi9TEKiB02C7YXz+Pba4MTDrpbLiMAxNgmXb+HpwVkZdoIrkn9isW7nRw/TZYaagZArAWyhfqsSDL/c9aTx7JUjGZCtYExRqCzAwGblwr6aFQ84nTo6qZ7XCeCVQNckE/KSWolvoQnxeoFFgIh8G/nA+kBAxxuQO5m9eFrwLIGJHgcyM63VFMhRSgNVyJr7og8y1vbTQpH8DIEVgxuYuexw0QECIalq5FYgEmpkgoFYltU/lnrqDz5osirSFpF7lrHAFKSWHYfEs+mY/82UnAStyMlW8sUPsVIciTZgz3jV1ebg0CEOpgPF22s1z1YQYKSXPJ1hbAhR8T26WdLhkuVfAzPR+YO1Ox5n58SmCcF6e3uzAoHA77RkevJdWH/3+f2O9TGf3w3fWQ2Hw5F/13mcsWAT+vv6DK4kFApJ/d3d1k+kJtbCrmxXHS3n8ER6b3CQbAqaEHVra6sGxcXW4SovLx+empxapS//FfwD9kpMJjMMBBAAAAAASUVORK5CYII="); - -define("text!cockpit/ui/images/pins.png", [], "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAQCAYAAABQrvyxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAGYklEQVRIDbVWe0yURxCf/R735o6DO0FBe0RFsaL4iLXGIKa2SY3P6JGa2GpjlJjUV9NosbU++tYUbEnaQIrVaKJBG7WiNFQFUWO1UUEsVg2CAgoeHHLewcH32O58cBdQsX9Y5+7LfrszOzO/2ZnZj1BKgTBiIwVGVvKd49OVVYunDlXn6wdBKh+ogXrv+DOz1melIb+3LM5fNv2XPYE5EHY+L3PJljN5zavHpJjsQNsA/JJEgyC2+WTjy3b0GfoJW8O4aoHtDwiHQrj5lw1LLyyb1bp5zAjJTus9klrVpdD6TqH2ngVO+0dsRJnp06cLIYU4fx7NnRI3bu7UIYOeJ/McnuY88q3k62gc0S4Dgf5qhICQtIXS2lqD7BhSduPk3YfyzXaANhBBJDxYdUqCywB2qS4RdyUuSkTF/VJxcbH5j8N7/75RuFrN3Zh8OS8zqf5m4UpPeenOyP42dbtBeuvVnCdkK1e4PfPouX03mo9se+c33M8wqDk5Ofqed8REUTicQhbySUxp9u3KlMSHTtrFU6Kyn03lz15PPpW25vsZeYSIKyiVURcqeZJOH9lTNZLfnxRjU/uwrjbEUBWsapcSO2Hq4k0VfZg9EzxdDNCEjDxgNqRDme9umz/btwlsHRIEePHgAf73RdnHZ6LTuIUBN7OBQ+c1Fdnp6cZ1BQUdeRuWZi97o3ktDQQkVeFFzqJARd1A5a0Vr7ta6Kp6TZjtZ+NTIOoKF6qDrL7e0QQIUCiqMMKk8Z1Q/SCSKvzocf2B6NEN0SQn/kTO6fKJ0zqjZUlQBSpJ0GjR77w0aoc1Pr6S5/kVJrNpakV5hR+LWKN4t7sLX+p0rx2vqSta64olIulUKUgCSXLWE1R4KPPSj+5vhm2hdDOG+CkQBmhhyyKq6SaFYWTn5bB3QJRNz54AuXKn8TJjhu0Wbv+wNEKQjVhnmKopjo4FxXmetCRnC4F7BhCiCUepqAepRh0TM/gjjzOOSK2NgWZPc05qampRWJHb7dbOffep2ednzLzgczlbrQA6gHYF9BYDh9GY+FjddMweHMscmMuep07gXlMQoqw9ALoYu5MJsak9QmJA2IvAgVmoCRciooyPujJtNCv1uHt3TmK9gegFKrG9kh6oXwZiIEAtBIjORGKNTWR/WeW8XVkbjuJepLAyloM8LmTN//njKZPbraATZaLjCHEww9Ei4FFiPg6Ja5gT6gxYgLgnRDHRQwJXbz2GOw0d4A3K4GXlUtMahJjYVxiYbrwOmxIS10bFnIBOSi6Tl9Jgs0zbOEX18wyEwgLPMrxD1Y4aCK8kmTpgYcpAF27Mzs42Hjx4kA8BICUlJfKArR7LcEvTB1xEC9AoEw9OPagWkVU/D1oesmK6U911zEczMVe01oZjiMggg6ux2Qk379qh4rYKet4GjrhhwEteBgBrH8BssoXEtbHzPpSBRRSpqlNpgAiUoxzHKxLRszoVuggIisxaDQWZqkQvQjAoax3NbDbLLGuUEABNGedXqSyLRupXgDT5JfAGZNLio9B0X8Uiwk4w77MDc1D4yejjWtykPS3DX01UDCY/GPQcVDe0QYT0CIxGFvUorfvBxZsRfVrUuWruMBAb/lXCUofoFNZfzGJtowXOX0vwUSFK4BgyMKm6P6s9wQUZld+jrYyMDC0iIQDaJdG4IyZQfL3RfbFcCBIlRgc+u3CjaTApuZ9KsANgG8PNzHlWWD3tCxd6kafNNiFp5HAalAkkJ0SCV2H3CgOD9Nc/FqrXuyb0Eocvfhq171p5eyuJ1omKJEP5rQGe/FOOnXtq335z8YmvYo9cHb2t8spIb3lVSseZW46FlGY/Sk9P50P2w20UlWJUkUHIushfc5PXGAzCo0PlD2pnpCYfCXga3lu+fPlevEhWrVrFyrN/Orfv87FOW9tlqb2Kc9pV8DzioMk3UNUbXM+8B/ATBr8C8CKdvGXWGD/9sqm3dkxtzA4McMjHMB8D2ftheYXo+qzt3pXvz8/PP/vk+v8537V+yYW87Zu+RZ1ZbrexoKAA/SBpaWn4+aL5w5zGk+/jW59JiMkESW5urpiVlWXENRb1H/Yf2I9txIxz5IdkX3TsraukpsbQjz6090yb4XsAvQoRE0YvJdamtIIbOnRoUVlZ2ftsLVQzIdEXHntsaZdimssVfCpFui109+BnWPsXaWLI/zactygAAAAASUVORK5CYII="); - -define("text!cockpit/ui/images/plus.png", [], "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAAZiS0dEANIA0gDS7KbF4AAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kFGw4yFTwuJTkAAAH7SURBVCjPdZKxa1NRFMZ/956XZMgFyyMlCZRA4hBx6lBcQ00GoYi4tEstFPwLAs7iLDi7FWuHThaUggihBDI5OWRoQAmBQFISQgvvpbwX3rsOaR4K+o2H8zvfOZxPWWtZqVarGaAJPAEe3ZW/A1+Bd+1221v1qhW4vb1dA44mk0nZ8zyCIAAgk8lgjGF9fb0PHF5cXLQTsF6vP/c879P19TVBEJDJZBARAKIoSmpra2sYY561Wq3PqtFouMBgMBgYay3ZbJZ/yfd9tNaUSqUboOKISPPq6sqsVvZ9H4AvL34B8PTj/QSO45jpdHovn883Ha31znw+JwzDpCEMQx4UloM8zyOdTif3zudztNY7jog8DMMQpRRxHPPt5TCBAEZvxlyOFTsfykRRBICIlB2t9a21Nh3HMXEc8+d7VhJHWCwWyzcohdZaHBHpO46z6fs+IsLj94XECaD4unCHL8FsNouI/HRE5Nx13c3ZbIbWOnG5HKtl+53TSq7rIiLnand31wUGnU7HjEYjlFLJZN/3yRnL1FMYY8jlcmxtbd0AFel2u7dnZ2eXxpi9xWJBEASkUimstYgIQSSkUimKxSKVSgVjzN7p6emPJHL7+/s14KjX65WHwyGz2SxZbWNjg2q12gcOT05O2n9lFeDg4MAAr/4T8rfHx8dJyH8DvvbYGzKvWukAAAAASUVORK5CYII="); - -define("text!cockpit/ui/images/throbber.gif", [], "data:image/gif;base64,R0lGODlh3AATAPQAAP///wAAAL6+vqamppycnLi4uLKyssjIyNjY2MTExNTU1Nzc3ODg4OTk5LCwsLy8vOjo6Ozs7MrKyvLy8vT09M7Ozvb29sbGxtDQ0O7u7tbW1sLCwqqqqvj4+KCgoJaWliH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAA3AATAAAF/yAgjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEgECAaEpHLJbDqf0Kh0Sq1ar9isdjoQtAQFg8PwKIMHnLF63N2438f0mv1I2O8buXjvaOPtaHx7fn96goR4hmuId4qDdX95c4+RG4GCBoyAjpmQhZN0YGYFXitdZBIVGAoKoq4CG6Qaswi1CBtkcG6ytrYJubq8vbfAcMK9v7q7D8O1ycrHvsW6zcTKsczNz8HZw9vG3cjTsMIYqQgDLAQGCQoLDA0QCwUHqfYSFw/xEPz88/X38Onr14+Bp4ADCco7eC8hQYMAEe57yNCew4IVBU7EGNDiRn8Z831cGLHhSIgdE/9chIeBgDoB7gjaWUWTlYAFE3LqzDCTlc9WOHfm7PkTqNCh54rePDqB6M+lR536hCpUqs2gVZM+xbrTqtGoWqdy1emValeXKwgcWABB5y1acFNZmEvXwoJ2cGfJrTv3bl69Ffj2xZt3L1+/fw3XRVw4sGDGcR0fJhxZsF3KtBTThZxZ8mLMgC3fRatCLYMIFCzwLEprg84OsDus/tvqdezZf13Hvr2B9Szdu2X3pg18N+68xXn7rh1c+PLksI/Dhe6cuO3ow3NfV92bdArTqC2Ebc3A8vjf5QWf15Bg7Nz17c2fj69+fnq+8N2Lty+fuP78/eV2X13neIcCeBRwxorbZrAxAJoCDHbgoG8RTshahQ9iSKEEzUmYIYfNWViUhheCGJyIP5E4oom7WWjgCeBBAJNv1DVV01MZdJhhjdkplWNzO/5oXI846njjVEIqR2OS2B1pE5PVscajkxhMycqLJgxQCwT40PjfAV4GqNSXYdZXJn5gSkmmmmJu1aZYb14V51do+pTOCmA00AqVB4hG5IJ9PvYnhIFOxmdqhpaI6GeHCtpooisuutmg+Eg62KOMKuqoTaXgicQWoIYq6qiklmoqFV0UoeqqrLbq6quwxirrrLTWauutJ4QAACH5BAkKAAAALAAAAADcABMAAAX/ICCOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSAQIBoSkcslsOp/QqHRKrVqv2Kx2OhC0BAXHx/EoCzboAcdhcLDdgwJ6nua03YZ8PMFPoBMca215eg98G36IgYNvDgOGh4lqjHd7fXOTjYV9nItvhJaIfYF4jXuIf4CCbHmOBZySdoOtj5eja59wBmYFXitdHhwSFRgKxhobBgUPAmdoyxoI0tPJaM5+u9PaCQZzZ9gP2tPcdM7L4tLVznPn6OQb18nh6NV0fu3i5OvP8/nd1qjwaasHcIPAcf/gBSyAAMMwBANYEAhWYQGDBhAyLihwYJiEjx8fYMxIcsGDAxVA/yYIOZIkBAaGPIK8INJlRpgrPeasaRPmx5QgJfB0abLjz50tSeIM+pFmUo0nQQIV+vRlTJUSnNq0KlXCSq09ozIFexEBAYkeNiwgOaEtn2LFpGEQsKCtXbcSjOmVlqDuhAx3+eg1Jo3u37sZBA9GoMAw4MB5FyMwfLht4sh7G/utPGHlYAV8Nz9OnOBz4c2VFWem/Pivar0aKCP2LFn2XwhnVxBwsPbuBAQbEGiIFg1BggoWkidva5z4cL7IlStfkED48OIYoiufYIH68+cKPkqfnsB58ePjmZd3Dj199/XE20tv6/27XO3S6z9nPCz9BP3FISDefL/Bt192/uWmAv8BFzAQAQUWWFaaBgqA11hbHWTIXWIVXifNhRlq6FqF1sm1QQYhdiAhbNEYc2KKK1pXnAIvhrjhBh0KxxiINlqQAY4UXjdcjSJyeAx2G2BYJJD7NZQkjCPKuCORKnbAIXsuKhlhBxEomAIBBzgIYXIfHfmhAAyMR2ZkHk62gJoWlNlhi33ZJZ2cQiKTJoG05Wjcm3xith9dcOK5X51tLRenoHTuud2iMnaolp3KGXrdBo7eKYF5p/mXgJcogClmcgzAR5gCKymXYqlCgmacdhp2UCqL96mq4nuDBTmgBasaCFp4sHaQHHUsGvNRiiGyep1exyIra2mS7dprrtA5++z/Z8ZKYGuGsy6GqgTIDvupRGE+6CO0x3xI5Y2mOTkBjD4ySeGU79o44mcaSEClhglgsKyJ9S5ZTGY0Bnzrj+3SiKK9Rh5zjAALCywZBk/ayCWO3hYM5Y8Dn6qxxRFsgAGoJwwgDQRtYXAAragyQOmaLKNZKGaEuUlpyiub+ad/KtPqpntypvvnzR30DBtjMhNodK6Eqrl0zU0/GjTUgG43wdN6Ra2pAhGtAAZGE5Ta8TH6wknd2IytNKaiZ+Or79oR/tcvthIcAPe7DGAs9Edwk6r3qWoTaNzY2fb9HuHh2S343Hs1VIHhYtOt+Hh551rh24vP5YvXSGzh+eeghy76GuikU9FFEainrvrqrLfu+uuwxy777LTXfkIIACH5BAkKAAAALAAAAADcABMAAAX/ICCOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSAQIBoSkcslsOp/QqHRKrVqv2Kx2OhC0BAWHB2l4CDZo9IDjcBja7UEhTV+3DXi3PJFA8xMcbHiDBgMPG31pgHBvg4Z9iYiBjYx7kWocb26OD398mI2EhoiegJlud4UFiZ5sm6Kdn2mBr5t7pJ9rlG0cHg5gXitdaxwFGArIGgoaGwYCZ3QFDwjU1AoIzdCQzdPV1c0bZ9vS3tUJBmjQaGXl1OB0feze1+faiBvk8wjnimn55e/o4OtWjp+4NPIKogsXjaA3g/fiGZBQAcEAFgQGOChgYEEDCCBBLihwQILJkxIe/3wMKfJBSQkJYJpUyRIkgwcVUJq8QLPmTYoyY6ZcyfJmTp08iYZc8MBkhZgxk9aEcPOlzp5FmwI9KdWn1qASurJkClRoWKwhq6IUqpJBAwQEMBYroAHkhLt3+RyzhgCDgAV48Wbgg+waAnoLMgTOm6DwQ8CLBzdGdvjw38V5JTg2lzhyTMeUEwBWHPgzZc4TSOM1bZia6LuqJxCmnOxv7NSsl1mGHHiw5tOuIWeAEHcFATwJME/ApgFBc3MVLEgPvE+Ddb4JokufPmFBAuvPXWu3MIF89wTOmxvOvp179evQtwf2nr6aApPyzVd3jn089e/8xdfeXe/xdZ9/d1ngHf98lbHH3V0LMrgPgsWpcFwBEFBgHmyNXWeYAgLc1UF5sG2wTHjIhNjBiIKZCN81GGyQwYq9uajeMiBOQGOLJ1KjTI40kmfBYNfc2NcGIpI4pI0vyrhjiT1WFqOOLEIZnjVOVpmajYfBiCSNLGbA5YdOkjdihSkQwIEEEWg4nQUmvYhYe+bFKaFodN5lp3rKvJYfnBKAJ+gGDMi3mmbwWYfng7IheuWihu5p32XcSWdSj+stkF95dp64jJ+RBipocHkCCp6PCiRQ6INookCAAwy0yd2CtNET3Yo7RvihBjFZAOaKDHT43DL4BQnsZMo8xx6uI1oQrHXXhHZrB28G62n/YSYxi+uzP2IrgbbHbiaer7hCiOxDFWhrbmGnLVuus5NFexhFuHLX6gkEECorlLpZo0CWJG4pLjIACykmBsp0eSSVeC15TDJeUhlkowlL+SWLNJpW2WEF87urXzNWSZ6JOEb7b8g1brZMjCg3ezBtWKKc4MvyEtwybPeaMAA1ECRoAQYHYLpbeYYCLfQ+mtL5c9CnfQpYpUtHOSejEgT9ogZ/GSqd0f2m+LR5WzOtHqlQX1pYwpC+WbXKqSYtpJ5Mt4a01lGzS3akF60AxkcTaLgAyRBPWCoDgHfJqwRuBuzdw/1ml3iCwTIeLUWJN0v4McMe7uasCTxseNWPSxc5RbvIgD7geZLbGrqCG3jepUmbbze63Y6fvjiOylbwOITPfIHEFsAHL/zwxBdvPBVdFKH88sw37/zz0Ecv/fTUV2/99SeEAAAh+QQJCgAAACwAAAAA3AATAAAF/yAgjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEgECAaEpHLJbDqf0Kh0Sq1ar9isdjoQtAQFh2cw8BQEm3T6yHEYHHD4oKCuD9qGvNsxT6QTgAkcHHmFeX11fm17hXwPG35qgnhxbwMPkXaLhgZ9gWp3bpyegX4DcG+inY+Qn6eclpiZkHh6epetgLSUcBxlD2csXXdvBQrHGgoaGhsGaIkFDwjTCArTzX+QadHU3c1ofpHc3dcGG89/4+TYktvS1NYI7OHu3fEJ5tpqBu/k+HX7+nXDB06SuoHm0KXhR65cQT8P3FRAMIAFgVMPwDCAwLHjggIHJIgceeFBg44eC/+ITCCBZYKSJ1FCWPBgpE2YMmc+qNCypwScMmnaXAkUJYOaFVyKLOqx5tCXJnMelcBzJNSYKIX2ZPkzqsyjPLku9Zr1QciVErYxaICAgEUOBRJIgzChbt0MLOPFwyBggV27eCUcmxZvg9+/dfPGo5bg8N/Ag61ZM4w4seDF1fpWhizZmoa+GSortgcaMWd/fkP/HY0MgWbTipVV++wY8GhvqSG4XUEgoYTKE+Qh0OCvggULiBckWEZ4Ggbjx5HXVc58IPQJ0idQJ66XanTpFraTe348+XLizRNcz658eHMN3rNPT+C+G/nodqk3t6a+fN3j+u0Xn3nVTQPfdRPspkL/b+dEIN8EeMm2GAYbTNABdrbJ1hyFFv5lQYTodSZABhc+loCEyhxTYYkZopdMMiNeiBxyIFajV4wYHpfBBspUl8yKHu6ooV5APsZjQxyyeNeJ3N1IYod38cgdPBUid6GCKfRWgAYU4IccSyHew8B3doGJHmMLkGkZcynKk2Z50Ym0zJzLbDCmfBbI6eIyCdyJmJmoqZmnBAXy9+Z/yOlZDZpwYihnj7IZpuYEevrYJ5mJEuqiof4l+NYDEXQpXQcMnNjZNDx1oGqJ4S2nF3EsqWrhqqVWl6JIslpAK5MaIqDeqjJq56qN1aTaQaPbHTPYr8Be6Gsyyh6Da7OkmmqP/7GyztdrNVQBm5+pgw3X7aoYKhfZosb6hyUKBHCgQKij1rghkOAJuZg1SeYIIY+nIpDvf/sqm4yNG5CY64f87qdAwSXKGqFkhPH1ZHb2EgYtw3bpKGVkPz5pJAav+gukjB1UHE/HLNJobWcSX8jiuicMMBFd2OmKwQFs2tjXpDfnPE1j30V3c7iRHlrzBD2HONzODyZtsQJMI4r0AUNaE3XNHQw95c9GC001MpIxDacFQ+ulTNTZlU3O1eWVHa6vb/pnQUUrgHHSBKIuwG+bCPyEqbAg25gMVV1iOB/IGh5YOKLKIQ6xBAcUHmzjIcIqgajZ+Ro42DcvXl7j0U4WOUd+2IGu7DWjI1pt4DYq8BPm0entuGSQY/4tBi9Ss0HqfwngBQtHbCH88MQXb/zxyFfRRRHMN+/889BHL/301Fdv/fXYZ39CCAAh+QQJCgAAACwAAAAA3AATAAAF/yAgjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEgECAaEpHLJbDqf0Kh0Sq1ar9isdjoQtAQFh2fAKXsKm7R6Q+Y43vABep0mGwwOPH7w2CT+gHZ3d3lyagl+CQNvg4yGh36LcHoGfHR/ZYOElQ9/a4ocmoRygIiRk5p8pYmZjXePaYBujHoOqp5qZHBlHAUFXitddg8PBg8KGsgayxvGkAkFDwgICtPTzX2mftHW3QnOpojG3dbYkNjk1waxsdDS1N7ga9zw1t/aifTk35fu6Qj3numL14fOuHTNECHqU4DDgQEsCCwidiHBAwYQMmpcUOCAhI8gJVzUuLGThAQnP/9abEAyI4MCIVOKZNnyJUqUJxNcGNlywYOQgHZirGkSJ8gHNEky+AkS58qWEJYC/bMzacmbQHkqNdlUJ1KoSz2i9COhmQYCEXtVrCBgwYS3cCf8qTcNQ9u4cFFOq2bPLV65Cf7dxZthbjW+CgbjnWtNgWPFcAsHdoxgWWK/iyV045sAc2S96SDn1exYw17REwpLQEYt2eW/qtPZRQAB7QoC61RW+GsBwYZ/CXb/XRCYLsAKFizEtUAc+G7lcZsjroscOvTmsoUvx15PwccJ0N8yL17N9PG/E7jv9S4hOV7pdIPDdZ+ePDzv2qMXn2b5+wTbKuAWnF3oZbABZY0lVmD/ApQd9thybxno2GGuCVDggaUpoyBsB1bGGgIYbJCBcuFJiOAyGohIInQSmmdeiBnMF2GHfNUlIoc1rncjYRjW6NgGf3VQGILWwNjBfxEZcAFbC7gHXQcfUYOYdwzQNxo5yUhQZXhvRYlMeVSuSOJHKJa5AQMQThBlZWZ6Bp4Fa1qzTAJbijcBlJrtxeaZ4lnnpZwpukWieGQmYx5ATXIplwTL8DdNZ07CtWYybNIJF4Ap4NZHe0920AEDk035kafieQrqXofK5ympn5JHKYjPrfoWcR8WWQGp4Ul32KPVgXdnqxM6OKqspjIYrGPDrlrsZtRIcOuR86nHFwbPvmes/6PH4frrqbvySh+mKGhaAARPzjjdhCramdoGGOhp44i+zogBkSDuWC5KlE4r4pHJkarXrj++Raq5iLmWLlxHBteavjG+6amJrUkJJI4Ro5sBv9AaOK+jAau77sbH7nspCwNIYIACffL7J4JtWQnen421nNzMcB6AqpRa9klonmBSiR4GNi+cJZpvwgX0ejj71W9yR+eIgaVvQgf0l/A8nWjUFhwtZYWC4hVnkZ3p/PJqNQ5NnwUQrQCGBBBMQIGTtL7abK+5JjAv1fi9bS0GLlJHgdjEgYzzARTwC1fgEWdJuKKBZzj331Y23qB3i9v5aY/rSUC4w7PaLeWXmr9NszMFoN79eeiM232o33EJAIzaSGwh++y012777bhT0UURvPfu++/ABy/88MQXb/zxyCd/QggAIfkECQoAAAAsAAAAANwAEwAABf8gII5kaZ5oqq5s675wLM90bd94ru987//AoHBIBAgGhKRyyWw6n9CodEqtWq/YrHY6ELQEBY5nwCk7xIWNer0hO95wziC9Ttg5b4ND/+Y87IBqZAaEe29zGwmJigmDfHoGiImTjXiQhJEPdYyWhXwDmpuVmHwOoHZqjI6kZ3+MqhyemJKAdo6Ge3OKbEd4ZRwFBV4rc4MPrgYPChrMzAgbyZSJBcoI1tfQoYsJydfe2amT3d7W0OGp1OTl0YtqyQrq0Lt11PDk3KGoG+nxBpvTD9QhwCctm0BzbOyMIwdOUwEDEgawIOCB2oMLgB4wgMCx44IHBySIHClBY0ePfyT/JCB5weRJCAwejFw58kGDlzBTqqTZcuPLmCIBiWx58+VHmiRLFj0JVCVLl0xl7qSZwCbOo0lFWv0pdefQrVFDJtr5gMBEYBgxqBWwYILbtxPsqMPAFu7blfa81bUbN4HAvXAzyLWnoDBguHIRFF6m4LBbwQngMYPXuC3fldbyPrMcGLM3w5wRS1iWWUNlvnElKDZtz/EEwaqvYahQoexEfyILi4RrYYKFZwJ3810QWZ2ECrx9Ew+O3K6F5Yq9zXbb+y30a7olJJ+wnLC16W97Py+uwdtx1NcLWzs/3G9e07stVPc9kHJ0BcLtQp+c3ewKAgYkUAFpCaAmmHqKLSYA/18WHEiZPRhsQF1nlLFWmIR8ZbDBYs0YZuCGpGXWmG92aWiPMwhEOOEEHXRwIALlwXjhio+BeE15IzpnInaLbZBBhhti9x2GbnVQo2Y9ZuCfCgBeMCB+DJDIolt4iVhOaNSJdCOBUfIlkmkyMpPAAvKJ59aXzTQzJo0WoJnmQF36Jp6W1qC4gWW9GZladCiyJd+KnsHImgRRVjfnaDEKuiZvbcYWo5htzefbl5LFWNeSKQAo1QXasdhiiwwUl2B21H3aQaghXnPcp1NagCqYslXAqnV+zYWcpNwVp9l5eepJnHqL4SdBi56CGlmw2Zn6aaiZjZqfb8Y2m+Cz1O0n3f+tnvrGbF6kToApCgAWoNWPeh754JA0vmajiAr4iOuOW7abQXVGNriBWoRdOK8FxNqLwX3oluubhv8yluRbegqGb536ykesuoXhyJqPQJIGbLvQhkcwjKs1zBvBwSZIsbcsDCCBAAf4ya+UEhyQoIiEJtfoZ7oxUOafE2BwgMWMqUydfC1LVtiArk0QtGkWEopzlqM9aJrKHfw5c6wKjFkmXDrbhwFockodtMGFLWpXy9JdiXN1ZDNszV4WSLQCGBKoQYHUyonqrHa4ErewAgMmcAAF7f2baIoVzC2p3gUvJtLcvIWqloy6/R04mIpLwDhciI8qLOB5yud44pHPLbA83hFDWPjNbuk9KnySN57Av+TMBvgEAgzzNhJb5K777rz37vvvVHRRxPDEF2/88cgnr/zyzDfv/PPQnxACACH5BAkKAAAALAAAAADcABMAAAX/ICCOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSAQIBoSkcslsOp/QqHRKrVqv2Kx2OhC0BIUCwcMpO84OT2HDbm8GHLQjnn6wE3g83SA3DB55G3llfHxnfnZ4gglvew6Gf4ySgmYGlpCJknochWiId3kJcZZyDn93i6KPl4eniopwq6SIoZKxhpenbhtHZRxhXisDopwPgHkGDxrLGgjLG8mC0gkFDwjX2AgJ0bXJ2djbgNJsAtbfCNB2oOnn6MmKbeXt226K1fMGi6j359D69ua+QZskjd+3cOvY9XNgp4ABCQNYEDBl7EIeCQkeMIDAseOCBwckiBSZ4ILGjh4B/40kaXIjSggMHmBcifHky5gYE6zM2OAlzGM6Z5rs+fIjTZ0tfcYMSlLCUJ8fL47kCVXmTjwPiKJkUCDnyqc3CxzQmYeAxAEGLGJYiwCDgAUT4sqdgOebArdw507IUNfuW71xdZ7DC5iuhGsKErf9CxhPYgUaEhPWyzfBMgUIJDPW6zhb5M1y+R5GjFkBaLmCM0dOfHqvztXYJnMejaFCBQlmVxAYsEGkYnQV4lqYMNyCtnYSggNekAC58uJxmTufW5w55mwKkg+nLp105uTC53a/nhg88fMTmDfDVl65Xum/IZt/3/zaag3a5W63nll1dvfiWbaaZLmpQIABCVQA2f9lAhTG112PQWYadXE9+FtmEwKWwQYQJrZagxomsOCAGVImInsSbpCBhhwug6KKcXXQQYUcYuDMggrASFmNzjjzzIrh7cUhhhHqONeGpSEW2QYxHsmjhxpgUGAKB16g4IIbMNCkXMlhaJ8GWVJo2I3NyKclYF1GxgyYDEAnXHJrMpNAm/rFBSczPiYAlwXF8ZnmesvoOdyMbx7m4o0S5LWdn4bex2Z4xYmEzaEb5EUcnxbA+WWglqIn6aHPTInCgVbdlZyMqMrIQHMRSiaBBakS1903p04w434n0loBoQFOt1yu2YAnY68RXiNsqh2s2qqxuyKb7Imtmgcrqsp6h8D/fMSpapldx55nwayK/SfqCQd2hcFdAgDp5GMvqhvakF4mZuS710WGIYy30khekRkMu92GNu6bo7r/ttjqwLaua5+HOdrKq5Cl3dcwi+xKiLBwwwom4b0E6xvuYyqOa8IAEghwQAV45VvovpkxBl2mo0W7AKbCZXoAhgMmWnOkEqx2JX5nUufbgJHpXCfMOGu2QAd8eitpW1eaNrNeMGN27mNz0swziYnpSbXN19gYtstzfXrdYjNHtAIYGFVwwAEvR1dfxdjKxVzAP0twAAW/ir2w3nzTd3W4yQWO3t0DfleB4XYnEHCEhffdKgaA29p0eo4fHLng9qoG+OVyXz0gMeWGY7qq3xhiRIEAwayNxBawxy777LTXbjsVXRSh++689+7778AHL/zwxBdv/PEnhAAAIfkECQoAAAAsAAAAANwAEwAABf8gII5kaZ5oqq5s675wLM90bd94ru987//AoHBIBAgGhKRyyWw6n9CodEqtWq/YrHY6ELQEhYLD4BlwHGg0ubBpuzdm9Dk9eCTu+MTZkDb4PXYbeIIcHHxqf4F3gnqGY2kOdQmCjHCGfpCSjHhmh2N+knmEkJmKg3uHfgaaeY2qn6t2i4t7sKAPbwIJD2VhXisDCQZgDrKDBQ8aGgjKyhvDlJMJyAjV1gjCunkP1NfVwpRtk93e2ZVt5NfCk27jD97f0LPP7/Dr4pTp1veLgvrx7AL+Q/BM25uBegoYkDCABYFhEobhkUBRwoMGEDJqXPDgQMUEFC9c1LjxQUUJICX/iMRIEgIDkycrjmzJMSXFlDNJvkwJsmdOjQwKfDz5M+PLoSGLQqgZU6XSoB/voHxawGbFlS2XGktAwKEADB0xiEWAodqGBRPSqp1wx5qCamDRrp2Qoa3bagLkzrULF4GCvHPTglRAmKxZvWsHayBcliDitHUlvGWM97FgCdYWVw4c2e/kw4HZJlCwmDBhwHPrjraGYTHqtaoxVKggoesKAgd2SX5rbUMFCxOAC8cGDwHFwBYWJCgu4XfwtcqZV0grPHj0u2SnqwU+IXph3rK5b1fOu7Bx5+K7L6/2/Xhg8uyXnQ8dvfRiDe7TwyfNuzlybKYpgIFtKhAgwEKkKcOf/wChZbBBgMucRh1so5XH3wbI1WXafRJy9iCErmX4IWHNaIAhZ6uxBxeGHXQA24P3yYfBBhmgSBozESpwongWOBhggn/N1aKG8a1YY2oVAklgCgQUUwGJ8iXAgItrWUARbwpqIOWEal0ZoYJbzmWlZCWSlsAC6VkwZonNbMAAl5cpg+NiZwpnJ0Xylegmlc+tWY1mjnGnZnB4QukMA9UJRxGOf5r4ppqDjjmnfKilh2ejGiyJAgF1XNmYbC2GmhZ5AcJVgajcXecNqM9Rx8B6bingnlotviqdkB3YCg+rtOaapFsUhSrsq6axJ6sEwoZK7I/HWpCsr57FBxJ1w8LqV/81zbkoXK3LfVeNpic0KRQG4NHoIW/XEmZuaiN6tti62/moWbk18uhjqerWS6GFpe2YVotskVssWfBOAHACrZHoWcGQwQhlvmsdXBZ/F9YLMF2jzUuYBP4a7CLCnoEHrgkDSCDAARUILAGaVVqAwQHR8pZXomm9/ONhgjrbgc2lyYxmpIRK9uSNjrXs8gEbTrYyl2ryTJmsLCdKkWzFQl1lWlOXGmifal6p9VnbQfpyY2SZyXKVV7JmZkMrgIFSyrIeUJ2r7YKnXdivUg1kAgdQ8B7IzJjGsd9zKSdwyBL03WpwDGxwuOASEP5vriO2F3nLjQdIrpaRDxqcBdgIHGA74pKrZXiR2ZWuZt49m+o3pKMC3p4Av7SNxBa456777rz37jsVXRQh/PDEF2/88cgnr/zyzDfv/PMnhAAAIfkECQoAAAAsAAAAANwAEwAABf8gII5kaZ5oqq5s675wLM90bd94ru987//AoHBIBAgGhKRyyWw6n9CodEqtWq/YrHY6ELQEhYLDUPAMHGi0weEpbN7wI8cxTzsGj4R+n+DUxwaBeBt7hH1/gYIPhox+Y3Z3iwmGk36BkIN8egOIl3h8hBuOkAaZhQlna4BrpnyWa4mleZOFjrGKcXoFA2ReKwMJBgISDw6abwUPGggazc0bBqG0G8kI1tcIwZp51djW2nC03d7BjG8J49jl4cgP3t/RetLp1+vT6O7v5fKhAvnk0UKFogeP3zmCCIoZkDCABQFhChQYuKBHgkUJkxpA2MhxQYEDFhNcvPBAI8eNCx7/gMQYckPJkxsZPLhIM8FLmDJrYiRp8mTKkCwT8IQJwSPQkENhpgQpEunNkzlpWkwKdSbGihKocowqVSvKWQkIOBSgQOYFDBgQpI0oYMGEt3AzTLKm4BqGtnDjirxW95vbvG/nWlub8G9euRsiqqWLF/AEkRoiprX2wLDeDQgkW9PQGLDgyNc665WguK8C0XAnRY6oGPUEuRLsgk5g+a3cCxUqSBC7gsCBBXcVq6swwULx4hayvctGPK8FCwsSLE9A3Hje6NOrHzeOnW695sffRi/9HfDz7sIVSNB+XXrmugo0rHcM3X388o6jr44ceb51uNjF1xcC8zk3wXiS8aYC/wESaLABBs7ch0ECjr2WAGvLsLZBeHqVFl9kGxooV0T81TVhBo6NiOEyJ4p4IYnNRBQiYCN6x4wCG3ZAY2If8jXjYRcyk2FmG/5nXAY8wqhWAii+1YGOSGLoY4VRfqiAgikwmIeS1gjAgHkWYLQZf9m49V9gDWYWY5nmTYCRM2TS5pxxb8IZGV5nhplmhJyZadxzbrpnZ2d/6rnZgHIid5xIMDaDgJfbLdrgMkKW+Rygz1kEZz1mehabkBpgiQIByVikwGTqVfDkk2/Vxxqiqur4X3fksHccre8xlxerDLiHjQIVUAgXr77yFeyuOvYqXGbMrbrqBMqaFpFFzhL7qv9i1FX7ZLR0LUNdcc4e6Cus263KbV+inkAAHhJg0BeITR6WmHcaxhvXg/AJiKO9R77ILF1FwmVdAu6WBu+ZFua72mkZWMfqBElKu0G8rFZ5n4ATp5jkmvsOq+Nj7u63ZMMPv4bveyYy6fDH+C6brgnACHBABQUrkGirz2FwAHnM4Mmhzq9yijOrOi/MKabH6VwBiYwZdukEQAvILKTWXVq0ZvH5/CfUM7M29Zetthp1eht0eqkFYw8IKXKA6mzXfTeH7fZg9zW0AhgY0TwthUa6Ch9dBeIsbsFrYkRBfgTfiG0FhwMWnbsoq3cABUYOnu/ejU/A6uNeT8u4wMb1WnBCyJJTLjjnr8o3OeJrUcpc5oCiPqAEkz8tXuLkPeDL3Uhs4fvvwAcv/PDEU9FFEcgnr/zyzDfv/PPQRy/99NRXf0IIACH5BAkKAAAALAAAAADcABMAAAX/ICCOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSAQIBoSkcslsOp/QqHRKrVqv2Kx2OhC0BIWCw/AoDziOtCHt8BQ28PjmzK57Hom8fo42+P8DeAkbeYQcfX9+gYOFg4d1bIGEjQmPbICClI9/YwaLjHAJdJeKmZOViGtpn3qOqZineoeJgG8CeWUbBV4rAwkGAhIVGL97hGACGsrKCAgbBoTRhLvN1c3PepnU1s2/oZO6AtzdBoPf4eMI3tIJyOnF0YwFD+nY8e3z7+Xfefnj9uz8cVsXCh89axgk7BrAggAwBQsYIChwQILFixIeNIDAseOCBwcSXMy2sSPHjxJE/6a0eEGjSY4MQGK86PIlypUJEmYsaTKmyJ8JW/Ls6HMkzaEn8YwMWtPkx4pGd76E4DMPRqFTY860OGhogwYagBFoKEABA46DEGBAoEBB0AUT4sqdIFKBNbcC4M6dkEEk22oYFOTdG9fvWrtsBxM23MytYL17666t9phwXwlum2lIDHmuSA2IGyuOLOHv38qLMbdFjHruZbWgRXeOe1nC2BUEDiyAMMHZuwoTLAQX3nvDOAUW5Vogru434d4JnAsnPmFB9NBshQXfa9104+Rxl8e13rZxN+CEydtVsFkd+vDjE7C/q52wOvb4s7+faz025frbxefWbSoQIAEDEUCwgf9j7bUlwHN9ZVaegxDK1xYzFMJH24L5saXABhlYxiEzHoKoIV8LYqAMaw9aZqFmJUK4YHuNfRjiXhmk+NcyJgaIolvM8BhiBx3IleN8lH1IWAcRgkZgCgYiaBGJojGgHHFTgtagAFYSZhF7/qnTpY+faVlNAnqJN0EHWa6ozAZjBtgmmBokwMB01LW5jAZwbqfmlNips4B4eOqJgDJ2+imXRZpthuigeC6XZTWIxilXmRo8iYKBCwiWmWkJVEAkfB0w8KI1IvlIpKnOkVpqdB5+h96o8d3lFnijrgprjbfGRSt0lH0nAZG5vsprWxYRW6Suq4UWqrLEsspWg8Io6yv/q6EhK0Fw0GLbjKYn5CZYBYht1laPrnEY67kyrhYbuyceiR28Pso7bYwiXjihjWsWuWF5p/H765HmNoiur3RJsGKNG/jq748XMrwmjhwCfO6QD9v7LQsDxPTAMKsFpthyJCdkmgYiw0VdXF/Om9dyv7YMWGXTLYpZg5wNR11C78oW3p8HSGgul4qyrJppgllJHJZHn0Y0yUwDXCXUNquFZNLKyYXBAVZvxtAKYIQEsmPgDacr0tltO1y/DMwYpkgUpJfTasLGzd3cdCN3gN3UWRcY3epIEPevfq+3njBxq/kqBoGBduvea8f393zICS63ivRBTqgFpgaWZEIUULdcK+frIfAAL2AjscXqrLfu+uuwx05FF0XUbvvtuOeu++689+7778AHL/wJIQAAOwAAAAAAAAAAAA=="); - diff --git a/build/src/cockpit.js b/build/src/cockpit.js deleted file mode 100644 index 62b6c4d2..00000000 --- a/build/src/cockpit.js +++ /dev/null @@ -1 +0,0 @@ -define("cockpit/index",["require","exports","module","pilot/index","cockpit/cli","cockpit/ui/settings","cockpit/ui/cli_view","cockpit/commands/basic"],function(a,b,c){b.startup=function(b,c){a("pilot/index"),a("cockpit/cli").startup(b,c),a("cockpit/ui/settings").startup(b,c),a("cockpit/ui/cli_view").startup(b,c),a("cockpit/commands/basic").startup(b,c)}}),define("cockpit/cli",["require","exports","module","pilot/console","pilot/lang","pilot/oop","pilot/event_emitter","pilot/types","pilot/canon"],function(a,b,c){function r(a,b){q.call(this,a),b&&b.flags&&(this.flags=b.flags)}function q(a){this.env=a,this.commandAssignment=new o(p,this)}function o(a,b){this.param=a,this.requisition=b,this.setValue(a.defaultValue)}function n(a,b,c,d,e,f){this.emitter=a,this.setText(b),this.start=c,this.end=d,this.prefix=e,this.suffix=f}function m(a,b){this.status=a.status,this.message=a.message,b?(this.start=b.start,this.end=b.end):(this.start=0,this.end=0),this.predictions=a.predictions}function l(a,b,c,d,e){this.status=a,this.message=b;if(typeof c==="number")this.start=c,this.end=d,this.predictions=e;else{var f=c;this.start=f.start,this.end=f.end,this.predictions=f.predictions}}var d=a("pilot/console"),e=a("pilot/lang"),f=a("pilot/oop"),g=a("pilot/event_emitter").EventEmitter,h=a("pilot/types"),i=a("pilot/types").Status,j=a("pilot/types").Conversion,k=a("pilot/canon");b.startup=function(a,b){k.upgradeType("command",p)},l.prototype={},l.sort=function(a,b){b!==undefined&&a.forEach(function(a){a.start===n.AT_CURSOR?a.distance=0:ba.end?a.distance=b-a.end:a.distance=0},this),a.sort(function(a,c){if(b!==undefined){var d=a.distance-c.distance;if(d!=0)return d}return c.status-a.status}),b!==undefined&&a.forEach(function(a){delete a.distance},this);return a},b.Hint=l,f.inherits(m,l),n.prototype={merge:function(a){if(a.emitter!=this.emitter)throw new Error("Can't merge Arguments from different EventEmitters");return new n(this.emitter,this.text+this.suffix+a.prefix+a.text,this.start,a.end,this.prefix,a.suffix)},setText:function(a){if(a==null)throw new Error("Illegal text for Argument: "+a);var b={argument:this,oldText:this.text,text:a};this.text=a,this.emitter._dispatchEvent("argumentChange",b)},toString:function(){return this.prefix+this.text+this.suffix}},n.merge=function(a,b,c){b=b===undefined?0:b,c=c===undefined?a.length:c;var d;for(var e=b;e: ";this.param.description&&(b+=this.param.description.trim(),b.charAt(b.length-1)!=="."&&(b+="."),b.charAt(b.length-1)!==" "&&(b+=" "));var c=i.VALID,d=this.arg?this.arg.start:n.AT_CURSOR,e=this.arg?this.arg.end:n.AT_CURSOR,f;this.conversion&&(c=this.conversion.status,this.conversion.message&&(b+=this.conversion.message),f=this.conversion.predictions);var g=this.arg&&this.arg.text!=="",h=this.value!==undefined||g;this.param.defaultValue===undefined&&!h&&(c=i.INVALID,b+="Required");return new l(c,b,d,e,f)},complete:function(){this.conversion&&this.conversion.predictions&&this.conversion.predictions.length>0&&this.setValue(this.conversion.predictions[0])},isPositionCaptured:function(a){if(!this.arg)return!1;if(this.arg.start===-1)return!1;if(a>this.arg.end)return!1;if(a===this.arg.end)return this.conversion.status!==i.VALID||this.conversion.predictions.length!==0;return!0},decrement:function(){var a=this.param.type.decrement(this.value);a!=null&&this.setValue(a)},increment:function(){var a=this.param.type.increment(this.value);a!=null&&this.setValue(a)},toString:function(){return this.arg?this.arg.toString():""}},b.Assignment=o;var p={name:"__command",type:"command",description:"The command to execute",getCustomHint:function(a,b){var c=[];c.push(" > "),c.push(a.name),a.params&&a.params.length>0&&a.params.forEach(function(a){a.defaultValue===undefined?c.push(" ["+a.name+"]"):c.push(" ["+a.name+"]")},this),c.push("
    "),c.push(a.description?a.description:"(No description)"),c.push("
    "),a.params&&a.params.length>0&&(c.push("
      "),a.params.forEach(function(a){c.push("
    • "),c.push(""+a.name+": "),c.push(a.description?a.description:"(No description)"),a.defaultValue===undefined?c.push(" [Required]"):a.defaultValue===null?c.push(" [Optional]"):c.push(" [Default: "+a.defaultValue+"]"),c.push("
    • ")},this),c.push("
    "));return new l(i.VALID,c.join(""),b)}};q.prototype={commandAssignment:undefined,assignmentCount:undefined,_assignments:undefined,_hints:undefined,_assignmentChanged:function(a){a.param.name==="__command"&&(this._assignments={},a.value&&a.value.params.forEach(function(a){this._assignments[a.name]=new o(a,this)},this),this.assignmentCount=Object.keys(this._assignments).length,this._dispatchEvent("commandChange",{command:a.value}))},getAssignment:function(a){var b=typeof a==="string"?a:Object.keys(this._assignments)[a];return this._assignments[b]},getParameterNames:function(){return Object.keys(this._assignments)},cloneAssignments:function(){return Object.keys(this._assignments).map(function(a){return this._assignments[a]},this)},_updateHints:function(){this.getAssignments(!0).forEach(function(a){this._hints.push(a.getHint())},this),l.sort(this._hints)},getWorstHint:function(){return this._hints[0]},getArgsObject:function(){var a={};this.getAssignments().forEach(function(b){a[b.param.name]=b.value},this);return a},getAssignments:function(a){var b=[];a===!0&&b.push(this.commandAssignment),Object.keys(this._assignments).forEach(function(a){b.push(this.getAssignment(a))},this);return b},setDefaultValues:function(){this.getAssignments().forEach(function(a){a.setValue(undefined)},this)},exec:function(){k.exec(this.commandAssignment.value,this.env,this.getArgsObject(),this.toCanonicalString())},toCanonicalString:function(){var a=[];a.push(this.commandAssignment.value.name),Object.keys(this._assignments).forEach(function(b){var c=this._assignments[b],d=c.param.type;c.value!==c.param.defaultValue&&(a.push(" "),a.push(d.stringify(c.value)))},this);return a.join("")}},f.implement(q.prototype,g),b.Requisition=q,f.inherits(r,q),function(){r.prototype.update=function(a){this.input=a,this._hints=[];var b=this._tokenize(a.typed);this._split(b),this.commandAssignment.value&&this._assign(b),this._updateHints()},r.prototype.getInputStatusMarkup=function(){var a=this.toString().split("").map(function(a){return i.VALID});this._hints.forEach(function(b){for(var c=b.start;c<=b.end;c++)b.status>a[c]&&(a[c]=b.status)},this);return a},r.prototype.toString=function(){return this.getAssignments(!0).map(function(a){return a.toString()},this).join("")};var a=r.prototype._updateHints;r.prototype._updateHints=function(){a.call(this);var b=this.input.cursor;this._hints.forEach(function(a){var c=b.start>=a.start&&b.start<=a.end,d=b.end>=a.start&&b.end<=a.end,e=c||d;!e&&a.status===i.INCOMPLETE&&(a.status=i.INVALID)},this),l.sort(this._hints)},r.prototype.getHints=function(){return this._hints},r.prototype.getAssignmentAt=function(a){var b=this.getAssignments(!0);for(var c=0;c=a.length){if(f!==b){var l=g(a.substring(i,h));k.push(new n(this,l,i,h,j,""))}else if(h!==i){var m=a.substring(i,h),o=k[k.length-1];o?o.suffix+=m:(o=new n(this,"",h,h,m,""),k.push(o))}break}var p=a[h];switch(f){case b:p==="'"?(j=a.substring(i,h+1),f=d,i=h+1):p==='"'?(j=a.substring(i,h+1),f=e,i=h+1):/ /.test(p)||(j=a.substring(i,h),f=c,i=h);break;case c:if(p===" "){var l=g(a.substring(i,h));k.push(new n(this,l,i,h,j,"")),f=b,i=h,j=""}break;case d:if(p==="'"){var l=g(a.substring(i,h));k.push(new n(this,l,i-1,h+1,j,p)),f=b,i=h+1,j=""}break;case e:if(p==='"'){var l=g(a.substring(i,h));k.push(new n(this,l,i-1,h+1,j,p)),f=b,i=h+1,j=""}}h++}return k},r.prototype._split=function(a){var b=1,c;while(b<=a.length){var c=n.merge(a,0,b);this.commandAssignment.setArgument(c);if(!this.commandAssignment.value)break;if(this.commandAssignment.value.exec){for(var d=0;d=a.length)break;continue}b.param.type.name==="boolean"?b.setValue(!0):f+10){var g=n.merge(a);this._hints.push(new l(i.INVALID,"Input '"+g.text+"' makes no sense.",g))}}}}(),b.CliRequisition=r}),define("cockpit/ui/settings",["require","exports","module","pilot/types","pilot/types/basic"],function(a,b,c){var d=a("pilot/types"),e=a("pilot/types/basic").SelectionType,f=new e({name:"direction",data:["above","below"]}),g={name:"hintDirection",description:"Are hints shown above or below the command line?",type:"direction",defaultValue:"above"},h={name:"outputDirection",description:"Is the output window shown above or below the command line?",type:"direction",defaultValue:"above"},i={name:"outputHeight",description:"What height should the output panel be?",type:"number",defaultValue:300};b.startup=function(a,b){d.registerType(f),a.env.settings.addSetting(g),a.env.settings.addSetting(h),a.env.settings.addSetting(i)},b.shutdown=function(a,b){d.unregisterType(f),a.env.settings.removeSetting(g),a.env.settings.removeSetting(h),a.env.settings.removeSetting(i)}}),define("cockpit/ui/cli_view",["require","exports","module","text!cockpit/ui/cli_view.css","pilot/event","pilot/dom","pilot/keys","pilot/canon","pilot/types","cockpit/cli","cockpit/ui/request_view"],function(a,b,c){function n(a,b){this.cli=a,this.doc=document,this.win=f.getParentWindow(this.doc),this.element=this.doc.getElementById("cockpitInput");this.element&&(this.settings=b.settings,this.hintDirection=this.settings.getSetting("hintDirection"),this.outputDirection=this.settings.getSetting("outputDirection"),this.outputHeight=this.settings.getSetting("outputHeight"),this.isUpdating=!1,this.createElements(),this.update())}var d=a("text!cockpit/ui/cli_view.css"),e=a("pilot/event"),f=a("pilot/dom");f.importCssString(d);var e=a("pilot/event"),g=a("pilot/keys"),h=a("pilot/canon"),i=a("pilot/types").Status,j=a("cockpit/cli").CliRequisition,k=a("cockpit/cli").Hint,l=a("cockpit/ui/request_view").RequestView,m=new k(i.VALID,"",0,0);b.startup=function(a,b){var c=new j(a.env),d=new n(c,a.env)},n.prototype={createElements:function(){var a=this.element;this.element.spellcheck=!1,this.output=this.doc.getElementById("cockpitOutput"),this.popupOutput=this.output==null;if(!this.output){this.output=this.doc.createElement("div"),this.output.id="cockpitOutput",this.output.className="cptFocusPopup",a.parentNode.insertBefore(this.output,a.nextSibling);var b=function(){this.output.style.maxHeight=this.outputHeight.get()+"px"}.bind(this);this.outputHeight.addEventListener("change",b),b()}this.completer=this.doc.createElement("div"),this.completer.className="cptCompletion VALID",this.completer.style.color=f.computedStyle(a,"color"),this.completer.style.fontSize=f.computedStyle(a,"fontSize"),this.completer.style.fontFamily=f.computedStyle(a,"fontFamily"),this.completer.style.fontWeight=f.computedStyle(a,"fontWeight"),this.completer.style.fontStyle=f.computedStyle(a,"fontStyle"),a.parentNode.insertBefore(this.completer,a.nextSibling),this.completer.style.backgroundColor=a.style.backgroundColor,a.style.backgroundColor="transparent",this.hinter=this.doc.createElement("div"),this.hinter.className="cptHints cptFocusPopup",a.parentNode.insertBefore(this.hinter,a.nextSibling);var c=this.resizer.bind(this);e.addListener(this.win,"resize",c),this.hintDirection.addEventListener("change",c),this.outputDirection.addEventListener("change",c),c(),h.addEventListener("output",function(a){new l(a.request,this)}.bind(this)),e.addCommandKeyListener(a,this.onCommandKey.bind(this)),e.addListener(a,"keyup",this.onKeyUp.bind(this)),e.addListener(a,"mouseup",function(a){this.isUpdating=!0,this.update(),this.isUpdating=!1}.bind(this)),this.cli.addEventListener("argumentChange",this.onArgChange.bind(this))},scrollOutputToBottom:function(){var a=Math.max(this.output.scrollHeight,this.output.clientHeight);this.output.scrollTop=a-this.output.clientHeight},resizer:function(){var a=this.element.getClientRects()[0];this.completer.style.top=a.top+"px";var b=a.bottom-a.top;this.completer.style.height=b+"px",this.completer.style.lineHeight=b+"px",this.completer.style.left=a.left+"px";var c=a.right-a.left;this.completer.style.width=c+"px",this.hintDirection.get()==="below"?(this.hinter.style.top=a.bottom+"px",this.hinter.style.bottom="auto"):(this.hinter.style.top="auto",this.hinter.style.bottom=this.doc.documentElement.clientHeight-a.top+"px"),this.hinter.style.left=a.left+30+"px",this.hinter.style.maxWidth=c-110+"px",this.popupOutput&&(this.outputDirection.get()==="below"?(this.output.style.top=a.bottom+"px",this.output.style.bottom="auto"):(this.output.style.top="auto",this.output.style.bottom=this.doc.documentElement.clientHeight-a.top+"px"),this.output.style.left=a.left+"px",this.output.style.width=c-80+"px")},onCommandKey:function(a,b,c){var d;(c===g.TAB||c===g.UP||c===g.DOWN)&&e.stopEvent(a);return d},onKeyUp:function(a){var b;if(a.keyCode===g.RETURN){var c=this.cli.getWorstHint();c.status===i.VALID?(this.cli.exec(),this.element.value=""):(f.setSelectionStart(this.element,c.start),f.setSelectionEnd(this.element,c.end))}this.update();var d=this.cli.getAssignmentAt(f.getSelectionStart(this.element));d&&(a.keyCode===g.TAB&&(d.complete(),this.update()),a.keyCode===g.UP&&(d.increment(),this.update()),a.keyCode===g.DOWN&&(d.decrement(),this.update()));return b},update:function(){this.isUpdating=!0;var a={typed:this.element.value,cursor:{start:f.getSelectionStart(this.element),end:f.getSelectionEnd(this.element.selectionEnd)}};this.cli.update(a);var b=this.cli.getAssignmentAt(a.cursor.start).getHint();f.removeCssClass(this.completer,i.VALID.toString()),f.removeCssClass(this.completer,i.INCOMPLETE.toString()),f.removeCssClass(this.completer,i.INVALID.toString());var c='> ';if(this.element.value.length>0){var d=this.cli.getInputStatusMarkup();c+=this.markupStatusScore(d)}if(this.element.value.length>0&&b.predictions&&b.predictions.length>0){var e=b.predictions[0];c+="  ⇥ "+(e.name?e.name:e)}this.completer.innerHTML=c,f.addCssClass(this.completer,this.cli.getWorstHint().status.toString());var g="";this.element.value.length!==0&&(g+=b.message,b.predictions&&b.predictions.length>0&&(g+=": [ ",b.predictions.forEach(function(a){g+=a.name?a.name:a,g+=" | "},this),g=g.replace(/\| $/,"]"))),this.hinter.innerHTML=g,g.length===0?f.addCssClass(this.hinter,"cptNoPopup"):f.removeCssClass(this.hinter,"cptNoPopup"),this.isUpdating=!1},markupStatusScore:function(a){var b="",c=0,d=-1;while(!0){d!==a[c]&&(b+="",d=a[c]),b+=this.element.value[c],c++;if(c===this.element.value.length){b+="";break}d!==a[c]&&(b+="")}return b},onArgChange:function(a){if(!this.isUpdating){var b=this.element.value.substring(0,a.argument.start),c=this.element.value.substring(a.argument.end),d=typeof a.text==="string"?a.text:a.text.name;this.element.value=b+d+c;var e=(b+d).length;this.element.selectionStart=e,this.element.selectionEnd=e}}},b.CliView=n}),define("cockpit/ui/request_view",["require","exports","module","pilot/dom","pilot/event","text!cockpit/ui/request_view.html","pilot/domtemplate","text!cockpit/ui/request_view.css"],function(a,b,c){function l(a,b){this.request=a,this.cliView=b,this.imageUrl=k,this.rowin=null,this.rowout=null,this.output=null,this.hide=null,this.show=null,this.duration=null,this.throb=null,(new g).processNode(j.cloneNode(!0),this),this.cliView.output.appendChild(this.rowin),this.cliView.output.appendChild(this.rowout),this.request.addEventListener("output",this.onRequestChange.bind(this))}function k(b){var d=a("text!cockpit/ui/"+b);if(d)return d;var e=c.id.split("/").pop()+".js",f;if(c.uri.substr(-e.length)!==e){console.error("Can't work out path from module.uri/module.id");return b}if(c.uri){var g=c.uri.length-e.length-1;return c.uri.substr(0,g)+b}return e+b}var d=a("pilot/dom"),e=a("pilot/event"),f=a("text!cockpit/ui/request_view.html"),g=a("pilot/domtemplate").Templater,h=a("text!cockpit/ui/request_view.css");d.importCssString(h);var i=document.createElement("div");i.innerHTML=f;var j=i.querySelector(".cptRow");l.prototype={copyToInput:function(){this.cliView.element.value=this.request.typed},executeRequest:function(a){this.cliView.cli.update({typed:this.request.typed,cursor:{start:0,end:0}}),this.cliView.cli.exec()},hideOutput:function(a){this.output.style.display="none",d.addCssClass(this.hide,"cmd_hidden"),d.removeCssClass(this.show,"cmd_hidden"),e.stopPropagation(a)},showOutput:function(a){this.output.style.display="block",d.removeCssClass(this.hide,"cmd_hidden"),d.addCssClass(this.show,"cmd_hidden"),e.stopPropagation(a)},remove:function(a){this.cliView.output.removeChild(this.rowin),this.cliView.output.removeChild(this.rowout),e.stopPropagation(a)},onRequestChange:function(a){this.duration.innerHTML=this.request.duration?"completed in "+this.request.duration/1e3+" sec ":"",this.output.innerHTML="",this.request.outputs.forEach(function(a){var b;typeof a=="string"?(b=document.createElement("p"),b.innerHTML=a):b=a,this.output.appendChild(b)},this),this.cliView.scrollOutputToBottom(),d.setCssClass(this.output,"cmd_error",this.request.error),this.throb.style.display=this.request.completed?"none":"block"}},b.RequestView=l}),define("pilot/domtemplate",["require","exports","module"],function(require,exports,module){function Templater(){this.scope=[]}Templater.prototype.processNode=function(a,b){typeof a==="string"&&(a=document.getElementById(a));if(b===null||b===undefined)b={};this.scope.push(a.nodeName+(a.id?"#"+a.id:""));try{if(a.attributes&&a.attributes.length){if(a.hasAttribute("foreach")){this.processForEach(a,b);return}if(a.hasAttribute("if"))if(!this.processIf(a,b))return;b.__element=a;var c=Array.prototype.slice.call(a.attributes);for(var d=0;d1&&(d.forEach(function(c){c!==null&&c!==undefined&&c!==""&&(c.charAt(0)==="$"&&(c=this.envEval(c.slice(1),b,a.data)),c===null&&(c="null"),c===undefined&&(c="undefined"),typeof c.cloneNode!=="function"&&(c=a.ownerDocument.createTextNode(c.toString())),a.parentNode.insertBefore(c,a))},this),a.parentNode.removeChild(a))},Templater.prototype.stripBraces=function(a){if(!a.match(/\$\{.*\}/g)){this.handleError("Expected "+a+" to match ${...}");return a}return a.slice(2,-1)},Templater.prototype.property=function(a,b,c){this.scope.push(a);try{typeof a==="string"&&(a=a.split("."));var d=b[a[0]];if(a.length===1){c!==undefined&&(b[a[0]]=c);if(typeof d==="function")return function(){return d.apply(b,arguments)};return d}if(!d){this.handleError("Can't find path="+a);return null}return this.property(a.slice(1),d,c)}finally{this.scope.pop()}},Templater.prototype.envEval=function(script,env,context){with(env)try{this.scope.push(context);return eval(script)}catch(ex){this.handleError("Template error evaluating '"+script+"'",ex);return script}finally{this.scope.pop()}},Templater.prototype.handleError=function(a,b){this.logError(a),this.logError("In: "+this.scope.join(" > ")),b&&this.logError(b)},Templater.prototype.logError=function(a){window.console&&window.console.log&&console.log(a)},exports.Templater=Templater}),define("cockpit/commands/basic",["require","exports","module","pilot/canon"],function(a,b,c){var d=a("pilot/canon"),e={name:"sh",description:"Execute a system command (requires server support)",params:[{name:"command",type:"text",description:"The string to send to the os shell."}],exec:function(a,b,c){var d=new XMLHttpRequest;d.open("GET","/exec?args="+b.command,!0),d.onreadystatechange=function(a){d.readyState==4&&(d.status==200&&c.done("
    "+d.responseText+"
    "))},d.send(null)}},d=a("pilot/canon");b.startup=function(a,b){d.addCommand(e)},b.shutdown=function(a,b){d.removeCommand(e)}}),define("text!cockpit/ui/cli_view.css",[],"#cockpitInput { padding-left: 16px; }#cockpitOutput { overflow: auto; }#cockpitOutput.cptFocusPopup { position: absolute; z-index: 999; }.cptFocusPopup { display: none; }#cockpitInput:focus ~ .cptFocusPopup { display: block; }#cockpitInput:focus ~ .cptFocusPopup.cptNoPopup { display: none; }.cptCompletion { padding: 0; position: absolute; z-index: -1000; }.cptCompletion.VALID { background: #FFF; }.cptCompletion.INCOMPLETE { background: #DDD; }.cptCompletion.INVALID { background: #DDD; }.cptCompletion span { color: #FFF; }.cptCompletion span.INCOMPLETE { color: #DDD; border-bottom: 2px dotted #F80; }.cptCompletion span.INVALID { color: #DDD; border-bottom: 2px dotted #F00; }span.cptPrompt { color: #66F; font-weight: bold; }.cptHints { color: #000; position: absolute; border: 1px solid rgba(230, 230, 230, 0.8); background: rgba(250, 250, 250, 0.8); -moz-border-radius-topleft: 10px; -moz-border-radius-topright: 10px; border-top-left-radius: 10px; border-top-right-radius: 10px; z-index: 1000; padding: 8px; display: none;}.cptHints ul { margin: 0; padding: 0 15px; }.cptGt { font-weight: bold; font-size: 120%; }"),define("text!cockpit/ui/request_view.css",[],".cptRowIn { display: box; display: -moz-box; display: -webkit-box; box-orient: horizontal; -moz-box-orient: horizontal; -webkit-box-orient: horizontal; box-align: center; -moz-box-align: center; -webkit-box-align: center; color: #333; background-color: #EEE; width: 100%; font-family: consolas, courier, monospace;}.cptRowIn > * { padding-left: 2px; padding-right: 2px; }.cptRowIn > img { cursor: pointer; }.cptHover { display: none; }.cptRowIn:hover > .cptHover { display: block; }.cptRowIn:hover > .cptHover.cptHidden { display: none; }.cptOutTyped { box-flex: 1; -moz-box-flex: 1; -webkit-box-flex: 1; font-weight: bold; color: #000; font-size: 120%;}.cptRowOutput { padding-left: 10px; line-height: 1.2em; }.cptRowOutput strong,.cptRowOutput b,.cptRowOutput th,.cptRowOutput h1,.cptRowOutput h2,.cptRowOutput h3 { color: #000; }.cptRowOutput a { font-weight: bold; color: #666; text-decoration: none; }.cptRowOutput a: hover { text-decoration: underline; cursor: pointer; }.cptRowOutput input[type=password],.cptRowOutput input[type=text],.cptRowOutput textarea { color: #000; font-size: 120%; background: transparent; padding: 3px; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px;}.cptRowOutput table,.cptRowOutput td,.cptRowOutput th { border: 0; padding: 0 2px; }.cptRowOutput .right { text-align: right; }"),define("text!cockpit/ui/request_view.html",[],'
    >
    ${request.typed}
    Hide command output Show command output Remove this command from the history
    '),define("text!cockpit/ui/images/closer.png",[],"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAj9JREFUeNp0ks+LUlEUx7/vV1o8Z8wUx3IEHcQmiBiQlomjRNCiZpEuEqF/oEUwq/6EhvoHggmRcJUQBM1CRJAW0aLIaGQimZJxJsWxyV/P9/R1zzWlFl04vPvOPZ9z7rnnK5imidmKRCIq+zxgdoPZ1T/ut8xeM3tcKpW6s1hhBkaj0Qj7bDebTX+324WmadxvsVigqipcLleN/d4rFoulORiLxTZY8ItOp8MBCpYkiYPj8Xjus9vtlORWoVB4KcTjcQc732dLpSRXvCZaAws6Q4WDdqsO52kNH+oCRFGEz+f7ydwBKRgMPmTXi49GI1x2D/DsznesB06ws2eDbI7w9HYN6bVjvGss4KAjwDAMq81mM2SW5Wa/3weBbz42UL9uYnVpiO2Nr9ANHSGXib2Wgm9tCYIggGKJEVkvlwgi5/FQRmTLxO6hgJVzI1x0T/fJrBtHJxPeL6tI/fsZLA6ot8lkQi8HRVbw94gkWYI5MaHrOjcCGSNRxZosy9y5cErDzn0Dqx7gcwO8WtBp4PndI35GMYqiUMUvBL5yOBz8yRfFNpbPmqgcCFh/IuHa1nR/YXGM8+oUpFhihEQiwcdRLpfVRqOBtWXWq34Gra6AXq8Hp2piZcmKT4cKnE4nwuHwdByVSmWQz+d32WCTlHG/qaHHREN9kgi0sYQfv0R4PB4EAgESQDKXy72fSy6VSnHJVatVf71eR7vd5n66mtfrRSgU4pLLZrOlf7RKK51Ok8g3/yPyR5lMZi7y3wIMAME4EigHWgKnAAAAAElFTkSuQmCC"),define("text!cockpit/ui/images/dot_clear.gif",[],"data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAEBMgA7"),define("text!cockpit/ui/images/minus.png",[],"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAAZiS0dEANIA0gDS7KbF4AAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kFGw4xMrIJw5EAAAHcSURBVCjPhZIxSxtxGMZ/976XhJA/RA5EAyJcFksnp64hjUPBoXRyCYLQTyD0UxScu0nFwalCQSgFCVk7dXAwUAiBDA2RO4W7yN1x9+9gcyhU+pteHt4H3pfncay1LOl0OgY4BN4Ar/7KP4BvwNFwOIyWu87S2O12O8DxfD73oygiSRIAarUaxhhWV1fHwMFgMBiWxl6v9y6Koi+3t7ckSUKtVkNVAcjzvNRWVlYwxry9vLz86uzs7HjAZDKZGGstjUaDfxHHMSLC5ubmHdB2VfVwNpuZ5clxHPMcRVFwc3PTXFtbO3RFZHexWJCmabnweAaoVqvlv4vFAhHZdVX1ZZqmOI5DURR8fz/lxbp9Yrz+7bD72SfPcwBU1XdF5N5aWy2KgqIoeBzPEnWVLMseYnAcRERdVR27rrsdxzGqyutP6898+GBsNBqo6i9XVS88z9sOggAR4X94noeqXoiIHPm+H9XrdYIgIAxDwjAkTVPCMESzBy3LMprNJr7v34nIkV5dXd2fn59fG2P2siwjSRIqlQrWWlSVJFcqlQqtVot2u40xZu/s7OxnWbl+v98BjkejkT+dTgmCoDxtY2ODra2tMXBweno6fNJVgP39fQN8eKbkH09OTsqS/wHFRdHPfTSfjwAAAABJRU5ErkJggg=="),define("text!cockpit/ui/images/pinaction.png",[],"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAC7mlDQ1BJQ0MgUHJvZmlsZQAAeAGFVM9rE0EU/jZuqdAiCFprDrJ4kCJJWatoRdQ2/RFiawzbH7ZFkGQzSdZuNuvuJrWliOTi0SreRe2hB/+AHnrwZC9KhVpFKN6rKGKhFy3xzW5MtqXqwM5+8943731vdt8ADXLSNPWABOQNx1KiEWlsfEJq/IgAjqIJQTQlVdvsTiQGQYNz+Xvn2HoPgVtWw3v7d7J3rZrStpoHhP1A4Eea2Sqw7xdxClkSAog836Epx3QI3+PY8uyPOU55eMG1Dys9xFkifEA1Lc5/TbhTzSXTQINIOJT1cVI+nNeLlNcdB2luZsbIEL1PkKa7zO6rYqGcTvYOkL2d9H5Os94+wiHCCxmtP0a4jZ71jNU/4mHhpObEhj0cGDX0+GAVtxqp+DXCFF8QTSeiVHHZLg3xmK79VvJKgnCQOMpkYYBzWkhP10xu+LqHBX0m1xOv4ndWUeF5jxNn3tTd70XaAq8wDh0MGgyaDUhQEEUEYZiwUECGPBoxNLJyPyOrBhuTezJ1JGq7dGJEsUF7Ntw9t1Gk3Tz+KCJxlEO1CJL8Qf4qr8lP5Xn5y1yw2Fb3lK2bmrry4DvF5Zm5Gh7X08jjc01efJXUdpNXR5aseXq8muwaP+xXlzHmgjWPxHOw+/EtX5XMlymMFMXjVfPqS4R1WjE3359sfzs94i7PLrXWc62JizdWm5dn/WpI++6qvJPmVflPXvXx/GfNxGPiKTEmdornIYmXxS7xkthLqwviYG3HCJ2VhinSbZH6JNVgYJq89S9dP1t4vUZ/DPVRlBnM0lSJ93/CKmQ0nbkOb/qP28f8F+T3iuefKAIvbODImbptU3HvEKFlpW5zrgIXv9F98LZua6N+OPwEWDyrFq1SNZ8gvAEcdod6HugpmNOWls05Uocsn5O66cpiUsxQ20NSUtcl12VLFrOZVWLpdtiZ0x1uHKE5QvfEp0plk/qv8RGw/bBS+fmsUtl+ThrWgZf6b8C8/UXAeIuJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAClklEQVQ4EX1TXUhUQRQ+Z3Zmd+9uN1q2P3UpZaEwcikKekkqLKggKHJ96MHe9DmLkCDa9U198Id8kErICmIlRAN96UdE6QdBW/tBA5Uic7E0zN297L17p5mb1zYjD3eYc+d83zlnON8g5xzWNUSEdUBkHTJasRWySPP7fw3hfwkk2GoNsc0vOaJRHo1GV/GiMctkTIJRFlpZli8opK+htmf83gXeG63oteOtra0u25e7TYJIJELb26vYCACTgUe1lXV86BTn745l+MsyHqs53S/Aq4VEUa9Y6ko14eYY4u3AyM3HYwdKU35DZyblGR2+qq6W0X2Nnh07xynnVYpHORx/E1/GvvqaAZUayjMjdM2f/Lgr5E+fV93zR4u3zKCLughsZqKwAzAxaz6dPY6JgjLUF+eSP5OpjmAw2E8DvldHSvJMKPg08aRor1tc4BuALu6mOwGWdQC3mKIqRsC8mKd8wYfD78/earzSYzdMDW9QgKb0Is8CBY1mQXOiaXAHEpMDE5XTJqIq4EiyxUqKlpfkF0pyV1OTAoFAhmTmyCCoDsZNZvIkUjELQpipo0sQqYZAswZHwsEEE10M0pq2SSZY9HqNcDicJcNTpBvQJz40UbSOTh1B8bDpuY0w9Hb3kkn9lPAlBLfhfD39XTtX/blFJqiqrjbkTi63Hbofj2uL4GMsmzFgbDJ/vmMgv/lB4syJ0oXO7d3j++vio6GFsYmD6cHJreWc3/jRVVHhsOYvM8iZ36mtjPDBk/xDZE8CoHlbrlAssbTxDdDJvdb536L7I6S7Vy++6Gi4Xi9BsUthJRaLOYSPz4XALKI4j4iObd/e5UtDKUjZzYyYRyGAJv01Zj8kC5cbs5WY83hQnv0DzCXl+r8APElkq0RU6oMAAAAASUVORK5CYII="),define("text!cockpit/ui/images/pinin.png",[],"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAC7mlDQ1BJQ0MgUHJvZmlsZQAAeAGFVM9rE0EU/jZuqdAiCFprDrJ4kCJJWatoRdQ2/RFiawzbH7ZFkGQzSdZuNuvuJrWliOTi0SreRe2hB/+AHnrwZC9KhVpFKN6rKGKhFy3xzW5MtqXqwM5+8943731vdt8ADXLSNPWABOQNx1KiEWlsfEJq/IgAjqIJQTQlVdvsTiQGQYNz+Xvn2HoPgVtWw3v7d7J3rZrStpoHhP1A4Eea2Sqw7xdxClkSAog836Epx3QI3+PY8uyPOU55eMG1Dys9xFkifEA1Lc5/TbhTzSXTQINIOJT1cVI+nNeLlNcdB2luZsbIEL1PkKa7zO6rYqGcTvYOkL2d9H5Os94+wiHCCxmtP0a4jZ71jNU/4mHhpObEhj0cGDX0+GAVtxqp+DXCFF8QTSeiVHHZLg3xmK79VvJKgnCQOMpkYYBzWkhP10xu+LqHBX0m1xOv4ndWUeF5jxNn3tTd70XaAq8wDh0MGgyaDUhQEEUEYZiwUECGPBoxNLJyPyOrBhuTezJ1JGq7dGJEsUF7Ntw9t1Gk3Tz+KCJxlEO1CJL8Qf4qr8lP5Xn5y1yw2Fb3lK2bmrry4DvF5Zm5Gh7X08jjc01efJXUdpNXR5aseXq8muwaP+xXlzHmgjWPxHOw+/EtX5XMlymMFMXjVfPqS4R1WjE3359sfzs94i7PLrXWc62JizdWm5dn/WpI++6qvJPmVflPXvXx/GfNxGPiKTEmdornIYmXxS7xkthLqwviYG3HCJ2VhinSbZH6JNVgYJq89S9dP1t4vUZ/DPVRlBnM0lSJ93/CKmQ0nbkOb/qP28f8F+T3iuefKAIvbODImbptU3HvEKFlpW5zrgIXv9F98LZua6N+OPwEWDyrFq1SNZ8gvAEcdod6HugpmNOWls05Uocsn5O66cpiUsxQ20NSUtcl12VLFrOZVWLpdtiZ0x1uHKE5QvfEp0plk/qv8RGw/bBS+fmsUtl+ThrWgZf6b8C8/UXAeIuJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABZ0lEQVQ4Ea2TPUsDQRCGZ89Eo4FACkULEQs1CH4Uamfjn7GxEYJFIFXgChFsbPwzNnZioREkaiHBQtEiEEiMRm/dZ8OEGAxR4sBxx877Pju7M2estTJIxLrNuVwuMxQEx0ZkzcFHyRtjXt02559RtB2GYanTYzoryOfz+6l4Nbszf2niwffKmpGRo9sVW22mDgqFwp5C2gDMm+P32a3JB1N+n5JifUGeP9JeNxGryPLYjcwMP8rJ07Q9fZltQzyAstOJ2vVu5sKc1ZZkRBrOcKeb+HexPidvkpCN5JUcllZtpZFc5DgBWc5M2eysZuMuofMBSA4NWjx4PUCsXefMlI0QY3ewRg4NWi4ZTQsgrjYXema+e4VqtEMK6KXvu+4B9Bklt90vVKMeD2BI6DOt4rZ/Gk7WyKFBi4fNPIAJY0joM61SCCZ9tI1o0OIB8D+DBIkYaJRbCBH9mZgNt+bb++ufSSF/eX8BYcDeAzuQJVUAAAAASUVORK5CYII="),define("text!cockpit/ui/images/pinout.png",[],"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAC7mlDQ1BJQ0MgUHJvZmlsZQAAeAGFVM9rE0EU/jZuqdAiCFprDrJ4kCJJWatoRdQ2/RFiawzbH7ZFkGQzSdZuNuvuJrWliOTi0SreRe2hB/+AHnrwZC9KhVpFKN6rKGKhFy3xzW5MtqXqwM5+8943731vdt8ADXLSNPWABOQNx1KiEWlsfEJq/IgAjqIJQTQlVdvsTiQGQYNz+Xvn2HoPgVtWw3v7d7J3rZrStpoHhP1A4Eea2Sqw7xdxClkSAog836Epx3QI3+PY8uyPOU55eMG1Dys9xFkifEA1Lc5/TbhTzSXTQINIOJT1cVI+nNeLlNcdB2luZsbIEL1PkKa7zO6rYqGcTvYOkL2d9H5Os94+wiHCCxmtP0a4jZ71jNU/4mHhpObEhj0cGDX0+GAVtxqp+DXCFF8QTSeiVHHZLg3xmK79VvJKgnCQOMpkYYBzWkhP10xu+LqHBX0m1xOv4ndWUeF5jxNn3tTd70XaAq8wDh0MGgyaDUhQEEUEYZiwUECGPBoxNLJyPyOrBhuTezJ1JGq7dGJEsUF7Ntw9t1Gk3Tz+KCJxlEO1CJL8Qf4qr8lP5Xn5y1yw2Fb3lK2bmrry4DvF5Zm5Gh7X08jjc01efJXUdpNXR5aseXq8muwaP+xXlzHmgjWPxHOw+/EtX5XMlymMFMXjVfPqS4R1WjE3359sfzs94i7PLrXWc62JizdWm5dn/WpI++6qvJPmVflPXvXx/GfNxGPiKTEmdornIYmXxS7xkthLqwviYG3HCJ2VhinSbZH6JNVgYJq89S9dP1t4vUZ/DPVRlBnM0lSJ93/CKmQ0nbkOb/qP28f8F+T3iuefKAIvbODImbptU3HvEKFlpW5zrgIXv9F98LZua6N+OPwEWDyrFq1SNZ8gvAEcdod6HugpmNOWls05Uocsn5O66cpiUsxQ20NSUtcl12VLFrOZVWLpdtiZ0x1uHKE5QvfEp0plk/qv8RGw/bBS+fmsUtl+ThrWgZf6b8C8/UXAeIuJAAAACXBIWXMAAAsTAAALEwEAmpwYAAACyUlEQVQ4EW1TXUgUURQ+Z3ZmnVV3QV2xJbVSEIowQbAfLQx8McLoYX2qjB58MRSkP3vZppceYhGxgrZaIughlYpE7CHFWiiKyj9II0qxWmwlNh1Xtp2f27mz7GDlZX7uuXO+73zfuXeQMQYIgAyALppgyBtse32stsw86txkHhATn+FbfPfzxnPB+vR3RMJYuTwW6bbB4a6WS5O3Yu2VlXIesDiAamiQNKVlVXfx5I0GJ7DY7p0/+erU4dgeMJIA31WNxZmAgibOreXDqF55sY4SFUURqbi+nkjgwTyAbHhLX8yOLsSM2QRA3JRAAgd4RGPbVhkKEp8qeJ7PFyW3fw++YHtC7CkaD0amqyqihSwlMQQ0wa07IjPVI/vbexreIUrVaQV2D4RMQ/o7m12Mdfx4H3PfB9FNzTR1U2cO0Bi45aV6xNvFBNaoIAfbSiwLlqi9/hR/R3Nrhua+Oqi9TEKiB02C7YXz+Pba4MTDrpbLiMAxNgmXb+HpwVkZdoIrkn9isW7nRw/TZYaagZArAWyhfqsSDL/c9aTx7JUjGZCtYExRqCzAwGblwr6aFQ84nTo6qZ7XCeCVQNckE/KSWolvoQnxeoFFgIh8G/nA+kBAxxuQO5m9eFrwLIGJHgcyM63VFMhRSgNVyJr7og8y1vbTQpH8DIEVgxuYuexw0QECIalq5FYgEmpkgoFYltU/lnrqDz5osirSFpF7lrHAFKSWHYfEs+mY/82UnAStyMlW8sUPsVIciTZgz3jV1ebg0CEOpgPF22s1z1YQYKSXPJ1hbAhR8T26WdLhkuVfAzPR+YO1Ox5n58SmCcF6e3uzAoHA77RkevJdWH/3+f2O9TGf3w3fWQ2Hw5F/13mcsWAT+vv6DK4kFApJ/d3d1k+kJtbCrmxXHS3n8ER6b3CQbAqaEHVra6sGxcXW4SovLx+empxapS//FfwD9kpMJjMMBBAAAAAASUVORK5CYII="),define("text!cockpit/ui/images/pins.png",[],"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAQCAYAAABQrvyxAAAACXBIWXMAAAsTAAALEwEAmpwYAAAGYklEQVRIDbVWe0yURxCf/R735o6DO0FBe0RFsaL4iLXGIKa2SY3P6JGa2GpjlJjUV9NosbU++tYUbEnaQIrVaKJBG7WiNFQFUWO1UUEsVg2CAgoeHHLewcH32O58cBdQsX9Y5+7LfrszOzO/2ZnZj1BKgTBiIwVGVvKd49OVVYunDlXn6wdBKh+ogXrv+DOz1melIb+3LM5fNv2XPYE5EHY+L3PJljN5zavHpJjsQNsA/JJEgyC2+WTjy3b0GfoJW8O4aoHtDwiHQrj5lw1LLyyb1bp5zAjJTus9klrVpdD6TqH2ngVO+0dsRJnp06cLIYU4fx7NnRI3bu7UIYOeJ/McnuY88q3k62gc0S4Dgf5qhICQtIXS2lqD7BhSduPk3YfyzXaANhBBJDxYdUqCywB2qS4RdyUuSkTF/VJxcbH5j8N7/75RuFrN3Zh8OS8zqf5m4UpPeenOyP42dbtBeuvVnCdkK1e4PfPouX03mo9se+c33M8wqDk5Ofqed8REUTicQhbySUxp9u3KlMSHTtrFU6Kyn03lz15PPpW25vsZeYSIKyiVURcqeZJOH9lTNZLfnxRjU/uwrjbEUBWsapcSO2Hq4k0VfZg9EzxdDNCEjDxgNqRDme9umz/btwlsHRIEePHgAf73RdnHZ6LTuIUBN7OBQ+c1Fdnp6cZ1BQUdeRuWZi97o3ktDQQkVeFFzqJARd1A5a0Vr7ta6Kp6TZjtZ+NTIOoKF6qDrL7e0QQIUCiqMMKk8Z1Q/SCSKvzocf2B6NEN0SQn/kTO6fKJ0zqjZUlQBSpJ0GjR77w0aoc1Pr6S5/kVJrNpakV5hR+LWKN4t7sLX+p0rx2vqSta64olIulUKUgCSXLWE1R4KPPSj+5vhm2hdDOG+CkQBmhhyyKq6SaFYWTn5bB3QJRNz54AuXKn8TJjhu0Wbv+wNEKQjVhnmKopjo4FxXmetCRnC4F7BhCiCUepqAepRh0TM/gjjzOOSK2NgWZPc05qampRWJHb7dbOffep2ednzLzgczlbrQA6gHYF9BYDh9GY+FjddMweHMscmMuep07gXlMQoqw9ALoYu5MJsak9QmJA2IvAgVmoCRciooyPujJtNCv1uHt3TmK9gegFKrG9kh6oXwZiIEAtBIjORGKNTWR/WeW8XVkbjuJepLAyloM8LmTN//njKZPbraATZaLjCHEww9Ei4FFiPg6Ja5gT6gxYgLgnRDHRQwJXbz2GOw0d4A3K4GXlUtMahJjYVxiYbrwOmxIS10bFnIBOSi6Tl9Jgs0zbOEX18wyEwgLPMrxD1Y4aCK8kmTpgYcpAF27Mzs42Hjx4kA8BICUlJfKArR7LcEvTB1xEC9AoEw9OPagWkVU/D1oesmK6U911zEczMVe01oZjiMggg6ux2Qk379qh4rYKet4GjrhhwEteBgBrH8BssoXEtbHzPpSBRRSpqlNpgAiUoxzHKxLRszoVuggIisxaDQWZqkQvQjAoax3NbDbLLGuUEABNGedXqSyLRupXgDT5JfAGZNLio9B0X8Uiwk4w77MDc1D4yejjWtykPS3DX01UDCY/GPQcVDe0QYT0CIxGFvUorfvBxZsRfVrUuWruMBAb/lXCUofoFNZfzGJtowXOX0vwUSFK4BgyMKm6P6s9wQUZld+jrYyMDC0iIQDaJdG4IyZQfL3RfbFcCBIlRgc+u3CjaTApuZ9KsANgG8PNzHlWWD3tCxd6kafNNiFp5HAalAkkJ0SCV2H3CgOD9Nc/FqrXuyb0Eocvfhq171p5eyuJ1omKJEP5rQGe/FOOnXtq335z8YmvYo9cHb2t8spIb3lVSseZW46FlGY/Sk9P50P2w20UlWJUkUHIushfc5PXGAzCo0PlD2pnpCYfCXga3lu+fPlevEhWrVrFyrN/Orfv87FOW9tlqb2Kc9pV8DzioMk3UNUbXM+8B/ATBr8C8CKdvGXWGD/9sqm3dkxtzA4McMjHMB8D2ftheYXo+qzt3pXvz8/PP/vk+v8537V+yYW87Zu+RZ1ZbrexoKAA/SBpaWn4+aL5w5zGk+/jW59JiMkESW5urpiVlWXENRb1H/Yf2I9txIxz5IdkX3TsraukpsbQjz6090yb4XsAvQoRE0YvJdamtIIbOnRoUVlZ2ftsLVQzIdEXHntsaZdimssVfCpFui109+BnWPsXaWLI/zactygAAAAASUVORK5CYII="),define("text!cockpit/ui/images/plus.png",[],"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAAZiS0dEANIA0gDS7KbF4AAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kFGw4yFTwuJTkAAAH7SURBVCjPdZKxa1NRFMZ/956XZMgFyyMlCZRA4hBx6lBcQ00GoYi4tEstFPwLAs7iLDi7FWuHThaUggihBDI5OWRoQAmBQFISQgvvpbwX3rsOaR4K+o2H8zvfOZxPWWtZqVarGaAJPAEe3ZW/A1+Bd+1221v1qhW4vb1dA44mk0nZ8zyCIAAgk8lgjGF9fb0PHF5cXLQTsF6vP/c879P19TVBEJDJZBARAKIoSmpra2sYY561Wq3PqtFouMBgMBgYay3ZbJZ/yfd9tNaUSqUboOKISPPq6sqsVvZ9H4AvL34B8PTj/QSO45jpdHovn883Ha31znw+JwzDpCEMQx4UloM8zyOdTif3zudztNY7jog8DMMQpRRxHPPt5TCBAEZvxlyOFTsfykRRBICIlB2t9a21Nh3HMXEc8+d7VhJHWCwWyzcohdZaHBHpO46z6fs+IsLj94XECaD4unCHL8FsNouI/HRE5Nx13c3ZbIbWOnG5HKtl+53TSq7rIiLnand31wUGnU7HjEYjlFLJZN/3yRnL1FMYY8jlcmxtbd0AFel2u7dnZ2eXxpi9xWJBEASkUimstYgIQSSkUimKxSKVSgVjzN7p6emPJHL7+/s14KjX65WHwyGz2SxZbWNjg2q12gcOT05O2n9lFeDg4MAAr/4T8rfHx8dJyH8DvvbYGzKvWukAAAAASUVORK5CYII="),define("text!cockpit/ui/images/throbber.gif",[],"data:image/gif;base64,R0lGODlh3AATAPQAAP///wAAAL6+vqamppycnLi4uLKyssjIyNjY2MTExNTU1Nzc3ODg4OTk5LCwsLy8vOjo6Ozs7MrKyvLy8vT09M7Ozvb29sbGxtDQ0O7u7tbW1sLCwqqqqvj4+KCgoJaWliH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAA3AATAAAF/yAgjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEgECAaEpHLJbDqf0Kh0Sq1ar9isdjoQtAQFg8PwKIMHnLF63N2438f0mv1I2O8buXjvaOPtaHx7fn96goR4hmuId4qDdX95c4+RG4GCBoyAjpmQhZN0YGYFXitdZBIVGAoKoq4CG6Qaswi1CBtkcG6ytrYJubq8vbfAcMK9v7q7D8O1ycrHvsW6zcTKsczNz8HZw9vG3cjTsMIYqQgDLAQGCQoLDA0QCwUHqfYSFw/xEPz88/X38Onr14+Bp4ADCco7eC8hQYMAEe57yNCew4IVBU7EGNDiRn8Z831cGLHhSIgdE/9chIeBgDoB7gjaWUWTlYAFE3LqzDCTlc9WOHfm7PkTqNCh54rePDqB6M+lR536hCpUqs2gVZM+xbrTqtGoWqdy1emValeXKwgcWABB5y1acFNZmEvXwoJ2cGfJrTv3bl69Ffj2xZt3L1+/fw3XRVw4sGDGcR0fJhxZsF3KtBTThZxZ8mLMgC3fRatCLYMIFCzwLEprg84OsDus/tvqdezZf13Hvr2B9Szdu2X3pg18N+68xXn7rh1c+PLksI/Dhe6cuO3ow3NfV92bdArTqC2Ebc3A8vjf5QWf15Bg7Nz17c2fj69+fnq+8N2Lty+fuP78/eV2X13neIcCeBRwxorbZrAxAJoCDHbgoG8RTshahQ9iSKEEzUmYIYfNWViUhheCGJyIP5E4oom7WWjgCeBBAJNv1DVV01MZdJhhjdkplWNzO/5oXI846njjVEIqR2OS2B1pE5PVscajkxhMycqLJgxQCwT40PjfAV4GqNSXYdZXJn5gSkmmmmJu1aZYb14V51do+pTOCmA00AqVB4hG5IJ9PvYnhIFOxmdqhpaI6GeHCtpooisuutmg+Eg62KOMKuqoTaXgicQWoIYq6qiklmoqFV0UoeqqrLbq6quwxirrrLTWauutJ4QAACH5BAkKAAAALAAAAADcABMAAAX/ICCOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSAQIBoSkcslsOp/QqHRKrVqv2Kx2OhC0BAXHx/EoCzboAcdhcLDdgwJ6nua03YZ8PMFPoBMca215eg98G36IgYNvDgOGh4lqjHd7fXOTjYV9nItvhJaIfYF4jXuIf4CCbHmOBZySdoOtj5eja59wBmYFXitdHhwSFRgKxhobBgUPAmdoyxoI0tPJaM5+u9PaCQZzZ9gP2tPcdM7L4tLVznPn6OQb18nh6NV0fu3i5OvP8/nd1qjwaasHcIPAcf/gBSyAAMMwBANYEAhWYQGDBhAyLihwYJiEjx8fYMxIcsGDAxVA/yYIOZIkBAaGPIK8INJlRpgrPeasaRPmx5QgJfB0abLjz50tSeIM+pFmUo0nQQIV+vRlTJUSnNq0KlXCSq09ozIFexEBAYkeNiwgOaEtn2LFpGEQsKCtXbcSjOmVlqDuhAx3+eg1Jo3u37sZBA9GoMAw4MB5FyMwfLht4sh7G/utPGHlYAV8Nz9OnOBz4c2VFWem/Pivar0aKCP2LFn2XwhnVxBwsPbuBAQbEGiIFg1BggoWkidva5z4cL7IlStfkED48OIYoiufYIH68+cKPkqfnsB58ePjmZd3Dj199/XE20tv6/27XO3S6z9nPCz9BP3FISDefL/Bt192/uWmAv8BFzAQAQUWWFaaBgqA11hbHWTIXWIVXifNhRlq6FqF1sm1QQYhdiAhbNEYc2KKK1pXnAIvhrjhBh0KxxiINlqQAY4UXjdcjSJyeAx2G2BYJJD7NZQkjCPKuCORKnbAIXsuKhlhBxEomAIBBzgIYXIfHfmhAAyMR2ZkHk62gJoWlNlhi33ZJZ2cQiKTJoG05Wjcm3xith9dcOK5X51tLRenoHTuud2iMnaolp3KGXrdBo7eKYF5p/mXgJcogClmcgzAR5gCKymXYqlCgmacdhp2UCqL96mq4nuDBTmgBasaCFp4sHaQHHUsGvNRiiGyep1exyIra2mS7dprrtA5++z/Z8ZKYGuGsy6GqgTIDvupRGE+6CO0x3xI5Y2mOTkBjD4ySeGU79o44mcaSEClhglgsKyJ9S5ZTGY0Bnzrj+3SiKK9Rh5zjAALCywZBk/ayCWO3hYM5Y8Dn6qxxRFsgAGoJwwgDQRtYXAAragyQOmaLKNZKGaEuUlpyiub+ad/KtPqpntypvvnzR30DBtjMhNodK6Eqrl0zU0/GjTUgG43wdN6Ra2pAhGtAAZGE5Ta8TH6wknd2IytNKaiZ+Or79oR/tcvthIcAPe7DGAs9Edwk6r3qWoTaNzY2fb9HuHh2S343Hs1VIHhYtOt+Hh551rh24vP5YvXSGzh+eeghy76GuikU9FFEainrvrqrLfu+uuwxy777LTXfkIIACH5BAkKAAAALAAAAADcABMAAAX/ICCOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSAQIBoSkcslsOp/QqHRKrVqv2Kx2OhC0BAWHB2l4CDZo9IDjcBja7UEhTV+3DXi3PJFA8xMcbHiDBgMPG31pgHBvg4Z9iYiBjYx7kWocb26OD398mI2EhoiegJlud4UFiZ5sm6Kdn2mBr5t7pJ9rlG0cHg5gXitdaxwFGArIGgoaGwYCZ3QFDwjU1AoIzdCQzdPV1c0bZ9vS3tUJBmjQaGXl1OB0feze1+faiBvk8wjnimn55e/o4OtWjp+4NPIKogsXjaA3g/fiGZBQAcEAFgQGOChgYEEDCCBBLihwQILJkxIe/3wMKfJBSQkJYJpUyRIkgwcVUJq8QLPmTYoyY6ZcyfJmTp08iYZc8MBkhZgxk9aEcPOlzp5FmwI9KdWn1qASurJkClRoWKwhq6IUqpJBAwQEMBYroAHkhLt3+RyzhgCDgAV48Wbgg+waAnoLMgTOm6DwQ8CLBzdGdvjw38V5JTg2lzhyTMeUEwBWHPgzZc4TSOM1bZia6LuqJxCmnOxv7NSsl1mGHHiw5tOuIWeAEHcFATwJME/ApgFBc3MVLEgPvE+Ddb4JokufPmFBAuvPXWu3MIF89wTOmxvOvp179evQtwf2nr6aApPyzVd3jn089e/8xdfeXe/xdZ9/d1ngHf98lbHH3V0LMrgPgsWpcFwBEFBgHmyNXWeYAgLc1UF5sG2wTHjIhNjBiIKZCN81GGyQwYq9uajeMiBOQGOLJ1KjTI40kmfBYNfc2NcGIpI4pI0vyrhjiT1WFqOOLEIZnjVOVpmajYfBiCSNLGbA5YdOkjdihSkQwIEEEWg4nQUmvYhYe+bFKaFodN5lp3rKvJYfnBKAJ+gGDMi3mmbwWYfng7IheuWihu5p32XcSWdSj+stkF95dp64jJ+RBipocHkCCp6PCiRQ6INookCAAwy0yd2CtNET3Yo7RvihBjFZAOaKDHT43DL4BQnsZMo8xx6uI1oQrHXXhHZrB28G62n/YSYxi+uzP2IrgbbHbiaer7hCiOxDFWhrbmGnLVuus5NFexhFuHLX6gkEECorlLpZo0CWJG4pLjIACykmBsp0eSSVeC15TDJeUhlkowlL+SWLNJpW2WEF87urXzNWSZ6JOEb7b8g1brZMjCg3ezBtWKKc4MvyEtwybPeaMAA1ECRoAQYHYLpbeYYCLfQ+mtL5c9CnfQpYpUtHOSejEgT9ogZ/GSqd0f2m+LR5WzOtHqlQX1pYwpC+WbXKqSYtpJ5Mt4a01lGzS3akF60AxkcTaLgAyRBPWCoDgHfJqwRuBuzdw/1ml3iCwTIeLUWJN0v4McMe7uasCTxseNWPSxc5RbvIgD7geZLbGrqCG3jepUmbbze63Y6fvjiOylbwOITPfIHEFsAHL/zwxBdvPBVdFKH88sw37/zz0Ecv/fTUV2/99SeEAAAh+QQJCgAAACwAAAAA3AATAAAF/yAgjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEgECAaEpHLJbDqf0Kh0Sq1ar9isdjoQtAQFh2cw8BQEm3T6yHEYHHD4oKCuD9qGvNsxT6QTgAkcHHmFeX11fm17hXwPG35qgnhxbwMPkXaLhgZ9gWp3bpyegX4DcG+inY+Qn6eclpiZkHh6epetgLSUcBxlD2csXXdvBQrHGgoaGhsGaIkFDwjTCArTzX+QadHU3c1ofpHc3dcGG89/4+TYktvS1NYI7OHu3fEJ5tpqBu/k+HX7+nXDB06SuoHm0KXhR65cQT8P3FRAMIAFgVMPwDCAwLHjggIHJIgceeFBg44eC/+ITCCBZYKSJ1FCWPBgpE2YMmc+qNCypwScMmnaXAkUJYOaFVyKLOqx5tCXJnMelcBzJNSYKIX2ZPkzqsyjPLku9Zr1QciVErYxaICAgEUOBRJIgzChbt0MLOPFwyBggV27eCUcmxZvg9+/dfPGo5bg8N/Ag61ZM4w4seDF1fpWhizZmoa+GSortgcaMWd/fkP/HY0MgWbTipVV++wY8GhvqSG4XUEgoYTKE+Qh0OCvggULiBckWEZ4Ggbjx5HXVc58IPQJ0idQJ66XanTpFraTe348+XLizRNcz658eHMN3rNPT+C+G/nodqk3t6a+fN3j+u0Xn3nVTQPfdRPspkL/b+dEIN8EeMm2GAYbTNABdrbJ1hyFFv5lQYTodSZABhc+loCEyhxTYYkZopdMMiNeiBxyIFajV4wYHpfBBspUl8yKHu6ooV5APsZjQxyyeNeJ3N1IYod38cgdPBUid6GCKfRWgAYU4IccSyHew8B3doGJHmMLkGkZcynKk2Z50Ym0zJzLbDCmfBbI6eIyCdyJmJmoqZmnBAXy9+Z/yOlZDZpwYihnj7IZpuYEevrYJ5mJEuqiof4l+NYDEXQpXQcMnNjZNDx1oGqJ4S2nF3EsqWrhqqVWl6JIslpAK5MaIqDeqjJq56qN1aTaQaPbHTPYr8Be6Gsyyh6Da7OkmmqP/7GyztdrNVQBm5+pgw3X7aoYKhfZosb6hyUKBHCgQKij1rghkOAJuZg1SeYIIY+nIpDvf/sqm4yNG5CY64f87qdAwSXKGqFkhPH1ZHb2EgYtw3bpKGVkPz5pJAav+gukjB1UHE/HLNJobWcSX8jiuicMMBFd2OmKwQFs2tjXpDfnPE1j30V3c7iRHlrzBD2HONzODyZtsQJMI4r0AUNaE3XNHQw95c9GC001MpIxDacFQ+ulTNTZlU3O1eWVHa6vb/pnQUUrgHHSBKIuwG+bCPyEqbAg25gMVV1iOB/IGh5YOKLKIQ6xBAcUHmzjIcIqgajZ+Ro42DcvXl7j0U4WOUd+2IGu7DWjI1pt4DYq8BPm0entuGSQY/4tBi9Ss0HqfwngBQtHbCH88MQXb/zxyFfRRRHMN+/889BHL/301Fdv/fXYZ39CCAAh+QQJCgAAACwAAAAA3AATAAAF/yAgjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEgECAaEpHLJbDqf0Kh0Sq1ar9isdjoQtAQFh2fAKXsKm7R6Q+Y43vABep0mGwwOPH7w2CT+gHZ3d3lyagl+CQNvg4yGh36LcHoGfHR/ZYOElQ9/a4ocmoRygIiRk5p8pYmZjXePaYBujHoOqp5qZHBlHAUFXitddg8PBg8KGsgayxvGkAkFDwgICtPTzX2mftHW3QnOpojG3dbYkNjk1waxsdDS1N7ga9zw1t/aifTk35fu6Qj3numL14fOuHTNECHqU4DDgQEsCCwidiHBAwYQMmpcUOCAhI8gJVzUuLGThAQnP/9abEAyI4MCIVOKZNnyJUqUJxNcGNlywYOQgHZirGkSJ8gHNEky+AkS58qWEJYC/bMzacmbQHkqNdlUJ1KoSz2i9COhmQYCEXtVrCBgwYS3cCf8qTcNQ9u4cFFOq2bPLV65Cf7dxZthbjW+CgbjnWtNgWPFcAsHdoxgWWK/iyV045sAc2S96SDn1exYw17REwpLQEYt2eW/qtPZRQAB7QoC61RW+GsBwYZ/CXb/XRCYLsAKFizEtUAc+G7lcZsjroscOvTmsoUvx15PwccJ0N8yL17N9PG/E7jv9S4hOV7pdIPDdZ+ePDzv2qMXn2b5+wTbKuAWnF3oZbABZY0lVmD/ApQd9thybxno2GGuCVDggaUpoyBsB1bGGgIYbJCBcuFJiOAyGohIInQSmmdeiBnMF2GHfNUlIoc1rncjYRjW6NgGf3VQGILWwNjBfxEZcAFbC7gHXQcfUYOYdwzQNxo5yUhQZXhvRYlMeVSuSOJHKJa5AQMQThBlZWZ6Bp4Fa1qzTAJbijcBlJrtxeaZ4lnnpZwpukWieGQmYx5ATXIplwTL8DdNZ07CtWYybNIJF4Ap4NZHe0920AEDk035kafieQrqXofK5ympn5JHKYjPrfoWcR8WWQGp4Ul32KPVgXdnqxM6OKqspjIYrGPDrlrsZtRIcOuR86nHFwbPvmes/6PH4frrqbvySh+mKGhaAARPzjjdhCramdoGGOhp44i+zogBkSDuWC5KlE4r4pHJkarXrj++Raq5iLmWLlxHBteavjG+6amJrUkJJI4Ro5sBv9AaOK+jAau77sbH7nspCwNIYIACffL7J4JtWQnen421nNzMcB6AqpRa9klonmBSiR4GNi+cJZpvwgX0ejj71W9yR+eIgaVvQgf0l/A8nWjUFhwtZYWC4hVnkZ3p/PJqNQ5NnwUQrQCGBBBMQIGTtL7abK+5JjAv1fi9bS0GLlJHgdjEgYzzARTwC1fgEWdJuKKBZzj331Y23qB3i9v5aY/rSUC4w7PaLeWXmr9NszMFoN79eeiM232o33EJAIzaSGwh++y012777bhT0UURvPfu++/ABy/88MQXb/zxyCd/QggAIfkECQoAAAAsAAAAANwAEwAABf8gII5kaZ5oqq5s675wLM90bd94ru987//AoHBIBAgGhKRyyWw6n9CodEqtWq/YrHY6ELQEBY5nwCk7xIWNer0hO95wziC9Ttg5b4ND/+Y87IBqZAaEe29zGwmJigmDfHoGiImTjXiQhJEPdYyWhXwDmpuVmHwOoHZqjI6kZ3+MqhyemJKAdo6Ge3OKbEd4ZRwFBV4rc4MPrgYPChrMzAgbyZSJBcoI1tfQoYsJydfe2amT3d7W0OGp1OTl0YtqyQrq0Lt11PDk3KGoG+nxBpvTD9QhwCctm0BzbOyMIwdOUwEDEgawIOCB2oMLgB4wgMCx44IHBySIHClBY0ePfyT/JCB5weRJCAwejFw58kGDlzBTqqTZcuPLmCIBiWx58+VHmiRLFj0JVCVLl0xl7qSZwCbOo0lFWv0pdefQrVFDJtr5gMBEYBgxqBWwYILbtxPsqMPAFu7blfa81bUbN4HAvXAzyLWnoDBguHIRFF6m4LBbwQngMYPXuC3fldbyPrMcGLM3w5wRS1iWWUNlvnElKDZtz/EEwaqvYahQoexEfyILi4RrYYKFZwJ3810QWZ2ECrx9Ew+O3K6F5Yq9zXbb+y30a7olJJ+wnLC16W97Py+uwdtx1NcLWzs/3G9e07stVPc9kHJ0BcLtQp+c3ewKAgYkUAFpCaAmmHqKLSYA/18WHEiZPRhsQF1nlLFWmIR8ZbDBYs0YZuCGpGXWmG92aWiPMwhEOOEEHXRwIALlwXjhio+BeE15IzpnInaLbZBBhhti9x2GbnVQo2Y9ZuCfCgBeMCB+DJDIolt4iVhOaNSJdCOBUfIlkmkyMpPAAvKJ59aXzTQzJo0WoJnmQF36Jp6W1qC4gWW9GZladCiyJd+KnsHImgRRVjfnaDEKuiZvbcYWo5htzefbl5LFWNeSKQAo1QXasdhiiwwUl2B21H3aQaghXnPcp1NagCqYslXAqnV+zYWcpNwVp9l5eepJnHqL4SdBi56CGlmw2Zn6aaiZjZqfb8Y2m+Cz1O0n3f+tnvrGbF6kToApCgAWoNWPeh754JA0vmajiAr4iOuOW7abQXVGNriBWoRdOK8FxNqLwX3oluubhv8yluRbegqGb536ykesuoXhyJqPQJIGbLvQhkcwjKs1zBvBwSZIsbcsDCCBAAf4ya+UEhyQoIiEJtfoZ7oxUOafE2BwgMWMqUydfC1LVtiArk0QtGkWEopzlqM9aJrKHfw5c6wKjFkmXDrbhwFockodtMGFLWpXy9JdiXN1ZDNszV4WSLQCGBKoQYHUyonqrHa4ErewAgMmcAAF7f2baIoVzC2p3gUvJtLcvIWqloy6/R04mIpLwDhciI8qLOB5yud44pHPLbA83hFDWPjNbuk9KnySN57Av+TMBvgEAgzzNhJb5K777rz37vvvVHRRxPDEF2/88cgnr/zyzDfv/PPQnxACACH5BAkKAAAALAAAAADcABMAAAX/ICCOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSAQIBoSkcslsOp/QqHRKrVqv2Kx2OhC0BIUCwcMpO84OT2HDbm8GHLQjnn6wE3g83SA3DB55G3llfHxnfnZ4gglvew6Gf4ySgmYGlpCJknochWiId3kJcZZyDn93i6KPl4eniopwq6SIoZKxhpenbhtHZRxhXisDopwPgHkGDxrLGgjLG8mC0gkFDwjX2AgJ0bXJ2djbgNJsAtbfCNB2oOnn6MmKbeXt226K1fMGi6j359D69ua+QZskjd+3cOvY9XNgp4ABCQNYEDBl7EIeCQkeMIDAseOCBwckiBSZ4ILGjh4B/40kaXIjSggMHmBcifHky5gYE6zM2OAlzGM6Z5rs+fIjTZ0tfcYMSlLCUJ8fL47kCVXmTjwPiKJkUCDnyqc3CxzQmYeAxAEGLGJYiwCDgAUT4sqdgOebArdw507IUNfuW71xdZ7DC5iuhGsKErf9CxhPYgUaEhPWyzfBMgUIJDPW6zhb5M1y+R5GjFkBaLmCM0dOfHqvztXYJnMejaFCBQlmVxAYsEGkYnQV4lqYMNyCtnYSggNekAC58uJxmTufW5w55mwKkg+nLp105uTC53a/nhg88fMTmDfDVl65Xum/IZt/3/zaag3a5W63nll1dvfiWbaaZLmpQIABCVQA2f9lAhTG112PQWYadXE9+FtmEwKWwQYQJrZagxomsOCAGVImInsSbpCBhhwug6KKcXXQQYUcYuDMggrASFmNzjjzzIrh7cUhhhHqONeGpSEW2QYxHsmjhxpgUGAKB16g4IIbMNCkXMlhaJ8GWVJo2I3NyKclYF1GxgyYDEAnXHJrMpNAm/rFBSczPiYAlwXF8ZnmesvoOdyMbx7m4o0S5LWdn4bex2Z4xYmEzaEb5EUcnxbA+WWglqIn6aHPTInCgVbdlZyMqMrIQHMRSiaBBakS1903p04w434n0loBoQFOt1yu2YAnY68RXiNsqh2s2qqxuyKb7Imtmgcrqsp6h8D/fMSpapldx55nwayK/SfqCQd2hcFdAgDp5GMvqhvakF4mZuS710WGIYy30khekRkMu92GNu6bo7r/ttjqwLaua5+HOdrKq5Cl3dcwi+xKiLBwwwom4b0E6xvuYyqOa8IAEghwQAV45VvovpkxBl2mo0W7AKbCZXoAhgMmWnOkEqx2JX5nUufbgJHpXCfMOGu2QAd8eitpW1eaNrNeMGN27mNz0swziYnpSbXN19gYtstzfXrdYjNHtAIYGFVwwAEvR1dfxdjKxVzAP0twAAW/ir2w3nzTd3W4yQWO3t0DfleB4XYnEHCEhffdKgaA29p0eo4fHLng9qoG+OVyXz0gMeWGY7qq3xhiRIEAwayNxBawxy777LTXbjsVXRSh++689+7778AHL/zwxBdv/PEnhAAAIfkECQoAAAAsAAAAANwAEwAABf8gII5kaZ5oqq5s675wLM90bd94ru987//AoHBIBAgGhKRyyWw6n9CodEqtWq/YrHY6ELQEhYLD4BlwHGg0ubBpuzdm9Dk9eCTu+MTZkDb4PXYbeIIcHHxqf4F3gnqGY2kOdQmCjHCGfpCSjHhmh2N+knmEkJmKg3uHfgaaeY2qn6t2i4t7sKAPbwIJD2VhXisDCQZgDrKDBQ8aGgjKyhvDlJMJyAjV1gjCunkP1NfVwpRtk93e2ZVt5NfCk27jD97f0LPP7/Dr4pTp1veLgvrx7AL+Q/BM25uBegoYkDCABYFhEobhkUBRwoMGEDJqXPDgQMUEFC9c1LjxQUUJICX/iMRIEgIDkycrjmzJMSXFlDNJvkwJsmdOjQwKfDz5M+PLoSGLQqgZU6XSoB/voHxawGbFlS2XGktAwKEADB0xiEWAodqGBRPSqp1wx5qCamDRrp2Qoa3bagLkzrULF4GCvHPTglRAmKxZvWsHayBcliDitHUlvGWM97FgCdYWVw4c2e/kw4HZJlCwmDBhwHPrjraGYTHqtaoxVKggoesKAgd2SX5rbUMFCxOAC8cGDwHFwBYWJCgu4XfwtcqZV0grPHj0u2SnqwU+IXph3rK5b1fOu7Bx5+K7L6/2/Xhg8uyXnQ8dvfRiDe7TwyfNuzlybKYpgIFtKhAgwEKkKcOf/wChZbBBgMucRh1so5XH3wbI1WXafRJy9iCErmX4IWHNaIAhZ6uxBxeGHXQA24P3yYfBBhmgSBozESpwongWOBhggn/N1aKG8a1YY2oVAklgCgQUUwGJ8iXAgItrWUARbwpqIOWEal0ZoYJbzmWlZCWSlsAC6VkwZonNbMAAl5cpg+NiZwpnJ0Xylegmlc+tWY1mjnGnZnB4QukMA9UJRxGOf5r4ppqDjjmnfKilh2ejGiyJAgF1XNmYbC2GmhZ5AcJVgajcXecNqM9Rx8B6bingnlotviqdkB3YCg+rtOaapFsUhSrsq6axJ6sEwoZK7I/HWpCsr57FBxJ1w8LqV/81zbkoXK3LfVeNpic0KRQG4NHoIW/XEmZuaiN6tti62/moWbk18uhjqerWS6GFpe2YVotskVssWfBOAHACrZHoWcGQwQhlvmsdXBZ/F9YLMF2jzUuYBP4a7CLCnoEHrgkDSCDAARUILAGaVVqAwQHR8pZXomm9/ONhgjrbgc2lyYxmpIRK9uSNjrXs8gEbTrYyl2ryTJmsLCdKkWzFQl1lWlOXGmifal6p9VnbQfpyY2SZyXKVV7JmZkMrgIFSyrIeUJ2r7YKnXdivUg1kAgdQ8B7IzJjGsd9zKSdwyBL03WpwDGxwuOASEP5vriO2F3nLjQdIrpaRDxqcBdgIHGA74pKrZXiR2ZWuZt49m+o3pKMC3p4Av7SNxBa456777rz37jsVXRQh/PDEF2/88cgnr/zyzDfv/PMnhAAAIfkECQoAAAAsAAAAANwAEwAABf8gII5kaZ5oqq5s675wLM90bd94ru987//AoHBIBAgGhKRyyWw6n9CodEqtWq/YrHY6ELQEhYLDUPAMHGi0weEpbN7wI8cxTzsGj4R+n+DUxwaBeBt7hH1/gYIPhox+Y3Z3iwmGk36BkIN8egOIl3h8hBuOkAaZhQlna4BrpnyWa4mleZOFjrGKcXoFA2ReKwMJBgISDw6abwUPGggazc0bBqG0G8kI1tcIwZp51djW2nC03d7BjG8J49jl4cgP3t/RetLp1+vT6O7v5fKhAvnk0UKFogeP3zmCCIoZkDCABQFhChQYuKBHgkUJkxpA2MhxQYEDFhNcvPBAI8eNCx7/gMQYckPJkxsZPLhIM8FLmDJrYiRp8mTKkCwT8IQJwSPQkENhpgQpEunNkzlpWkwKdSbGihKocowqVSvKWQkIOBSgQOYFDBgQpI0oYMGEt3AzTLKm4BqGtnDjirxW95vbvG/nWlub8G9euRsiqqWLF/AEkRoiprX2wLDeDQgkW9PQGLDgyNc665WguK8C0XAnRY6oGPUEuRLsgk5g+a3cCxUqSBC7gsCBBXcVq6swwULx4hayvctGPK8FCwsSLE9A3Hje6NOrHzeOnW695sffRi/9HfDz7sIVSNB+XXrmugo0rHcM3X388o6jr44ceb51uNjF1xcC8zk3wXiS8aYC/wESaLABBs7ch0ECjr2WAGvLsLZBeHqVFl9kGxooV0T81TVhBo6NiOEyJ4p4IYnNRBQiYCN6x4wCG3ZAY2If8jXjYRcyk2FmG/5nXAY8wqhWAii+1YGOSGLoY4VRfqiAgikwmIeS1gjAgHkWYLQZf9m49V9gDWYWY5nmTYCRM2TS5pxxb8IZGV5nhplmhJyZadxzbrpnZ2d/6rnZgHIid5xIMDaDgJfbLdrgMkKW+Rygz1kEZz1mehabkBpgiQIByVikwGTqVfDkk2/Vxxqiqur4X3fksHccre8xlxerDLiHjQIVUAgXr77yFeyuOvYqXGbMrbrqBMqaFpFFzhL7qv9i1FX7ZLR0LUNdcc4e6Cus263KbV+inkAAHhJg0BeITR6WmHcaxhvXg/AJiKO9R77ILF1FwmVdAu6WBu+ZFua72mkZWMfqBElKu0G8rFZ5n4ATp5jkmvsOq+Nj7u63ZMMPv4bveyYy6fDH+C6brgnACHBABQUrkGirz2FwAHnM4Mmhzq9yijOrOi/MKabH6VwBiYwZdukEQAvILKTWXVq0ZvH5/CfUM7M29Zetthp1eht0eqkFYw8IKXKA6mzXfTeH7fZg9zW0AhgY0TwthUa6Ch9dBeIsbsFrYkRBfgTfiG0FhwMWnbsoq3cABUYOnu/ejU/A6uNeT8u4wMb1WnBCyJJTLjjnr8o3OeJrUcpc5oCiPqAEkz8tXuLkPeDL3Uhs4fvvwAcv/PDEU9FFEcgnr/zyzDfv/PPQRy/99NRXf0IIACH5BAkKAAAALAAAAADcABMAAAX/ICCOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSAQIBoSkcslsOp/QqHRKrVqv2Kx2OhC0BIWCw/AoDziOtCHt8BQ28PjmzK57Hom8fo42+P8DeAkbeYQcfX9+gYOFg4d1bIGEjQmPbICClI9/YwaLjHAJdJeKmZOViGtpn3qOqZineoeJgG8CeWUbBV4rAwkGAhIVGL97hGACGsrKCAgbBoTRhLvN1c3PepnU1s2/oZO6AtzdBoPf4eMI3tIJyOnF0YwFD+nY8e3z7+Xfefnj9uz8cVsXCh89axgk7BrAggAwBQsYIChwQILFixIeNIDAseOCBwcSXMy2sSPHjxJE/6a0eEGjSY4MQGK86PIlypUJEmYsaTKmyJ8JW/Ls6HMkzaEn8YwMWtPkx4pGd76E4DMPRqFTY860OGhogwYagBFoKEABA46DEGBAoEBB0AUT4sqdIFKBNbcC4M6dkEEk22oYFOTdG9fvWrtsBxM23MytYL17666t9phwXwlum2lIDHmuSA2IGyuOLOHv38qLMbdFjHruZbWgRXeOe1nC2BUEDiyAMMHZuwoTLAQX3nvDOAUW5Vogru434d4JnAsnPmFB9NBshQXfa9104+Rxl8e13rZxN+CEydtVsFkd+vDjE7C/q52wOvb4s7+faz025frbxefWbSoQIAEDEUCwgf9j7bUlwHN9ZVaegxDK1xYzFMJH24L5saXABhlYxiEzHoKoIV8LYqAMaw9aZqFmJUK4YHuNfRjiXhmk+NcyJgaIolvM8BhiBx3IleN8lH1IWAcRgkZgCgYiaBGJojGgHHFTgtagAFYSZhF7/qnTpY+faVlNAnqJN0EHWa6ozAZjBtgmmBokwMB01LW5jAZwbqfmlNips4B4eOqJgDJ2+imXRZpthuigeC6XZTWIxilXmRo8iYKBCwiWmWkJVEAkfB0w8KI1IvlIpKnOkVpqdB5+h96o8d3lFnijrgprjbfGRSt0lH0nAZG5vsprWxYRW6Suq4UWqrLEsspWg8Io6yv/q6EhK0Fw0GLbjKYn5CZYBYht1laPrnEY67kyrhYbuyceiR28Pso7bYwiXjihjWsWuWF5p/H765HmNoiur3RJsGKNG/jq748XMrwmjhwCfO6QD9v7LQsDxPTAMKsFpthyJCdkmgYiw0VdXF/Om9dyv7YMWGXTLYpZg5wNR11C78oW3p8HSGgul4qyrJppgllJHJZHn0Y0yUwDXCXUNquFZNLKyYXBAVZvxtAKYIQEsmPgDacr0tltO1y/DMwYpkgUpJfTasLGzd3cdCN3gN3UWRcY3epIEPevfq+3njBxq/kqBoGBduvea8f393zICS63ivRBTqgFpgaWZEIUULdcK+frIfAAL2AjscXqrLfu+uuwx05FF0XUbvvtuOeu++689+7778AHL/wJIQAAOwAAAAAAAAAAAA==") \ No newline at end of file diff --git a/build/src/keybinding-emacs.js b/build/src/keybinding-emacs.js deleted file mode 100644 index 12030e2f..00000000 --- a/build/src/keybinding-emacs.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/keyboard/keybinding/emacs",["require","exports","module","ace/keyboard/state_handler"],function(a,b,c){var d=a("ace/keyboard/state_handler").StateHandler,e=a("ace/keyboard/state_handler").matchCharacterOnly,f={start:[{key:"ctrl-x",then:"c-x"},{regex:["(?:command-([0-9]*))*","(down|ctrl-n)"],exec:"golinedown",params:[{name:"times",match:1,type:"number",defaultValue:1}]},{regex:["(?:command-([0-9]*))*","(right|ctrl-f)"],exec:"gotoright",params:[{name:"times",match:1,type:"number",defaultValue:1}]},{regex:["(?:command-([0-9]*))*","(up|ctrl-p)"],exec:"golineup",params:[{name:"times",match:1,type:"number",defaultValue:1}]},{regex:["(?:command-([0-9]*))*","(left|ctrl-b)"],exec:"gotoleft",params:[{name:"times",match:1,type:"number",defaultValue:1}]},{comment:"This binding matches all printable characters except numbers as long as they are no numbers and print them n times.",regex:["(?:command-([0-9]*))","([^0-9]+)*"],match:e,exec:"inserttext",params:[{name:"times",match:1,type:"number",defaultValue:"1"},{name:"text",match:2}]},{comment:"This binding matches numbers as long as there is no meta_number in the buffer.",regex:["(command-[0-9]*)*","([0-9]+)"],match:e,disallowMatches:[1],exec:"inserttext",params:[{name:"text",match:2,type:"text"}]},{regex:["command-([0-9]*)","(command-[0-9]|[0-9])"],comment:"Stops execution if the regex /meta_[0-9]+/ matches to avoid resetting the buffer."}],"c-x":[{key:"ctrl-g",then:"start"},{key:"ctrl-s",exec:"save",then:"start"}]};b.Emacs=new d(f)}),define("ace/keyboard/state_handler",["require","exports","module"],function(a,b,c){function e(a){this.keymapping=this.$buildKeymappingRegex(a)}var d=!1;e.prototype={$buildKeymappingRegex:function(a){for(state in a)this.$buildBindingsRegex(a[state]);return a},$buildBindingsRegex:function(a){a.forEach(function(a){a.key?a.key=new RegExp("^"+a.key+"$"):Array.isArray(a.regex)?(a.key=new RegExp("^"+a.regex[1]+"$"),a.regex=new RegExp(a.regex.join("")+"$")):a.regex&&(a.regex=new RegExp(a.regex+"$"))})},$composeBuffer:function(a,b,c){if(a.state==null||a.buffer==null)a.state="start",a.buffer="";var d=[];b&1&&d.push("ctrl"),b&8&&d.push("command"),b&2&&d.push("option"),b&4&&d.push("shift"),c&&d.push(c);var e=d.join("-"),f=a.buffer+e;b!=2&&(a.buffer=f);return{bufferToUse:f,symbolicName:e}},$find:function(a,b,c,e,f){var g={};this.keymapping[a.state].some(function(h){var i;if(h.key&&!h.key.test(c))return!1;if(h.regex&&!(i=h.regex.exec(b)))return!1;if(h.match&&!h.match(b,e,f,c))return!1;if(h.disallowMatches)for(var j=0;j"},{token:"keyword",regex:"(?:#include|#pragma|#line|#define|#undef|#ifdef|#else|#elif|#endif|#ifndef)"},{token:function(a){return a=="this"?"variable.language":b.hasOwnProperty(a)?"keyword":c.hasOwnProperty(a)?"constant.language":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]},this.addRules(a.getRules(),"doc-"),this.$rules["doc-start"][0].next="start"};d.inherits(h,g),b.c_cppHighlightRules=h}),define("ace/mode/doc_comment_highlight_rules",["require","exports","module","pilot/oop","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc",regex:"\\*\\/",next:"start"},{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",regex:"s+"},{token:"comment.doc",regex:"TODO"},{token:"comment.doc",regex:"[^@\\*]+"},{token:"comment.doc",regex:"."}]}};d.inherits(f,e),function(){this.getStartRule=function(a){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:a}}}.call(f.prototype),b.DocCommentHighlightRules=f}) \ No newline at end of file diff --git a/build/src/mode-coffee.js b/build/src/mode-coffee.js deleted file mode 100644 index 865ebd79..00000000 --- a/build/src/mode-coffee.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/mode/coffee",["require","exports","module","ace/tokenizer","ace/mode/coffee_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/text","pilot/oop"],function(a,b,c){function j(){this.$tokenizer=new d((new e).getRules()),this.$outdent=new f}var d=a("ace/tokenizer").Tokenizer,e=a("ace/mode/coffee_highlight_rules").CoffeeHighlightRules,f=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,g=a("ace/range").Range,h=a("ace/mode/text").Mode,i=a("pilot/oop");i.inherits(j,h);var k=j.prototype,l=/(?:[({[=:]|[-=]>|\b(?:else|switch|try|catch(?:\s*[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)?|finally))\s*$/,m=/^(\s*)#/,n=/^\s*###(?!#)/,o=/^\s*/;k.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a).tokens;(!e.length||e[e.length-1].type!=="comment")&&a==="start"&&l.test(b)&&(d+=c);return d},k.toggleCommentLines=function(a,b,c,d){console.log("toggle");var e=new g(0,0,0,0);for(var f=c;f<=d;++f){var h=b.getLine(f);if(n.test(h))continue;m.test(h)?h=h.replace(m,"$1"):h=h.replace(o,"$&#"),e.end.row=e.start.row=f,e.end.column=h.length+1,b.replace(e,h)}},k.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},k.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)},b.Mode=j}),define("ace/mode/coffee_highlight_rules",["require","exports","module","pilot/oop","ace/mode/text_highlight_rules"],function(a,b,c){function d(){var a="[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*",b="(?![$\\w]|\\s*:)",c={token:"string",regex:".+"};this.$rules={start:[{token:"identifier",regex:"(?:@|(?:\\.|::)\\s*)"+a},{token:"keyword",regex:"(?:t(?:h(?:is|row|en)|ry|ypeof)|s(?:uper|witch)|return|b(?:reak|y)|c(?:ontinue|atch|lass)|i(?:n(?:stanceof)?|s(?:nt)?|f)|e(?:lse|xtends)|f(?:or (?:own)?|inally|unction)|wh(?:ile|en)|n(?:ew|ot?)|d(?:e(?:lete|bugger)|o)|loop|o(?:ff?|[rn])|un(?:less|til)|and|yes)"+b},{token:"constant.language",regex:"(?:true|false|null|undefined)"+b},{token:"invalid.illegal",regex:"(?:c(?:ase|onst)|default|function|v(?:ar|oid)|with|e(?:num|xport)|i(?:mplements|nterface)|let|p(?:ackage|r(?:ivate|otected)|ublic)|static|yield|__(?:hasProp|extends|slice|bind|indexOf))"+b},{token:"language.support.class",regex:"(?:Array|Boolean|Date|Function|Number|Object|R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|TypeError|URIError)"+b},{token:"language.support.function",regex:"(?:Math|JSON|is(?:NaN|Finite)|parse(?:Int|Float)|encodeURI(?:Component)?|decodeURI(?:Component)?)"+b},{token:"identifier",regex:a},{token:"constant.numeric",regex:"(?:0x[\\da-fA-F]+|(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:[eE][+-]?\\d+)?)"},{token:"string",regex:"'''",next:"qdoc"},{token:"string",regex:'"""',next:"qqdoc"},{token:"string",regex:"'",next:"qstring"},{token:"string",regex:'"',next:"qqstring"},{token:"string",regex:"`",next:"js"},{token:"string.regex",regex:"///",next:"heregex"},{token:"string.regex",regex:"/(?!\\s)[^[/\\n\\\\]*(?: (?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[/\\n\\\\]*)*/[imgy]{0,4}(?!\\w)"},{token:"comment",regex:"###(?!#)",next:"comment"},{token:"comment",regex:"#.*"},{token:"lparen",regex:"[({[]"},{token:"rparen",regex:"[\\]})]"},{token:"keyword.operator",regex:"\\S+"},{token:"text",regex:"\\s+"}],qdoc:[{token:"string",regex:".*?'''",next:"start"},c],qqdoc:[{token:"string",regex:'.*?"""',next:"start"},c],qstring:[{token:"string",regex:"[^\\\\']*(?:\\\\.[^\\\\']*)*'",next:"start"},c],qqstring:[{token:"string",regex:'[^\\\\"]*(?:\\\\.[^\\\\"]*)*"',next:"start"},c],js:[{token:"string",regex:"[^\\\\`]*(?:\\\\.[^\\\\`]*)*`",next:"start"},c],heregex:[{token:"string.regex",regex:".*?///[imgy]{0,4}",next:"start"},{token:"comment.regex",regex:"\\s+(?:#.*)?"},{token:"string.regex",regex:"\\S+"}],comment:[{token:"comment",regex:".*?###",next:"start"},{token:"comment",regex:".+"}]}}a("pilot/oop").inherits(d,a("ace/mode/text_highlight_rules").TextHighlightRules),b.CoffeeHighlightRules=d}) \ No newline at end of file diff --git a/build/src/mode-csharp.js b/build/src/mode-csharp.js deleted file mode 100644 index 32a65590..00000000 --- a/build/src/mode-csharp.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/mode/csharp",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/csharp_highlight_rules","ace/mode/matching_brace_outdent"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/csharp_highlight_rules").CSharpHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(i,e),function(){this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[]\s*$/);h&&(d+=c)}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)},this.createWorker=function(a){return null}}.call(i.prototype),b.Mode=i}),define("ace/mode/csharp_highlight_rules",["require","exports","module","pilot/oop","pilot/lang","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/doc_comment_highlight_rules").DocCommentHighlightRules,g=a("ace/mode/text_highlight_rules").TextHighlightRules,h=function(){var a=new f,b=e.arrayToMap("abstract|event|new|struct|as|explicit|null|switch|base|extern|object|this|bool|false|operator|throw|break|finally|out|true|byte|fixed|override|try|case|float|params|typeof|catch|for|private|uint|char|foreach|protected|ulong|checked|goto|public|unchecked|class|if|readonly|unsafe|const|implicit|ref|ushort|continue|in|return|using|decimal|int|sbyte|virtual|default|interface|sealed|volatile|delegate|internal|short|void|do|is|sizeof|while|double|lock|stackalloc|else|long|static|enum|namespace|string|var|dynamic".split("|")),c=e.arrayToMap("null|true|false".split("|"));this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},a.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"comment",regex:"\\/\\*\\*",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:function(a){return a=="this"?"variable.language":b.hasOwnProperty(a)?"keyword":c.hasOwnProperty(a)?"constant.language":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]},this.addRules(a.getRules(),"doc-"),this.$rules["doc-start"][0].next="start"};d.inherits(h,g),b.CSharpHighlightRules=h}),define("ace/mode/doc_comment_highlight_rules",["require","exports","module","pilot/oop","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc",regex:"\\*\\/",next:"start"},{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",regex:"s+"},{token:"comment.doc",regex:"TODO"},{token:"comment.doc",regex:"[^@\\*]+"},{token:"comment.doc",regex:"."}]}};d.inherits(f,e),function(){this.getStartRule=function(a){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:a}}}.call(f.prototype),b.DocCommentHighlightRules=f}) \ No newline at end of file diff --git a/build/src/mode-css.js b/build/src/mode-css.js deleted file mode 100644 index fcf1359b..00000000 --- a/build/src/mode-css.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/mode/css",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/css_highlight_rules").CssHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(i,e),function(){this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a).tokens;if(e.length&&e[e.length-1].type=="comment")return d;var f=b.match(/^.*\{\s*$/);f&&(d+=c);return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)}}.call(i.prototype),b.Mode=i}),define("ace/mode/css_highlight_rules",["require","exports","module","pilot/oop","pilot/lang","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/text_highlight_rules").TextHighlightRules,g=function(){function g(a){var b=[],c=a.split("");for(var d=0;d=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]},this.addRules(a.getRules(),"doc-"),this.$rules["doc-start"][0].next="start"};d.inherits(h,g),b.JavaScriptHighlightRules=h}),define("ace/mode/doc_comment_highlight_rules",["require","exports","module","pilot/oop","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc",regex:"\\*\\/",next:"start"},{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",regex:"s+"},{token:"comment.doc",regex:"TODO"},{token:"comment.doc",regex:"[^@\\*]+"},{token:"comment.doc",regex:"."}]}};d.inherits(f,e),function(){this.getStartRule=function(a){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:a}}}.call(f.prototype),b.DocCommentHighlightRules=f}),define("ace/worker/worker_client",["require","exports","module","pilot/oop","pilot/event_emitter"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/event_emitter").EventEmitter,f=function(b,c,d,e){this.callbacks=[];if(a.packaged)var f=this.$guessBasePath(),g=this.$worker=new Worker(f+c);else{var h=a.nameToUrl("ace/worker/worker",null,"_"),g=this.$worker=new Worker(h),i={};for(var j=0;j"},{token:"comment",regex:"<\\!--",next:"comment"},{token:"text",regex:"<(?=s*script)",next:"script"},{token:"text",regex:"<(?=s*style)",next:"css"},{token:"text",regex:"<\\/?",next:"tag"},{token:"text",regex:"\\s+"},{token:"text",regex:"[^<]+"}],script:[{token:"text",regex:">",next:"js-start"},{token:"keyword",regex:"[-_a-zA-Z0-9:]+"},{token:"text",regex:"\\s+"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"}],css:[{token:"text",regex:">",next:"css-start"},{token:"keyword",regex:"[-_a-zA-Z0-9:]+"},{token:"text",regex:"\\s+"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"}],tag:[{token:"text",regex:">",next:"start"},{token:"keyword",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:".+"}]};var a=(new f).getRules();this.addRules(a,"js-"),this.$rules["js-start"].unshift({token:"comment",regex:"\\/\\/.*(?=<\\/script>)",next:"tag"},{token:"text",regex:"<\\/(?=script)",next:"tag"});var b=(new e).getRules();this.addRules(b,"css-"),this.$rules["css-start"].unshift({token:"text",regex:"<\\/(?=style)",next:"tag"})};d.inherits(h,g),b.HtmlHighlightRules=h}) \ No newline at end of file diff --git a/build/src/mode-java.js b/build/src/mode-java.js deleted file mode 100644 index b67a8ea3..00000000 --- a/build/src/mode-java.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/mode/java",["require","exports","module","pilot/oop","ace/mode/javascript","ace/tokenizer","ace/mode/java_highlight_rules","ace/mode/matching_brace_outdent"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/javascript").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/java_highlight_rules").JavaHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(i,e),function(){this.createWorker=function(a){return null}}.call(i.prototype),b.Mode=i}),define("ace/mode/javascript",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/javascript_highlight_rules").JavaScriptHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=a("ace/worker/worker_client").WorkerClient,k=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(k,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)\/\//;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,"//")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[]\s*$/);h&&(d+=c)}else if(a=="doc-start"){if(g=="start")return"";var h=b.match(/^\s*(\/?)\*/);h&&(h[1]&&(d+=" "),d+="* ")}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)},this.createWorker=function(a){var b=a.getDocument(),c=new j(["ace","pilot"],"worker-javascript.js","ace/mode/javascript_worker","JavaScriptWorker");c.call("setValue",[b.getValue()]),b.on("change",function(a){a.range={start:a.data.range.start,end:a.data.range.end},c.emit("change",a)}),c.on("jslint",function(b){var c=[];for(var d=0;d=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]},this.addRules(a.getRules(),"doc-"),this.$rules["doc-start"][0].next="start"};d.inherits(h,g),b.JavaScriptHighlightRules=h}),define("ace/mode/doc_comment_highlight_rules",["require","exports","module","pilot/oop","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc",regex:"\\*\\/",next:"start"},{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",regex:"s+"},{token:"comment.doc",regex:"TODO"},{token:"comment.doc",regex:"[^@\\*]+"},{token:"comment.doc",regex:"."}]}};d.inherits(f,e),function(){this.getStartRule=function(a){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:a}}}.call(f.prototype),b.DocCommentHighlightRules=f}),define("ace/worker/worker_client",["require","exports","module","pilot/oop","pilot/event_emitter"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/event_emitter").EventEmitter,f=function(b,c,d,e){this.callbacks=[];if(a.packaged)var f=this.$guessBasePath(),g=this.$worker=new Worker(f+c);else{var h=a.nameToUrl("ace/worker/worker",null,"_"),g=this.$worker=new Worker(h),i={};for(var j=0;j=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]},this.addRules(a.getRules(),"doc-"),this.$rules["doc-start"][0].next="start"};d.inherits(h,g),b.JavaHighlightRules=h}) \ No newline at end of file diff --git a/build/src/mode-javascript.js b/build/src/mode-javascript.js deleted file mode 100644 index 40f193e3..00000000 --- a/build/src/mode-javascript.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/mode/javascript",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/javascript_highlight_rules").JavaScriptHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=a("ace/worker/worker_client").WorkerClient,k=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(k,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)\/\//;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,"//")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[]\s*$/);h&&(d+=c)}else if(a=="doc-start"){if(g=="start")return"";var h=b.match(/^\s*(\/?)\*/);h&&(h[1]&&(d+=" "),d+="* ")}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)},this.createWorker=function(a){var b=a.getDocument(),c=new j(["ace","pilot"],"worker-javascript.js","ace/mode/javascript_worker","JavaScriptWorker");c.call("setValue",[b.getValue()]),b.on("change",function(a){a.range={start:a.data.range.start,end:a.data.range.end},c.emit("change",a)}),c.on("jslint",function(b){var c=[];for(var d=0;d=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]},this.addRules(a.getRules(),"doc-"),this.$rules["doc-start"][0].next="start"};d.inherits(h,g),b.JavaScriptHighlightRules=h}),define("ace/mode/doc_comment_highlight_rules",["require","exports","module","pilot/oop","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc",regex:"\\*\\/",next:"start"},{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",regex:"s+"},{token:"comment.doc",regex:"TODO"},{token:"comment.doc",regex:"[^@\\*]+"},{token:"comment.doc",regex:"."}]}};d.inherits(f,e),function(){this.getStartRule=function(a){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:a}}}.call(f.prototype),b.DocCommentHighlightRules=f}),define("ace/worker/worker_client",["require","exports","module","pilot/oop","pilot/event_emitter"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/event_emitter").EventEmitter,f=function(b,c,d,e){this.callbacks=[];if(a.packaged)var f=this.$guessBasePath(),g=this.$worker=new Worker(f+c);else{var h=a.nameToUrl("ace/worker/worker",null,"_"),g=this.$worker=new Worker(h),i={};for(var j=0;j>=|<<=|<=>|&&=|=>|!~|\\^=|&=|\\|=|\\.=|x=|%=|\\/=|\\*=|\\-=|\\+=|=~|\\*\\*|\\-\\-|\\.\\.|\\|\\||&&|\\+\\+|\\->|!=|==|>=|<=|>>|<<|,|=|\\?\\:|\\^|\\||x|%|\\/|\\*|<|&|\\\\|~|!|>|\\.|\\-|\\+|\\-C|\\-b|\\-S|\\-u|\\-t|\\-p|\\-l|\\-d|\\-f|\\-g|\\-s|\\-z|\\-k|\\-e|\\-O|\\-T|\\-B|\\-M|\\-A|\\-X|\\-W|\\-c|\\-R|\\-o|\\-x|\\-w|\\-r|\\b(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|xor)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]}};d.inherits(g,f),b.PerlHighlightRules=g}) \ No newline at end of file diff --git a/build/src/mode-php.js b/build/src/mode-php.js deleted file mode 100644 index 0af0d7a0..00000000 --- a/build/src/mode-php.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/mode/php",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/php_highlight_rules","ace/mode/matching_brace_outdent","ace/range"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/php_highlight_rules").PhpHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(j,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)#/;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,"#")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[\:]\s*$/);h&&(d+=c)}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)}}.call(j.prototype),b.Mode=j}),define("ace/mode/php_highlight_rules",["require","exports","module","pilot/oop","pilot/lang","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/doc_comment_highlight_rules").DocCommentHighlightRules,g=a("ace/mode/text_highlight_rules").TextHighlightRules,h=function(){var a=new f,b=e.arrayToMap("abs|acos|acosh|addcslashes|addslashes|aggregate|aggregate_info|aggregate_methods|aggregate_methods_by_list|aggregate_methods_by_regexp|aggregate_properties|aggregate_properties_by_list|aggregate_properties_by_regexp|aggregation_info|apache_child_terminate|apache_get_modules|apache_get_version|apache_getenv|apache_lookup_uri|apache_note|apache_request_headers|apache_response_headers|apache_setenv|array|array_change_key_case|array_chunk|array_combine|array_count_values|array_diff|array_diff_assoc|array_diff_uassoc|array_fill|array_filter|array_flip|array_intersect|array_intersect_assoc|array_key_exists|array_keys|array_map|array_merge|array_merge_recursive|array_multisort|array_pad|array_pop|array_push|array_rand|array_reduce|array_reverse|array_search|array_shift|array_slice|array_splice|array_sum|array_udiff|array_udiff_assoc|array_udiff_uassoc|array_unique|array_unshift|array_values|array_walk|arsort|ascii2ebcdic|asin|asinh|asort|aspell_check|aspell_check_raw|aspell_new|aspell_suggest|assert|assert_options|atan|atan2|atanh|base64_decode|base64_encode|base_convert|basename|bcadd|bccomp|bcdiv|bcmod|bcmul|bcpow|bcpowmod|bcscale|bcsqrt|bcsub|bin2hex|bind_textdomain_codeset|bindec|bindtextdomain|bzclose|bzcompress|bzdecompress|bzerrno|bzerror|bzerrstr|bzflush|bzopen|bzread|bzwrite|cal_days_in_month|cal_from_jd|cal_info|cal_to_jd|call_user_func|call_user_func_array|call_user_method|call_user_method_array|ccvs_add|ccvs_auth|ccvs_command|ccvs_count|ccvs_delete|ccvs_done|ccvs_init|ccvs_lookup|ccvs_new|ccvs_report|ccvs_return|ccvs_reverse|ccvs_sale|ccvs_status|ccvs_textvalue|ccvs_void|ceil|chdir|checkdate|checkdnsrr|chgrp|chmod|chop|chown|chr|chroot|chunk_split|class_exists|clearstatcache|closedir|closelog|com|com_addref|com_get|com_invoke|com_isenum|com_load|com_load_typelib|com_propget|com_propput|com_propset|com_release|com_set|compact|connection_aborted|connection_status|connection_timeout|constant|convert_cyr_string|copy|cos|cosh|count|count_chars|cpdf_add_annotation|cpdf_add_outline|cpdf_arc|cpdf_begin_text|cpdf_circle|cpdf_clip|cpdf_close|cpdf_closepath|cpdf_closepath_fill_stroke|cpdf_closepath_stroke|cpdf_continue_text|cpdf_curveto|cpdf_end_text|cpdf_fill|cpdf_fill_stroke|cpdf_finalize|cpdf_finalize_page|cpdf_global_set_document_limits|cpdf_import_jpeg|cpdf_lineto|cpdf_moveto|cpdf_newpath|cpdf_open|cpdf_output_buffer|cpdf_page_init|cpdf_place_inline_image|cpdf_rect|cpdf_restore|cpdf_rlineto|cpdf_rmoveto|cpdf_rotate|cpdf_rotate_text|cpdf_save|cpdf_save_to_file|cpdf_scale|cpdf_set_action_url|cpdf_set_char_spacing|cpdf_set_creator|cpdf_set_current_page|cpdf_set_font|cpdf_set_font_directories|cpdf_set_font_map_file|cpdf_set_horiz_scaling|cpdf_set_keywords|cpdf_set_leading|cpdf_set_page_animation|cpdf_set_subject|cpdf_set_text_matrix|cpdf_set_text_pos|cpdf_set_text_rendering|cpdf_set_text_rise|cpdf_set_title|cpdf_set_viewer_preferences|cpdf_set_word_spacing|cpdf_setdash|cpdf_setflat|cpdf_setgray|cpdf_setgray_fill|cpdf_setgray_stroke|cpdf_setlinecap|cpdf_setlinejoin|cpdf_setlinewidth|cpdf_setmiterlimit|cpdf_setrgbcolor|cpdf_setrgbcolor_fill|cpdf_setrgbcolor_stroke|cpdf_show|cpdf_show_xy|cpdf_stringwidth|cpdf_stroke|cpdf_text|cpdf_translate|crack_check|crack_closedict|crack_getlastmessage|crack_opendict|crc32|create_function|crypt|ctype_alnum|ctype_alpha|ctype_cntrl|ctype_digit|ctype_graph|ctype_lower|ctype_print|ctype_punct|ctype_space|ctype_upper|ctype_xdigit|curl_close|curl_errno|curl_error|curl_exec|curl_getinfo|curl_init|curl_multi_add_handle|curl_multi_close|curl_multi_exec|curl_multi_getcontent|curl_multi_info_read|curl_multi_init|curl_multi_remove_handle|curl_multi_select|curl_setopt|curl_version|current|cybercash_base64_decode|cybercash_base64_encode|cybercash_decr|cybercash_encr|cyrus_authenticate|cyrus_bind|cyrus_close|cyrus_connect|cyrus_query|cyrus_unbind|date|dba_close|dba_delete|dba_exists|dba_fetch|dba_firstkey|dba_handlers|dba_insert|dba_key_split|dba_list|dba_nextkey|dba_open|dba_optimize|dba_popen|dba_replace|dba_sync|dbase_add_record|dbase_close|dbase_create|dbase_delete_record|dbase_get_header_info|dbase_get_record|dbase_get_record_with_names|dbase_numfields|dbase_numrecords|dbase_open|dbase_pack|dbase_replace_record|dblist|dbmclose|dbmdelete|dbmexists|dbmfetch|dbmfirstkey|dbminsert|dbmnextkey|dbmopen|dbmreplace|dbplus_add|dbplus_aql|dbplus_chdir|dbplus_close|dbplus_curr|dbplus_errcode|dbplus_errno|dbplus_find|dbplus_first|dbplus_flush|dbplus_freealllocks|dbplus_freelock|dbplus_freerlocks|dbplus_getlock|dbplus_getunique|dbplus_info|dbplus_last|dbplus_lockrel|dbplus_next|dbplus_open|dbplus_prev|dbplus_rchperm|dbplus_rcreate|dbplus_rcrtexact|dbplus_rcrtlike|dbplus_resolve|dbplus_restorepos|dbplus_rkeys|dbplus_ropen|dbplus_rquery|dbplus_rrename|dbplus_rsecindex|dbplus_runlink|dbplus_rzap|dbplus_savepos|dbplus_setindex|dbplus_setindexbynumber|dbplus_sql|dbplus_tcl|dbplus_tremove|dbplus_undo|dbplus_undoprepare|dbplus_unlockrel|dbplus_unselect|dbplus_update|dbplus_xlockrel|dbplus_xunlockrel|dbx_close|dbx_compare|dbx_connect|dbx_error|dbx_escape_string|dbx_fetch_row|dbx_query|dbx_sort|dcgettext|dcngettext|deaggregate|debug_backtrace|debug_print_backtrace|debugger_off|debugger_on|decbin|dechex|decoct|define|define_syslog_variables|defined|deg2rad|delete|dgettext|die|dio_close|dio_fcntl|dio_open|dio_read|dio_seek|dio_stat|dio_tcsetattr|dio_truncate|dio_write|dir|dirname|disk_free_space|disk_total_space|diskfreespace|dl|dngettext|dns_check_record|dns_get_mx|dns_get_record|domxml_new_doc|domxml_open_file|domxml_open_mem|domxml_version|domxml_xmltree|domxml_xslt_stylesheet|domxml_xslt_stylesheet_doc|domxml_xslt_stylesheet_file|dotnet_load|doubleval|each|easter_date|easter_days|ebcdic2ascii|echo|empty|end|ereg|ereg_replace|eregi|eregi_replace|error_log|error_reporting|escapeshellarg|escapeshellcmd|eval|exec|exif_imagetype|exif_read_data|exif_thumbnail|exit|exp|explode|expm1|extension_loaded|extract|ezmlm_hash|fam_cancel_monitor|fam_close|fam_monitor_collection|fam_monitor_directory|fam_monitor_file|fam_next_event|fam_open|fam_pending|fam_resume_monitor|fam_suspend_monitor|fbsql_affected_rows|fbsql_autocommit|fbsql_blob_size|fbsql_change_user|fbsql_clob_size|fbsql_close|fbsql_commit|fbsql_connect|fbsql_create_blob|fbsql_create_clob|fbsql_create_db|fbsql_data_seek|fbsql_database|fbsql_database_password|fbsql_db_query|fbsql_db_status|fbsql_drop_db|fbsql_errno|fbsql_error|fbsql_fetch_array|fbsql_fetch_assoc|fbsql_fetch_field|fbsql_fetch_lengths|fbsql_fetch_object|fbsql_fetch_row|fbsql_field_flags|fbsql_field_len|fbsql_field_name|fbsql_field_seek|fbsql_field_table|fbsql_field_type|fbsql_free_result|fbsql_get_autostart_info|fbsql_hostname|fbsql_insert_id|fbsql_list_dbs|fbsql_list_fields|fbsql_list_tables|fbsql_next_result|fbsql_num_fields|fbsql_num_rows|fbsql_password|fbsql_pconnect|fbsql_query|fbsql_read_blob|fbsql_read_clob|fbsql_result|fbsql_rollback|fbsql_select_db|fbsql_set_lob_mode|fbsql_set_password|fbsql_set_transaction|fbsql_start_db|fbsql_stop_db|fbsql_tablename|fbsql_username|fbsql_warnings|fclose|fdf_add_doc_javascript|fdf_add_template|fdf_close|fdf_create|fdf_enum_values|fdf_errno|fdf_error|fdf_get_ap|fdf_get_attachment|fdf_get_encoding|fdf_get_file|fdf_get_flags|fdf_get_opt|fdf_get_status|fdf_get_value|fdf_get_version|fdf_header|fdf_next_field_name|fdf_open|fdf_open_string|fdf_remove_item|fdf_save|fdf_save_string|fdf_set_ap|fdf_set_encoding|fdf_set_file|fdf_set_flags|fdf_set_javascript_action|fdf_set_opt|fdf_set_status|fdf_set_submit_form_action|fdf_set_target_frame|fdf_set_value|fdf_set_version|feof|fflush|fgetc|fgetcsv|fgets|fgetss|file|file_exists|file_get_contents|file_put_contents|fileatime|filectime|filegroup|fileinode|filemtime|fileowner|fileperms|filepro|filepro_fieldcount|filepro_fieldname|filepro_fieldtype|filepro_fieldwidth|filepro_retrieve|filepro_rowcount|filesize|filetype|floatval|flock|floor|flush|fmod|fnmatch|fopen|fpassthru|fprintf|fputs|fread|frenchtojd|fribidi_log2vis|fscanf|fseek|fsockopen|fstat|ftell|ftok|ftp_alloc|ftp_cdup|ftp_chdir|ftp_chmod|ftp_close|ftp_connect|ftp_delete|ftp_exec|ftp_fget|ftp_fput|ftp_get|ftp_get_option|ftp_login|ftp_mdtm|ftp_mkdir|ftp_nb_continue|ftp_nb_fget|ftp_nb_fput|ftp_nb_get|ftp_nb_put|ftp_nlist|ftp_pasv|ftp_put|ftp_pwd|ftp_quit|ftp_raw|ftp_rawlist|ftp_rename|ftp_rmdir|ftp_set_option|ftp_site|ftp_size|ftp_ssl_connect|ftp_systype|ftruncate|func_get_arg|func_get_args|func_num_args|function_exists|fwrite|gd_info|get_browser|get_cfg_var|get_class|get_class_methods|get_class_vars|get_current_user|get_declared_classes|get_declared_interfaces|get_defined_constants|get_defined_functions|get_defined_vars|get_extension_funcs|get_headers|get_html_translation_table|get_include_path|get_included_files|get_loaded_extensions|get_magic_quotes_gpc|get_magic_quotes_runtime|get_meta_tags|get_object_vars|get_parent_class|get_required_files|get_resource_type|getallheaders|getcwd|getdate|getenv|gethostbyaddr|gethostbyname|gethostbynamel|getimagesize|getlastmod|getmxrr|getmygid|getmyinode|getmypid|getmyuid|getopt|getprotobyname|getprotobynumber|getrandmax|getrusage|getservbyname|getservbyport|gettext|gettimeofday|gettype|glob|gmdate|gmmktime|gmp_abs|gmp_add|gmp_and|gmp_clrbit|gmp_cmp|gmp_com|gmp_div|gmp_div_q|gmp_div_qr|gmp_div_r|gmp_divexact|gmp_fact|gmp_gcd|gmp_gcdext|gmp_hamdist|gmp_init|gmp_intval|gmp_invert|gmp_jacobi|gmp_legendre|gmp_mod|gmp_mul|gmp_neg|gmp_or|gmp_perfect_square|gmp_popcount|gmp_pow|gmp_powm|gmp_prob_prime|gmp_random|gmp_scan0|gmp_scan1|gmp_setbit|gmp_sign|gmp_sqrt|gmp_sqrtrem|gmp_strval|gmp_sub|gmp_xor|gmstrftime|gregoriantojd|gzclose|gzcompress|gzdeflate|gzencode|gzeof|gzfile|gzgetc|gzgets|gzgetss|gzinflate|gzopen|gzpassthru|gzputs|gzread|gzrewind|gzseek|gztell|gzuncompress|gzwrite|header|headers_list|headers_sent|hebrev|hebrevc|hexdec|highlight_file|highlight_string|html_entity_decode|htmlentities|htmlspecialchars|http_build_query|hw_api_attribute|hw_api_content|hw_api_object|hw_array2objrec|hw_changeobject|hw_children|hw_childrenobj|hw_close|hw_connect|hw_connection_info|hw_cp|hw_deleteobject|hw_docbyanchor|hw_docbyanchorobj|hw_document_attributes|hw_document_bodytag|hw_document_content|hw_document_setcontent|hw_document_size|hw_dummy|hw_edittext|hw_error|hw_errormsg|hw_free_document|hw_getanchors|hw_getanchorsobj|hw_getandlock|hw_getchildcoll|hw_getchildcollobj|hw_getchilddoccoll|hw_getchilddoccollobj|hw_getobject|hw_getobjectbyquery|hw_getobjectbyquerycoll|hw_getobjectbyquerycollobj|hw_getobjectbyqueryobj|hw_getparents|hw_getparentsobj|hw_getrellink|hw_getremote|hw_getremotechildren|hw_getsrcbydestobj|hw_gettext|hw_getusername|hw_identify|hw_incollections|hw_info|hw_inscoll|hw_insdoc|hw_insertanchors|hw_insertdocument|hw_insertobject|hw_mapid|hw_modifyobject|hw_mv|hw_new_document|hw_objrec2array|hw_output_document|hw_pconnect|hw_pipedocument|hw_root|hw_setlinkroot|hw_stat|hw_unlock|hw_who|hwapi_hgcsp|hypot|ibase_add_user|ibase_affected_rows|ibase_backup|ibase_blob_add|ibase_blob_cancel|ibase_blob_close|ibase_blob_create|ibase_blob_echo|ibase_blob_get|ibase_blob_import|ibase_blob_info|ibase_blob_open|ibase_close|ibase_commit|ibase_commit_ret|ibase_connect|ibase_db_info|ibase_delete_user|ibase_drop_db|ibase_errcode|ibase_errmsg|ibase_execute|ibase_fetch_assoc|ibase_fetch_object|ibase_fetch_row|ibase_field_info|ibase_free_event_handler|ibase_free_query|ibase_free_result|ibase_gen_id|ibase_maintain_db|ibase_modify_user|ibase_name_result|ibase_num_fields|ibase_num_params|ibase_param_info|ibase_pconnect|ibase_prepare|ibase_query|ibase_restore|ibase_rollback|ibase_rollback_ret|ibase_server_info|ibase_service_attach|ibase_service_detach|ibase_set_event_handler|ibase_timefmt|ibase_trans|ibase_wait_event|iconv|iconv_get_encoding|iconv_mime_decode|iconv_mime_decode_headers|iconv_mime_encode|iconv_set_encoding|iconv_strlen|iconv_strpos|iconv_strrpos|iconv_substr|idate|ifx_affected_rows|ifx_blobinfile_mode|ifx_byteasvarchar|ifx_close|ifx_connect|ifx_copy_blob|ifx_create_blob|ifx_create_char|ifx_do|ifx_error|ifx_errormsg|ifx_fetch_row|ifx_fieldproperties|ifx_fieldtypes|ifx_free_blob|ifx_free_char|ifx_free_result|ifx_get_blob|ifx_get_char|ifx_getsqlca|ifx_htmltbl_result|ifx_nullformat|ifx_num_fields|ifx_num_rows|ifx_pconnect|ifx_prepare|ifx_query|ifx_textasvarchar|ifx_update_blob|ifx_update_char|ifxus_close_slob|ifxus_create_slob|ifxus_free_slob|ifxus_open_slob|ifxus_read_slob|ifxus_seek_slob|ifxus_tell_slob|ifxus_write_slob|ignore_user_abort|image2wbmp|image_type_to_mime_type|imagealphablending|imageantialias|imagearc|imagechar|imagecharup|imagecolorallocate|imagecolorallocatealpha|imagecolorat|imagecolorclosest|imagecolorclosestalpha|imagecolorclosesthwb|imagecolordeallocate|imagecolorexact|imagecolorexactalpha|imagecolormatch|imagecolorresolve|imagecolorresolvealpha|imagecolorset|imagecolorsforindex|imagecolorstotal|imagecolortransparent|imagecopy|imagecopymerge|imagecopymergegray|imagecopyresampled|imagecopyresized|imagecreate|imagecreatefromgd|imagecreatefromgd2|imagecreatefromgd2part|imagecreatefromgif|imagecreatefromjpeg|imagecreatefrompng|imagecreatefromstring|imagecreatefromwbmp|imagecreatefromxbm|imagecreatefromxpm|imagecreatetruecolor|imagedashedline|imagedestroy|imageellipse|imagefill|imagefilledarc|imagefilledellipse|imagefilledpolygon|imagefilledrectangle|imagefilltoborder|imagefilter|imagefontheight|imagefontwidth|imageftbbox|imagefttext|imagegammacorrect|imagegd|imagegd2|imagegif|imageinterlace|imageistruecolor|imagejpeg|imagelayereffect|imageline|imageloadfont|imagepalettecopy|imagepng|imagepolygon|imagepsbbox|imagepscopyfont|imagepsencodefont|imagepsextendfont|imagepsfreefont|imagepsloadfont|imagepsslantfont|imagepstext|imagerectangle|imagerotate|imagesavealpha|imagesetbrush|imagesetpixel|imagesetstyle|imagesetthickness|imagesettile|imagestring|imagestringup|imagesx|imagesy|imagetruecolortopalette|imagettfbbox|imagettftext|imagetypes|imagewbmp|imagexbm|imap_8bit|imap_alerts|imap_append|imap_base64|imap_binary|imap_body|imap_bodystruct|imap_check|imap_clearflag_full|imap_close|imap_createmailbox|imap_delete|imap_deletemailbox|imap_errors|imap_expunge|imap_fetch_overview|imap_fetchbody|imap_fetchheader|imap_fetchstructure|imap_get_quota|imap_get_quotaroot|imap_getacl|imap_getmailboxes|imap_getsubscribed|imap_header|imap_headerinfo|imap_headers|imap_last_error|imap_list|imap_listmailbox|imap_listscan|imap_listsubscribed|imap_lsub|imap_mail|imap_mail_compose|imap_mail_copy|imap_mail_move|imap_mailboxmsginfo|imap_mime_header_decode|imap_msgno|imap_num_msg|imap_num_recent|imap_open|imap_ping|imap_qprint|imap_renamemailbox|imap_reopen|imap_rfc822_parse_adrlist|imap_rfc822_parse_headers|imap_rfc822_write_address|imap_scanmailbox|imap_search|imap_set_quota|imap_setacl|imap_setflag_full|imap_sort|imap_status|imap_subscribe|imap_thread|imap_timeout|imap_uid|imap_undelete|imap_unsubscribe|imap_utf7_decode|imap_utf7_encode|imap_utf8|implode|import_request_variables|in_array|ingres_autocommit|ingres_close|ingres_commit|ingres_connect|ingres_fetch_array|ingres_fetch_object|ingres_fetch_row|ingres_field_length|ingres_field_name|ingres_field_nullable|ingres_field_precision|ingres_field_scale|ingres_field_type|ingres_num_fields|ingres_num_rows|ingres_pconnect|ingres_query|ingres_rollback|ini_alter|ini_get|ini_get_all|ini_restore|ini_set|intval|ip2long|iptcembed|iptcparse|ircg_channel_mode|ircg_disconnect|ircg_fetch_error_msg|ircg_get_username|ircg_html_encode|ircg_ignore_add|ircg_ignore_del|ircg_invite|ircg_is_conn_alive|ircg_join|ircg_kick|ircg_list|ircg_lookup_format_messages|ircg_lusers|ircg_msg|ircg_nick|ircg_nickname_escape|ircg_nickname_unescape|ircg_notice|ircg_oper|ircg_part|ircg_pconnect|ircg_register_format_messages|ircg_set_current|ircg_set_file|ircg_set_on_die|ircg_topic|ircg_who|ircg_whois|is_a|is_array|is_bool|is_callable|is_dir|is_double|is_executable|is_file|is_finite|is_float|is_infinite|is_int|is_integer|is_link|is_long|is_nan|is_null|is_numeric|is_object|is_readable|is_real|is_resource|is_scalar|is_soap_fault|is_string|is_subclass_of|is_uploaded_file|is_writable|is_writeable|isset|java_last_exception_clear|java_last_exception_get|jddayofweek|jdmonthname|jdtofrench|jdtogregorian|jdtojewish|jdtojulian|jdtounix|jewishtojd|join|jpeg2wbmp|juliantojd|key|krsort|ksort|lcg_value|ldap_8859_to_t61|ldap_add|ldap_bind|ldap_close|ldap_compare|ldap_connect|ldap_count_entries|ldap_delete|ldap_dn2ufn|ldap_err2str|ldap_errno|ldap_error|ldap_explode_dn|ldap_first_attribute|ldap_first_entry|ldap_first_reference|ldap_free_result|ldap_get_attributes|ldap_get_dn|ldap_get_entries|ldap_get_option|ldap_get_values|ldap_get_values_len|ldap_list|ldap_mod_add|ldap_mod_del|ldap_mod_replace|ldap_modify|ldap_next_attribute|ldap_next_entry|ldap_next_reference|ldap_parse_reference|ldap_parse_result|ldap_read|ldap_rename|ldap_search|ldap_set_option|ldap_set_rebind_proc|ldap_sort|ldap_start_tls|ldap_t61_to_8859|ldap_unbind|levenshtein|link|linkinfo|list|localeconv|localtime|log|log10|log1p|long2ip|lstat|ltrim|lzf_compress|lzf_decompress|lzf_optimized_for|mail|mailparse_determine_best_xfer_encoding|mailparse_msg_create|mailparse_msg_extract_part|mailparse_msg_extract_part_file|mailparse_msg_free|mailparse_msg_get_part|mailparse_msg_get_part_data|mailparse_msg_get_structure|mailparse_msg_parse|mailparse_msg_parse_file|mailparse_rfc822_parse_addresses|mailparse_stream_encode|mailparse_uudecode_all|main|max|mb_convert_case|mb_convert_encoding|mb_convert_kana|mb_convert_variables|mb_decode_mimeheader|mb_decode_numericentity|mb_detect_encoding|mb_detect_order|mb_encode_mimeheader|mb_encode_numericentity|mb_ereg|mb_ereg_match|mb_ereg_replace|mb_ereg_search|mb_ereg_search_getpos|mb_ereg_search_getregs|mb_ereg_search_init|mb_ereg_search_pos|mb_ereg_search_regs|mb_ereg_search_setpos|mb_eregi|mb_eregi_replace|mb_get_info|mb_http_input|mb_http_output|mb_internal_encoding|mb_language|mb_output_handler|mb_parse_str|mb_preferred_mime_name|mb_regex_encoding|mb_regex_set_options|mb_send_mail|mb_split|mb_strcut|mb_strimwidth|mb_strlen|mb_strpos|mb_strrpos|mb_strtolower|mb_strtoupper|mb_strwidth|mb_substitute_character|mb_substr|mb_substr_count|mcal_append_event|mcal_close|mcal_create_calendar|mcal_date_compare|mcal_date_valid|mcal_day_of_week|mcal_day_of_year|mcal_days_in_month|mcal_delete_calendar|mcal_delete_event|mcal_event_add_attribute|mcal_event_init|mcal_event_set_alarm|mcal_event_set_category|mcal_event_set_class|mcal_event_set_description|mcal_event_set_end|mcal_event_set_recur_daily|mcal_event_set_recur_monthly_mday|mcal_event_set_recur_monthly_wday|mcal_event_set_recur_none|mcal_event_set_recur_weekly|mcal_event_set_recur_yearly|mcal_event_set_start|mcal_event_set_title|mcal_expunge|mcal_fetch_current_stream_event|mcal_fetch_event|mcal_is_leap_year|mcal_list_alarms|mcal_list_events|mcal_next_recurrence|mcal_open|mcal_popen|mcal_rename_calendar|mcal_reopen|mcal_snooze|mcal_store_event|mcal_time_valid|mcal_week_of_year|mcrypt_cbc|mcrypt_cfb|mcrypt_create_iv|mcrypt_decrypt|mcrypt_ecb|mcrypt_enc_get_algorithms_name|mcrypt_enc_get_block_size|mcrypt_enc_get_iv_size|mcrypt_enc_get_key_size|mcrypt_enc_get_modes_name|mcrypt_enc_get_supported_key_sizes|mcrypt_enc_is_block_algorithm|mcrypt_enc_is_block_algorithm_mode|mcrypt_enc_is_block_mode|mcrypt_enc_self_test|mcrypt_encrypt|mcrypt_generic|mcrypt_generic_deinit|mcrypt_generic_end|mcrypt_generic_init|mcrypt_get_block_size|mcrypt_get_cipher_name|mcrypt_get_iv_size|mcrypt_get_key_size|mcrypt_list_algorithms|mcrypt_list_modes|mcrypt_module_close|mcrypt_module_get_algo_block_size|mcrypt_module_get_algo_key_size|mcrypt_module_get_supported_key_sizes|mcrypt_module_is_block_algorithm|mcrypt_module_is_block_algorithm_mode|mcrypt_module_is_block_mode|mcrypt_module_open|mcrypt_module_self_test|mcrypt_ofb|mcve_adduser|mcve_adduserarg|mcve_bt|mcve_checkstatus|mcve_chkpwd|mcve_chngpwd|mcve_completeauthorizations|mcve_connect|mcve_connectionerror|mcve_deleteresponse|mcve_deletetrans|mcve_deleteusersetup|mcve_deluser|mcve_destroyconn|mcve_destroyengine|mcve_disableuser|mcve_edituser|mcve_enableuser|mcve_force|mcve_getcell|mcve_getcellbynum|mcve_getcommadelimited|mcve_getheader|mcve_getuserarg|mcve_getuserparam|mcve_gft|mcve_gl|mcve_gut|mcve_initconn|mcve_initengine|mcve_initusersetup|mcve_iscommadelimited|mcve_liststats|mcve_listusers|mcve_maxconntimeout|mcve_monitor|mcve_numcolumns|mcve_numrows|mcve_override|mcve_parsecommadelimited|mcve_ping|mcve_preauth|mcve_preauthcompletion|mcve_qc|mcve_responseparam|mcve_return|mcve_returncode|mcve_returnstatus|mcve_sale|mcve_setblocking|mcve_setdropfile|mcve_setip|mcve_setssl|mcve_setssl_files|mcve_settimeout|mcve_settle|mcve_text_avs|mcve_text_code|mcve_text_cv|mcve_transactionauth|mcve_transactionavs|mcve_transactionbatch|mcve_transactioncv|mcve_transactionid|mcve_transactionitem|mcve_transactionssent|mcve_transactiontext|mcve_transinqueue|mcve_transnew|mcve_transparam|mcve_transsend|mcve_ub|mcve_uwait|mcve_verifyconnection|mcve_verifysslcert|mcve_void|md5|md5_file|mdecrypt_generic|memory_get_usage|metaphone|method_exists|mhash|mhash_count|mhash_get_block_size|mhash_get_hash_name|mhash_keygen_s2k|microtime|mime_content_type|min|ming_setcubicthreshold|ming_setscale|ming_useswfversion|mkdir|mktime|money_format|move_uploaded_file|msession_connect|msession_count|msession_create|msession_destroy|msession_disconnect|msession_find|msession_get|msession_get_array|msession_getdata|msession_inc|msession_list|msession_listvar|msession_lock|msession_plugin|msession_randstr|msession_set|msession_set_array|msession_setdata|msession_timeout|msession_uniq|msession_unlock|msg_get_queue|msg_receive|msg_remove_queue|msg_send|msg_set_queue|msg_stat_queue|msql|msql|msql_affected_rows|msql_close|msql_connect|msql_create_db|msql_createdb|msql_data_seek|msql_dbname|msql_drop_db|msql_error|msql_fetch_array|msql_fetch_field|msql_fetch_object|msql_fetch_row|msql_field_flags|msql_field_len|msql_field_name|msql_field_seek|msql_field_table|msql_field_type|msql_fieldflags|msql_fieldlen|msql_fieldname|msql_fieldtable|msql_fieldtype|msql_free_result|msql_list_dbs|msql_list_fields|msql_list_tables|msql_num_fields|msql_num_rows|msql_numfields|msql_numrows|msql_pconnect|msql_query|msql_regcase|msql_result|msql_select_db|msql_tablename|mssql_bind|mssql_close|mssql_connect|mssql_data_seek|mssql_execute|mssql_fetch_array|mssql_fetch_assoc|mssql_fetch_batch|mssql_fetch_field|mssql_fetch_object|mssql_fetch_row|mssql_field_length|mssql_field_name|mssql_field_seek|mssql_field_type|mssql_free_result|mssql_free_statement|mssql_get_last_message|mssql_guid_string|mssql_init|mssql_min_error_severity|mssql_min_message_severity|mssql_next_result|mssql_num_fields|mssql_num_rows|mssql_pconnect|mssql_query|mssql_result|mssql_rows_affected|mssql_select_db|mt_getrandmax|mt_rand|mt_srand|muscat_close|muscat_get|muscat_give|muscat_setup|muscat_setup_net|mysql_affected_rows|mysql_change_user|mysql_client_encoding|mysql_close|mysql_connect|mysql_create_db|mysql_data_seek|mysql_db_name|mysql_db_query|mysql_drop_db|mysql_errno|mysql_error|mysql_escape_string|mysql_fetch_array|mysql_fetch_assoc|mysql_fetch_field|mysql_fetch_lengths|mysql_fetch_object|mysql_fetch_row|mysql_field_flags|mysql_field_len|mysql_field_name|mysql_field_seek|mysql_field_table|mysql_field_type|mysql_free_result|mysql_get_client_info|mysql_get_host_info|mysql_get_proto_info|mysql_get_server_info|mysql_info|mysql_insert_id|mysql_list_dbs|mysql_list_fields|mysql_list_processes|mysql_list_tables|mysql_num_fields|mysql_num_rows|mysql_pconnect|mysql_ping|mysql_query|mysql_real_escape_string|mysql_result|mysql_select_db|mysql_stat|mysql_tablename|mysql_thread_id|mysql_unbuffered_query|mysqli_affected_rows|mysqli_autocommit|mysqli_bind_param|mysqli_bind_result|mysqli_change_user|mysqli_character_set_name|mysqli_client_encoding|mysqli_close|mysqli_commit|mysqli_connect|mysqli_connect_errno|mysqli_connect_error|mysqli_data_seek|mysqli_debug|mysqli_disable_reads_from_master|mysqli_disable_rpl_parse|mysqli_dump_debug_info|mysqli_embedded_connect|mysqli_enable_reads_from_master|mysqli_enable_rpl_parse|mysqli_errno|mysqli_error|mysqli_escape_string|mysqli_execute|mysqli_fetch|mysqli_fetch_array|mysqli_fetch_assoc|mysqli_fetch_field|mysqli_fetch_field_direct|mysqli_fetch_fields|mysqli_fetch_lengths|mysqli_fetch_object|mysqli_fetch_row|mysqli_field_count|mysqli_field_seek|mysqli_field_tell|mysqli_free_result|mysqli_get_client_info|mysqli_get_client_version|mysqli_get_host_info|mysqli_get_metadata|mysqli_get_proto_info|mysqli_get_server_info|mysqli_get_server_version|mysqli_info|mysqli_init|mysqli_insert_id|mysqli_kill|mysqli_master_query|mysqli_more_results|mysqli_multi_query|mysqli_next_result|mysqli_num_fields|mysqli_num_rows|mysqli_options|mysqli_param_count|mysqli_ping|mysqli_prepare|mysqli_query|mysqli_real_connect|mysqli_real_escape_string|mysqli_real_query|mysqli_report|mysqli_rollback|mysqli_rpl_parse_enabled|mysqli_rpl_probe|mysqli_rpl_query_type|mysqli_select_db|mysqli_send_long_data|mysqli_send_query|mysqli_server_end|mysqli_server_init|mysqli_set_opt|mysqli_sqlstate|mysqli_ssl_set|mysqli_stat|mysqli_stmt_init|mysqli_stmt_affected_rows|mysqli_stmt_bind_param|mysqli_stmt_bind_result|mysqli_stmt_close|mysqli_stmt_data_seek|mysqli_stmt_errno|mysqli_stmt_error|mysqli_stmt_execute|mysqli_stmt_fetch|mysqli_stmt_free_result|mysqli_stmt_num_rows|mysqli_stmt_param_count|mysqli_stmt_prepare|mysqli_stmt_result_metadata|mysqli_stmt_send_long_data|mysqli_stmt_sqlstate|mysqli_stmt_store_result|mysqli_store_result|mysqli_thread_id|mysqli_thread_safe|mysqli_use_result|mysqli_warning_count|natcasesort|natsort|ncurses_addch|ncurses_addchnstr|ncurses_addchstr|ncurses_addnstr|ncurses_addstr|ncurses_assume_default_colors|ncurses_attroff|ncurses_attron|ncurses_attrset|ncurses_baudrate|ncurses_beep|ncurses_bkgd|ncurses_bkgdset|ncurses_border|ncurses_bottom_panel|ncurses_can_change_color|ncurses_cbreak|ncurses_clear|ncurses_clrtobot|ncurses_clrtoeol|ncurses_color_content|ncurses_color_set|ncurses_curs_set|ncurses_def_prog_mode|ncurses_def_shell_mode|ncurses_define_key|ncurses_del_panel|ncurses_delay_output|ncurses_delch|ncurses_deleteln|ncurses_delwin|ncurses_doupdate|ncurses_echo|ncurses_echochar|ncurses_end|ncurses_erase|ncurses_erasechar|ncurses_filter|ncurses_flash|ncurses_flushinp|ncurses_getch|ncurses_getmaxyx|ncurses_getmouse|ncurses_getyx|ncurses_halfdelay|ncurses_has_colors|ncurses_has_ic|ncurses_has_il|ncurses_has_key|ncurses_hide_panel|ncurses_hline|ncurses_inch|ncurses_init|ncurses_init_color|ncurses_init_pair|ncurses_insch|ncurses_insdelln|ncurses_insertln|ncurses_insstr|ncurses_instr|ncurses_isendwin|ncurses_keyok|ncurses_keypad|ncurses_killchar|ncurses_longname|ncurses_meta|ncurses_mouse_trafo|ncurses_mouseinterval|ncurses_mousemask|ncurses_move|ncurses_move_panel|ncurses_mvaddch|ncurses_mvaddchnstr|ncurses_mvaddchstr|ncurses_mvaddnstr|ncurses_mvaddstr|ncurses_mvcur|ncurses_mvdelch|ncurses_mvgetch|ncurses_mvhline|ncurses_mvinch|ncurses_mvvline|ncurses_mvwaddstr|ncurses_napms|ncurses_new_panel|ncurses_newpad|ncurses_newwin|ncurses_nl|ncurses_nocbreak|ncurses_noecho|ncurses_nonl|ncurses_noqiflush|ncurses_noraw|ncurses_pair_content|ncurses_panel_above|ncurses_panel_below|ncurses_panel_window|ncurses_pnoutrefresh|ncurses_prefresh|ncurses_putp|ncurses_qiflush|ncurses_raw|ncurses_refresh|ncurses_replace_panel|ncurses_reset_prog_mode|ncurses_reset_shell_mode|ncurses_resetty|ncurses_savetty|ncurses_scr_dump|ncurses_scr_init|ncurses_scr_restore|ncurses_scr_set|ncurses_scrl|ncurses_show_panel|ncurses_slk_attr|ncurses_slk_attroff|ncurses_slk_attron|ncurses_slk_attrset|ncurses_slk_clear|ncurses_slk_color|ncurses_slk_init|ncurses_slk_noutrefresh|ncurses_slk_refresh|ncurses_slk_restore|ncurses_slk_set|ncurses_slk_touch|ncurses_standend|ncurses_standout|ncurses_start_color|ncurses_termattrs|ncurses_termname|ncurses_timeout|ncurses_top_panel|ncurses_typeahead|ncurses_ungetch|ncurses_ungetmouse|ncurses_update_panels|ncurses_use_default_colors|ncurses_use_env|ncurses_use_extended_names|ncurses_vidattr|ncurses_vline|ncurses_waddch|ncurses_waddstr|ncurses_wattroff|ncurses_wattron|ncurses_wattrset|ncurses_wborder|ncurses_wclear|ncurses_wcolor_set|ncurses_werase|ncurses_wgetch|ncurses_whline|ncurses_wmouse_trafo|ncurses_wmove|ncurses_wnoutrefresh|ncurses_wrefresh|ncurses_wstandend|ncurses_wstandout|ncurses_wvline|next|ngettext|nl2br|nl_langinfo|notes_body|notes_copy_db|notes_create_db|notes_create_note|notes_drop_db|notes_find_note|notes_header_info|notes_list_msgs|notes_mark_read|notes_mark_unread|notes_nav_create|notes_search|notes_unread|notes_version|nsapi_request_headers|nsapi_response_headers|nsapi_virtual|number_format|ob_clean|ob_end_clean|ob_end_flush|ob_flush|ob_get_clean|ob_get_contents|ob_get_flush|ob_get_length|ob_get_level|ob_get_status|ob_gzhandler|ob_iconv_handler|ob_implicit_flush|ob_list_handlers|ob_start|ob_tidyhandler|oci_bind_by_name|oci_cancel|oci_close|oci_commit|oci_connect|oci_define_by_name|oci_error|oci_execute|oci_fetch|oci_fetch_all|oci_fetch_array|oci_fetch_assoc|oci_fetch_object|oci_fetch_row|oci_field_is_null|oci_field_name|oci_field_precision|oci_field_scale|oci_field_size|oci_field_type|oci_field_type_raw|oci_free_statement|oci_internal_debug|oci_lob_copy|oci_lob_is_equal|oci_new_collection|oci_new_connect|oci_new_cursor|oci_new_descriptor|oci_num_fields|oci_num_rows|oci_parse|oci_password_change|oci_pconnect|oci_result|oci_rollback|oci_server_version|oci_set_prefetch|oci_statement_type|ocibindbyname|ocicancel|ocicloselob|ocicollappend|ocicollassign|ocicollassignelem|ocicollgetelem|ocicollmax|ocicollsize|ocicolltrim|ocicolumnisnull|ocicolumnname|ocicolumnprecision|ocicolumnscale|ocicolumnsize|ocicolumntype|ocicolumntyperaw|ocicommit|ocidefinebyname|ocierror|ociexecute|ocifetch|ocifetchinto|ocifetchstatement|ocifreecollection|ocifreecursor|ocifreedesc|ocifreestatement|ociinternaldebug|ociloadlob|ocilogoff|ocilogon|ocinewcollection|ocinewcursor|ocinewdescriptor|ocinlogon|ocinumcols|ociparse|ociplogon|ociresult|ocirollback|ocirowcount|ocisavelob|ocisavelobfile|ociserverversion|ocisetprefetch|ocistatementtype|ociwritelobtofile|ociwritetemporarylob|octdec|odbc_autocommit|odbc_binmode|odbc_close|odbc_close_all|odbc_columnprivileges|odbc_columns|odbc_commit|odbc_connect|odbc_cursor|odbc_data_source|odbc_do|odbc_error|odbc_errormsg|odbc_exec|odbc_execute|odbc_fetch_array|odbc_fetch_into|odbc_fetch_object|odbc_fetch_row|odbc_field_len|odbc_field_name|odbc_field_num|odbc_field_precision|odbc_field_scale|odbc_field_type|odbc_foreignkeys|odbc_free_result|odbc_gettypeinfo|odbc_longreadlen|odbc_next_result|odbc_num_fields|odbc_num_rows|odbc_pconnect|odbc_prepare|odbc_primarykeys|odbc_procedurecolumns|odbc_procedures|odbc_result|odbc_result_all|odbc_rollback|odbc_setoption|odbc_specialcolumns|odbc_statistics|odbc_tableprivileges|odbc_tables|opendir|openlog|openssl_csr_export|openssl_csr_export_to_file|openssl_csr_new|openssl_csr_sign|openssl_error_string|openssl_free_key|openssl_get_privatekey|openssl_get_publickey|openssl_open|openssl_pkcs7_decrypt|openssl_pkcs7_encrypt|openssl_pkcs7_sign|openssl_pkcs7_verify|openssl_pkey_export|openssl_pkey_export_to_file|openssl_pkey_get_private|openssl_pkey_get_public|openssl_pkey_new|openssl_private_decrypt|openssl_private_encrypt|openssl_public_decrypt|openssl_public_encrypt|openssl_seal|openssl_sign|openssl_verify|openssl_x509_check_private_key|openssl_x509_checkpurpose|openssl_x509_export|openssl_x509_export_to_file|openssl_x509_free|openssl_x509_parse|openssl_x509_read|ora_bind|ora_close|ora_columnname|ora_columnsize|ora_columntype|ora_commit|ora_commitoff|ora_commiton|ora_do|ora_error|ora_errorcode|ora_exec|ora_fetch|ora_fetch_into|ora_getcolumn|ora_logoff|ora_logon|ora_numcols|ora_numrows|ora_open|ora_parse|ora_plogon|ora_rollback|ord|output_add_rewrite_var|output_reset_rewrite_vars|overload|ovrimos_close|ovrimos_commit|ovrimos_connect|ovrimos_cursor|ovrimos_exec|ovrimos_execute|ovrimos_fetch_into|ovrimos_fetch_row|ovrimos_field_len|ovrimos_field_name|ovrimos_field_num|ovrimos_field_type|ovrimos_free_result|ovrimos_longreadlen|ovrimos_num_fields|ovrimos_num_rows|ovrimos_prepare|ovrimos_result|ovrimos_result_all|ovrimos_rollback|pack|parse_ini_file|parse_str|parse_url|passthru|pathinfo|pclose|pcntl_alarm|pcntl_exec|pcntl_fork|pcntl_getpriority|pcntl_setpriority|pcntl_signal|pcntl_wait|pcntl_waitpid|pcntl_wexitstatus|pcntl_wifexited|pcntl_wifsignaled|pcntl_wifstopped|pcntl_wstopsig|pcntl_wtermsig|pdf_add_annotation|pdf_add_bookmark|pdf_add_launchlink|pdf_add_locallink|pdf_add_note|pdf_add_outline|pdf_add_pdflink|pdf_add_thumbnail|pdf_add_weblink|pdf_arc|pdf_arcn|pdf_attach_file|pdf_begin_page|pdf_begin_pattern|pdf_begin_template|pdf_circle|pdf_clip|pdf_close|pdf_close_image|pdf_close_pdi|pdf_close_pdi_page|pdf_closepath|pdf_closepath_fill_stroke|pdf_closepath_stroke|pdf_concat|pdf_continue_text|pdf_curveto|pdf_delete|pdf_end_page|pdf_end_pattern|pdf_end_template|pdf_endpath|pdf_fill|pdf_fill_stroke|pdf_findfont|pdf_get_buffer|pdf_get_font|pdf_get_fontname|pdf_get_fontsize|pdf_get_image_height|pdf_get_image_width|pdf_get_majorversion|pdf_get_minorversion|pdf_get_parameter|pdf_get_pdi_parameter|pdf_get_pdi_value|pdf_get_value|pdf_initgraphics|pdf_lineto|pdf_makespotcolor|pdf_moveto|pdf_new|pdf_open|pdf_open_ccitt|pdf_open_file|pdf_open_gif|pdf_open_image|pdf_open_image_file|pdf_open_jpeg|pdf_open_memory_image|pdf_open_pdi|pdf_open_pdi_page|pdf_open_png|pdf_open_tiff|pdf_place_image|pdf_place_pdi_page|pdf_rect|pdf_restore|pdf_rotate|pdf_save|pdf_scale|pdf_set_border_color|pdf_set_border_dash|pdf_set_border_style|pdf_set_char_spacing|pdf_set_duration|pdf_set_font|pdf_set_horiz_scaling|pdf_set_info|pdf_set_info_author|pdf_set_info_creator|pdf_set_info_keywords|pdf_set_info_subject|pdf_set_info_title|pdf_set_leading|pdf_set_parameter|pdf_set_text_matrix|pdf_set_text_pos|pdf_set_text_rendering|pdf_set_text_rise|pdf_set_value|pdf_set_word_spacing|pdf_setcolor|pdf_setdash|pdf_setflat|pdf_setfont|pdf_setgray|pdf_setgray_fill|pdf_setgray_stroke|pdf_setlinecap|pdf_setlinejoin|pdf_setlinewidth|pdf_setmatrix|pdf_setmiterlimit|pdf_setpolydash|pdf_setrgbcolor|pdf_setrgbcolor_fill|pdf_setrgbcolor_stroke|pdf_show|pdf_show_boxed|pdf_show_xy|pdf_skew|pdf_stringwidth|pdf_stroke|pdf_translate|pfpro_cleanup|pfpro_init|pfpro_process|pfpro_process_raw|pfpro_version|pfsockopen|pg_affected_rows|pg_cancel_query|pg_client_encoding|pg_close|pg_connect|pg_connection_busy|pg_connection_reset|pg_connection_status|pg_convert|pg_copy_from|pg_copy_to|pg_dbname|pg_delete|pg_end_copy|pg_escape_bytea|pg_escape_string|pg_fetch_all|pg_fetch_array|pg_fetch_assoc|pg_fetch_object|pg_fetch_result|pg_fetch_row|pg_field_is_null|pg_field_name|pg_field_num|pg_field_prtlen|pg_field_size|pg_field_type|pg_free_result|pg_get_notify|pg_get_pid|pg_get_result|pg_host|pg_insert|pg_last_error|pg_last_notice|pg_last_oid|pg_lo_close|pg_lo_create|pg_lo_export|pg_lo_import|pg_lo_open|pg_lo_read|pg_lo_read_all|pg_lo_seek|pg_lo_tell|pg_lo_unlink|pg_lo_write|pg_meta_data|pg_num_fields|pg_num_rows|pg_options|pg_pconnect|pg_ping|pg_port|pg_put_line|pg_query|pg_result_error|pg_result_seek|pg_result_status|pg_select|pg_send_query|pg_set_client_encoding|pg_trace|pg_tty|pg_unescape_bytea|pg_untrace|pg_update|php_ini_scanned_files|php_logo_guid|php_sapi_name|php_uname|phpcredits|phpinfo|phpversion|pi|png2wbmp|popen|pos|posix_ctermid|posix_get_last_error|posix_getcwd|posix_getegid|posix_geteuid|posix_getgid|posix_getgrgid|posix_getgrnam|posix_getgroups|posix_getlogin|posix_getpgid|posix_getpgrp|posix_getpid|posix_getppid|posix_getpwnam|posix_getpwuid|posix_getrlimit|posix_getsid|posix_getuid|posix_isatty|posix_kill|posix_mkfifo|posix_setegid|posix_seteuid|posix_setgid|posix_setpgid|posix_setsid|posix_setuid|posix_strerror|posix_times|posix_ttyname|posix_uname|pow|preg_grep|preg_match|preg_match_all|preg_quote|preg_replace|preg_replace_callback|preg_split|prev|print|print_r|printer_abort|printer_close|printer_create_brush|printer_create_dc|printer_create_font|printer_create_pen|printer_delete_brush|printer_delete_dc|printer_delete_font|printer_delete_pen|printer_draw_bmp|printer_draw_chord|printer_draw_elipse|printer_draw_line|printer_draw_pie|printer_draw_rectangle|printer_draw_roundrect|printer_draw_text|printer_end_doc|printer_end_page|printer_get_option|printer_list|printer_logical_fontheight|printer_open|printer_select_brush|printer_select_font|printer_select_pen|printer_set_option|printer_start_doc|printer_start_page|printer_write|printf|proc_close|proc_get_status|proc_nice|proc_open|proc_terminate|pspell_add_to_personal|pspell_add_to_session|pspell_check|pspell_clear_session|pspell_config_create|pspell_config_ignore|pspell_config_mode|pspell_config_personal|pspell_config_repl|pspell_config_runtogether|pspell_config_save_repl|pspell_new|pspell_new_config|pspell_new_personal|pspell_save_wordlist|pspell_store_replacement|pspell_suggest|putenv|qdom_error|qdom_tree|quoted_printable_decode|quotemeta|rad2deg|rand|range|rawurldecode|rawurlencode|read_exif_data|readdir|readfile|readgzfile|readline|readline_add_history|readline_clear_history|readline_completion_function|readline_info|readline_list_history|readline_read_history|readline_write_history|readlink|realpath|recode|recode_file|recode_string|register_shutdown_function|register_tick_function|rename|reset|restore_error_handler|restore_include_path|rewind|rewinddir|rmdir|round|rsort|rtrim|scandir|sem_acquire|sem_get|sem_release|sem_remove|serialize|sesam_affected_rows|sesam_commit|sesam_connect|sesam_diagnostic|sesam_disconnect|sesam_errormsg|sesam_execimm|sesam_fetch_array|sesam_fetch_result|sesam_fetch_row|sesam_field_array|sesam_field_name|sesam_free_result|sesam_num_fields|sesam_query|sesam_rollback|sesam_seek_row|sesam_settransaction|session_cache_expire|session_cache_limiter|session_commit|session_decode|session_destroy|session_encode|session_get_cookie_params|session_id|session_is_registered|session_module_name|session_name|session_regenerate_id|session_register|session_save_path|session_set_cookie_params|session_set_save_handler|session_start|session_unregister|session_unset|session_write_close|set_error_handler|set_file_buffer|set_include_path|set_magic_quotes_runtime|set_time_limit|setcookie|setlocale|setrawcookie|settype|sha1|sha1_file|shell_exec|shm_attach|shm_detach|shm_get_var|shm_put_var|shm_remove|shm_remove_var|shmop_close|shmop_delete|shmop_open|shmop_read|shmop_size|shmop_write|show_source|shuffle|similar_text|simplexml_import_dom|simplexml_load_file|simplexml_load_string|sin|sinh|sizeof|sleep|snmp_get_quick_print|snmp_set_quick_print|snmpget|snmprealwalk|snmpset|snmpwalk|snmpwalkoid|socket_accept|socket_bind|socket_clear_error|socket_close|socket_connect|socket_create|socket_create_listen|socket_create_pair|socket_get_option|socket_get_status|socket_getpeername|socket_getsockname|socket_iovec_add|socket_iovec_alloc|socket_iovec_delete|socket_iovec_fetch|socket_iovec_free|socket_iovec_set|socket_last_error|socket_listen|socket_read|socket_readv|socket_recv|socket_recvfrom|socket_recvmsg|socket_select|socket_send|socket_sendmsg|socket_sendto|socket_set_block|socket_set_blocking|socket_set_nonblock|socket_set_option|socket_set_timeout|socket_shutdown|socket_strerror|socket_write|socket_writev|sort|soundex|split|spliti|sprintf|sql_regcase|sqlite_array_query|sqlite_busy_timeout|sqlite_changes|sqlite_close|sqlite_column|sqlite_create_aggregate|sqlite_create_function|sqlite_current|sqlite_error_string|sqlite_escape_string|sqlite_fetch_array|sqlite_fetch_single|sqlite_fetch_string|sqlite_field_name|sqlite_has_more|sqlite_last_error|sqlite_last_insert_rowid|sqlite_libencoding|sqlite_libversion|sqlite_next|sqlite_num_fields|sqlite_num_rows|sqlite_open|sqlite_popen|sqlite_query|sqlite_rewind|sqlite_seek|sqlite_udf_decode_binary|sqlite_udf_encode_binary|sqlite_unbuffered_query|sqrt|srand|sscanf|stat|str_ireplace|str_pad|str_repeat|str_replace|str_rot13|str_shuffle|str_split|str_word_count|strcasecmp|strchr|strcmp|strcoll|strcspn|stream_context_create|stream_context_get_options|stream_context_set_option|stream_context_set_params|stream_copy_to_stream|stream_filter_append|stream_filter_prepend|stream_filter_register|stream_get_contents|stream_get_filters|stream_get_line|stream_get_meta_data|stream_get_transports|stream_get_wrappers|stream_register_wrapper|stream_select|stream_set_blocking|stream_set_timeout|stream_set_write_buffer|stream_socket_accept|stream_socket_client|stream_socket_get_name|stream_socket_recvfrom|stream_socket_sendto|stream_socket_server|stream_wrapper_register|strftime|strip_tags|stripcslashes|stripos|stripslashes|stristr|strlen|strnatcasecmp|strnatcmp|strncasecmp|strncmp|strpos|strrchr|strrev|strripos|strrpos|strspn|strstr|strtok|strtolower|strtotime|strtoupper|strtr|strval|substr|substr_compare|substr_count|substr_replace|swf_actiongeturl|swf_actiongotoframe|swf_actiongotolabel|swf_actionnextframe|swf_actionplay|swf_actionprevframe|swf_actionsettarget|swf_actionstop|swf_actiontogglequality|swf_actionwaitforframe|swf_addbuttonrecord|swf_addcolor|swf_closefile|swf_definebitmap|swf_definefont|swf_defineline|swf_definepoly|swf_definerect|swf_definetext|swf_endbutton|swf_enddoaction|swf_endshape|swf_endsymbol|swf_fontsize|swf_fontslant|swf_fonttracking|swf_getbitmapinfo|swf_getfontinfo|swf_getframe|swf_labelframe|swf_lookat|swf_modifyobject|swf_mulcolor|swf_nextid|swf_oncondition|swf_openfile|swf_ortho|swf_ortho2|swf_perspective|swf_placeobject|swf_polarview|swf_popmatrix|swf_posround|swf_pushmatrix|swf_removeobject|swf_rotate|swf_scale|swf_setfont|swf_setframe|swf_shapearc|swf_shapecurveto|swf_shapecurveto3|swf_shapefillbitmapclip|swf_shapefillbitmaptile|swf_shapefilloff|swf_shapefillsolid|swf_shapelinesolid|swf_shapelineto|swf_shapemoveto|swf_showframe|swf_startbutton|swf_startdoaction|swf_startshape|swf_startsymbol|swf_textwidth|swf_translate|swf_viewport|swfaction|swfbitmap|swfbutton|swfbutton_keypress|swfdisplayitem|swffill|swffont|swfgradient|swfmorph|swfmovie|swfshape|swfsprite|swftext|swftextfield|sybase_affected_rows|sybase_close|sybase_connect|sybase_data_seek|sybase_deadlock_retry_count|sybase_fetch_array|sybase_fetch_assoc|sybase_fetch_field|sybase_fetch_object|sybase_fetch_row|sybase_field_seek|sybase_free_result|sybase_get_last_message|sybase_min_client_severity|sybase_min_error_severity|sybase_min_message_severity|sybase_min_server_severity|sybase_num_fields|sybase_num_rows|sybase_pconnect|sybase_query|sybase_result|sybase_select_db|sybase_set_message_handler|sybase_unbuffered_query|symlink|syslog|system|tan|tanh|tcpwrap_check|tempnam|textdomain|tidy_access_count|tidy_clean_repair|tidy_config_count|tidy_diagnose|tidy_error_count|tidy_get_body|tidy_get_config|tidy_get_error_buffer|tidy_get_head|tidy_get_html|tidy_get_html_ver|tidy_get_output|tidy_get_release|tidy_get_root|tidy_get_status|tidy_getopt|tidy_is_xhtml|tidy_is_xml|tidy_load_config|tidy_parse_file|tidy_parse_string|tidy_repair_file|tidy_repair_string|tidy_reset_config|tidy_save_config|tidy_set_encoding|tidy_setopt|tidy_warning_count|time|tmpfile|token_get_all|token_name|touch|trigger_error|trim|uasort|ucfirst|ucwords|udm_add_search_limit|udm_alloc_agent|udm_alloc_agent_array|udm_api_version|udm_cat_list|udm_cat_path|udm_check_charset|udm_check_stored|udm_clear_search_limits|udm_close_stored|udm_crc32|udm_errno|udm_error|udm_find|udm_free_agent|udm_free_ispell_data|udm_free_res|udm_get_doc_count|udm_get_res_field|udm_get_res_param|udm_hash32|udm_load_ispell_data|udm_open_stored|udm_set_agent_param|uksort|umask|uniqid|unixtojd|unlink|unpack|unregister_tick_function|unserialize|unset|urldecode|urlencode|user_error|usleep|usort|utf8_decode|utf8_encode|var_dump|var_export|variant|version_compare|virtual|vpopmail_add_alias_domain|vpopmail_add_alias_domain_ex|vpopmail_add_domain|vpopmail_add_domain_ex|vpopmail_add_user|vpopmail_alias_add|vpopmail_alias_del|vpopmail_alias_del_domain|vpopmail_alias_get|vpopmail_alias_get_all|vpopmail_auth_user|vpopmail_del_domain|vpopmail_del_domain_ex|vpopmail_del_user|vpopmail_error|vpopmail_passwd|vpopmail_set_user_quota|vprintf|vsprintf|w32api_deftype|w32api_init_dtype|w32api_invoke_function|w32api_register_function|w32api_set_call_method|wddx_add_vars|wddx_deserialize|wddx_packet_end|wddx_packet_start|wddx_serialize_value|wddx_serialize_vars|wordwrap|xdiff_file_diff|xdiff_file_diff_binary|xdiff_file_merge3|xdiff_file_patch|xdiff_file_patch_binary|xdiff_string_diff|xdiff_string_diff_binary|xdiff_string_merge3|xdiff_string_patch|xdiff_string_patch_binary|xml_error_string|xml_get_current_byte_index|xml_get_current_column_number|xml_get_current_line_number|xml_get_error_code|xml_parse|xml_parse_into_struct|xml_parser_create|xml_parser_create_ns|xml_parser_free|xml_parser_get_option|xml_parser_set_option|xml_set_character_data_handler|xml_set_default_handler|xml_set_element_handler|xml_set_end_namespace_decl_handler|xml_set_external_entity_ref_handler|xml_set_notation_decl_handler|xml_set_object|xml_set_processing_instruction_handler|xml_set_start_namespace_decl_handler|xml_set_unparsed_entity_decl_handler|xmlrpc_decode|xmlrpc_decode_request|xmlrpc_encode|xmlrpc_encode_request|xmlrpc_get_type|xmlrpc_parse_method_descriptions|xmlrpc_server_add_introspection_data|xmlrpc_server_call_method|xmlrpc_server_create|xmlrpc_server_destroy|xmlrpc_server_register_introspection_callback|xmlrpc_server_register_method|xmlrpc_set_type|xpath_eval|xpath_eval_expression|xpath_new_context|xptr_eval|xptr_new_context|xsl_xsltprocessor_get_parameter|xsl_xsltprocessor_has_exslt_support|xsl_xsltprocessor_import_stylesheet|xsl_xsltprocessor_register_php_functions|xsl_xsltprocessor_remove_parameter|xsl_xsltprocessor_set_parameter|xsl_xsltprocessor_transform_to_doc|xsl_xsltprocessor_transform_to_uri|xsl_xsltprocessor_transform_to_xml|xslt_create|xslt_errno|xslt_error|xslt_free|xslt_process|xslt_set_base|xslt_set_encoding|xslt_set_error_handler|xslt_set_log|xslt_set_sax_handler|xslt_set_sax_handlers|xslt_set_scheme_handler|xslt_set_scheme_handlers|yaz_addinfo|yaz_ccl_conf|yaz_ccl_parse|yaz_close|yaz_connect|yaz_database|yaz_element|yaz_errno|yaz_error|yaz_es_result|yaz_get_option|yaz_hits|yaz_itemorder|yaz_present|yaz_range|yaz_record|yaz_scan|yaz_scan_result|yaz_schema|yaz_search|yaz_set_option|yaz_sort|yaz_syntax|yaz_wait|yp_all|yp_cat|yp_err_string|yp_errno|yp_first|yp_get_default_domain|yp_master|yp_match|yp_next|yp_order|zend_logo_guid|zend_version|zip_close|zip_entry_close|zip_entry_compressedsize|zip_entry_compressionmethod|zip_entry_filesize|zip_entry_name|zip_entry_open|zip_entry_read|zip_open|zip_read|zlib_get_coding_type".split("|")),c=e.arrayToMap("abstract|and|array|as|break|case|catch|cfunction|class|clone|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|final|for|foreach|function|include|include_once|global|goto|if|implements|interface|instanceof|namespace|new|old_function|or|private|protected|public|return|require|require_once|static|switch|throw|try|use|var|while|xor".split("|")),d=e.arrayToMap("true|false|null|__FILE__|__LINE__|__METHOD__|__FUNCTION__|__CLASS__".split("|")),g=e.arrayToMap("$_GLOBALS|$_SERVER|$_GET|$_POST|$_FILES|$_REQUEST|$_SESSION|$_ENV|$_COOKIE|$php_errormsg|$HTTP_RAW_POST_DATA|$http_response_header|$argc|$argv".split("|")),h=e.arrayToMap([]);this.$rules={start:[{token:"support",regex:"<\\?(?:php|\\=)"},{token:"support",regex:"\\?>"},{token:"comment",regex:"\\/\\/.*$"},{token:"comment",regex:"#.*$"},a.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/][gimy]*\\s*(?=[).,;]|$)"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language",regex:"\\b(?:DEFAULT_INCLUDE_PATH|E_(?:ALL|CO(?:MPILE_(?:ERROR|WARNING)|RE_(?:ERROR|WARNING))|ERROR|NOTICE|PARSE|STRICT|USER_(?:ERROR|NOTICE|WARNING)|WARNING)|P(?:EAR_(?:EXTENSION_DIR|INSTALL_DIR)|HP_(?:BINDIR|CONFIG_FILE_(?:PATH|SCAN_DIR)|DATADIR|E(?:OL|XTENSION_DIR)|INT_(?:MAX|SIZE)|L(?:IBDIR|OCALSTATEDIR)|O(?:S|UTPUT_HANDLER_(?:CONT|END|START))|PREFIX|S(?:API|HLIB_SUFFIX|YSCONFDIR)|VERSION))|__COMPILER_HALT_OFFSET__)\\b"},{token:"constant.language",regex:"\\b(?:A(?:B(?:DAY_(?:1|2|3|4|5|6|7)|MON_(?:1(?:0|1|2|)|2|3|4|5|6|7|8|9))|LT_DIGITS|M_STR|SSERT_(?:ACTIVE|BAIL|CALLBACK|QUIET_EVAL|WARNING))|C(?:ASE_(?:LOWER|UPPER)|HAR_MAX|O(?:DESET|NNECTION_(?:ABORTED|NORMAL|TIMEOUT)|UNT_(?:NORMAL|RECURSIVE))|R(?:EDITS_(?:ALL|DOCS|FULLPAGE|G(?:ENERAL|ROUP)|MODULES|QA|SAPI)|NCYSTR|YPT_(?:BLOWFISH|EXT_DES|MD5|S(?:ALT_LENGTH|TD_DES)))|URRENCY_SYMBOL)|D(?:AY_(?:1|2|3|4|5|6|7)|ECIMAL_POINT|IRECTORY_SEPARATOR|_(?:FMT|T_FMT))|E(?:NT_(?:COMPAT|NOQUOTES|QUOTES)|RA(?:_(?:D_(?:FMT|T_FMT)|T_FMT|YEAR)|)|XTR_(?:IF_EXISTS|OVERWRITE|PREFIX_(?:ALL|I(?:F_EXISTS|NVALID)|SAME)|SKIP))|FRAC_DIGITS|GROUPING|HTML_(?:ENTITIES|SPECIALCHARS)|IN(?:FO_(?:ALL|C(?:ONFIGURATION|REDITS)|ENVIRONMENT|GENERAL|LICENSE|MODULES|VARIABLES)|I_(?:ALL|PERDIR|SYSTEM|USER)|T_(?:CURR_SYMBOL|FRAC_DIGITS))|L(?:C_(?:ALL|C(?:OLLATE|TYPE)|M(?:ESSAGES|ONETARY)|NUMERIC|TIME)|O(?:CK_(?:EX|NB|SH|UN)|G_(?:A(?:LERT|UTH(?:PRIV|))|C(?:ONS|R(?:IT|ON))|D(?:AEMON|EBUG)|E(?:MERG|RR)|INFO|KERN|L(?:OCAL(?:0|1|2|3|4|5|6|7)|PR)|MAIL|N(?:DELAY|EWS|O(?:TICE|WAIT))|ODELAY|P(?:ERROR|ID)|SYSLOG|U(?:SER|UCP)|WARNING)))|M(?:ON_(?:1(?:0|1|2|)|2|3|4|5|6|7|8|9|DECIMAL_POINT|GROUPING|THOUSANDS_SEP)|_(?:1_PI|2_(?:PI|SQRTPI)|E|L(?:N(?:10|2)|OG(?:10E|2E))|PI(?:_(?:2|4)|)|SQRT(?:1_2|2)))|N(?:EGATIVE_SIGN|O(?:EXPR|STR)|_(?:CS_PRECEDES|S(?:EP_BY_SPACE|IGN_POSN)))|P(?:ATH(?:INFO_(?:BASENAME|DIRNAME|EXTENSION)|_SEPARATOR)|M_STR|OSITIVE_SIGN|_(?:CS_PRECEDES|S(?:EP_BY_SPACE|IGN_POSN)))|RADIXCHAR|S(?:EEK_(?:CUR|END|SET)|ORT_(?:ASC|DESC|NUMERIC|REGULAR|STRING)|TR_PAD_(?:BOTH|LEFT|RIGHT))|T(?:HOUS(?:ANDS_SEP|EP)|_FMT(?:_AMPM|))|YES(?:EXPR|STR)|STD(?:IN|OUT|ERR))\\b"},{token:function(a){if(c.hasOwnProperty(a))return"keyword";if(d.hasOwnProperty(a))return"constant.language";if(g.hasOwnProperty(a))return"variable.language";if(h.hasOwnProperty(a))return"invalid.illegal";if(b.hasOwnProperty(a))return"support.function";if(a=="debugger")return"invalid.deprecated";if(a.match(/^(\$[a-zA-Z][a-zA-Z0-9_]*|self|parent)$/))return"variable";return"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]},this.addRules(a.getRules(),"doc-"),this.$rules["doc-start"][0].next="start"};d.inherits(h,g),b.PhpHighlightRules=h}),define("ace/mode/doc_comment_highlight_rules",["require","exports","module","pilot/oop","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc",regex:"\\*\\/",next:"start"},{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",regex:"s+"},{token:"comment.doc",regex:"TODO"},{token:"comment.doc",regex:"[^@\\*]+"},{token:"comment.doc",regex:"."}]}};d.inherits(f,e),function(){this.getStartRule=function(a){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:a}}}.call(f.prototype),b.DocCommentHighlightRules=f}) \ No newline at end of file diff --git a/build/src/mode-python.js b/build/src/mode-python.js deleted file mode 100644 index 0c3edefa..00000000 --- a/build/src/mode-python.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/mode/python",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/python_highlight_rules","ace/mode/matching_brace_outdent","ace/range"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/python_highlight_rules").PythonHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(j,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)#/;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,"#")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[\:]\s*$/);h&&(d+=c)}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)}}.call(j.prototype),b.Mode=j}),define("ace/mode/python_highlight_rules",["require","exports","module","pilot/oop","pilot/lang","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/text_highlight_rules").TextHighlightRules,g=function(){var a=e.arrayToMap("and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield".split("|")),b=e.arrayToMap("True|False|None|NotImplemented|Ellipsis|__debug__".split("|")),c=e.arrayToMap("abs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|binfile|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|set|apply|delattr|help|next|setattr|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern".split("|")),d=e.arrayToMap("".split("|")),f="(?:r|u|ur|R|U|UR|Ur|uR)?",g="(?:(?:[1-9]\\d*)|(?:0))",h="(?:0[oO]?[0-7]+)",i="(?:0[xX][\\dA-Fa-f]+)",j="(?:0[bB][01]+)",k="(?:"+g+"|"+h+"|"+i+"|"+j+")",l="(?:[eE][+-]?\\d+)",m="(?:\\.\\d+)",n="(?:\\d+)",o="(?:(?:"+n+"?"+m+")|(?:"+n+"\\.))",p="(?:(?:"+o+"|"+n+")"+l+")",q="(?:"+p+"|"+o+")";this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"string",regex:f+'"{3}(?:[^\\\\]|\\\\.)*?"{3}'},{token:"string",regex:f+'"{3}.*$',next:"qqstring"},{token:"string",regex:f+'"(?:[^\\\\]|\\\\.)*?"'},{token:"string",regex:f+"'{3}(?:[^\\\\]|\\\\.)*?'{3}"},{token:"string",regex:f+"'{3}.*$",next:"qstring"},{token:"string",regex:f+"'(?:[^\\\\]|\\\\.)*?'"},{token:"constant.numeric",regex:"(?:"+q+"|\\d+)[jJ]\\b"},{token:"constant.numeric",regex:q},{token:"constant.numeric",regex:k+"[lL]\\b"},{token:"constant.numeric",regex:k+"\\b"},{token:function(e){return a.hasOwnProperty(e)?"keyword":b.hasOwnProperty(e)?"constant.language":d.hasOwnProperty(e)?"invalid.illegal":c.hasOwnProperty(e)?"support.function":e=="debugger"?"invalid.deprecated":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|%|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"lparen",regex:"[\\[\\(\\{]"},{token:"rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+"}],qqstring:[{token:"string",regex:'(?:[^\\\\]|\\\\.)*?"{3}',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:[^\\\\]|\\\\.)*?'{3}",next:"start"},{token:"string",regex:".+"}]}};d.inherits(g,f),b.PythonHighlightRules=g}) \ No newline at end of file diff --git a/build/src/mode-ruby.js b/build/src/mode-ruby.js deleted file mode 100644 index d4b77f6d..00000000 --- a/build/src/mode-ruby.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/mode/ruby",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/ruby_highlight_rules").RubyHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(j,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)#/;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,"#")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[]\s*$/);h&&(d+=c)}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)}}.call(j.prototype),b.Mode=j}),define("ace/mode/ruby_highlight_rules",["require","exports","module","pilot/oop","pilot/lang","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/text_highlight_rules").TextHighlightRules,g=function(){var a=e.arrayToMap("abort|Array|at_exit|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|eval|exec|exit|exit!fail|Float|fork|format|gets|global_variables|gsub|gsub!|Integer|lambda|load|local_variables|loop|open|p|print|printf|proc|putc|puts|raise|rand|readline|readlines|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan".split("|")),b=e.arrayToMap("alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|if|in|__LINE__|module|next|not|or|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield".split("|")),c=e.arrayToMap("true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING".split("|")),d=e.arrayToMap("$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE".split("|"));this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment",regex:"^=begin$",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:function(e){return e=="self"?"variable.language":b.hasOwnProperty(e)?"keyword":c.hasOwnProperty(e)?"constant.language":d.hasOwnProperty(e)?"variable.language":a.hasOwnProperty(e)?"support.function":e=="debugger"?"invalid.deprecated":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end$",next:"start"},{token:"comment",regex:".+"}]}};d.inherits(g,f),b.RubyHighlightRules=g}) \ No newline at end of file diff --git a/build/src/mode-xml.js b/build/src/mode-xml.js deleted file mode 100644 index f2ee6a25..00000000 --- a/build/src/mode-xml.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/mode/xml",["require","exports","module","pilot/oop","ace/mode/text","ace/tokenizer","ace/mode/xml_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/xml_highlight_rules").XmlHighlightRules,h=function(){this.$tokenizer=new f((new g).getRules())};d.inherits(h,e),function(){this.getNextLineIndent=function(a,b,c){return this.$getIndent(b)}}.call(h.prototype),b.Mode=h}),define("ace/mode/xml_highlight_rules",["require","exports","module","pilot/oop","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"text",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:"xml_pe",regex:"<\\?.*?\\?>"},{token:"comment",regex:"<\\!--",next:"comment"},{token:"text",regex:"<\\/?",next:"tag"},{token:"text",regex:"\\s+"},{token:"text",regex:"[^<]+"}],tag:[{token:"text",regex:">",next:"start"},{token:"keyword",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:".+"}]}};d.inherits(f,e),b.XmlHighlightRules=f}) \ No newline at end of file diff --git a/build/src/theme-clouds.js b/build/src/theme-clouds.js deleted file mode 100644 index c14d3cbc..00000000 --- a/build/src/theme-clouds.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/theme/clouds",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-clouds .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-clouds .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-clouds .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-clouds .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-clouds .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-clouds .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-clouds .ace_scroller {\n background-color: #FFFFFF;\n}\n\n.ace-clouds .ace_text-layer {\n cursor: text;\n color: #000000;\n}\n\n.ace-clouds .ace_cursor {\n border-left: 2px solid #000000;\n}\n\n.ace-clouds .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #000000;\n}\n \n.ace-clouds .ace_marker-layer .ace_selection {\n background: #BDD5FC;\n}\n\n.ace-clouds .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-clouds .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid #BFBFBF;\n}\n\n.ace-clouds .ace_marker-layer .ace_active_line {\n background: #FFFBD1;\n}\n\n \n.ace-clouds .ace_invisible {\n color: #BFBFBF;\n}\n\n.ace-clouds .ace_keyword {\n color:#AF956F;\n}\n\n.ace-clouds .ace_keyword.ace_operator {\n color:#484848;\n}\n\n.ace-clouds .ace_constant {\n \n}\n\n.ace-clouds .ace_constant.ace_language {\n color:#39946A;\n}\n\n.ace-clouds .ace_constant.ace_library {\n \n}\n\n.ace-clouds .ace_constant.ace_numeric {\n color:#46A609;\n}\n\n.ace-clouds .ace_invalid {\n background-color:#FF002A;\n}\n\n.ace-clouds .ace_invalid.ace_illegal {\n \n}\n\n.ace-clouds .ace_invalid.ace_deprecated {\n \n}\n\n.ace-clouds .ace_support {\n \n}\n\n.ace-clouds .ace_support.ace_function {\n color:#C52727;\n}\n\n.ace-clouds .ace_function.ace_buildin {\n \n}\n\n.ace-clouds .ace_string {\n color:#5D90CD;\n}\n\n.ace-clouds .ace_string.ace_regexp {\n \n}\n\n.ace-clouds .ace_comment {\n color:#BCC8BA;\n}\n\n.ace-clouds .ace_comment.ace_doc {\n \n}\n\n.ace-clouds .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-clouds .ace_variable {\n \n}\n\n.ace-clouds .ace_variable.ace_language {\n \n}\n\n.ace-clouds .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-clouds"}) \ No newline at end of file diff --git a/build/src/theme-clouds_midnight.js b/build/src/theme-clouds_midnight.js deleted file mode 100644 index 52137fb2..00000000 --- a/build/src/theme-clouds_midnight.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/theme/clouds_midnight",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-clouds-midnight .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-clouds-midnight .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-clouds-midnight .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-clouds-midnight .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-clouds-midnight .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-clouds-midnight .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-clouds-midnight .ace_scroller {\n background-color: #191919;\n}\n\n.ace-clouds-midnight .ace_text-layer {\n cursor: text;\n color: #929292;\n}\n\n.ace-clouds-midnight .ace_cursor {\n border-left: 2px solid #7DA5DC;\n}\n\n.ace-clouds-midnight .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #7DA5DC;\n}\n \n.ace-clouds-midnight .ace_marker-layer .ace_selection {\n background: #000000;\n}\n\n.ace-clouds-midnight .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-clouds-midnight .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid #BFBFBF;\n}\n\n.ace-clouds-midnight .ace_marker-layer .ace_active_line {\n background: rgba(215, 215, 215, 0.031);\n}\n\n \n.ace-clouds-midnight .ace_invisible {\n color: #BFBFBF;\n}\n\n.ace-clouds-midnight .ace_keyword {\n color:#927C5D;\n}\n\n.ace-clouds-midnight .ace_keyword.ace_operator {\n color:#4B4B4B;\n}\n\n.ace-clouds-midnight .ace_constant {\n \n}\n\n.ace-clouds-midnight .ace_constant.ace_language {\n color:#39946A;\n}\n\n.ace-clouds-midnight .ace_constant.ace_library {\n \n}\n\n.ace-clouds-midnight .ace_constant.ace_numeric {\n color:#46A609;\n}\n\n.ace-clouds-midnight .ace_invalid {\n color:#FFFFFF;\nbackground-color:#E92E2E;\n}\n\n.ace-clouds-midnight .ace_invalid.ace_illegal {\n \n}\n\n.ace-clouds-midnight .ace_invalid.ace_deprecated {\n \n}\n\n.ace-clouds-midnight .ace_support {\n \n}\n\n.ace-clouds-midnight .ace_support.ace_function {\n color:#E92E2E;\n}\n\n.ace-clouds-midnight .ace_function.ace_buildin {\n \n}\n\n.ace-clouds-midnight .ace_string {\n color:#5D90CD;\n}\n\n.ace-clouds-midnight .ace_string.ace_regexp {\n \n}\n\n.ace-clouds-midnight .ace_comment {\n color:#3C403B;\n}\n\n.ace-clouds-midnight .ace_comment.ace_doc {\n \n}\n\n.ace-clouds-midnight .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-clouds-midnight .ace_variable {\n \n}\n\n.ace-clouds-midnight .ace_variable.ace_language {\n \n}\n\n.ace-clouds-midnight .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-clouds-midnight"}) \ No newline at end of file diff --git a/build/src/theme-cobalt.js b/build/src/theme-cobalt.js deleted file mode 100644 index 51be7b23..00000000 --- a/build/src/theme-cobalt.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/theme/cobalt",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-cobalt .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-cobalt .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-cobalt .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-cobalt .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-cobalt .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-cobalt .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-cobalt .ace_scroller {\n background-color: #002240;\n}\n\n.ace-cobalt .ace_text-layer {\n cursor: text;\n color: #FFFFFF;\n}\n\n.ace-cobalt .ace_cursor {\n border-left: 2px solid #FFFFFF;\n}\n\n.ace-cobalt .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #FFFFFF;\n}\n \n.ace-cobalt .ace_marker-layer .ace_selection {\n background: rgba(179, 101, 57, 0.75);\n}\n\n.ace-cobalt .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-cobalt .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(255, 255, 255, 0.15);\n}\n\n.ace-cobalt .ace_marker-layer .ace_active_line {\n background: rgba(0, 0, 0, 0.35);\n}\n\n \n.ace-cobalt .ace_invisible {\n color: rgba(255, 255, 255, 0.15);\n}\n\n.ace-cobalt .ace_keyword {\n color:#FF9D00;\n}\n\n.ace-cobalt .ace_keyword.ace_operator {\n \n}\n\n.ace-cobalt .ace_constant {\n color:#FF628C;\n}\n\n.ace-cobalt .ace_constant.ace_language {\n \n}\n\n.ace-cobalt .ace_constant.ace_library {\n \n}\n\n.ace-cobalt .ace_constant.ace_numeric {\n \n}\n\n.ace-cobalt .ace_invalid {\n color:#F8F8F8;\nbackground-color:#800F00;\n}\n\n.ace-cobalt .ace_invalid.ace_illegal {\n \n}\n\n.ace-cobalt .ace_invalid.ace_deprecated {\n \n}\n\n.ace-cobalt .ace_support {\n color:#80FFBB;\n}\n\n.ace-cobalt .ace_support.ace_function {\n color:#FFB054;\n}\n\n.ace-cobalt .ace_function.ace_buildin {\n \n}\n\n.ace-cobalt .ace_string {\n \n}\n\n.ace-cobalt .ace_string.ace_regexp {\n color:#80FFC2;\n}\n\n.ace-cobalt .ace_comment {\n font-style:italic;\ncolor:#0088FF;\n}\n\n.ace-cobalt .ace_comment.ace_doc {\n \n}\n\n.ace-cobalt .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-cobalt .ace_variable {\n color:#CCCCCC;\n}\n\n.ace-cobalt .ace_variable.ace_language {\n color:#FF80E1;\n}\n\n.ace-cobalt .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-cobalt"}) \ No newline at end of file diff --git a/build/src/theme-dawn.js b/build/src/theme-dawn.js deleted file mode 100644 index 3b98416e..00000000 --- a/build/src/theme-dawn.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/theme/dawn",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-dawn .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-dawn .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-dawn .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-dawn .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-dawn .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-dawn .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-dawn .ace_scroller {\n background-color: #F9F9F9;\n}\n\n.ace-dawn .ace_text-layer {\n cursor: text;\n color: #080808;\n}\n\n.ace-dawn .ace_cursor {\n border-left: 2px solid #000000;\n}\n\n.ace-dawn .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #000000;\n}\n \n.ace-dawn .ace_marker-layer .ace_selection {\n background: rgba(39, 95, 255, 0.30);\n}\n\n.ace-dawn .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-dawn .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(75, 75, 126, 0.50);\n}\n\n.ace-dawn .ace_marker-layer .ace_active_line {\n background: rgba(36, 99, 180, 0.12);\n}\n\n \n.ace-dawn .ace_invisible {\n color: rgba(75, 75, 126, 0.50);\n}\n\n.ace-dawn .ace_keyword {\n color:#794938;\n}\n\n.ace-dawn .ace_keyword.ace_operator {\n \n}\n\n.ace-dawn .ace_constant {\n color:#811F24;\n}\n\n.ace-dawn .ace_constant.ace_language {\n \n}\n\n.ace-dawn .ace_constant.ace_library {\n \n}\n\n.ace-dawn .ace_constant.ace_numeric {\n \n}\n\n.ace-dawn .ace_invalid {\n \n}\n\n.ace-dawn .ace_invalid.ace_illegal {\n text-decoration:underline;\nfont-style:italic;\ncolor:#F8F8F8;\nbackground-color:#B52A1D;\n}\n\n.ace-dawn .ace_invalid.ace_deprecated {\n text-decoration:underline;\nfont-style:italic;\ncolor:#B52A1D;\n}\n\n.ace-dawn .ace_support {\n color:#691C97;\n}\n\n.ace-dawn .ace_support.ace_function {\n color:#693A17;\n}\n\n.ace-dawn .ace_function.ace_buildin {\n \n}\n\n.ace-dawn .ace_string {\n color:#0B6125;\n}\n\n.ace-dawn .ace_string.ace_regexp {\n color:#CF5628;\n}\n\n.ace-dawn .ace_comment {\n font-style:italic;\ncolor:#5A525F;\n}\n\n.ace-dawn .ace_comment.ace_doc {\n \n}\n\n.ace-dawn .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-dawn .ace_variable {\n color:#234A97;\n}\n\n.ace-dawn .ace_variable.ace_language {\n \n}\n\n.ace-dawn .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-dawn"}) \ No newline at end of file diff --git a/build/src/theme-eclipse.js b/build/src/theme-eclipse.js deleted file mode 100644 index e74e173e..00000000 --- a/build/src/theme-eclipse.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/theme/eclipse",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-eclipse .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-eclipse .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-eclipse .ace_gutter {\n width: 50px;\n background: rgb(227, 227, 227);\n border-right: 1px solid rgb(159, 159, 159);\t \n color: rgb(136, 136, 136);\n}\n\n.ace-eclipse .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-eclipse .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-eclipse .ace_text-layer {\n cursor: text;\n}\n\n.ace-eclipse .ace_cursor {\n border-left: 1px solid black;\n}\n\n.ace-eclipse .ace_line .ace_keyword, .ace-eclipse .ace_line .ace_variable {\n color: rgb(127, 0, 85);\n}\n\n.ace-eclipse .ace_line .ace_constant.ace_buildin {\n color: rgb(88, 72, 246);\n}\n\n.ace-eclipse .ace_line .ace_constant.ace_library {\n color: rgb(6, 150, 14);\n}\n\n.ace-eclipse .ace_line .ace_function {\n color: rgb(60, 76, 114);\n}\n\n.ace-eclipse .ace_line .ace_string {\n color: rgb(42, 0, 255);\n}\n\n.ace-eclipse .ace_line .ace_comment {\n color: rgb(63, 127, 95);\n}\n\n.ace-eclipse .ace_line .ace_comment.ace_doc {\n color: rgb(63, 95, 191);\n}\n\n.ace-eclipse .ace_line .ace_comment.ace_doc.ace_tag {\n color: rgb(127, 159, 191);\n}\n\n.ace-eclipse .ace_line .ace_constant.ace_numeric {\n}\n\n.ace-eclipse .ace_line .ace_tag {\n\tcolor: rgb(63, 127, 127);\n}\n\n.ace-eclipse .ace_line .ace_xml_pe {\n color: rgb(104, 104, 91);\n}\n\n.ace-eclipse .ace_marker-layer .ace_selection {\n background: rgb(181, 213, 255);\n}\n\n.ace-eclipse .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-eclipse .ace_marker-layer .ace_active_line {\n background: rgb(232, 242, 254);\n}";d.importCssString(e),b.cssClass="ace-eclipse"}) \ No newline at end of file diff --git a/build/src/theme-idle_fingers.js b/build/src/theme-idle_fingers.js deleted file mode 100644 index 40c7b952..00000000 --- a/build/src/theme-idle_fingers.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/theme/idle_fingers",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-idle-fingers .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-idle-fingers .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-idle-fingers .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-idle-fingers .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-idle-fingers .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-idle-fingers .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-idle-fingers .ace_scroller {\n background-color: #323232;\n}\n\n.ace-idle-fingers .ace_text-layer {\n cursor: text;\n color: #FFFFFF;\n}\n\n.ace-idle-fingers .ace_cursor {\n border-left: 2px solid #91FF00;\n}\n\n.ace-idle-fingers .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #91FF00;\n}\n \n.ace-idle-fingers .ace_marker-layer .ace_selection {\n background: rgba(90, 100, 126, 0.88);\n}\n\n.ace-idle-fingers .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-idle-fingers .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid #404040;\n}\n\n.ace-idle-fingers .ace_marker-layer .ace_active_line {\n background: #353637;\n}\n\n \n.ace-idle-fingers .ace_invisible {\n color: #404040;\n}\n\n.ace-idle-fingers .ace_keyword {\n color:#CC7833;\n}\n\n.ace-idle-fingers .ace_keyword.ace_operator {\n \n}\n\n.ace-idle-fingers .ace_constant {\n color:#6C99BB;\n}\n\n.ace-idle-fingers .ace_constant.ace_language {\n \n}\n\n.ace-idle-fingers .ace_constant.ace_library {\n \n}\n\n.ace-idle-fingers .ace_constant.ace_numeric {\n \n}\n\n.ace-idle-fingers .ace_invalid {\n color:#FFFFFF;\nbackground-color:#FF0000;\n}\n\n.ace-idle-fingers .ace_invalid.ace_illegal {\n \n}\n\n.ace-idle-fingers .ace_invalid.ace_deprecated {\n \n}\n\n.ace-idle-fingers .ace_support {\n \n}\n\n.ace-idle-fingers .ace_support.ace_function {\n color:#B83426;\n}\n\n.ace-idle-fingers .ace_function.ace_buildin {\n \n}\n\n.ace-idle-fingers .ace_string {\n color:#A5C261;\n}\n\n.ace-idle-fingers .ace_string.ace_regexp {\n color:#CCCC33;\n}\n\n.ace-idle-fingers .ace_comment {\n font-style:italic;\ncolor:#BC9458;\n}\n\n.ace-idle-fingers .ace_comment.ace_doc {\n \n}\n\n.ace-idle-fingers .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-idle-fingers .ace_variable {\n \n}\n\n.ace-idle-fingers .ace_variable.ace_language {\n \n}\n\n.ace-idle-fingers .ace_xml_pe {\n \n}\n\n.ace-idle-fingers .ace_collab.ace_user1 {\n color:#323232;\nbackground-color:#FFF980; \n}";d.importCssString(e),b.cssClass="ace-idle-fingers"}) \ No newline at end of file diff --git a/build/src/theme-kr_theme.js b/build/src/theme-kr_theme.js deleted file mode 100644 index 2fac8bac..00000000 --- a/build/src/theme-kr_theme.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/theme/kr_theme",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-kr-theme .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-kr-theme .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-kr-theme .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-kr-theme .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-kr-theme .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-kr-theme .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-kr-theme .ace_scroller {\n background-color: #0B0A09;\n}\n\n.ace-kr-theme .ace_text-layer {\n cursor: text;\n color: #FCFFE0;\n}\n\n.ace-kr-theme .ace_cursor {\n border-left: 2px solid #FF9900;\n}\n\n.ace-kr-theme .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #FF9900;\n}\n \n.ace-kr-theme .ace_marker-layer .ace_selection {\n background: rgba(170, 0, 255, 0.45);\n}\n\n.ace-kr-theme .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-kr-theme .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(255, 177, 111, 0.32);\n}\n\n.ace-kr-theme .ace_marker-layer .ace_active_line {\n background: #38403D;\n}\n\n \n.ace-kr-theme .ace_invisible {\n color: rgba(255, 177, 111, 0.32);\n}\n\n.ace-kr-theme .ace_keyword {\n color:#949C8B;\n}\n\n.ace-kr-theme .ace_keyword.ace_operator {\n \n}\n\n.ace-kr-theme .ace_constant {\n color:rgba(210, 117, 24, 0.76);\n}\n\n.ace-kr-theme .ace_constant.ace_language {\n \n}\n\n.ace-kr-theme .ace_constant.ace_library {\n \n}\n\n.ace-kr-theme .ace_constant.ace_numeric {\n \n}\n\n.ace-kr-theme .ace_invalid {\n color:#F8F8F8;\nbackground-color:#A41300;\n}\n\n.ace-kr-theme .ace_invalid.ace_illegal {\n \n}\n\n.ace-kr-theme .ace_invalid.ace_deprecated {\n \n}\n\n.ace-kr-theme .ace_support {\n color:#9FC28A;\n}\n\n.ace-kr-theme .ace_support.ace_function {\n color:#85873A;\n}\n\n.ace-kr-theme .ace_function.ace_buildin {\n \n}\n\n.ace-kr-theme .ace_string {\n \n}\n\n.ace-kr-theme .ace_string.ace_regexp {\n color:rgba(125, 255, 192, 0.65);\n}\n\n.ace-kr-theme .ace_comment {\n font-style:italic;\ncolor:#706D5B;\n}\n\n.ace-kr-theme .ace_comment.ace_doc {\n \n}\n\n.ace-kr-theme .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-kr-theme .ace_variable {\n color:#D1A796;\n}\n\n.ace-kr-theme .ace_variable.ace_language {\n color:#FF80E1;\n}\n\n.ace-kr-theme .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-kr-theme"}) \ No newline at end of file diff --git a/build/src/theme-mono_industrial.js b/build/src/theme-mono_industrial.js deleted file mode 100644 index 354de6bf..00000000 --- a/build/src/theme-mono_industrial.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/theme/mono_industrial",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-mono-industrial .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-mono-industrial .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-mono-industrial .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-mono-industrial .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-mono-industrial .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-mono-industrial .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-mono-industrial .ace_scroller {\n background-color: #222C28;\n}\n\n.ace-mono-industrial .ace_text-layer {\n cursor: text;\n color: #FFFFFF;\n}\n\n.ace-mono-industrial .ace_cursor {\n border-left: 2px solid #FFFFFF;\n}\n\n.ace-mono-industrial .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #FFFFFF;\n}\n \n.ace-mono-industrial .ace_marker-layer .ace_selection {\n background: rgba(145, 153, 148, 0.40);\n}\n\n.ace-mono-industrial .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-mono-industrial .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(102, 108, 104, 0.50);\n}\n\n.ace-mono-industrial .ace_marker-layer .ace_active_line {\n background: rgba(12, 13, 12, 0.25);\n}\n\n \n.ace-mono-industrial .ace_invisible {\n color: rgba(102, 108, 104, 0.50);\n}\n\n.ace-mono-industrial .ace_keyword {\n color:#A39E64;\n}\n\n.ace-mono-industrial .ace_keyword.ace_operator {\n color:#A8B3AB;\n}\n\n.ace-mono-industrial .ace_constant {\n color:#E98800;\n}\n\n.ace-mono-industrial .ace_constant.ace_language {\n \n}\n\n.ace-mono-industrial .ace_constant.ace_library {\n \n}\n\n.ace-mono-industrial .ace_constant.ace_numeric {\n color:#E98800;\n}\n\n.ace-mono-industrial .ace_invalid {\n color:#FFFFFF;\nbackground-color:rgba(153, 0, 0, 0.68);\n}\n\n.ace-mono-industrial .ace_invalid.ace_illegal {\n \n}\n\n.ace-mono-industrial .ace_invalid.ace_deprecated {\n \n}\n\n.ace-mono-industrial .ace_support {\n \n}\n\n.ace-mono-industrial .ace_support.ace_function {\n color:#588E60;\n}\n\n.ace-mono-industrial .ace_function.ace_buildin {\n \n}\n\n.ace-mono-industrial .ace_string {\n \n}\n\n.ace-mono-industrial .ace_string.ace_regexp {\n \n}\n\n.ace-mono-industrial .ace_comment {\n color:#666C68;\nbackground-color:#151C19;\n}\n\n.ace-mono-industrial .ace_comment.ace_doc {\n \n}\n\n.ace-mono-industrial .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-mono-industrial .ace_variable {\n \n}\n\n.ace-mono-industrial .ace_variable.ace_language {\n color:#648BD2;\n}\n\n.ace-mono-industrial .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-mono-industrial"}) \ No newline at end of file diff --git a/build/src/theme-monokai.js b/build/src/theme-monokai.js deleted file mode 100644 index 398195fd..00000000 --- a/build/src/theme-monokai.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/theme/monokai",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-monokai .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-monokai .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-monokai .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-monokai .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-monokai .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-monokai .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-monokai .ace_scroller {\n background-color: #272822;\n}\n\n.ace-monokai .ace_text-layer {\n cursor: text;\n color: #F8F8F2;\n}\n\n.ace-monokai .ace_cursor {\n border-left: 2px solid #F8F8F0;\n}\n\n.ace-monokai .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #F8F8F0;\n}\n \n.ace-monokai .ace_marker-layer .ace_selection {\n background: #49483E;\n}\n\n.ace-monokai .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-monokai .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid #49483E;\n}\n\n.ace-monokai .ace_marker-layer .ace_active_line {\n background: #49483E;\n}\n\n \n.ace-monokai .ace_invisible {\n color: #49483E;\n}\n\n.ace-monokai .ace_keyword {\n color:#F92672;\n}\n\n.ace-monokai .ace_keyword.ace_operator {\n \n}\n\n.ace-monokai .ace_constant {\n \n}\n\n.ace-monokai .ace_constant.ace_language {\n color:#AE81FF;\n}\n\n.ace-monokai .ace_constant.ace_library {\n \n}\n\n.ace-monokai .ace_constant.ace_numeric {\n color:#AE81FF;\n}\n\n.ace-monokai .ace_invalid {\n color:#F8F8F0;\nbackground-color:#F92672;\n}\n\n.ace-monokai .ace_invalid.ace_illegal {\n \n}\n\n.ace-monokai .ace_invalid.ace_deprecated {\n color:#F8F8F0;\nbackground-color:#AE81FF;\n}\n\n.ace-monokai .ace_support {\n \n}\n\n.ace-monokai .ace_support.ace_function {\n color:#66D9EF;\n}\n\n.ace-monokai .ace_function.ace_buildin {\n \n}\n\n.ace-monokai .ace_string {\n color:#E6DB74;\n}\n\n.ace-monokai .ace_string.ace_regexp {\n \n}\n\n.ace-monokai .ace_comment {\n color:#75715E;\n}\n\n.ace-monokai .ace_comment.ace_doc {\n \n}\n\n.ace-monokai .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-monokai .ace_variable {\n \n}\n\n.ace-monokai .ace_variable.ace_language {\n \n}\n\n.ace-monokai .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-monokai"}) \ No newline at end of file diff --git a/build/src/theme-pastel_on_dark.js b/build/src/theme-pastel_on_dark.js deleted file mode 100644 index 79cdb107..00000000 --- a/build/src/theme-pastel_on_dark.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/theme/pastel_on_dark",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-pastel-on-dark .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-pastel-on-dark .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-pastel-on-dark .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-pastel-on-dark .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-pastel-on-dark .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-pastel-on-dark .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-pastel-on-dark .ace_scroller {\n background-color: #2c2828;\n}\n\n.ace-pastel-on-dark .ace_text-layer {\n cursor: text;\n color: #8f938f;\n}\n\n.ace-pastel-on-dark .ace_cursor {\n border-left: 2px solid #A7A7A7;\n}\n\n.ace-pastel-on-dark .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #A7A7A7;\n}\n \n.ace-pastel-on-dark .ace_marker-layer .ace_selection {\n background: rgba(221, 240, 255, 0.20);\n}\n\n.ace-pastel-on-dark .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-pastel-on-dark .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(255, 255, 255, 0.25);\n}\n\n.ace-pastel-on-dark .ace_marker-layer .ace_active_line {\n background: rgba(255, 255, 255, 0.031);\n}\n\n \n.ace-pastel-on-dark .ace_invisible {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.ace-pastel-on-dark .ace_keyword {\n color:#757ad8;\n}\n\n.ace-pastel-on-dark .ace_keyword.ace_operator {\n color:#797878;\n}\n\n.ace-pastel-on-dark .ace_constant {\n color:#4fb7c5;\n}\n\n.ace-pastel-on-dark .ace_constant.ace_language {\n \n}\n\n.ace-pastel-on-dark .ace_constant.ace_library {\n \n}\n\n.ace-pastel-on-dark .ace_constant.ace_numeric {\n \n}\n\n.ace-pastel-on-dark .ace_invalid {\n \n}\n\n.ace-pastel-on-dark .ace_invalid.ace_illegal {\n color:#F8F8F8;\nbackground-color:rgba(86, 45, 86, 0.75);\n}\n\n.ace-pastel-on-dark .ace_invalid.ace_deprecated {\n text-decoration:underline;\nfont-style:italic;\ncolor:#D2A8A1;\n}\n\n.ace-pastel-on-dark .ace_support {\n color:#9a9a9a;\n}\n\n.ace-pastel-on-dark .ace_support.ace_function {\n color:#aeb2f8;\n}\n\n.ace-pastel-on-dark .ace_function.ace_buildin {\n \n}\n\n.ace-pastel-on-dark .ace_string {\n color:#66a968;\n}\n\n.ace-pastel-on-dark .ace_string.ace_regexp {\n color:#E9C062;\n}\n\n.ace-pastel-on-dark .ace_comment {\n color:#656865;\n}\n\n.ace-pastel-on-dark .ace_comment.ace_doc {\n color:A6C6FF;\n}\n\n.ace-pastel-on-dark .ace_comment.ace_doc.ace_tag {\n color:A6C6FF;\n}\n\n.ace-pastel-on-dark .ace_variable {\n color:#bebf55;\n}\n\n.ace-pastel-on-dark .ace_variable.ace_language {\n color:#bebf55;\n}\n\n.ace-pastel-on-dark .ace_xml_pe {\n color:#494949;\n}";d.importCssString(e),b.cssClass="ace-pastel-on-dark"}) \ No newline at end of file diff --git a/build/src/theme-twilight.js b/build/src/theme-twilight.js deleted file mode 100644 index 40724628..00000000 --- a/build/src/theme-twilight.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/theme/twilight",["require","exports","module"],function(a,b,c){var d=a("pilot/dom"),e=".ace-twilight .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-twilight .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-twilight .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-twilight .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-twilight .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-twilight .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-twilight .ace_scroller {\n background-color: #141414;\n}\n\n.ace-twilight .ace_text-layer {\n cursor: text;\n color: #F8F8F8;\n}\n\n.ace-twilight .ace_cursor {\n border-left: 2px solid #A7A7A7;\n}\n\n.ace-twilight .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #A7A7A7;\n}\n \n.ace-twilight .ace_marker-layer .ace_selection {\n background: rgba(221, 240, 255, 0.20);\n}\n\n.ace-twilight .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-twilight .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(255, 255, 255, 0.25);\n}\n\n.ace-twilight .ace_marker-layer .ace_active_line {\n background: rgba(255, 255, 255, 0.031);\n}\n\n \n.ace-twilight .ace_invisible {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.ace-twilight .ace_keyword {\n color:#CDA869;\n}\n\n.ace-twilight .ace_keyword.ace_operator {\n \n}\n\n.ace-twilight .ace_constant {\n color:#CF6A4C;\n}\n\n.ace-twilight .ace_constant.ace_language {\n \n}\n\n.ace-twilight .ace_constant.ace_library {\n \n}\n\n.ace-twilight .ace_constant.ace_numeric {\n \n}\n\n.ace-twilight .ace_invalid {\n \n}\n\n.ace-twilight .ace_invalid.ace_illegal {\n color:#F8F8F8;\nbackground-color:rgba(86, 45, 86, 0.75);\n}\n\n.ace-twilight .ace_invalid.ace_deprecated {\n text-decoration:underline;\nfont-style:italic;\ncolor:#D2A8A1;\n}\n\n.ace-twilight .ace_support {\n color:#9B859D;\n}\n\n.ace-twilight .ace_support.ace_function {\n color:#DAD085;\n}\n\n.ace-twilight .ace_function.ace_buildin {\n \n}\n\n.ace-twilight .ace_string {\n color:#8F9D6A;\n}\n\n.ace-twilight .ace_string.ace_regexp {\n color:#E9C062;\n}\n\n.ace-twilight .ace_comment {\n font-style:italic;\ncolor:#5F5A60;\n}\n\n.ace-twilight .ace_comment.ace_doc {\n \n}\n\n.ace-twilight .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-twilight .ace_variable {\n color:#7587A6;\n}\n\n.ace-twilight .ace_variable.ace_language {\n \n}\n\n.ace-twilight .ace_xml_pe {\n color:#494949;\n}";d.importCssString(e),b.cssClass="ace-twilight"}) \ No newline at end of file diff --git a/build/src/worker-javascript.js b/build/src/worker-javascript.js deleted file mode 100644 index 1e90bbd9..00000000 --- a/build/src/worker-javascript.js +++ /dev/null @@ -1 +0,0 @@ -function initSender(){var a=require("pilot/event_emitter").EventEmitter,b=require("pilot/oop"),c=function(){};(function(){b.implement(this,a),this.callback=function(a,b){postMessage({type:"call",id:b,data:a})},this.emit=function(a,b){postMessage({type:"event",name:a,data:b})}}).call(c.prototype);return new c}function initBaseUrls(a){require.tlns=a}var console={log:function(a){postMessage({type:"log",data:a})}},window={console:console},require=function(a){var b=require.modules[a];if(b){b.initialized||(b.exports=b.factory().exports,b.initialized=!0);return b.exports}var c=a.split("/");c[0]=require.tlns[c[0]]||c[0],path=c.join("/")+".js",require.id=a,importScripts(path);return require(a)};require.modules={},require.tlns={};var define=function(a,b,c){arguments.length==2?c=b:arguments.length==1&&(c=a,a=require.id);a.indexOf("text!")!==0&&(require.modules[a]={factory:function(){var a={exports:{}},b=c(require,a.exports,a);b&&(a.exports=exports);return a}})},main,sender;onmessage=function(a){var b=a.data;if(b.command)main[b.command].apply(main,b.args);else if(b.init){initBaseUrls(b.tlns),require("pilot/fixoldbrowsers"),sender=initSender();var c=require(b.module)[b.classname];main=new c(sender)}else b.event&&sender._dispatchEvent(b.event,b.data)},define("pilot/fixoldbrowsers",["require","exports","module"],function(a,b,c){Function.prototype.bind||(Function.prototype.bind=function(a){var b=[].slice,c=b.call(arguments,1),d=this,e=function(){};if(arguments.length==1)var f=function(){var b=d.prototype===undefined?this instanceof arguments.callee:this instanceof e;return d.apply(b?this:a,arguments)};else var f=function(){var f=d.prototype===undefined?this instanceof arguments.callee:this instanceof e;return d.apply(f?this:a||{},c.concat(b.call(arguments)))};e.prototype=d.prototype,f.prototype=new e,f.name=this.name,f.displayName=this.displayName,f.length=this.length,f.unbound=d;return f});var d=function(){},e=Function.prototype.call,f=e.bind(Object.prototype.hasOwnProperty),g,h,i,j;g=h=i=j=d,Object.prototype.__lookupGetter__&&(g=e.bind(Object.prototype.__lookupGetter__)),Object.prototype.__lookupSetter__&&(h=e.bind(Object.prototype.__lookupSetter__)),Object.prototype.__defineGetter__&&(i=e.bind(Object.prototype.__defineGetter__)),Object.prototype.__defineSetter__&&(j=e.bind(Object.prototype.__defineSetter__)),Array.isArray||(Array.isArray=function(a){return a&&Object.prototype.toString.call(a)==="[object Array]"}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){if(this===void 0||this===null)throw new TypeError;var b=Object(this),c=b.length>>>0;if(c===0)return-1;var d=0,e=d;arguments.length>0&&(d=Number(arguments[1]),d!==d?d=0:d!==0&&d!==1/e&&d!==-(1/e)&&(d=(d>0||-1)*Math.floor(Math.abs(d))));if(d>=c)return-1;var f=d>=0?d:Math.max(c-Math.abs(d),0);for(;f>>0;if(c===0)return-1;var d=c,e=!1|0;arguments.length>0&&(d=Number(arguments[1]),d!==d?d=0:d!==0&&d!==1/e&&d!==-(1/e)&&(d=(d>0||-1)*Math.floor(Math.abs(d))));var f=d>=0?Math.min(d,c-1):c-Math.abs(d);while(f>=0)if(f in b&&b[f]===a)return f;return-1}),Array.prototype.map||(Array.prototype.map=function(a){if(this===void 0||this===null)throw new TypeError;var b=Object(this),c=b.length>>>0;if(typeof a!=="function")throw new TypeError;res=Array(c);var d=arguments[1];for(var e=0;e>>0;if(typeof a!=="function")throw new TypeError;var d=arguments[1];for(var e=0;e>>0;if(typeof a!="function")throw new TypeError;if(b==0&&arguments.length==1)throw new TypeError;var c=0;if(arguments.length<2){do{if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}while(!0)}else var d=arguments[1];for(;c>>0;if(typeof a!="function")throw new TypeError;if(b==0&&arguments.length==1)throw new TypeError;var c=b-1;if(arguments.length<2){do{if(c in this){d=this[c--];break}if(--c<0)throw new TypeError}while(!0)}else var d=arguments[1];for(;c>=0;c--)c in this&&(d=a.call(null,d,this[c],c,this));return d}),Object.keys||(Object.keys=function m(a){var b,c=[];for(b in a)f(a,b)&&c.push(b);return c}),Object.getOwnPropertyNames||(Object.getOwnPropertyNames=Object.keys);var n="Object.getOwnPropertyDescriptor called on a non-object";Object.getOwnPropertyDescriptor||(Object.getOwnPropertyDescriptor=function o(a,b){var c,d,e;if(typeof a!=="object"&&typeof a!=="function"||a===null)throw new TypeError(n);f(a,b)&&(c={configurable:!0,enumerable:!0},d=c.get=g(a,b),e=c.set=h(a,b),!d&&!e&&(c.writeable=!0,c.value=a[b]));return c}),Object.getPrototypeOf||(Object.getPrototypeOf=function p(a){return a.__proto__||a.constructor.prototype}),Object.create||(Object.create=function q(a,b){var c;if(a===null)c={"__proto__":null};else{if(typeof a!=="object")throw new TypeError(a+" is not an object or null");d.prototype=a,c=new d}typeof b!=="undefined"&&Object.defineProperties(c,b);return c}),Object.defineProperty||(Object.defineProperty=function r(a,b,c){var d,e,f;if("object"!==typeof a&&"function"!==typeof a)throw new TypeError(a+"is not an object");if(c&&"object"!==typeof c)throw new TypeError("Property descriptor map must be an object");if("value"in c){if("get"in c||"set"in c)throw new TypeError('Invalid property. "value" present on property with getter or setter.');if(d=a.__proto__)a.__proto__=Object.prototype;delete a[b],a[b]=c.value,d&&(a.__proto__=d)}else(f=c.get)&&i(a,f),(e=c.set)&&j(a,e);return a}),Object.defineProperties||(Object.defineProperties=function s(a,b){Object.getOwnPropertyNames(b).forEach(function(c){Object.defineProperty(a,c,b[c])});return a});var t=function(a){return a};Object.seal||(Object.seal=t),Object.freeze||(Object.freeze=t),Object.preventExtensions||(Object.preventExtension=t);var u=function(){return!1},v=function(){return!0};Object.isSealed||(Object.isSealed=u),Object.isFrozen||(Object.isFrozen=u),Object.isExtensible||(Object.isExtensible=v),String.prototype.trim||(String.prototype.trim=function(){return this.trimLeft().trimRight()}),String.prototype.trimRight||(String.prototype.trimRight=function(){return this.replace(/[\t\v\f\s\u00a0\ufeff]+$/,"")}),String.prototype.trimLeft||(String.prototype.trimLeft=function(){return this.replace(/^[\t\v\f\s\u00a0\ufeff]+/,"")}),b.globalsLoaded=!0}),define("pilot/event_emitter",["require","exports","module"],function(a,b,c){var d={};d._emit=d._dispatchEvent=function(a,b){this._eventRegistry=this._eventRegistry||{};var c=this._eventRegistry[a];if(c&&c.length){var b=b||{};b.type=a;for(var d=0;d=b&&(a.row=Math.max(0,b-1),a.column=this.getLine(b-1).length);return a},this.insert=function(a,b){if(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];a=this.insertInLine(a,d),e!==null&&(a=this.insertNewLine(a),a=this.insertLines(a.row,c),a=this.insertInLine(a,e||""));return 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};this._dispatchEvent("change",{data:e});return 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()};this._dispatchEvent("change",{data:d});return 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};this._dispatchEvent("change",{data:e});return 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){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};this._dispatchEvent("change",{data:i});return 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};this._dispatchEvent("change",{data:e});return 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._dispatchEvent("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/range",["require","exports","module"],function(a,b,c){var d=function(a,b,c,d){this.start={row:a,column:b},this.end={row:c,column:d}};(function(){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.compare=function(a,b){if(!this.isMultiLine())if(a===this.start.row)return bthis.end.column?1:0;if(athis.end.row)return 1;if(this.start.row===a)return b>=this.start.column?0:-1;if(this.end.row===a)return b<=this.end.column?0:1;return 0},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.rowthis.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&&c.start.rowd?(d=c.start.row,e=0):d-=c.end.row-c.start.row)),this.setPosition(d,e,!0)}},this.setPosition=function(a,b,c){c?pos={row:a,column:b}:pos=this.$clipPositionToDocument(a,b);if(this.row!=pos.row||this.column!=pos.column){var d={row:this.row,column:this.column};this.row=pos.row,this.column=pos.column,this._dispatchEvent("change",{old:d,value:pos})}},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.$clipPositionToDocument=function(a,b){var c={};a'.",f,d),c=g.empty,f.type=d;for(;;){if(K.id==="/"){bI("/"),K.id!==">"&&bA("Expected '{a}' and instead saw '{b}'.",K,">",K.value);break}if(K.id&&K.id.substr(0,1)===">")break;K.identifier||((K.id==="(end)"||K.id==="(error)")&&bC("Missing '>'.",K),bA("Bad identifier.")),N.white=!0,bN($,K),a=K.value,N.white=h,bI(),!N.cap&&a!==a.toLowerCase()&&bA("Attribute '{a}' not all lower case.",K,a),a=a.toLowerCase(),be="",bw(b,a)&&bA("Attribute '{a}' repeated.",K,a),a.slice(0,2)==="on"?(N.on||bA("Avoid HTML event handlers."),bd="scriptstring",bI("="),e=K.id,e!=='"'&&e!=="'"&&bC("Missing quote."),be=e,i=N.white,N.white=!1,bI(e),ck(),cl("on"),N.white=i,K.id!==e&&bC("Missing close quote on script attribute."),bd="html",be="",bI(e),g=!1):a==="style"?(bd="scriptstring",bI("="),e=K.id,e!=='"'&&e!=="'"&&bC("Missing quote."),bd="styleproperty",be=e,bI(e),cF(),bd="html",be="",bI(e),g=!1):K.id==="="?(bI("="),g=K.value,!K.identifier&&K.id!=='"'&&K.id!=="'"&&K.type!=="(string)"&&K.type!=="(number)"&&K.type!=="(color)"&&bA("Expected an attribute value and instead saw '{a}'.",$,a),bI()):g=!0,b[a]=g,cL(d,a,g)}cM(d,b),c||U.push(f),bd="outer",bI(">");break;case""&&bC("Missing '{a}'.",K,">"),bd="outer",bI(">");break;case""||K.id==="(end)")break;K.value.indexOf("--")>=0&&bC("Unexpected --."),K.value.indexOf("<")>=0&&bC("Unexpected <."),K.value.indexOf(">")>=0&&bC("Unexpected >.")}bd="outer",bI(">");break;case"(end)":return;default:K.id==="(end)"?bC("Missing '{a}'.",K,""):bI()}if(U&&U.length===0&&(N.adsafe||!N.fragment||K.id==="(end)"))break}K.id!=="(end)"&&bC("Unexpected material after the end.")}function cN(a){return""}function cM(d,e){var g,h=z[d],i;T=!1,h||bC("Unrecognized tag '<{a}>'.",K,d===d.toLowerCase()?d:d+" (capitalization error)");if(U.length>0){d==="html"&&bC("Too many tags.",$),i=h.parent;if(i)i.indexOf(" "+U[U.length-1].name+" ")<0&&bC("A '<{a}>' must be within '<{b}>'.",$,d,i);else if(!N.adsafe&&!N.fragment){g=U.length;do g<=0&&bC("A '<{a}>' must be within '<{b}>'.",$,d,"body"),g-=1;while(U[g].name!=="body")}}switch(d){case"div":N.adsafe&&U.length===1&&!a&&bA("ADSAFE violation: missing ID_.");break;case"script":bd="script",bI(">"),D=K.from,e.lang&&bA("lang is deprecated.",$),N.adsafe&&U.length!==1&&bA("ADsafe script placement violation.",$),e.src?(N.adsafe&&(!b||!f[e.src])&&bA("ADsafe unapproved script source.",$),e.type&&bA("type is unnecessary.",$)):(c&&bC("ADsafe script violation.",$),ck(),cl("script")),bd="html",bI(""),cJ(),bd="html",bI("=0&&bA("Unexpected character '{a}' in {b}.",$,d.charAt(f),c),A[e]=!0):c==="class"||c==="type"||c==="name"?(f=d.search(bs),f>=0&&bA("Unexpected character '{a}' in {b}.",$,d.charAt(f),c),A[e]=!0):c!=="href"&&c!=="background"&&c!=="content"&&c!=="data"&&c.indexOf("src")<0&&c.indexOf("url")<0?c==="for"?N.adsafe&&(a?d.slice(0,a.length)!==a?bA("ADsafe violation: An id must have a '{a}' prefix",K,a):/^[A-Z]+_[A-Z]+$/.test(d)||bA("ADSAFE violation: bad id."):bA("ADSAFE violation: bad id.")):c==="name"&&(N.adsafe&&d.indexOf("_")>=0&&bA("ADsafe name violation.")):(N.safe&&bp.test(d)&&bC("ADsafe URL violation."),_.push(d))}function cK(a){a!=="html"&&!N.fragment&&(a==="div"&&N.adsafe?bC("ADSAFE: Use the fragment option."):bC("Expected '{a}' and instead saw '{b}'.",$,"html",a)),N.adsafe&&(a==="html"&&bC("Currently, ADsafe does not operate on whole HTML documents. It operates on
    "); - } - this.element = dom.setInnerHtml(this.element, html.join("")); - this.element.style.height = config.minHeight + "px"; - }; - -}).call(Gutter.prototype); - -exports.Gutter = Gutter; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/layer/marker', function(require, exports, module) { - -var Range = require("ace/range").Range; -var dom = require("pilot/dom"); - -var Marker = function(parentEl) { - this.element = document.createElement("div"); - this.element.className = "ace_layer ace_marker-layer"; - parentEl.appendChild(this.element); -}; - -(function() { - - this.setSession = function(session) { - this.session = session; - }; - - this.setMarkers = function(markers) { - this.markers = markers; - }; - - this.update = function(config) { - var config = config || this.config; - if (!config) - return; - - this.config = config; - - var html = []; - for ( var key in this.markers) { - var marker = this.markers[key]; - - var range = marker.range.clipRows(config.firstRow, config.lastRow); - if (range.isEmpty()) continue; - - range = range.toScreenRange(this.session); - - if (marker.renderer) { - var top = this.$getTop(range.start.row, config); - var left = Math.round(range.start.column * config.characterWidth); - marker.renderer(html, range, left, top, config); - } - else if (range.isMultiLine()) { - if (marker.type == "text") { - this.drawTextMarker(html, range, marker.clazz, config); - } else { - this.drawMultiLineMarker(html, range, marker.clazz, config); - } - } - else { - this.drawSingleLineMarker(html, range, marker.clazz, config); - } - } - this.element = dom.setInnerHtml(this.element, html.join("")); - }; - - this.$getTop = function(row, layerConfig) { - return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight; - }; - - this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) { - // selection start - var row = range.start.row; - - var lineRange = new Range(row, range.start.column, - row, this.session.getScreenLastRowColumn(row)); - this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1); - - // selection end - var row = range.end.row; - var lineRange = new Range(row, 0, row, range.end.column); - this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig); - - for (var row = range.start.row + 1; row < range.end.row; row++) { - lineRange.start.row = row; - lineRange.end.row = row; - lineRange.end.column = this.session.getScreenLastRowColumn(row); - this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1); - } - }; - - this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig) { - // from selection start to the end of the line - var height = layerConfig.lineHeight; - var width = Math.round(layerConfig.width - (range.start.column * layerConfig.characterWidth)); - var top = this.$getTop(range.start.row, layerConfig); - var left = Math.round(range.start.column * layerConfig.characterWidth); - - stringBuilder.push( - "
    " - ); - - // from start of the last line to the selection end - var top = this.$getTop(range.end.row, layerConfig); - var width = Math.round(range.end.column * layerConfig.characterWidth); - - stringBuilder.push( - "
    " - ); - - // all the complete lines - var height = (range.end.row - range.start.row - 1) * layerConfig.lineHeight; - if (height < 0) - return; - var top = this.$getTop(range.start.row + 1, layerConfig); - - stringBuilder.push( - "
    " - ); - }; - - this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig, extraLength) { - var height = layerConfig.lineHeight; - var width = Math.round((range.end.column + (extraLength || 0) - range.start.column) * layerConfig.characterWidth); - var top = this.$getTop(range.start.row, layerConfig); - var left = Math.round(range.start.column * layerConfig.characterWidth); - - stringBuilder.push( - "
    " - ); - }; - -}).call(Marker.prototype); - -exports.Marker = Marker; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/layer/text', function(require, exports, module) { - -var oop = require("pilot/oop"); -var dom = require("pilot/dom"); -var lang = require("pilot/lang"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; - -var Text = function(parentEl) { - this.element = document.createElement("div"); - this.element.className = "ace_layer ace_text-layer"; - parentEl.appendChild(this.element); - - this.$characterSize = this.$measureSizes(); - this.$pollSizeChanges(); -}; - -(function() { - - oop.implement(this, EventEmitter); - - this.EOF_CHAR = "¶"; - this.EOL_CHAR = "¬"; - this.TAB_CHAR = "→"; - this.SPACE_CHAR = "·"; - - this.setTokenizer = function(tokenizer) { - this.tokenizer = tokenizer; - }; - - this.getLineHeight = function() { - return this.$characterSize.height || 1; - }; - - this.getCharacterWidth = function() { - return this.$characterSize.width || 1; - }; - - this.$pollSizeChanges = function() { - var self = this; - setInterval(function() { - var size = self.$measureSizes(); - if (self.$characterSize.width !== size.width || self.$characterSize.height !== size.height) { - self.$characterSize = size; - self._dispatchEvent("changeCharaterSize", {data: size}); - } - }, 500); - }; - - this.$fontStyles = { - fontFamily : 1, - fontSize : 1, - fontWeight : 1, - fontStyle : 1, - lineHeight : 1 - }, - - this.$measureSizes = function() { - var n = 1000; - if (!this.$measureNode) { - var measureNode = this.$measureNode = document.createElement("div"); - var style = measureNode.style; - - style.width = style.height = "auto"; - style.left = style.top = (-n * 40) + "px"; - - style.visibility = "hidden"; - style.position = "absolute"; - style.overflow = "visible"; - style.whiteSpace = "nowrap"; - - // in FF 3.6 monospace fonts can have a fixed sub pixel width. - // that's why we have to measure many characters - // Note: characterWidth can be a float! - measureNode.innerHTML = lang.stringRepeat("Xy", n); - document.body.insertBefore(measureNode, document.body.firstChild); - } - - var style = this.$measureNode.style; - for (var prop in this.$fontStyles) { - var value = dom.computedStyle(this.element, prop); - style[prop] = value; - } - - var size = { - height: this.$measureNode.offsetHeight, - width: this.$measureNode.offsetWidth / (n * 2) - }; - return size; - }; - - this.setSession = function(session) { - this.session = session; - }; - - this.showInvisibles = false; - this.setShowInvisibles = function(showInvisibles) { - if (this.showInvisibles == showInvisibles) - return false; - - this.showInvisibles = showInvisibles; - return true; - }; - - this.$computeTabString = function() { - var tabSize = this.session.getTabSize(); - if (this.showInvisibles) { - var halfTab = (tabSize) / 2; - this.$tabString = "" - + new Array(Math.floor(halfTab)).join(" ") - + this.TAB_CHAR - + new Array(Math.ceil(halfTab)+1).join(" ") - + ""; - } else { - this.$tabString = new Array(tabSize+1).join(" "); - } - }; - - this.updateLines = function(config, firstRow, lastRow) { - this.$computeTabString(); - // Due to wrap line changes there can be new lines if e.g. - // the line to updated wrapped in the meantime. - if (this.config.lastRow != config.lastRow || - this.config.firstRow != config.firstRow) { - this.scrollLines(config); - } - this.config = config; - - var first = Math.max(firstRow, config.firstRow); - var last = Math.min(lastRow, config.lastRow); - - var lineElements = this.element.childNodes; - var tokens = this.tokenizer.getTokens(first, last); - for (var i=first; i<=last; i++) { - var lineElement = lineElements[i - config.firstRow]; - if (!lineElement) - continue; - - var html = []; - this.$renderLine(html, i, tokens[i-first].tokens); - lineElement = dom.setInnerHtml(lineElement, html.join("")); - lineElement.style.height = - this.session.getRowHeight(config, i) + "px"; - } - }; - - this.scrollLines = function(config) { - this.$computeTabString(); - var oldConfig = this.config; - this.config = config; - - if (!oldConfig || oldConfig.lastRow < config.firstRow) - return this.update(config); - - if (config.lastRow < oldConfig.firstRow) - return this.update(config); - - var el = this.element; - - if (oldConfig.firstRow < config.firstRow) - for (var row=oldConfig.firstRow; row config.lastRow) - for (var row=config.lastRow+1; row<=oldConfig.lastRow; row++) - el.removeChild(el.lastChild); - - if (config.firstRow < oldConfig.firstRow) { - var fragment = this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1); - if (el.firstChild) - el.insertBefore(fragment, el.firstChild); - else - el.appendChild(fragment); - } - - if (config.lastRow > oldConfig.lastRow) { - var fragment = this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow); - el.appendChild(fragment); - } - }; - - this.$renderLinesFragment = function(config, firstRow, lastRow) { - var fragment = document.createDocumentFragment(); - var tokens = this.tokenizer.getTokens(firstRow, lastRow); - for (var row=firstRow; row<=lastRow; row++) { - var lineEl = document.createElement("div"); - lineEl.className = "ace_line"; - var style = lineEl.style; - style.height = this.session.getRowHeight(config, row) + "px"; - style.width = config.width + "px"; - - var html = []; - if (tokens.length > row-firstRow) - this.$renderLine(html, row, tokens[row-firstRow].tokens); - // don't use setInnerHtml since we are working with an empty DIV - lineEl.innerHTML = html.join(""); - fragment.appendChild(lineEl); - } - return fragment; - }; - - this.update = function(config) { - this.$computeTabString(); - this.config = config; - - var html = []; - var tokens = this.tokenizer.getTokens(config.firstRow, config.lastRow) - var fragment = this.$renderLinesFragment(config, config.firstRow, config.lastRow); - - // Clear the current content of the element and add the rendered fragment. - this.element.innerHTML = ""; - this.element.appendChild(fragment); - }; - - this.$textToken = { - "text": true, - "rparen": true, - "lparen": true - }; - - this.$renderLine = function(stringBuilder, row, tokens) { - if (this.showInvisibles) { - var self = this; - var spaceRe = /( +)|([\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000])/g; - var spaceReplace = function(space) { - if (space.charCodeAt(0) == 32) - return new Array(space.length+1).join(" "); - else { - var space = new Array(space.length+1).join(self.SPACE_CHAR); - return "" + space + ""; - } - - }; - } - else { - var spaceRe = /[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/g; - var spaceReplace = " "; - } - - var _self = this; - var characterWidth = this.config.characterWidth; - function addToken(token, value) { - var output = value - .replace(/&/g, "&") - .replace(/" + c + "" - }); - - if (!_self.$textToken[token.type]) { - var classes = "ace_" + token.type.replace(/\./g, " ace_"); - stringBuilder.push("", output, ""); - } - else { - stringBuilder.push(output); - } - } - - var splits = this.session.getRowSplitData(row); - var chars = 0, split = 0, splitChars; - - if (!splits || splits.length == 0) { - splitChars = Number.MAX_VALUE; - } else { - splitChars = splits[0]; - } - - stringBuilder.push("
    "); - for (var i = 0; i < tokens.length; i++) { - var token = tokens[i]; - var value = token.value; - - if (chars + value.length < splitChars) { - addToken(token, value); - chars += value.length; - } else { - while (chars + value.length >= splitChars) { - addToken(token, value.substring(0, splitChars - chars)); - value = value.substring(splitChars - chars); - chars = splitChars; - stringBuilder.push("
    ", - "
    "); - split ++; - splitChars = splits[split] || Number.MAX_VALUE; - } - if (value.length != 0) { - chars += value.length; - addToken(token, value); - } - } - }; - - if (this.showInvisibles) { - if (row !== this.session.getLength() - 1) { - stringBuilder.push("" + this.EOL_CHAR + ""); - } else { - stringBuilder.push("" + this.EOF_CHAR + ""); - } - } - stringBuilder.push("
    "); - }; - -}).call(Text.prototype); - -exports.Text = Text; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/layer/cursor', function(require, exports, module) { - -var dom = require("pilot/dom"); - -var Cursor = function(parentEl) { - this.element = document.createElement("div"); - this.element.className = "ace_layer ace_cursor-layer"; - parentEl.appendChild(this.element); - - this.cursor = document.createElement("div"); - this.cursor.className = "ace_cursor"; - - this.isVisible = false; -}; - -(function() { - - this.setSession = function(session) { - this.session = session; - }; - - this.setCursor = function(position, overwrite) { - this.position = - this.session.documentToScreenPosition(position); - - if (overwrite) { - dom.addCssClass(this.cursor, "ace_overwrite"); - } else { - dom.removeCssClass(this.cursor, "ace_overwrite"); - } - }; - - this.hideCursor = function() { - this.isVisible = false; - if (this.cursor.parentNode) { - this.cursor.parentNode.removeChild(this.cursor); - } - clearInterval(this.blinkId); - }; - - this.showCursor = function() { - this.isVisible = true; - this.element.appendChild(this.cursor); - - var cursor = this.cursor; - cursor.style.visibility = "visible"; - this.restartTimer(); - }; - - this.restartTimer = function() { - clearInterval(this.blinkId); - if (!this.isVisible) { - return; - } - - var cursor = this.cursor; - this.blinkId = setInterval(function() { - cursor.style.visibility = "hidden"; - setTimeout(function() { - cursor.style.visibility = "visible"; - }, 400); - }, 1000); - }; - - this.getPixelPosition = function(onScreen) { - if (!this.config || !this.position) { - return { - left : 0, - top : 0 - }; - } - - var pos = this.position; - var cursorLeft = Math.round(pos.column * this.config.characterWidth); - var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) * - this.config.lineHeight; - - return { - left : cursorLeft, - top : cursorTop - }; - }; - - this.update = function(config) { - if (!this.position) - return; - - this.config = config; - - this.pixelPos = this.getPixelPosition(true); - - this.cursor.style.left = this.pixelPos.left + "px"; - this.cursor.style.top = this.pixelPos.top + "px"; - this.cursor.style.width = config.characterWidth + "px"; - this.cursor.style.height = config.lineHeight + "px"; - - if (this.isVisible) { - this.element.appendChild(this.cursor); - } - this.restartTimer(); - }; - -}).call(Cursor.prototype); - -exports.Cursor = Cursor; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/scrollbar', function(require, exports, module) { - -var oop = require("pilot/oop"); -var dom = require("pilot/dom"); -var event = require("pilot/event"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; - -var ScrollBar = function(parent) { - this.element = document.createElement("div"); - this.element.className = "ace_sb"; - - this.inner = document.createElement("div"); - this.element.appendChild(this.inner); - - parent.appendChild(this.element); - - this.width = dom.scrollbarWidth(); - this.element.style.width = this.width; - - event.addListener(this.element, "scroll", this.onScroll.bind(this)); -}; - -(function() { - oop.implement(this, EventEmitter); - - this.onScroll = function() { - this._dispatchEvent("scroll", {data: this.element.scrollTop}); - }; - - this.getWidth = function() { - return this.width; - }; - - this.setHeight = function(height) { - this.element.style.height = Math.max(0, height - this.width) + "px"; - }; - - this.setInnerHeight = function(height) { - this.inner.style.height = height + "px"; - }; - - this.setScrollTop = function(scrollTop) { - this.element.scrollTop = scrollTop; - }; - -}).call(ScrollBar.prototype); - -exports.ScrollBar = ScrollBar; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/renderloop', function(require, exports, module) { - -var event = require("pilot/event"); - -var RenderLoop = function(onRender) { - this.onRender = onRender; - this.pending = false; - this.changes = 0; -}; - -(function() { - - this.schedule = function(change) { - //this.onRender(change); - //return; - this.changes = this.changes | change; - if (!this.pending) { - this.pending = true; - var _self = this; - this.setTimeoutZero(function() { - _self.pending = false; - var changes = _self.changes; - _self.changes = 0; - _self.onRender(changes); - }) - } - }; - - if (window.postMessage) { - - this.messageName = "zero-timeout-message"; - - this.setTimeoutZero = function(callback) { - if (!this.attached) { - var _self = this; - event.addListener(window, "message", function(e) { - if (_self.callback && e.data == _self.messageName) { - event.stopPropagation(e); - _self.callback(); - } - }); - this.attached = true; - } - this.callback = callback; - window.postMessage(this.messageName, "*"); - } - - } else { - - this.setTimeoutZero = function(callback) { - setTimeout(callback, 0); - } - } - -}).call(RenderLoop.prototype); - -exports.RenderLoop = RenderLoop; -}); -__ace_shadowed__.define("text!ace/css/editor.css", ".ace_editor {" + - " position: absolute;" + - " overflow: hidden;" + - "" + - " font-family: \"Menlo\", \"Monaco\", \"Courier New\", monospace;" + - " font-size: 12px; " + - "}" + - "" + - ".ace_scroller {" + - " position: absolute;" + - " overflow-x: scroll;" + - " overflow-y: hidden; " + - "}" + - "" + - ".ace_content {" + - " position: absolute;" + - " box-sizing: border-box;" + - " -moz-box-sizing: border-box;" + - " -webkit-box-sizing: border-box;" + - "}" + - "" + - ".ace_composition {" + - " position: absolute;" + - " background: #555;" + - " color: #DDD;" + - " z-index: 4;" + - "}" + - "" + - ".ace_gutter {" + - " position: absolute;" + - " overflow-x: hidden;" + - " overflow-y: hidden;" + - " height: 100%;" + - "}" + - "" + - ".ace_gutter-cell.ace_error {" + - " 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\");" + - " background-repeat: no-repeat;" + - " background-position: 4px center;" + - "}" + - "" + - ".ace_gutter-cell.ace_warning {" + - " 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\");" + - " background-repeat: no-repeat;" + - " background-position: 4px center;" + - "}" + - "" + - ".ace_editor .ace_sb {" + - " position: absolute;" + - " overflow-x: hidden;" + - " overflow-y: scroll;" + - " right: 0;" + - "}" + - "" + - ".ace_editor .ace_sb div {" + - " position: absolute;" + - " width: 1px;" + - " left: 0;" + - "}" + - "" + - ".ace_editor .ace_print_margin_layer {" + - " z-index: 0;" + - " position: absolute;" + - " overflow: hidden;" + - " margin: 0;" + - " left: 0;" + - " height: 100%;" + - " width: 100%;" + - "}" + - "" + - ".ace_editor .ace_print_margin {" + - " position: absolute;" + - " height: 100%;" + - "}" + - "" + - ".ace_editor textarea {" + - " position: fixed;" + - " z-index: -1;" + - " width: 10px;" + - " height: 30px;" + - " opacity: 0;" + - " background: transparent;" + - " appearance: none;" + - " border: none;" + - " resize: none;" + - " outline: none;" + - " overflow: hidden;" + - "}" + - "" + - ".ace_layer {" + - " z-index: 1;" + - " position: absolute;" + - " overflow: hidden; " + - " white-space: nowrap;" + - " height: 100%;" + - " width: 100%;" + - "}" + - "" + - ".ace_text-layer {" + - " font-family: Monaco, \"Courier New\", monospace;" + - " color: black;" + - "}" + - "" + - ".ace_cjk {" + - " display: inline-block;" + - " text-align: center;" + - "}" + - "" + - ".ace_cursor-layer {" + - " z-index: 4;" + - " cursor: text;" + - " pointer-events: none;" + - "}" + - "" + - ".ace_cursor {" + - " z-index: 4;" + - " position: absolute;" + - "}" + - "" + - ".ace_line {" + - " white-space: nowrap;" + - "}" + - "" + - ".ace_marker-layer {" + - " cursor: text;" + - "}" + - "" + - ".ace_marker-layer .ace_step {" + - " position: absolute;" + - " z-index: 3;" + - "}" + - "" + - ".ace_marker-layer .ace_selection {" + - " position: absolute;" + - " z-index: 4;" + - "}" + - "" + - ".ace_marker-layer .ace_bracket {" + - " position: absolute;" + - " z-index: 5;" + - "}" + - "" + - ".ace_marker-layer .ace_active_line {" + - " position: absolute;" + - " z-index: 2;" + - "}" + - "" + - ".ace_marker-layer .ace_selected_word {" + - " position: absolute;" + - " z-index: 6;" + - " box-sizing: border-box;" + - " -moz-box-sizing: border-box;" + - " -webkit-box-sizing: border-box;" + - "}" + - ""); - -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kevin Dangoor (kdangoor@mozilla.com) - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -(function() { - -var require = window.__ace_shadowed__.require; -var deps = [ - "pilot/fixoldbrowsers", - "pilot/index", - "pilot/plugin_manager", - "pilot/environment", - "ace/editor", - "ace/edit_session", - "ace/virtual_renderer", - "ace/undomanager", - "ace/theme/textmate" -]; - -require(deps, function() { - -var catalog = require("pilot/plugin_manager").catalog; -catalog.registerPlugins([ "pilot/index" ]); - -var Dom = require("pilot/dom"); -var Event = require("pilot/event"); -var UA = require("pilot/useragent") - -var Editor = require("ace/editor").Editor; -var EditSession = require("ace/edit_session").EditSession; -var UndoManager = require("ace/undomanager").UndoManager; -var Renderer = require("ace/virtual_renderer").VirtualRenderer; - -window.__ace_shadowed__.edit = function(el) { - if (typeof(el) == "string") { - el = document.getElementById(el); - } - - var doc = new EditSession(Dom.getInnerText(el)); - doc.setUndoManager(new UndoManager()); - el.innerHTML = ''; - - var editor = new Editor(new Renderer(el, "ace/theme/textmate")); - editor.setSession(doc); - - var env = require("pilot/environment").create(); - catalog.startupPlugins({ env: env }).then(function() { - env.document = doc; - env.editor = env; - editor.resize(); - Event.addListener(window, "resize", function() { - editor.resize(); - }); - el.env = env; - }); - return editor; -} - - -/** - * 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 - * - * If the property can't get computed, is 'auto' or 'intrinsic', the former - * calculated property is uesd (this can happen in cases where the textarea - * is hidden and has no dimension styles). - */ -var getCSSProperty = function(element, container, property) { - var ret = element.style[property]; - - if (!ret) { - if (window.getComputedStyle) { - ret = window.getComputedStyle(element, '').getPropertyValue(property); - } else { - ret = element.currentStyle[property]; - } - } - - if (!ret || ret == 'auto' || ret == 'intrinsic') { - ret = container.style[property]; - } - return ret; -}; - -function applyStyles(elm, styles) { - for (style in styles) { - elm.style[style] = styles[style]; - } -} - -function setupContainer(element, getValue) { - if (element.type != 'textarea') { - throw "Textarea required!"; - } - - var parentNode = element.parentNode; - - // This will hold the Bespin editor. - var container = document.createElement('div'); - - // To put Bespin in the place of the textarea, we have to copy a - // few of the textarea's style attributes to the div container. - // - // The problem is, that the properties have to get computed (they - // might be defined by a CSS file on the page - you can't access - // such rules that apply to an element via elm.style). Computed - // properties are converted to pixels although the dimension might - // be given as percentage. When the window resizes, the dimensions - // defined by percentages changes, so the properties have to get - // recomputed to get the new/true pixels. - var resizeEvent = function() { - var style = 'position:relative;'; - [ - 'margin-top', 'margin-left', 'margin-right', 'margin-bottom' - ].forEach(function(item) { - style += item + ':' + - getCSSProperty(element, container, item) + ';'; - }); - - // Calculating the width/height of the textarea is somewhat - // tricky. To do it right, you have to include the paddings - // to the sides as well (eg. width = width + padding-left, -right). - // This works well, as long as the width of the element is not - // set or given in pixels. In this case and after the textarea - // is hidden, getCSSProperty(element, container, 'width') will - // still return pixel value. If the element has realtiv dimensions - // (e.g. width='95') getCSSProperty(...) will return pixel values - // only as long as the textarea is visible. After it is hidden - // getCSSProperty will return the relativ dimensions as they - // are set on the element (in the case of width, 95). - // Making the sum of pixel vaules (e.g. padding) and realtive - // values (e.g. ) is not possible. As such the padding styles - // are ignored. - - // The complete width is the width of the textarea + the padding - // to the left and right. - var width = getCSSProperty(element, container, 'width') || (element.clientWidth + "px"); - var height = getCSSProperty(element, container, 'height') || (element.clientHeight + "px"); - style += 'height:' + height + ';width:' + width + ';'; - - // Set the display property to 'inline-block'. - style += 'display:inline-block;'; - container.setAttribute('style', style); - }; - Event.addListener(window, 'resize', resizeEvent); - - // Call the resizeEvent once, so that the size of the container is - // calculated. - resizeEvent(); - - // Insert the div container after the element. - if (element.nextSibling) { - parentNode.insertBefore(container, element.nextSibling); - } else { - parentNode.appendChild(container); - } - - // Override the forms onsubmit function. Set the innerHTML and value - // of the textarea before submitting. - while (parentNode !== document) { - if (parentNode.tagName.toUpperCase() === 'FORM') { - var oldSumit = parentNode.onsubmit; - // Override the onsubmit function of the form. - parentNode.onsubmit = function(evt) { - element.value = getValue(); - element.innerHTML = getValue(); - // If there is a onsubmit function already, then call - // it with the current context and pass the event. - if (oldSumit) { - oldSumit.call(this, evt); - } - } - break; - } - parentNode = parentNode.parentNode; - } - return container; -} - -window.__ace_shadowed__.transformTextarea = function(element) { - var session; - var container = setupContainer(element, function() { - return session.getValue(); - }); - - // Hide the element. - element.style.display = 'none'; - container.style.background = 'white'; - - // - var editorDiv = document.createElement("div"); - applyStyles(editorDiv, { - top: "0px", - left: "0px", - right: "0px", - bottom: "0px", - border: "1px solid gray" - }); - container.appendChild(editorDiv); - - var settingOpener = document.createElement("div"); - applyStyles(settingOpener, { - position: "absolute", - width: "15px", - right: "0px", - bottom: "0px", - background: "red", - cursor: "pointer", - textAlign: "center", - fontSize: "12px" - }); - settingOpener.innerHTML = "I"; - - var settingDiv = document.createElement("div"); - var settingDivStyles = { - top: "0px", - left: "0px", - right: "0px", - bottom: "0px", - position: "absolute", - padding: "5px", - zIndex: 100, - color: "white", - display: "none", - overflow: "auto", - fontSize: "14px" - }; - if (!UA.isIE) { - settingDivStyles.backgroundColor = "rgba(0, 0, 0, 0.6)"; - } else { - settingDivStyles.backgroundColor = "#333"; - } - - applyStyles(settingDiv, settingDivStyles); - container.appendChild(settingDiv); - - // Power up ace on the textarea: - var ace = window.__ace_shadowed__; - var require = ace.require; - var define = ace.define; - var options = {}; - - var editor = ace.edit(editorDiv); - session = editor.getSession(); - - session.setValue(element.value || element.innerHTML); - editor.focus(); - - // Add the settingPanel opener to the editor's div. - editorDiv.appendChild(settingOpener); - - // Create the API. - var api = setupApi(editor, editorDiv, settingDiv, ace, options) - - // Create the setting's panel. - setupSettingPanel(settingDiv, settingOpener, api, options); - - return api; -} - -function setupApi(editor, editorDiv, settingDiv, ace, options) { - var session = editor.getSession(); - var renderer = editor.renderer; - - function toBool(value) { - return value == "true"; - } - - var ret = { - setDisplaySettings: function(display) { - settingDiv.style.display = display ? "block" : "none"; - }, - - setOption: function(key, value) { - if (options[key] == value) return; - - var load = window.__ace_shadowed_load__; - - switch (key) { - case "gutter": - renderer.setShowGutter(toBool(value)); - break; - - case "mode": - if (value != "text") { - // Load the required mode file. Files get loaded only once. - load("mode-" + value + ".js", "ace/mode/" + value, function() { - var aceMode = require("ace/mode/" + value).Mode; - session.setMode(new aceMode()); - }); - } else { - session.setMode(new (require("ace/mode/text").Mode)); - } - break; - - case "theme": - if (value != "textmate") { - // Load the required theme file. Files get loaded only once. - load("theme-" + value + ".js", "ace/theme/" + value, function() { - editor.setTheme("ace/theme/" + value); - }); - } else { - editor.setTheme("ace/theme/textmate"); - } - break; - - case "fontSize": - editorDiv.style.fontSize = value; - break; - - case "softWrap": - switch (value) { - case "off": - session.setUseWrapMode(false); - renderer.setPrintMarginColumn(80); - break; - case "40": - session.setUseWrapMode(true); - session.setWrapLimitRange(40, 40); - renderer.setPrintMarginColumn(40); - break; - case "80": - session.setUseWrapMode(true); - session.setWrapLimitRange(80, 80); - renderer.setPrintMarginColumn(80); - break; - case "free": - session.setUseWrapMode(true); - session.setWrapLimitRange(null, null); - renderer.setPrintMarginColumn(80); - break; - } - break; - - case "showPrintMargin": - renderer.setShowPrintMargin(toBool(value)); - break - } - - options[key] = value; - }, - - getOption: function(key) { - return options[key]; - }, - - getOptions: function() { - return options; - } - } - - for (option in ace.options) { - ret.setOption(option, ace.options[option]); - } - - return ret; -} - -function setupSettingPanel(settingDiv, settingOpener, api, options) { - var BOOL = { - "true": true, - "false": false - } - - var desc = { - mode: "Mode:", - gutter: "Display Gutter:", - theme: "Theme:", - fontSize: "Font Size:", - softWrap: "Soft Wrap:", - showPrintMargin: "Show Print Margin:" - } - - var optionValues = { - mode: { - text: "Plain", - javascript: "JavaScript", - coffee: "CoffeeScript", - html: "HTML", - css: "CSS", - c_cpp: "C++", - php: "PHP", - ruby: "Ruby", - python: "Python" - - }, - theme: { - textmate: "Textmate", - eclipse: "Eclipse", - clouds: "Clouds", - clouds_midnight: "Clouds Midnight", - cobalt: "Cobalt", - dawn: "Dawn", - idle_fingers: "Idle Fingers", - kr_theme: "Kr Theme", - mono_industrial: "Mono Industrial", - monokai: "Monokai", - pastel_on_dark: "Pastel On Dark", - twilight: "Twilight" - }, - gutter: BOOL, - fontSize: { - "10px": "10px", - "11px": "11px", - "12px": "12px", - "14px": "14px", - "16px": "16px" - }, - softWrap: { - off: "Off", - 40: "40", - 80: "80", - free: "Free" - }, - showPrintMargin: BOOL - } - - var table = []; - table.push(""); - - function renderOption(builder, option, obj, cValue) { - builder.push("") - } - - for (var option in options) { - table.push(""); - table.push(""); - } - table.push("
    SettingValue
    ", desc[option], ""); - renderOption(table, option, optionValues[option], options[option]); - table.push("
    "); - settingDiv.innerHTML = table.join(""); - - var selects = settingDiv.getElementsByTagName("select"); - for (var i = 0; i < selects.length; i++) { - var onChange = (function() { - var select = selects[i]; - return function() { - var option = select.title; - var value = select.value; - api.setOption(option, value); - } - })(); - selects[i].onchange = onChange; - } - - var button = document.createElement("input"); - button.type = "button"; - button.value = "Hide"; - button.onclick = function() { - api.setDisplaySettings(false); - } - settingDiv.appendChild(button); - - settingOpener.onclick = function() { - api.setDisplaySettings(true); - } -} - -// Default startup options. -window.__ace_shadowed__.options = { - mode: "text", - theme: "textmate", - gutter: "false", - fontSize: "12px", - softWrap: "off", - showPrintMargin: "false" -} - -}); - -})() diff --git a/build/textarea/src/ace.js b/build/textarea/src/ace.js deleted file mode 100644 index d663dba3..00000000 --- a/build/textarea/src/ace.js +++ /dev/null @@ -1 +0,0 @@ -(function(){var a=function(b,c){typeof b!=="string"?a.original?a.original.apply(window,arguments):(console.error("dropping module because define wasn't a string."),console.trace()):(a.modules||(a.modules={}),a.modules[b]=c)},b=function(a,d){if(Object.prototype.toString.call(a)==="[object Array]"){var e=[];for(var f=0,g=a.length;f>>0;if(c===0)return-1;var d=0,e=d;arguments.length>0&&(d=Number(arguments[1]),d!==d?d=0:d!==0&&d!==1/e&&d!==-(1/e)&&(d=(d>0||-1)*Math.floor(Math.abs(d))));if(d>=c)return-1;var f=d>=0?d:Math.max(c-Math.abs(d),0);for(;f>>0;if(c===0)return-1;var d=c,e=!1|0;arguments.length>0&&(d=Number(arguments[1]),d!==d?d=0:d!==0&&d!==1/e&&d!==-(1/e)&&(d=(d>0||-1)*Math.floor(Math.abs(d))));var f=d>=0?Math.min(d,c-1):c-Math.abs(d);while(f>=0)if(f in b&&b[f]===a)return f;return-1}),Array.prototype.map||(Array.prototype.map=function(a){if(this===void 0||this===null)throw new TypeError;var b=Object(this),c=b.length>>>0;if(typeof a!=="function")throw new TypeError;res=Array(c);var d=arguments[1];for(var e=0;e>>0;if(typeof a!=="function")throw new TypeError;var d=arguments[1];for(var e=0;e>>0;if(typeof a!="function")throw new TypeError;if(b==0&&arguments.length==1)throw new TypeError;var c=0;if(arguments.length<2){do{if(c in this){d=this[c++];break}if(++c>=b)throw new TypeError}while(!0)}else var d=arguments[1];for(;c>>0;if(typeof a!="function")throw new TypeError;if(b==0&&arguments.length==1)throw new TypeError;var c=b-1;if(arguments.length<2){do{if(c in this){d=this[c--];break}if(--c<0)throw new TypeError}while(!0)}else var d=arguments[1];for(;c>=0;c--)c in this&&(d=a.call(null,d,this[c],c,this));return d}),Object.keys||(Object.keys=function m(a){var b,c=[];for(b in a)f(a,b)&&c.push(b);return c}),Object.getOwnPropertyNames||(Object.getOwnPropertyNames=Object.keys);var n="Object.getOwnPropertyDescriptor called on a non-object";Object.getOwnPropertyDescriptor||(Object.getOwnPropertyDescriptor=function o(a,b){var c,d,e;if(typeof a!=="object"&&typeof a!=="function"||a===null)throw new TypeError(n);f(a,b)&&(c={configurable:!0,enumerable:!0},d=c.get=g(a,b),e=c.set=h(a,b),!d&&!e&&(c.writeable=!0,c.value=a[b]));return c}),Object.getPrototypeOf||(Object.getPrototypeOf=function p(a){return a.__proto__||a.constructor.prototype}),Object.create||(Object.create=function q(a,b){var c;if(a===null)c={"__proto__":null};else{if(typeof a!=="object")throw new TypeError(a+" is not an object or null");d.prototype=a,c=new d}typeof b!=="undefined"&&Object.defineProperties(c,b);return c}),Object.defineProperty||(Object.defineProperty=function r(a,b,c){var d,e,f;if("object"!==typeof a&&"function"!==typeof a)throw new TypeError(a+"is not an object");if(c&&"object"!==typeof c)throw new TypeError("Property descriptor map must be an object");if("value"in c){if("get"in c||"set"in c)throw new TypeError('Invalid property. "value" present on property with getter or setter.');if(d=a.__proto__)a.__proto__=Object.prototype;delete a[b],a[b]=c.value,d&&(a.__proto__=d)}else(f=c.get)&&i(a,f),(e=c.set)&&j(a,e);return a}),Object.defineProperties||(Object.defineProperties=function s(a,b){Object.getOwnPropertyNames(b).forEach(function(c){Object.defineProperty(a,c,b[c])});return a});var t=function(a){return a};Object.seal||(Object.seal=t),Object.freeze||(Object.freeze=t),Object.preventExtensions||(Object.preventExtension=t);var u=function(){return!1},v=function(){return!0};Object.isSealed||(Object.isSealed=u),Object.isFrozen||(Object.isFrozen=u),Object.isExtensible||(Object.isExtensible=v),String.prototype.trim||(String.prototype.trim=function(){return this.trimLeft().trimRight()}),String.prototype.trimRight||(String.prototype.trimRight=function(){return this.replace(/[\t\v\f\s\u00a0\ufeff]+$/,"")}),String.prototype.trimLeft||(String.prototype.trimLeft=function(){return this.replace(/^[\t\v\f\s\u00a0\ufeff]+/,"")}),b.globalsLoaded=!0}),__ace_shadowed__.define("pilot/index",function(a,b,c){b.startup=function(b,c){a("pilot/fixoldbrowsers"),a("pilot/types/basic").startup(b,c),a("pilot/types/command").startup(b,c),a("pilot/types/settings").startup(b,c),a("pilot/commands/settings").startup(b,c),a("pilot/commands/basic").startup(b,c),a("pilot/settings/canon").startup(b,c),a("pilot/canon").startup(b,c)},b.shutdown=function(b,c){a("pilot/types/basic").shutdown(b,c),a("pilot/types/command").shutdown(b,c),a("pilot/types/settings").shutdown(b,c),a("pilot/commands/settings").shutdown(b,c),a("pilot/commands/basic").shutdown(b,c),a("pilot/settings/canon").shutdown(b,c),a("pilot/canon").shutdown(b,c)}}),__ace_shadowed__.define("pilot/types/basic",function(a,b,c){function m(a){if(a instanceof e)this.subtype=a;else{if(typeof a!=="string")throw new Error("Can' handle array subtype");this.subtype=d.getType(a);if(this.subtype==null)throw new Error("Unknown array subtype: "+a)}}function l(a){if(typeof a.defer!=="function")throw new Error("Instances of DeferredType need typeSpec.defer to be a function that returns a type");Object.keys(a).forEach(function(b){this[b]=a[b]},this)}function j(a){if(!Array.isArray(a.data)&&typeof a.data!=="function")throw new Error("instances of SelectionType need typeSpec.data to be an array or function that returns an array:"+JSON.stringify(a));Object.keys(a).forEach(function(b){this[b]=a[b]},this)}var d=a("pilot/types"),e=d.Type,f=d.Conversion,g=d.Status,h=new e;h.stringify=function(a){return a},h.parse=function(a){if(typeof a!="string")throw new Error("non-string passed to text.parse()");return new f(a)},h.name="text";var i=new e;i.stringify=function(a){if(!a)return null;return""+a},i.parse=function(a){if(typeof a!="string")throw new Error("non-string passed to number.parse()");if(a.replace(/\s/g,"").length===0)return new f(null,g.INCOMPLETE,"");var b=new f(parseInt(a,10));isNaN(b.value)&&(b.status=g.INVALID,b.message="Can't convert \""+a+'" to a number.');return b},i.decrement=function(a){return a-1},i.increment=function(a){return a+1},i.name="number",j.prototype=new e,j.prototype.stringify=function(a){return a},j.prototype.parse=function(a){if(typeof a!="string")throw new Error("non-string passed to parse()");if(!this.data)throw new Error("Missing data on selection type extension.");var b=typeof this.data==="function"?this.data():this.data,c=!1,d,e=[];b.forEach(function(b){a==b?(d=this.fromString(b),c=!0):b.indexOf(a)===0&&e.push(this.fromString(b))},this);if(c)return new f(d);this.noMatch&&this.noMatch();if(e.length>0){var h="Possibilities"+(a.length===0?"":" for '"+a+"'");return new f(null,g.INCOMPLETE,h,e)}var h="Can't use '"+a+"'.";return new f(null,g.INVALID,h,e)},j.prototype.fromString=function(a){return a},j.prototype.decrement=function(a){var b=typeof this.data==="function"?this.data():this.data,c;if(a==null)c=b.length-1;else{var d=this.stringify(a),c=b.indexOf(d);c=c===0?b.length-1:c-1}return this.fromString(b[c])},j.prototype.increment=function(a){var b=typeof this.data==="function"?this.data():this.data,c;if(a==null)c=0;else{var d=this.stringify(a),c=b.indexOf(d);c=c===b.length-1?0:c+1}return this.fromString(b[c])},j.prototype.name="selection",b.SelectionType=j;var k=new j({name:"bool",data:["true","false"],stringify:function(a){return""+a},fromString:function(a){return a==="true"?!0:!1}});l.prototype=new e,l.prototype.stringify=function(a){return this.defer().stringify(a)},l.prototype.parse=function(a){return this.defer().parse(a)},l.prototype.decrement=function(a){var b=this.defer();return b.decrement?b.decrement(a):undefined},l.prototype.increment=function(a){var b=this.defer();return b.increment?b.increment(a):undefined},l.prototype.name="deferred",b.DeferredType=l,m.prototype=new e,m.prototype.stringify=function(a){return a.join(" ")},m.prototype.parse=function(a){return this.defer().parse(a)},m.prototype.name="array",b.startup=function(){d.registerType(h),d.registerType(i),d.registerType(k),d.registerType(j),d.registerType(l),d.registerType(m)},b.shutdown=function(){d.unregisterType(h),d.unregisterType(i),d.unregisterType(k),d.unregisterType(j),d.unregisterType(l),d.unregisterType(m)}}),__ace_shadowed__.define("pilot/types",function(a,b,c){function i(a,b){if(a.substr(-2)==="[]"){var c=a.slice(0,-2);return new g.array(c)}var d=g[a];typeof d==="function"&&(d=new d(b));return d}function f(){}function e(a,b,c,e){this.value=a,this.status=b||d.VALID,this.message=c,this.predictions=e||[]}var d={VALID:{toString:function(){return"VALID"},valueOf:function(){return 0}},INCOMPLETE:{toString:function(){return"INCOMPLETE"},valueOf:function(){return 1}},INVALID:{toString:function(){return"INVALID"},valueOf:function(){return 2}},combine:function(a){var b=d.VALID;for(var c=0;cb&&(b=arguments[c]);return b}};b.Status=d,b.Conversion=e,f.prototype={stringify:function(a){throw new Error("not implemented")},parse:function(a){throw new Error("not implemented")},name:undefined,increment:function(a){return undefined},decrement:function(a){return undefined},getDefault:function(){return this.parse("")}},b.Type=f;var g={};b.registerType=function(a){if(typeof a==="object"){if(!(a instanceof f))throw new Error("Can't registerType using: "+a);if(!a.name)throw new Error("All registered types must have a name");g[a.name]=a}else{if(typeof a!=="function")throw new Error("Unknown type: "+a);if(!a.prototype.name)throw new Error("All registered types must have a name");g[a.prototype.name]=a}},b.registerTypes=function h(a){Object.keys(a).forEach(function(c){var d=a[c];d.name=c,b.registerType(d)})},b.deregisterType=function(a){delete g[a.name]},b.getType=function(a){if(typeof a==="string")return i(a);if(typeof a==="object"){if(!a.name)throw new Error("Missing 'name' member to typeSpec");return i(a.name,a)}throw new Error("Can't extract type from "+a)}}),__ace_shadowed__.define("pilot/types/command",function(a,b,c){var d=a("pilot/canon"),e=a("pilot/types/basic").SelectionType,f=a("pilot/types"),g=new e({name:"command",data:function(){return d.getCommandNames()},stringify:function(a){return a.name},fromString:function(a){return d.getCommand(a)}});b.startup=function(){f.registerType(g)},b.shutdown=function(){f.unregisterType(g)}}),__ace_shadowed__.define("pilot/canon",function(a,b,c){function x(a){a=a||{},this.command=a.command,this.args=a.args,this.typed=a.typed,this._begunOutput=!1,this.start=new Date,this.end=null,this.completed=!1,this.error=!1}function u(a,b,c,d){typeof a==="string"&&(a=n[a]);if(!a)return!1;var e=new x({command:a,args:c,typed:d});a.exec(b,c||{},e);return!0}function t(){return o}function s(a){return n[a]}function r(a){var b=typeof a==="string"?a:a.name;delete n[b],k.arrayRemove(o,b)}function q(a,b){var c=b.type;b.type=j.getType(c);if(b.type==null)throw new Error("In "+a+"/"+b.name+": can't find type for: "+JSON.stringify(c))}function p(a){if(!a.name)throw new Error("All registered commands must have a name");a.params==null&&(a.params=[]);if(!Array.isArray(a.params))throw new Error("command.params must be an array in "+a.name);a.params.forEach(function(b){if(!b.name)throw new Error("In "+a.name+": all params must have a name");q(a.name,b)},this),n[a.name]=a,o.push(a.name),o.sort()}var d=a("pilot/console"),e=a("pilot/stacktrace").Trace,f=a("pilot/oop"),g=a("pilot/event_emitter").EventEmitter,h=a("pilot/catalog"),i=a("pilot/types").Status,j=a("pilot/types"),k=a("pilot/lang"),l={name:"command",description:"A command is a bit of functionality with optional typed arguments which can do something small like moving the cursor around the screen, or large like cloning a project from VCS.",indexOn:"name"};b.startup=function(a,b){h.addExtensionSpec(l)},b.shutdown=function(a,b){h.removeExtensionSpec(l)};var m={name:"thing",description:"thing is an example command",params:[{name:"param1",description:"an example parameter",type:"text",defaultValue:null}],exec:function(a,b,c){thing()}},n={},o=[];b.removeCommand=r,b.addCommand=p,b.getCommand=s,b.getCommandNames=t,b.exec=u,b.upgradeType=q,f.implement(b,g);var v=[],w=100;f.implement(x.prototype,g),x.prototype._beginOutput=function(){this._begunOutput=!0,this.outputs=[],v.push(this);while(v.length>w)v.shiftObject();b._dispatchEvent("output",{requests:v,request:this})},x.prototype.doneWithError=function(a){this.error=!0,this.done(a)},x.prototype.async=function(){this._begunOutput||this._beginOutput()},x.prototype.output=function(a){this._begunOutput||this._beginOutput(),typeof a!=="string"&&!(a instanceof Node)&&(a=a.toString()),this.outputs.push(a),this._dispatchEvent("output",{});return this},x.prototype.done=function(a){this.completed=!0,this.end=new Date,this.duration=this.end.getTime()-this.start.getTime(),a&&this.output(a),this._dispatchEvent("output",{})},b.Request=x}),__ace_shadowed__.define("pilot/console",function(a,b,c){var d=function(){},e=["assert","count","debug","dir","dirxml","error","group","groupEnd","info","log","profile","profileEnd","time","timeEnd","trace","warn"];typeof window==="undefined"?e.forEach(function(a){b[a]=function(){var b=Array.prototype.slice.call(arguments),c={op:"log",method:a,args:b};postMessage(JSON.stringify(c))}}):e.forEach(function(a){window.console&&window.console[a]?b[a]=Function.prototype.bind.call(window.console[a],window.console):b[a]=d})}),__ace_shadowed__.define("pilot/stacktrace",function(a,b,c){function i(){}function g(a){for(var b=0;b\s*\(/gm,"{anonymous}()@").split("\n")},firefox:function(a){var b=a.stack;if(!b){e.log(a);return[]}b=b.replace(/(?:\n@:0)?\s+$/m,""),b=b.replace(/^\(/gm,"{anonymous}(");return b.split("\n")},opera:function(a){var b=a.message.split("\n"),c="{anonymous}",d=/Line\s+(\d+).*?script\s+(http\S+)(?:.*?in\s+function\s+(\S+))?/i,e,f,g;for(e=4,f=0,g=b.length;e=0,b.isIPad=e.indexOf("iPad")>=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_shadowed__.define("pilot/oop",function(a,b,c){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_shadowed__.define("pilot/event_emitter",function(a,b,c){var d={};d._emit=d._dispatchEvent=function(a,b){this._eventRegistry=this._eventRegistry||{};var c=this._eventRegistry[a];if(c&&c.length){var b=b||{};b.type=a;for(var d=0;d"+setting.name+" = "+setting.get():(b.setting.set(b.value),d="Setting: "+b.setting.name+" = "+b.setting.get());else{var e=a.settings.getSettingNames();d="",e.sort(function(a,b){return a.localeCompare(b)}),e.forEach(function(b){var c=a.settings.getSetting(b),e="https://wiki.mozilla.org/Labs/Skywriter/Settings#"+c.name;d+=''+c.name+" = "+c.value+"
    "})}c.done(d)}},e={name:"unset",params:[{name:"setting",type:"setting",description:"The name of the setting to return to defaults"}],description:"unset a setting entirely",exec:function(a,b,c){var d=a.settings.get(b.setting);d?(d.reset(),c.done("Reset "+d.name+" to default: "+a.settings.get(b.setting))):c.doneWithError("No setting with the name "+b.setting+".")}},f=a("pilot/canon");b.startup=function(a,b){f.addCommand(d),f.addCommand(e)},b.shutdown=function(a,b){f.removeCommand(d),f.removeCommand(e)}}),__ace_shadowed__.define("pilot/commands/basic",function(require,exports,module){var checks=require("pilot/typecheck"),canon=require("pilot/canon"),helpMessages={plainPrefix:'

    Welcome to Skywriter - Code in the Cloud

    ',plainSuffix:'For more information, see the Skywriter Wiki.'},helpCommandSpec={name:"help",params:[{name:"search",type:"text",description:"Search string to narrow the output.",defaultValue:null}],description:"Get help on the available commands.",exec:function(a,b,c){var d=[],e=canon.getCommand(b.search);if(e&&e.exec)d.push(e.description?e.description:"No description for "+b.search);else{var f=!1;!b.search&&helpMessages.plainPrefix&&d.push(helpMessages.plainPrefix),e?(d.push("

    Sub-Commands of "+e.name+"

    "),d.push("

    "+e.description+"

    ")):b.search?(b.search=="hidden"&&(b.search="",f=!0),d.push("

    Commands starting with '"+b.search+"':

    ")):d.push("

    Available Commands:

    ");var g=canon.getCommandNames();g.sort(),d.push("");for(var h=0;h"),d.push('"),d.push(""),d.push("")}d.push("
    '+e.name+""+e.description+"
    "),!b.search&&helpMessages.plainSuffix&&d.push(helpMessages.plainSuffix)}c.done(d.join(""))}},evalCommandSpec={name:"eval",params:[{name:"javascript",type:"text",description:"The JavaScript to evaluate"}],description:"evals given js code and show the result",hidden:!0,exec:function(env,args,request){var result,javascript=args.javascript;try{result=eval(javascript)}catch(e){result="Error: "+e.message+""}var msg="",type="",x;if(checks.isFunction(result))msg=(result+"").replace(/\n/g,"
    ").replace(/ /g," "),type="function";else if(checks.isObject(result)){Array.isArray(result)?type="array":type="object";var items=[],value;for(x in result)result.hasOwnProperty(x)&&(checks.isFunction(result[x])?value="[function]":checks.isObject(result[x])?value="[object]":value=result[x],items.push({name:x,value:value}));items.sort(function(a,b){return a.name.toLowerCase()"+items[x].name+": "+items[x].value+"
    "}else msg=result,type=typeof result;request.done("Result for eval '"+javascript+"' (type: "+type+"):

    "+msg)}},versionCommandSpec={name:"version",description:"show the Skywriter version",hidden:!0,exec:function(a,b,c){var d="Skywriter "+skywriter.versionNumber+" ("+skywriter.versionCodename+")";c.done(d)}},skywriterCommandSpec={name:"skywriter",hidden:!0,exec:function(a,b,c){var d=Math.floor(Math.random()*messages.length);c.done("Skywriter "+messages[d])}},messages=["really wants you to trick it out in some way.","is your Web editor.","would love to be like Emacs on the Web.","is written on the Web platform, so you can tweak it."],canon=require("pilot/canon");exports.startup=function(a,b){canon.addCommand(helpCommandSpec),canon.addCommand(evalCommandSpec),canon.addCommand(skywriterCommandSpec)},exports.shutdown=function(a,b){canon.removeCommand(helpCommandSpec),canon.removeCommand(evalCommandSpec),canon.removeCommand(skywriterCommandSpec)}}),__ace_shadowed__.define("pilot/typecheck",function(a,b,c){var d=Object.prototype.toString;b.isString=function(a){return a&&d.call(a)==="[object String]"},b.isBoolean=function(a){return a&&d.call(a)==="[object Boolean]"},b.isNumber=function(a){return a&&d.call(a)==="[object Number]"&&isFinite(a)},b.isObject=function(a){return a!==undefined&&(a===null||typeof a=="object"||Array.isArray(a)||b.isFunction(a))},b.isFunction=function(a){return a&&d.call(a)==="[object Function]"}}),__ace_shadowed__.define("pilot/settings/canon",function(a,b,c){var d={name:"historyLength",description:"How many typed commands do we recall for reference?",type:"number",defaultValue:50};b.startup=function(a,b){a.env.settings.addSetting(d)},b.shutdown=function(a,b){a.env.settings.removeSetting(d)}}),__ace_shadowed__.define("pilot/plugin_manager",function(a,b,c){var d=a("pilot/promise").Promise;b.REASONS={APP_STARTUP:1,APP_SHUTDOWN:2,PLUGIN_ENABLE:3,PLUGIN_DISABLE:4,PLUGIN_INSTALL:5,PLUGIN_UNINSTALL:6,PLUGIN_UPGRADE:7,PLUGIN_DOWNGRADE:8},b.Plugin=function(a){this.name=a,this.status=this.INSTALLED},b.Plugin.prototype={NEW:0,INSTALLED:1,REGISTERED:2,STARTED:3,UNREGISTERED:4,SHUTDOWN:5,install:function(b,c){var e=new d;if(this.status>this.NEW){e.resolve(this);return e}a([this.name],function(a){a.install&&a.install(b,c),this.status=this.INSTALLED,e.resolve(this)}.bind(this));return e},register:function(b,c){var e=new d;if(this.status!=this.INSTALLED){e.resolve(this);return e}a([this.name],function(a){a.register&&a.register(b,c),this.status=this.REGISTERED,e.resolve(this)}.bind(this));return e},startup:function(c,e){e=e||b.REASONS.APP_STARTUP;var f=new d;if(this.status!=this.REGISTERED){f.resolve(this);return f}a([this.name],function(a){a.startup&&a.startup(c,e),this.status=this.STARTED,f.resolve(this)}.bind(this));return f},shutdown:function(b,c){this.status==this.STARTED&&(pluginModule=a(this.name),pluginModule.shutdown&&pluginModule.shutdown(b,c))}},b.PluginCatalog=function(){this.plugins={}},b.PluginCatalog.prototype={registerPlugins:function(a,c,e){var f=[];a.forEach(function(a){var d=this.plugins[a];d===undefined&&(d=new b.Plugin(a),this.plugins[a]=d,f.push(d.register(c,e)))}.bind(this));return d.group(f)},startupPlugins:function(a,b){var c=[];for(var e in this.plugins){var f=this.plugins[e];c.push(f.startup(a,b))}return d.group(c)}},b.catalog=new b.PluginCatalog}),__ace_shadowed__.define("pilot/promise",function(a,b,c){var d=a("pilot/console"),e=a("pilot/stacktrace").Trace,f=-1,g=0,h=1,i=0,j=!1,k=[],l=[];Promise=function(){this._status=g,this._value=undefined,this._onSuccessHandlers=[],this._onErrorHandlers=[],this._id=i++,k[this._id]=this},Promise.prototype.isPromise=!0,Promise.prototype.isComplete=function(){return this._status!=g},Promise.prototype.isResolved=function(){return this._status==h},Promise.prototype.isRejected=function(){return this._status==f},Promise.prototype.then=function(a,b){typeof a==="function"&&(this._status===h?a.call(null,this._value):this._status===g&&this._onSuccessHandlers.push(a)),typeof b==="function"&&(this._status===f?b.call(null,this._value):this._status===g&&this._onErrorHandlers.push(b));return this},Promise.prototype.chainPromise=function(a){var b=new Promise;b._chainedFrom=this,this.then(function(c){try{b.resolve(a(c))}catch(d){b.reject(d)}},function(a){b.reject(a)});return b},Promise.prototype.resolve=function(a){return this._complete(this._onSuccessHandlers,h,a,"resolve")},Promise.prototype.reject=function(a){return this._complete(this._onErrorHandlers,f,a,"reject")},Promise.prototype._complete=function(a,b,c,f){if(this._status!=g){d.group("Promise already closed"),d.error("Attempted "+f+"() with ",c),d.error("Previous status = ",this._status,", previous value = ",this._value),d.trace(),this._completeTrace&&(d.error("Trace of previous completion:"),this._completeTrace.log(5)),d.groupEnd();return this}j&&(this._completeTrace=new e(new Error)),this._status=b,this._value=c,a.forEach(function(a){a.call(null,this._value)},this),this._onSuccessHandlers.length=0,this._onErrorHandlers.length=0,delete k[this._id],l.push(this);while(l.length>20)l.shift();return this},Promise.group=function(a){a instanceof Array||(a=Array.prototype.slice.call(arguments));if(a.length===0)return(new Promise).resolve([]);var b=new Promise,c=[],d=0,e=function(e){return function(g){c[e]=g,d++,b._status!==f&&(d===a.length&&b.resolve(c))}};a.forEach(function(a,c){var d=e(c),f=b.reject.bind(b);a.then(d,f)});return b},b.Promise=Promise,b._outstanding=k,b._recent=l}),__ace_shadowed__.define("pilot/environment",function(a,b,c){function e(){return{settings:d}}var d=a("pilot/settings").settings;b.create=e}),__ace_shadowed__.define("ace/editor",function(a,b,c){a("pilot/fixoldbrowsers");var d=a("pilot/oop"),e=a("pilot/event"),f=a("pilot/lang"),g=a("pilot/useragent"),h=a("ace/keyboard/textinput").TextInput,i=a("ace/mouse_handler").MouseHandler,j=a("ace/keyboard/keybinding").KeyBinding,k=a("ace/edit_session").EditSession,l=a("ace/search").Search,m=a("ace/background_tokenizer").BackgroundTokenizer,n=a("ace/range").Range,o=a("pilot/event_emitter").EventEmitter,p=function(a,b){var c=a.getContainerElement();this.container=c,this.renderer=a,this.textInput=new h(a.getTextAreaContainer(),this),this.keyBinding=new j(this),g.isIPad||(this.$mouseHandler=new i(this)),this.$blockScrolling=0,this.$search=(new l).set({wrap:!0}),this.setSession(b||new k(""))};(function(){d.implement(this,o),this.$forwardEvents={gutterclick:1,gutterdblclick:1},this.$originalAddEventListener=this.addEventListener,this.$originalRemoveEventListener=this.removeEventListener,this.addEventListener=function(a,b){return this.$forwardEvents[a]?this.renderer.addEventListener(a,b):this.$originalAddEventListener(a,b)},this.removeEventListener=function(a,b){return this.$forwardEvents[a]?this.renderer.removeEventListener(a,b):this.$originalRemoveEventListener(a,b)},this.setKeyboardHandler=function(a){this.keyBinding.setKeyboardHandler(a)},this.getKeyboardHandler=function(){return this.keyBinding.getKeyboardHandler()},this.setSession=function(a){if(this.session!=a){if(this.session){var b=this.session;this.session.removeEventListener("change",this.$onDocumentChange),this.session.removeEventListener("changeMode",this.$onDocumentModeChange),this.session.removeEventListener("changeTabSize",this.$onDocumentChangeTabSize),this.session.removeEventListener("changeWrapLimit",this.$onDocumentChangeWrapLimit),this.session.removeEventListener("changeWrapMode",this.$onDocumentChangeWrapMode),this.session.removeEventListener("changeFrontMarker",this.$onChangeFrontMarker),this.session.removeEventListener("changeBackMarker",this.$onChangeBackMarker),this.session.removeEventListener("changeBreakpoint",this.$onDocumentChangeBreakpoint),this.session.removeEventListener("changeAnnotation",this.$onDocumentChangeAnnotation);var c=this.session.getSelection();c.removeEventListener("changeCursor",this.$onCursorChange),c.removeEventListener("changeSelection",this.$onSelectionChange),this.session.setScrollTopRow(this.renderer.getScrollTopRow())}this.session=a,this.$onDocumentChange=this.onDocumentChange.bind(this),a.addEventListener("change",this.$onDocumentChange),this.renderer.setSession(a),this.$onDocumentModeChange=this.onDocumentModeChange.bind(this),a.addEventListener("changeMode",this.$onDocumentModeChange),this.$onDocumentChangeTabSize=this.renderer.updateText.bind(this.renderer),a.addEventListener("changeTabSize",this.$onDocumentChangeTabSize),this.$onDocumentChangeWrapLimit=this.onDocumentChangeWrapLimit.bind(this),a.addEventListener("changeWrapLimit",this.$onDocumentChangeWrapLimit),this.$onDocumentChangeWrapMode=this.onDocumentChangeWrapMode.bind(this),a.addEventListener("changeWrapMode",this.$onDocumentChangeWrapMode),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.$onDocumentChangeBreakpoint=this.onDocumentChangeBreakpoint.bind(this),this.session.addEventListener("changeBreakpoint",this.$onDocumentChangeBreakpoint),this.$onDocumentChangeAnnotation=this.onDocumentChangeAnnotation.bind(this),this.session.addEventListener("changeAnnotation",this.$onDocumentChangeAnnotation),this.selection=a.getSelection(),this.$onCursorChange=this.onCursorChange.bind(this),this.selection.addEventListener("changeCursor",this.$onCursorChange),this.$onSelectionChange=this.onSelectionChange.bind(this),this.selection.addEventListener("changeSelection",this.$onSelectionChange),this.onDocumentModeChange(),this.bgTokenizer.setDocument(a.getDocument()),this.bgTokenizer.start(0),this.onCursorChange(),this.onSelectionChange(),this.onChangeFrontMarker(),this.onChangeBackMarker(),this.onDocumentChangeBreakpoint(),this.onDocumentChangeAnnotation(),this.renderer.scrollToRow(a.getScrollTopRow()),this.renderer.updateFull(),this._dispatchEvent("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.setStyle=function(a){this.renderer.setStyle(a)},this.unsetStyle=function(a){this.renderer.unsetStyle(a)},this.$highlightBrackets=function(){this.session.$bracketHighlight&&(this.session.removeMarker(this.session.$bracketHighlight),this.session.$bracketHighlight=null);if(!this.$highlightPending){var a=this;this.$highlightPending=!0,setTimeout(function(){a.$highlightPending=!1;var b=a.session.findMatchingBracket(a.getCursorPosition());if(b){var c=new n(b.row,b.column,b.row,b.column+1);a.session.$bracketHighlight=a.session.addMarker(c,"ace_bracket")}},10)}},this.focus=function(){var a=this;setTimeout(function(){a.textInput.focus()}),this.textInput.focus()},this.blur=function(){this.textInput.blur()},this.onFocus=function(){this.renderer.showCursor(),this.renderer.visualizeFocus(),this._dispatchEvent("focus")},this.onBlur=function(){this.renderer.hideCursor(),this.renderer.visualizeBlur(),this._dispatchEvent("blur")},this.onDocumentChange=function(a){var b=a.data,c=b.range;this.bgTokenizer.start(c.start.row);if(c.start.row==c.end.row&&b.action!="insertLines"&&b.action!="removeLines")var d=c.end.row;else d=Infinity;this.renderer.updateLines(c.start.row,d),this.renderer.updateCursor(this.getCursorPosition(),this.$overwrite)},this.onTokenizerUpdate=function(a){var b=a.data;this.renderer.updateLines(b.first,b.last)},this.onCursorChange=function(a){this.renderer.updateCursor(this.getCursorPosition(),this.$overwrite),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),a.$highlightLineMarker=null;if(this.getHighlightActiveLine()&&(this.getSelectionStyle()!="line"||!this.selection.isMultiLine())){var b=this.getCursorPosition(),c=new n(b.row,0,b.row+1,0);a.$highlightLineMarker=a.addMarker(c,"ace_active_line","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)}this.onCursorChange(a),this.$highlightSelectedWord&&this.mode.highlightSelection(this)},this.onChangeFrontMarker=function(){this.renderer.updateFrontMarkers()},this.onChangeBackMarker=function(){this.renderer.updateBackMarkers()},this.onDocumentChangeBreakpoint=function(){this.renderer.setBreakpoints(this.session.getBreakpoints())},this.onDocumentChangeAnnotation=function(){this.renderer.setAnnotations(this.session.getAnnotations())},this.onDocumentModeChange=function(){var a=this.session.getMode();if(this.mode!=a){this.mode=a;var b=a.getTokenizer();if(this.bgTokenizer)this.bgTokenizer.setTokenizer(b);else{var c=this.onTokenizerUpdate.bind(this);this.bgTokenizer=new m(b,this),this.bgTokenizer.addEventListener("update",c)}this.renderer.setTokenizer(this.bgTokenizer)}},this.onDocumentChangeWrapLimit=function(){this.renderer.updateCursor(this.getCursorPosition(),this.$overwrite),this.renderer.updateFull()},this.onDocumentChangeWrapMode=function(){this.renderer.onResize(!0)},this.getCopyText=function(){return this.selection.isEmpty()?"":this.session.getTextRange(this.getSelectionRange())},this.onCut=function(){this.$readOnly||(this.selection.isEmpty()||(this.session.remove(this.getSelectionRange()),this.clearSelection()))},this.insert=function(a){if(!this.$readOnly){var b=this.getCursorPosition();a=a.replace("\t",this.session.getTabString());if(this.selection.isEmpty()){if(this.$overwrite){var c=new n.fromPoints(b,b);c.end.column+=a.length,this.session.remove(c)}}else{var b=this.session.remove(this.getSelectionRange());this.clearSelection()}this.clearSelection();var d=this.bgTokenizer.getState(b.row),e=this.mode.checkOutdent(d,this.session.getLine(b.row),a),f=this.session.getLine(b.row),g=this.mode.getNextLineIndent(d,f.slice(0,b.column),this.session.getTabString()),h=this.session.insert(b,a);this.moveCursorToPosition(h);var d=this.bgTokenizer.getState(b.row);if(b.row!==h.row){var i=this.session.getTabSize(),j=Number.MAX_VALUE;for(var k=b.row+1;k<=h.row;++k){var l=0;f=this.session.getLine(k);for(var m=0;m0;++m)f.charAt(m)=="\t"?o-=i:f.charAt(m)==" "&&(o-=1);this.session.remove(new n(k,0,k,m))}this.session.indentRows(b.row+1,h.row,g)}else e&&this.mode.autoOutdent(d,this.session,b.row)}},this.onTextInput=function(a){this.keyBinding.onTextInput(a)},this.onCommandKey=function(a,b,c){this.keyBinding.onCommandKey(a,b,c)},this.$overwrite=!1,this.setOverwrite=function(a){this.$overwrite!=a&&(this.$overwrite=a,this.$blockScrolling+=1,this.onCursorChange(),this.$blockScrolling-=1,this._dispatchEvent("changeOverwrite",{data:a}))},this.getOverwrite=function(){return this.$overwrite},this.toggleOverwrite=function(){this.setOverwrite(!this.$overwrite)},this.setScrollSpeed=function(a){this.$mouseHandler.setScrollSpeed(a)},this.getScrollSpeed=function(){return this.$mouseHandler.getScrollSpeed()},this.$selectionStyle="line",this.setSelectionStyle=function(a){this.$selectionStyle!=a&&(this.$selectionStyle=a,this.onSelectionChange(),this._dispatchEvent("changeSelectionStyle",{data:a}))},this.getSelectionStyle=function(){return this.$selectionStyle},this.$highlightActiveLine=!0,this.setHighlightActiveLine=function(a){this.$highlightActiveLine!=a&&(this.$highlightActiveLine=a,this.$updateHighlightActiveLine())},this.getHighlightActiveLine=function(){return this.$highlightActiveLine},this.$highlightSelectedWord=!0,this.setHighlightSelectedWord=function(a){this.$highlightSelectedWord!=a&&(this.$highlightSelectedWord=a,a?this.mode.highlightSelection(this):this.mode.clearSelectionHighlight(this))},this.getHighlightSelectedWord=function(){return this.$highlightSelectedWord},this.setShowInvisibles=function(a){this.getShowInvisibles()!=a&&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.removeRight=function(){this.$readOnly||(this.selection.isEmpty()&&this.selection.selectRight(),this.session.remove(this.getSelectionRange()),this.clearSelection())},this.removeLeft=function(){this.$readOnly||(this.selection.isEmpty()&&this.selection.selectLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection())},this.removeWordRight=function(){this.$readOnly||(this.selection.isEmpty()&&this.selection.selectWordRight(),this.session.remove(this.getSelectionRange()),this.clearSelection())},this.removeWordLeft=function(){this.$readOnly||(this.selection.isEmpty()&&this.selection.selectWordLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection())},this.removeToLineStart=function(){this.$readOnly||(this.selection.isEmpty()&&this.selection.selectLineStart(),this.session.remove(this.getSelectionRange()),this.clearSelection())},this.removeToLineEnd=function(){this.$readOnly||(this.selection.isEmpty()&&this.selection.selectLineEnd(),this.session.remove(this.getSelectionRange()),this.clearSelection())},this.splitLine=function(){if(!this.$readOnly){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.$readOnly){if(!this.selection.isEmpty())return;var a=this.getCursorPosition(),b=a.column;if(b==0)return;var c=this.session.getLine(a.row);if(b=b.end.row&&b.start.column>=b.end.column){var d;if(this.session.getUseSoftTabs()){var e=a.getTabSize(),g=this.getCursorPosition(),h=a.documentToScreenColumn(g.row,g.column),i=e-h%e;d=f.stringRepeat(" ",i)}else d="\t";return this.onTextInput(d)}var c=this.$getSelectedRows();a.indentRows(c.first,c.last,"\t")}},this.blockOutdent=function(){if(!this.$readOnly){var a=this.session.getSelection();this.session.outdentRows(a.getRange())}},this.toggleCommentLines=function(){if(!this.$readOnly){var a=this.bgTokenizer.getState(this.getCursorPosition().row),b=this.$getSelectedRows();this.mode.toggleCommentLines(a,this.session,b.first,b.last)}},this.removeLines=function(){if(!this.$readOnly){var a=this.$getSelectedRows();this.session.remove(new n(a.first,0,a.last+1,0)),this.clearSelection()}},this.moveLinesDown=function(){this.$readOnly||this.$moveLines(function(a,b){return this.session.moveLinesDown(a,b)})},this.moveLinesUp=function(){this.$readOnly||this.$moveLines(function(a,b){return this.session.moveLinesUp(a,b)})},this.copyLinesUp=function(){this.$readOnly||this.$moveLines(function(a,b){this.session.duplicateLines(a,b);return 0})},this.copyLinesDown=function(){this.$readOnly||this.$moveLines(function(a,b){return this.session.duplicateLines(a,b)})},this.$moveLines=function(a){var b=this.$getSelectedRows(),c=a.call(this,b.first,b.last),d=this.selection;d.setSelectionAnchor(b.last+c+1,0),d.$moveSelection(function(){d.moveCursorTo(b.first+c,0)})},this.$getSelectedRows=function(){var a=this.getSelectionRange().collapseRows();return{first:a.start.row,last:a.end.row}},this.onCompositionStart=function(a){this.renderer.showComposition(this.getCursorPosition())},this.onCompositionUpdate=function(a){this.renderer.setCompositionText(a)},this.onCompositionEnd=function(){this.renderer.hideComposition()},this.getFirstVisibleRow=function(){return this.renderer.getFirstVisibleRow()},this.getLastVisibleRow=function(){return this.renderer.getLastVisibleRow()},this.isRowVisible=function(a){return a>=this.getFirstVisibleRow()&&a<=this.getLastVisibleRow()},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.gotoLine=function(a,b){this.selection.clearSelection(),this.$blockScrolling+=1,this.moveCursorTo(a-1,b||0),this.$blockScrolling-=1,this.isRowVisible(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()){a=a||1;while(a--)this.selection.moveCursorLeft()}else{var b=this.getSelectionRange().start;this.moveCursorToPosition(b)}this.clearSelection()},this.navigateRight=function(a){if(this.selection.isEmpty()){a=a||1;while(a--)this.selection.moveCursorRight()}else{var b=this.getSelectionRange().end;this.moveCursorToPosition(b)}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);this.$tryReplace(c,a),c!==null&&this.selection.setSelectionRange(c)},this.replaceAll=function(a,b){b&&this.$search.set(b);var c=this.$search.findAll(this.session);if(c.length){var d=this.getSelectionRange();this.clearSelection(),this.selection.moveCursorTo(0,0),this.$blockScrolling+=1;for(var e=c.length-1;e>=0;--e)this.$tryReplace(c[e],a);this.selection.setSelectionRange(d),this.$blockScrolling-=1}},this.$tryReplace=function(a,b){var c=this.session.getTextRange(a),b=this.$search.replace(c,b);if(b!==null){a.end=this.session.replace(a,b);return a}return 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);b&&(this.gotoLine(b.end.row+1,b.end.column),this.selection.setSelectionRange(b))},this.undo=function(){this.session.getUndoManager().undo()},this.redo=function(){this.session.getUndoManager().redo()}}).call(p.prototype),b.Editor=p}),__ace_shadowed__.define("pilot/event",function(a,b,c){function g(a,b,c){var f=0;e.isOpera&&e.isMac?f=0|(b.metaKey?1:0)|(b.altKey?2:0)|(b.shiftKey?4:0)|(b.ctrlKey?8:0):f=0|(b.ctrlKey?1:0)|(b.altKey?2:0)|(b.shiftKey?4:0)|(b.metaKey?8:0);if(c in d.MODIFIER_KEYS){switch(d.MODIFIER_KEYS[c]){case"Alt":f=2;break;case"Shift":f=4;break;case"Ctrl":f=1;break;default:f=8}c=0}f&8&&(c==91||c==93)&&(c=0);if(f==0&&!(c in d.FUNCTION_KEYS))return!1;return a(b,f,c)}var d=a("pilot/keys"),e=a("pilot/useragent"),f=a("pilot/dom");b.addListener=function(a,b,c){if(a.addEventListener)return a.addEventListener(b,c,!1);if(a.attachEvent){var d=function(){c(window.event)};c._wrapper=d,a.attachEvent("on"+b,d)}},b.removeListener=function(a,b,c){if(a.removeEventListener)return a.removeEventListener(b,c,!1);a.detachEvent&&a.detachEvent("on"+b,c._wrapper||c)},b.stopEvent=function(a){b.stopPropagation(a),b.preventDefault(a);return!1},b.stopPropagation=function(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0},b.preventDefault=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1},b.getDocumentX=function(a){return a.clientX?a.clientX+f.getPageScrollLeft():a.pageX},b.getDocumentY=function(a){return a.clientY?a.clientY+f.getPageScrollTop():a.pageY},b.getButton=function(a){if(a.type=="dblclick")return 0;if(a.type=="contextmenu")return 2;return a.preventDefault?a.button:({1:0,2:2,4:1})[a.button]},document.documentElement.setCapture?b.capture=function(a,c,d){function f(e){c&&c(e),d&&d(),b.removeListener(a,"mousemove",c),b.removeListener(a,"mouseup",f),b.removeListener(a,"losecapture",f),a.releaseCapture()}function e(a){c(a);return b.stopPropagation(a)}b.addListener(a,"mousemove",c),b.addListener(a,"mouseup",f),b.addListener(a,"losecapture",f),a.setCapture()}:b.capture=function(a,b,c){function e(a){b&&b(a),c&&c(),document.removeEventListener("mousemove",d,!0),document.removeEventListener("mouseup",e,!0),a.stopPropagation()}function d(a){b(a),a.stopPropagation()}document.addEventListener("mousemove",d,!0),document.addEventListener("mouseup",e,!0)},b.addMouseWheelListener=function(a,c){var d=function(a){a.wheelDelta!==undefined?a.wheelDeltaX!==undefined?(a.wheelX=-a.wheelDeltaX/8,a.wheelY=-a.wheelDeltaY/8):(a.wheelX=0,a.wheelY=-a.wheelDelta/8):a.axis&&a.axis==a.HORIZONTAL_AXIS?(a.wheelX=(a.detail||0)*5,a.wheelY=0):(a.wheelX=0,a.wheelY=(a.detail||0)*5),c(a)};b.addListener(a,"DOMMouseScroll",d),b.addListener(a,"mousewheel",d)},b.addMultiMouseDownListener=function(a,c,d,f,g){var h=0,i,j,k=function(a){h+=1,h==1&&(i=a.clientX,j=a.clientY,setTimeout(function(){h=0},f||600));if(b.getButton(a)!=c||Math.abs(a.clientX-i)>5||Math.abs(a.clientY-j)>5)h=0;h==d&&(h=0,g(a));return b.preventDefault(a)};b.addListener(a,"mousedown",k),e.isIE&&b.addListener(a,"dblclick",k)},b.addCommandKeyListener=function(a,c){var d=b.addListener;if(e.isOldGecko){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){h=a.keyIdentifier||a.keyCode;return g(c,a,a.keyCode)}),e.isMac&&e.isOpera&&d(a,"keypress",function(a){var b=a.keyIdentifier||a.keyCode;if(h!==b)return g(c,a,a.keyCode);h=null})}}}),__ace_shadowed__.define("pilot/keys",function(a,b,c){var d=a("pilot/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",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(i in a.FUNCTION_KEYS){var b=a.FUNCTION_KEYS[i].toUpperCase();a[b]=parseInt(i,10)}d.mixin(a,a.MODIFIER_KEYS),d.mixin(a,a.PRINTABLE_KEYS),d.mixin(a,a.FUNCTION_KEYS);return a}();d.mixin(b,e)}),__ace_shadowed__.define("pilot/dom",function(a,b,c){b.setText=function(a,b){a.innerText!==undefined&&(a.innerText=b),a.textContent!==undefined&&(a.textContent=b)},document.documentElement.classList?(b.hasCssClass=function(a,b){return a.classList.contains(b)},b.addCssClass=function(a,b){a.classList.add(b)},b.removeCssClass=function(a,b){a.classList.remove(b)},b.toggleCssClass=function(a,b){return a.classList.toggle(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);while(!0){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;while(!0){var e=c.indexOf(b);if(e==-1)break;d=!1,c.splice(e,1)}d&&c.push(b),a.className=c.join(" ");return d}),b.setCssClass=function(a,c,d){d?b.addCssClass(a,c):b.removeCssClass(a,c)},b.importCssString=function(a,b){b=b||document;if(b.createStyleSheet){var c=b.createStyleSheet();c.cssText=a}else{var d=b.createElement("style");d.appendChild(b.createTextNode(a)),b.getElementsByTagName("head")[0].appendChild(d)}},b.getInnerWidth=function(a){return parseInt(b.computedStyle(a,"paddingLeft"))+parseInt(b.computedStyle(a,"paddingRight"))+a.clientWidth},b.getInnerHeight=function(a){return parseInt(b.computedStyle(a,"paddingTop"))+parseInt(b.computedStyle(a,"paddingBottom"))+a.clientHeight},window.pageYOffset!==undefined?(b.getPageScrollTop=function(){return window.pageYOffset},b.getPageScrollLeft=function(){return window.pageXOffset}):(b.getPageScrollTop=function(){return document.body.scrollTop},b.getPageScrollLeft=function(){return document.body.scrollLeft}),b.computedStyle=function(a,b){return window.getComputedStyle?(window.getComputedStyle(a,"")||{})[b]||"":a.currentStyle[b]},b.scrollbarWidth=function(){var a=document.createElement("p");a.style.width="100%",a.style.height="200px";var b=document.createElement("div"),c=b.style;c.position="absolute",c.left="-10000px",c.overflow="hidden",c.width="200px",c.height="150px",b.appendChild(a),document.body.appendChild(b);var d=a.offsetWidth;c.overflow="scroll";var e=a.offsetWidth;d==e&&(e=b.clientWidth),document.body.removeChild(b);return d-e},b.setInnerHtml=function(a,b){var c=a.cloneNode(!1);c.innerHTML=b,a.parentNode.replaceChild(c,a);return c},b.setInnerText=function(a,b){"textContent"in document.body?a.textContent=b:a.innerText=b},b.getInnerText=function(a){return"textContent"in document.body?a.textContent:a.innerText},b.getParentWindow=function(a){return a.defaultView||a.parentWindow},b.getSelectionStart=function(a){var b;try{b=a.selectionStart||0}catch(c){b=0}return b},b.setSelectionStart=function(a,b){return a.selectionStart=b},b.getSelectionEnd=function(a){var b;try{b=a.selectionEnd||0}catch(c){b=0}return b},b.setSelectionEnd=function(a,b){return a.selectionEnd=b}}),__ace_shadowed__.define("ace/keyboard/textinput",function(a,b,c){var d=a("pilot/event"),e=a("pilot/useragent"),f=function(a,b){function j(a){if(!h){var d=a||c.value;d&&(d.charCodeAt(d.length-1)==f.charCodeAt(0)?(d=d.slice(0,-1),d&&b.onTextInput(d)):b.onTextInput(d))}h=!1,c.value=f,c.select()}var c=document.createElement("textarea");c.style.left="-10000px",a.appendChild(c);var f=String.fromCharCode(0);j();var g=!1,h=!1,i="",k=function(a){(!e.isIE||c.value.charCodeAt(0)<=128)&&setTimeout(function(){g||j()},0)},l=function(a){g=!0,e.isIE||(j(),c.value=""),b.onCompositionStart(),e.isGecko||setTimeout(m,0)},m=function(){g&&b.onCompositionUpdate(c.value)},n=function(){g=!1,b.onCompositionEnd(),setTimeout(function(){j()},0)},o=function(a){h=!0;var d=b.getCopyText();d?c.value=d:a.preventDefault(),c.select(),setTimeout(function(){j()},0)},p=function(a){h=!0;var d=b.getCopyText();d?(c.value=d,b.onCut()):a.preventDefault(),c.select(),setTimeout(function(){j()},0)};d.addCommandKeyListener(c,b.onCommandKey.bind(b)),d.addListener(c,"keypress",k);if(e.isIE){var q={13:1,27:1};d.addListener(c,"keyup",function(a){g&&(!c.value||q[a.keyCode])&&setTimeout(n,0);(c.value.charCodeAt(0)|0)>=129&&(g?m():l())})}d.addListener(c,"textInput",k),d.addListener(c,"paste",function(a){a.clipboardData&&a.clipboardData.getData?(j(a.clipboardData.getData("text/plain")),a.preventDefault()):k()}),e.isIE||d.addListener(c,"propertychange",k),e.isIE?(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",o),d.addListener(c,"cut",p)),d.addListener(c,"compositionstart",l),e.isGecko&&d.addListener(c,"text",m),e.isWebKit&&d.addListener(c,"keyup",m),d.addListener(c,"compositionend",n),d.addListener(c,"blur",function(){b.onBlur()}),d.addListener(c,"focus",function(){b.onFocus(),c.select()}),this.focus=function(){b.onFocus(),c.select(),c.focus()},this.blur=function(){c.blur()},this.getElement=function(){return c},this.onContextMenu=function(a,b){a&&(i||(i=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(){i&&(c.style.cssText=i,i=""),j()},0)}};b.TextInput=f}),__ace_shadowed__.define("ace/mouse_handler",function(a,b,c){var d=a("pilot/event"),e=function(a){this.editor=a,d.addListener(a.container,"mousedown",function(b){a.focus();return d.preventDefault(b)}),d.addListener(a.container,"selectstart",function(a){return d.preventDefault(a)});var b=a.renderer.getMouseEventTarget();d.addListener(b,"mousedown",this.onMouseDown.bind(this)),d.addMultiMouseDownListener(b,0,2,500,this.onMouseDoubleClick.bind(this)),d.addMultiMouseDownListener(b,0,3,600,this.onMouseTripleClick.bind(this)),d.addMouseWheelListener(b,this.onMouseWheel.bind(this))};(function(){this.$scrollSpeed=1,this.setScrollSpeed=function(a){this.$scrollSpeed=a},this.getScrollSpeed=function(){return this.$scrollSpeed},this.onMouseDown=function(a){var b=d.getDocumentX(a),c=d.getDocumentY(a),e=this.editor,f=e.renderer.screenToTextCoordinates(b,c);f.row=Math.max(0,Math.min(f.row,e.session.getLength()-1));var g=d.getButton(a);{if(g==0){a.shiftKey?e.selection.selectToPosition(f):(e.moveCursorToPosition(f),e.$clickSelection||e.selection.clearSelection(f.row,f.column)),e.renderer.scrollCursorIntoView();var i=this,j,k,l=function(a){j=d.getDocumentX(a),k=d.getDocumentY(a)},m=function(){clearInterval(o),i.$clickSelection=null},n=function(){if(j!==undefined&&k!==undefined){var a=e.renderer.screenToTextCoordinates(j,k);a.row=Math.max(0,Math.min(a.row,e.session.getLength()-1));if(i.$clickSelection)if(i.$clickSelection.contains(a.row,a.column))e.selection.setSelectionRange(i.$clickSelection);else{if(i.$clickSelection.compare(a.row,a.column)==-1)var b=i.$clickSelection.end;else var b=i.$clickSelection.start;e.selection.setSelectionAnchor(b.row,b.column),e.selection.selectToPosition(a)}else e.selection.selectToPosition(a);e.renderer.scrollCursorIntoView()}};d.capture(e.container,l,m);var o=setInterval(n,20);return d.preventDefault(a)}var h=e.selection.isEmpty();h&&e.moveCursorToPosition(f),g==2&&(e.textInput.onContextMenu({x:b,y:c},h),d.capture(e.container,function(){},e.textInput.onContextMenuClose))}},this.onMouseDoubleClick=function(a){this.editor.selection.selectWord(),this.$clickSelection=this.editor.getSelectionRange()},this.onMouseTripleClick=function(a){this.editor.selection.selectLine(),this.$clickSelection=this.editor.getSelectionRange()},this.onMouseWheel=function(a){var b=this.$scrollSpeed*2;this.editor.renderer.scrollBy(a.wheelX*b,a.wheelY*b);return d.preventDefault(a)}}).call(e.prototype),b.MouseHandler=e}),__ace_shadowed__.define("ace/keyboard/keybinding",function(a,b,c){var d=a("pilot/useragent"),e=a("pilot/keys"),f=a("pilot/event"),g=a("pilot/settings").settings,h=a("ace/keyboard/hash_handler").HashHandler,i=a("ace/keyboard/keybinding/default_mac").bindings,j=a("ace/keyboard/keybinding/default_win").bindings,k=a("pilot/canon");a("ace/commands/default_commands");var l=function(a,b){this.$editor=a,this.$data={},this.$keyboardHandler=null,this.$defaulKeyboardHandler=new h(b||(d.isMac?i:j))};(function(){this.setKeyboardHandler=function(a){this.$keyboardHandler!=a&&(this.$data={},this.$keyboardHandler=a)},this.getKeyboardHandler=function(){return this.$keyboardHandler},this.$callKeyboardHandler=function(a,b,c,d){var e;this.$keyboardHandler&&(e=this.$keyboardHandler.handleKeyboard(this.$data,b,c,d,a));if(!e||!e.command)e=this.$defaulKeyboardHandler.handleKeyboard(this.$data,b,c,d,a);if(e){var g=k.exec(e.command,{editor:this.$editor},e.args);if(g)return f.stopEvent(a)}},this.onCommandKey=function(a,b,c){key=(e[c]||String.fromCharCode(c)).toLowerCase(),this.$callKeyboardHandler(a,b,key,c)},this.onTextInput=function(a){this.$callKeyboardHandler({},0,a,0)}}).call(l.prototype),b.KeyBinding=l}),__ace_shadowed__.define("ace/keyboard/hash_handler",function(a,b,c){function e(a){this.setConfig(a)}var d=a("pilot/keys");(function(){function c(a,c){var d,e,f,g,h={};for(d in a){g=a[d];if(c&&typeof g=="string"){g=g.split(c);for(e=0,f=g.length;e0&&a.execute({action:"aceupdate",args:[b.$deltas,b]}),b.$deltas=[]})}},this.$defaultUndoManager={undo:function(){},redo:function(){}},this.getUndoManager=function(){return this.$undoManager||this.$defaultUndoManager},this.getTabString=function(){return this.getUseSoftTabs()?e.stringRepeat(" ",this.getTabSize()):"\t"},this.$useSoftTabs=!0,this.setUseSoftTabs=function(a){this.$useSoftTabs!==a&&(this.$useSoftTabs=a)},this.getUseSoftTabs=function(){return this.$useSoftTabs},this.$tabSize=4,this.setTabSize=function(a){!isNaN(a)&&this.$tabSize!==a&&(this.$modified=!0,this.$tabSize=a,this._dispatchEvent("changeTabSize"))},this.getTabSize=function(){return this.$tabSize},this.isTabStop=function(a){return this.$useSoftTabs&&a.column%this.$tabSize==0},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=0){var h=g.charAt(d);if(h==c){f-=1;if(f==0)return{row:e,column:d}}else h==a&&(f+=1);d-=1}e-=1;if(e<0)break;var g=this.getLine(e),d=g.length-1}return null},this.$findClosingBracket=function(a,b){var c=this.$brackets[a],d=b.column,e=b.row,f=1,g=this.getLine(e),h=this.getLength();while(!0){while(d=h)break;var g=this.getLine(e),d=0}return null},this.insert=function(a,b){return this.doc.insert(a,b)},this.remove=function(a){return this.doc.remove(a)},this.undoChanges=function(a){if(a.length){this.$fromUndo=!0,this.doc.revertDeltas(a),this.$fromUndo=!1;var b=a[0],c=a[a.length-1];this.selection.clearSelection(),(b.action=="insertText"||b.action=="insertLines")&&this.selection.moveCursorToPosition(b.range.start),(b.action=="removeText"||b.action=="removeLines")&&this.selection.setSelectionRange(j.fromPoints(c.range.start,b.range.end))}},this.redoChanges=function(a){if(a.length){this.$fromUndo=!0,this.doc.applyDeltas(a),this.$fromUndo=!1;var b=a[0],c=a[a.length-1];this.selection.clearSelection(),(b.action=="insertText"||b.action=="insertLines")&&this.selection.setSelectionRange(j.fromPoints(b.range.start,c.range.end)),(b.action=="removeText"||b.action=="removeLines")&&this.selection.moveCursorToPosition(c.range.start)}},this.replace=function(a,b){return this.doc.replace(a,b)},this.indentRows=function(a,b,c){c=c.replace(/\t/g,this.getTabString());for(var d=a;d<=b;d++)this.insert({row:d,column:0},c)},this.outdentRows=function(a){var b=a.collapseRows(),c=new j(0,0,0,0),d=this.getTabSize();for(var e=b.start.row;e<=b.end.row;++e){var f=this.getLine(e);c.start.row=e,c.end.row=e;for(var g=0;g=this.doc.getLength()-1)return 0;var c=this.doc.removeLines(a,b);this.doc.insertLines(a+1,c);return 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.$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;if(a){var b=this.getLength();this.$wrapData=[];for(i=0;i0){this.$wrapLimit=b,this.$modified=!0,this.$useWrapMode&&(this.$updateWrapData(0,this.getLength()-1),this._dispatchEvent("changeWrapLimit"));return!0}return!1},this.$constrainWrapLimit=function(a){var b=this.$wrapLimitRange.min;b&&(a=Math.max(b,a));var c=this.$wrapLimitRange.max;c&&(a=Math.min(c,a));return Math.max(1,a)},this.getWrapLimit=function(){return this.$wrapLimit},this.getWrapLimitRange=function(){return{min:this.$wrapLimitRange.min,max:this.$wrapLimitRange.max}},this.$updateWrapDataOnChange=function(a){if(this.$useWrapMode){var b,c=a.data.action,d=a.data.range.start.row,e=a.data.range.end.row;c.indexOf("Lines")!=-1?(c=="insertLines"?e=d+a.data.lines.length:e=d,b=a.data.lines.length):b=e-d;if(b!=0)if(c.indexOf("remove")!=-1)this.$wrapData.splice(d,b),e=d;else{var f=[d,0];for(var g=0;gb){var k=h+b;if(e[k]=g){k++;break}k>h?j(k):j(h+b)}else{while(e[k]>=g)k++;j(k)}}return d},this.$getDisplayTokens=function(a){var d=[],e=this.getTabSize();for(var f=0;f=12352&&h<=12447||h>=12448&&h<=12543||h>=19968&&h<=40959||h>=63744&&h<=64255||h>=13312&&h<=19903?d.push(b,c):d.push(b)}return d},this.$getStringScreenWidth=function(a){var b=0,c=this.getTabSize();for(var d=0;d=12352&&e<=12447||e>=12448&&e<=12543||e>=19968&&e<=40959||e>=63744&&e<=64255||e>=13312&&e<=19903?b+=2:b+=1}return b},this.getRowHeight=function(a,b){var c;this.$useWrapMode&&this.$wrapData[b]?c=this.$wrapData[b].length+1:c=1;return c*a.lineHeight},this.getScreenLastRowColumn=function(a,b){if(!this.$useWrapMode)return this.$getStringScreenWidth(this.getLine(a));var c=this.$screenToDocumentRow(a),d=c[0],e=c[1],f,g;this.$wrapData[d][e]?(f=this.$wrapData[d][e-1]||0,g=this.$wrapData[d][e],b&&g--):(g=this.getLine(d).length,f=this.$wrapData[d][e-1]||0);return b?g:this.$getStringScreenWidth(this.getLine(d).substring(f,g))},this.getDocumentLastRowColumn=function(a,b){if(!this.$useWrapMode)return this.getLine(a).length;var c=this.documentToScreenRow(a,b);return this.getScreenLastRowColumn(c,!0)},this.getScreenFirstRowColumn=function(a){if(!this.$useWrapMode)return 0;var b=this.$screenToDocumentRow(a),c=b[0],d=b[1];return this.$wrapData[c][d-1]||0},this.getRowSplitData=function(a){return this.$useWrapMode?this.$wrapData[a]:undefined},this.$screenToDocumentRow=function(a){if(!this.$useWrapMode)return[a,0];var b=this.$wrapData,c=this.getLength(),d=0;while(d=b[d].length+1)a-=b[d].length+1,d++;return[d,a]},this.screenToDocumentRow=function(a){return this.$screenToDocumentRow(a)[0]},this.screenToDocumentColumn=function(a,b){return this.screenToDocumentPosition(a,b).column},this.screenToDocumentPosition=function(a,b){var c,d,e,f=b,g=this.getLength();if(this.$useWrapMode){var h=this.$wrapData,d=0;while(d=h[d].length+1)a-=h[d].length+1,d++;d>=g&&(d=g-1,a=h[d].length),e=h[d][a-1]||0,c=this.getLine(d).substring(e)}else d=a>=g?g-1:a<0?0:a,a=0,e=0,c=this.getLine(d);var i=this.getTabSize();for(var j=0;j0)e+=1,k==9?f=12352&&k<=12447||k>=12448&&k<=12543||k>=19968&&k<=40959||k>=63744&&k<=64255||k>=13312&&k<=19903?f<2?(f=0,e-=1):f-=2:f-=1;else break}this.$useWrapMode?(b=h[d][a],e>=b&&(e=b-1)):c&&(e=Math.min(e,c.length));return{row:d,column:e}},this.documentToScreenColumn=function(a,b){return this.documentToScreenPosition(a,b).column},this.$documentToScreenRow=function(a,b){if(!this.$useWrapMode)return[a,0];var c=this.$wrapData,d=0;if(a>c.length-1)return[this.getScreenLength(),c.length==0?0:c[c.length-1].length-1];for(var e=0;e=c[a][f])d++,f++;return[d,f]},this.documentToScreenRow=function(a,b){return this.$documentToScreenRow(a,b)[0]},this.documentToScreenPosition=function(a,b){var c,d=this.getTabSize(),e;b!=null?e=a:(e=a.row,b=a.column);if(!this.$useWrapMode){c=this.getLine(e).substring(0,b),b=this.$getStringScreenWidth(c);return{row:e,column:b}}var f=this.$documentToScreenRow(e,b),g=f[0];if(e>=this.getLength())return{row:g,column:0};var h,i=this.$wrapData[e],j,k=f[1];c=this.getLine(e).substring(i[k-1]||0,b),j=this.$getStringScreenWidth(c);return{row:g,column:j}},this.getScreenLength=function(){if(!this.$useWrapMode)return this.getLength();var a=0;for(var b=0;bb.row||a.row==b.row&&a.column>b.column},this.getRange=function(){var a=this.selectionAnchor,b=this.selectionLead;if(this.isEmpty())return g.fromPoints(b,b);return this.isBackwards()?g.fromPoints(b,a):g.fromPoints(a,b)},this.clearSelection=function(){this.$isEmpty||(this.$isEmpty=!0,this._dispatchEvent("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.$updateDesiredColumn()},this.$updateDesiredColumn=function(){var a=this.getCursor();this.$desiredColumn=this.session.documentToScreenColumn(a.row,a.column)},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.selectLine=function(){this.setSelectionAnchor(this.selectionLead.row,0),this.$moveSelection(function(){this.moveCursorTo(this.selectionLead.row+1,0)})},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.moveCursorLeft=function(){var a=this.selectionLead.getPosition();if(a.column==0)a.row>0&&this.moveCursorTo(a.row-1,this.doc.getLine(a.row-1).length);else{var b=this.session.getTabSize();this.session.isTabStop(a)&&this.doc.getLine(a.row).slice(a.column-b,a.column).split(" ").length-1==b?this.moveCursorBy(0,-b):this.moveCursorBy(0,-1)}},this.moveCursorRight=function(){if(this.selectionLead.column==this.doc.getLine(this.selectionLead.row).length)this.selectionLead.row ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(a,b){return this.compare(a,b)==0},this.compare=function(a,b){if(!this.isMultiLine())if(a===this.start.row)return bthis.end.column?1:0;if(athis.end.row)return 1;if(this.start.row===a)return b>=this.start.column?0:-1;if(this.end.row===a)return b<=this.end.column?0:1;return 0},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.rowthis.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&&c.start.rowd?(d=c.start.row,e=0):d-=c.end.row-c.start.row)),this.setPosition(d,e)}},this.setPosition=function(a,b){pos=this.$clipPositionToDocument(a,b);if(this.row!=pos.row||this.column!=pos.column){var c={row:this.row,column:this.column};this.row=pos.row,this.column=pos.column,this._dispatchEvent("change",{old:c,value:pos})}},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.$clipPositionToDocument=function(a,b){var c={};a=0&&!/[^\w\d]/.test(h.charAt(0))||e<=g&&!/[^\w\d]/.test(h.charAt(h.length-1)))return;h=f.substring(c.start.column,c.end.column);if(!/^[\w\d]+$/.test(h))return;var i={wrap:!0,wholeWord:!0,needle:h},j=a.$search.getOptions();a.$search.set(i);var k=a.$search.findAll(b);b.$selectionOccurrences=[],k.forEach(function(a){if(!a.contains(c.start.row,c.start.column)){var d=b.addMarker(a,"ace_selected_word");b.$selectionOccurrences.push(d)}}),a.$search.set(j)}},this.clearSelectionHighlight=function(a){a.session.$selectionOccurrences&&a.session.$selectionOccurrences.forEach(function(b){a.session.removeMarker(b)})}}).call(f.prototype),b.Mode=f}),__ace_shadowed__.define("ace/tokenizer",function(a,b,c){var d=function(a){this.rules=a,this.regExps={};for(var b in this.rules){var c=this.rules[b],d=[];for(var e=0;e=b&&(a.row=Math.max(0,b-1),a.column=this.getLine(b-1).length);return a},this.insert=function(a,b){if(b.length==0)return a;a=this.$clipPosition(a),this.getLength()<=1&&this.$detectNewLine(b);var c=this.$split(b);if(this.isNewLine(b))var d=this.insertNewLine(a);else if(c.length==1)var d=this.insertInLine(a,b);else{if(c[0].length>0){var d=this.insertInLine(a,c[0]);this.insertNewLine(d)}if(a.row+1==this.getLength()){this.insertLines(a.row+1,c.slice(1,c.length));var d={row:a.row+c.length-1,column:a.column+c[c.length-1].length}}else{c.length>2&&this.insertLines(a.row+1,c.slice(1,c.length-1));var d=this.insertInLine({row:a.row+c.length-1,column:0},c[c.length-1])}}return d},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};this._dispatchEvent("change",{data:e});return 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()};this._dispatchEvent("change",{data:d});return 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};this._dispatchEvent("change",{data:e});return 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){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};this._dispatchEvent("change",{data:i});return 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};this._dispatchEvent("change",{data:e});return 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._dispatchEvent("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(g.prototype),b.Document=g}),__ace_shadowed__.define("ace/search",function(a,b,c){var d=a("pilot/lang"),e=a("pilot/oop"),f=a("ace/range").Range,g=function(){this.$options={needle:"",backwards:!1,wrap:!1,caseSensitive:!1,wholeWord:!1,scope:g.ALL,regExp:!1}};g.ALL=1,g.SELECTION=2,function(){this.set=function(a){e.mixin(this.$options,a);return this},this.getOptions=function(){return d.copyObject(this.$options)},this.find=function(a){if(!this.$options.needle)return null;if(this.$options.backwards)var b=this.$backwardMatchIterator(a);else b=this.$forwardMatchIterator(a);var c=null;b.forEach(function(a){c=a;return!0});return c},this.findAll=function(a){if(!this.$options.needle)return[];if(this.$options.backwards)var b=this.$backwardMatchIterator(a);else b=this.$forwardMatchIterator(a);var c=[];b.forEach(function(a){c.push(a)});return c},this.replace=function(a,b){var c=this.$assembleRegExp(),d=c.exec(a);return d&&d[0].length==a.length?this.$options.regExp?a.replace(c,b):b:null},this.$forwardMatchIterator=function(a){var b=this.$assembleRegExp(),c=this;return{forEach:function(d){c.$forwardLineIterator(a).forEach(function(a,e,f){e&&(a=a.substring(e));var g=[];a.replace(b,function(a){var b=arguments[arguments.length-2];g.push({str:a,offset:e+b});return a});for(var h=0;h=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 j(d){var e=a.getLine(d);b&&d==c.end.row&&(e=e.substring(0,c.end.column));return e}var b=this.$options.scope==g.SELECTION,c=a.getSelection().getRange(),d=a.getSelection().getCursor(),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(a){var b=d.row,c=j(b),g=d.column,k=!1;while(!a(c,g,b)){if(k)return;b++,g=0;if(b>h)if(i)b=e,g=f;else return;b==d.row&&(k=!0),c=j(b)}}}},this.$backwardLineIterator=function(a){var b=this.$options.scope==g.SELECTION,c=a.getSelection().getRange(),d=b?c.end:c.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;while(!g(k,l,j)){if(m)return;j--,l=0;if(j20){c.fireUpdateEvent(d,c.currentLine-1);var i=c.currentLine0&&this.lines[a-1]&&(d=this.lines[a-1].state,e=!0);var f=this.doc.getLines(a,b);for(var g=a;g<=b;g++)if(this.lines[g]){var h=this.lines[g];d=h.state,c.push(h)}else{var h=this.tokenizer.getLineTokens(f[g-a]||"",d),d=h.state;c.push(h),e&&(this.lines[g]=h)}return c}}).call(f.prototype),b.BackgroundTokenizer=f}),__ace_shadowed__.define("ace/undomanager",function(a,b,c){var d=function(){this.$undoStack=[],this.$redoStack=[]};(function(){this.execute=function(a){var b=a.args[0];this.$doc=a.args[1],this.$undoStack.push(b)},this.undo=function(){var a=this.$undoStack.pop();a&&(this.$doc.undoChanges(a),this.$redoStack.push(a))},this.redo=function(){var a=this.$redoStack.pop();a&&(this.$doc.redoChanges(a),this.$undoStack.push(a))}}).call(d.prototype),b.UndoManager=d}),__ace_shadowed__.define("ace/theme/textmate",function(a,b,c){var d=a("pilot/dom"),e=".ace-tm .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-tm .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-tm .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-tm .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-tm .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-tm .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-tm .ace_text-layer {\n cursor: text;\n}\n\n.ace-tm .ace_cursor {\n border-left: 2px solid black;\n}\n\n.ace-tm .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid black;\n}\n \n.ace-tm .ace_line .ace_invisible {\n color: rgb(191, 191, 191);\n}\n\n.ace-tm .ace_line .ace_keyword {\n color: blue;\n}\n\n.ace-tm .ace_line .ace_constant.ace_buildin {\n color: rgb(88, 72, 246);\n}\n\n.ace-tm .ace_line .ace_constant.ace_language {\n color: rgb(88, 92, 246);\n}\n\n.ace-tm .ace_line .ace_constant.ace_library {\n color: rgb(6, 150, 14);\n}\n\n.ace-tm .ace_line .ace_invalid {\n background-color: rgb(153, 0, 0);\n color: white;\n}\n\n.ace-tm .ace_line .ace_support.ace_function {\n color: rgb(60, 76, 114);\n}\n\n.ace-tm .ace_line .ace_support.ace_constant {\n color: rgb(6, 150, 14);\n}\n\n.ace-tm .ace_line .ace_support.ace_type,\n.ace-tm .ace_line .ace_support.ace_class {\n color: rgb(109, 121, 222);\n}\n\n.ace-tm .ace_line .ace_keyword.ace_operator {\n color: rgb(104, 118, 135);\n}\n\n.ace-tm .ace_line .ace_string {\n color: rgb(3, 106, 7);\n}\n\n.ace-tm .ace_line .ace_comment {\n color: rgb(76, 136, 107);\n}\n\n.ace-tm .ace_line .ace_comment.ace_doc {\n color: rgb(0, 102, 255);\n}\n\n.ace-tm .ace_line .ace_comment.ace_doc.ace_tag {\n color: rgb(128, 159, 191);\n}\n\n.ace-tm .ace_line .ace_constant.ace_numeric {\n color: rgb(0, 0, 205);\n}\n\n.ace-tm .ace_line .ace_variable {\n color: rgb(49, 132, 149);\n}\n\n.ace-tm .ace_line .ace_xml_pe {\n color: rgb(104, 104, 91);\n}\n\n.ace-tm .ace_marker-layer .ace_selection {\n background: rgb(181, 213, 255);\n}\n\n.ace-tm .ace_marker-layer .ace_step {\n background: rgb(252, 255, 0);\n}\n\n.ace-tm .ace_marker-layer .ace_stack {\n background: rgb(164, 229, 101);\n}\n\n.ace-tm .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-tm .ace_marker-layer .ace_active_line {\n background: rgb(232, 242, 254);\n}\n\n.ace-tm .ace_marker-layer .ace_selected_word {\n background: rgb(250, 250, 255);\n border: 1px solid rgb(200, 200, 250);\n}\n\n.ace-tm .ace_string.ace_regex {\n color: rgb(255, 0, 0)\n}";d.importCssString(e),b.cssClass="ace-tm"}),__ace_shadowed__.define("ace/mode/matching_brace_outdent",function(a,b,c){var d=a("ace/range").Range,e=function(){};(function(){this.checkOutdent=function(a,b){if(!/^\s+$/.test(a))return!1;return/^\s*\}/.test(b)},this.autoOutdent=function(a,b){var c=a.getLine(b),e=c.match(/^(\s*\})/);if(!e)return 0;var f=e[1].length,g=a.findMatchingBracket({row:b,column:f});if(!g||g.row==b)return 0;var h=this.$getIndent(a.getLine(g.row));a.replace(new d(b,0,b,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);if(b)return b[1];return""}}).call(e.prototype),b.MatchingBraceOutdent=e}),__ace_shadowed__.define("ace/virtual_renderer",function(a,b,c){var d=a("pilot/oop"),e=a("pilot/dom"),f=a("pilot/event"),g=a("pilot/useragent"),h=a("ace/layer/gutter").Gutter,i=a("ace/layer/marker").Marker,j=a("ace/layer/text").Text,k=a("ace/layer/cursor").Cursor,l=a("ace/scrollbar").ScrollBar,m=a("ace/renderloop").RenderLoop,n=a("pilot/event_emitter").EventEmitter,o=a("text!ace/css/editor.css");e.importCssString(o);var p=function(a,b){this.container=a,e.addCssClass(this.container,"ace_editor"),this.setTheme(b),this.$gutter=document.createElement("div"),this.$gutter.className="ace_gutter",this.container.appendChild(this.$gutter),this.scroller=document.createElement("div"),this.scroller.className="ace_scroller",this.container.appendChild(this.scroller),this.content=document.createElement("div"),this.content.className="ace_content",this.scroller.appendChild(this.content),this.$gutterLayer=new h(this.$gutter),this.$markerBack=new i(this.content);var c=this.$textLayer=new j(this.content);this.canvas=c.element,this.$markerFront=new i(this.content),this.characterWidth=c.getCharacterWidth(),this.lineHeight=c.getLineHeight(),this.$cursorLayer=new k(this.content),this.$cursorPadding=8,this.scrollBar=new l(a),this.scrollBar.addEventListener("scroll",this.onScroll.bind(this)),this.scrollTop=0,this.cursorPos={row:0,column:0};var d=this;this.$textLayer.addEventListener("changeCharaterSize",function(){d.characterWidth=c.getCharacterWidth(),d.lineHeight=c.getLineHeight(),d.$updatePrintMargin(),d.onResize(!0),d.$loop.schedule(d.CHANGE_FULL)}),f.addListener(this.$gutter,"click",this.$onGutterClick.bind(this)),f.addListener(this.$gutter,"dblclick",this.$onGutterClick.bind(this)),this.$size={width:0,height:0,scrollerHeight:0,scrollerWidth:0},this.$loop=new m(this.$renderChanges.bind(this)),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,d.implement(this,n),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&&this.scrollToY(c),this.getScrollTop()+this.$size.scrollerHeightb&&this.scrollToX(b),this.scroller.scrollLeft+this.$size.scrollerWidththis.scroller.scrollWidth&&this.$renderChanges(this.CHANGE_SIZE),this.scrollToX(Math.round(b+this.characterWidth-this.$size.scrollerWidth)))},this.getScrollTop=function(){return this.scrollTop},this.getScrollLeft=function(){return this.scroller.scrollLeft},this.getScrollTopRow=function(){return this.scrollTop/this.lineHeight},this.getScrollBottomRow=function(){return Math.max(0,Math.floor((this.scrollTop+this.$size.scrollerHeight)/this.lineHeight)-1)},this.scrollToRow=function(a){this.scrollToY(a*this.lineHeight)},this.scrollToLine=function(a,b){var c={lineHeight:this.lineHeight},d=0;for(var e=1;e",c+1,""),b.push("")}this.element=d.setInnerHtml(this.element,b.join("")),this.element.style.height=a.minHeight+"px"}}).call(e.prototype),b.Gutter=e}),__ace_shadowed__.define("ace/layer/marker",function(a,b,c){var d=a("ace/range").Range,e=a("pilot/dom"),f=function(a){this.element=document.createElement("div"),this.element.className="ace_layer ace_marker-layer",a.appendChild(this.element)};(function(){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){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(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):this.drawSingleLineMarker(b,f,d.clazz,a)}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,e,1);var f=b.end.row,g=new d(f,0,f,b.end.column);this.drawSingleLineMarker(a,g,c,e);for(var f=b.start.row+1;f");var g=this.$getTop(b.end.row,d),f=Math.round(b.end.column*d.characterWidth);a.push("
    ");var e=(b.end.row-b.start.row-1)*d.lineHeight;if(e>=0){var g=this.$getTop(b.start.row+1,d);a.push("
    ")}},this.drawSingleLineMarker=function(a,b,c,d,e){var f=d.lineHeight,g=Math.round((b.end.column+(e||0)-b.start.column)*d.characterWidth),h=this.$getTop(b.start.row,d),i=Math.round(b.start.column*d.characterWidth);a.push("
    ")}}).call(f.prototype),b.Marker=f}),__ace_shadowed__.define("ace/layer/text",function(a,b,c){var d=a("pilot/oop"),e=a("pilot/dom"),f=a("pilot/lang"),g=a("pilot/event_emitter").EventEmitter,h=function(a){this.element=document.createElement("div"),this.element.className="ace_layer ace_text-layer",a.appendChild(this.element),this.$characterSize=this.$measureSizes(),this.$pollSizeChanges()};(function(){d.implement(this,g),this.EOF_CHAR="¶",this.EOL_CHAR="¬",this.TAB_CHAR="→",this.SPACE_CHAR="·",this.setTokenizer=function(a){this.tokenizer=a},this.getLineHeight=function(){return this.$characterSize.height||1},this.getCharacterWidth=function(){return this.$characterSize.width||1},this.$pollSizeChanges=function(){var a=this;setInterval(function(){var b=a.$measureSizes();if(a.$characterSize.width!==b.width||a.$characterSize.height!==b.height)a.$characterSize=b,a._dispatchEvent("changeCharaterSize",{data:b})},500)},this.$fontStyles={fontFamily:1,fontSize:1,fontWeight:1,fontStyle:1,lineHeight:1},this.$measureSizes=function(){var a=1e3;if(!this.$measureNode){var b=this.$measureNode=document.createElement("div"),c=b.style;c.width=c.height="auto",c.left=c.top=-a*40+"px",c.visibility="hidden",c.position="absolute",c.overflow="visible",c.whiteSpace="nowrap",b.innerHTML=f.stringRepeat("Xy",a),document.body.insertBefore(b,document.body.firstChild)}var c=this.$measureNode.style;for(var d in this.$fontStyles){var g=e.computedStyle(this.element,d);c[d]=g}var h={height:this.$measureNode.offsetHeight,width:this.$measureNode.offsetWidth/(a*2)};return h},this.setSession=function(a){this.session=a},this.showInvisibles=!1,this.setShowInvisibles=function(a){if(this.showInvisibles==a)return!1;this.showInvisibles=a;return!0},this.$computeTabString=function(){var a=this.session.getTabSize();if(this.showInvisibles){var b=a/2;this.$tabString=""+Array(Math.floor(b)).join(" ")+this.TAB_CHAR+Array(Math.ceil(b)+1).join(" ")+""}else this.$tabString=Array(a+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=this.tokenizer.getTokens(d,f);for(var i=d;i<=f;i++){var j=g[i-a.firstRow];if(!j)continue;var k=[];this.$renderLine(k,i,h[i-d].tokens),j=e.setInnerHtml(j,k.join("")),j.style.height=this.session.getRowHeight(a,i)+"px"}},this.scrollLines=function(a){this.$computeTabString();var b=this.config;this.config=a;if(!b||b.lastRowa.lastRow)for(var d=a.lastRow+1;d<=b.lastRow;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=document.createDocumentFragment(),e=this.tokenizer.getTokens(b,c);for(var f=b;f<=c;f++){var g=document.createElement("div");g.className="ace_line";var h=g.style;h.height=this.session.getRowHeight(a,f)+"px",h.width=a.width+"px";var i=[];e.length>f-b&&this.$renderLine(i,f,e[f-b].tokens),g.innerHTML=i.join(""),d.appendChild(g)}return d},this.update=function(a){this.$computeTabString(),this.config=a;var b=[],c=this.tokenizer.getTokens(a.firstRow,a.lastRow),d=this.$renderLinesFragment(a,a.firstRow,a.lastRow);this.element.innerHTML="",this.element.appendChild(d)},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderLine=function(a,b,c){function i(b,c){var d=c.replace(/&/g,"&").replace(/"+a+""});if(g.$textToken[b.type])a.push(d);else{var i="ace_"+b.type.replace(/\./g," ace_");a.push("",d,"")}}if(this.showInvisibles)var d=this,e=/( +)|([\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000])/g,f=function(a){if(a.charCodeAt(0)==32)return Array(a.length+1).join(" ");var a=Array(a.length+1).join(d.SPACE_CHAR);return""+a+""};else var e=/[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/g,f=" ";var g=this,h=this.config.characterWidth,j=this.session.getRowSplitData(b),k=0,l=0,m;j&&j.length!=0?m=j[0]:m=Number.MAX_VALUE,a.push("
    ");for(var n=0;n=m)i(o,p.substring(0,m-k)),p=p.substring(m-k),k=m,a.push("
    ","
    "),l++,m=j[l]||Number.MAX_VALUE;p.length!=0&&(k+=p.length,i(o,p))}}this.showInvisibles&&(b!==this.session.getLength()-1?a.push(""+this.EOL_CHAR+""):a.push(""+this.EOF_CHAR+"")),a.push("
    ")}}).call(h.prototype),b.Text=h}),__ace_shadowed__.define("ace/layer/cursor",function(a,b,c){var d=a("pilot/dom"),e=function(a){this.element=document.createElement("div"),this.element.className="ace_layer ace_cursor-layer",a.appendChild(this.element),this.cursor=document.createElement("div"),this.cursor.className="ace_cursor",this.isVisible=!1};(function(){this.setSession=function(a){this.session=a},this.setCursor=function(a,b){this.position=this.session.documentToScreenPosition(a),b?d.addCssClass(this.cursor,"ace_overwrite"):d.removeCssClass(this.cursor,"ace_overwrite")},this.hideCursor=function(){this.isVisible=!1,this.cursor.parentNode&&this.cursor.parentNode.removeChild(this.cursor),clearInterval(this.blinkId)},this.showCursor=function(){this.isVisible=!0,this.element.appendChild(this.cursor);var a=this.cursor;a.style.visibility="visible",this.restartTimer()},this.restartTimer=function(){clearInterval(this.blinkId);if(this.isVisible){var a=this.cursor;this.blinkId=setInterval(function(){a.style.visibility="hidden",setTimeout(function(){a.style.visibility="visible"},400)},1e3)}},this.getPixelPosition=function(a){if(!this.config||!this.position)return{left:0,top:0};var b=this.position,c=Math.round(b.column*this.config.characterWidth),d=(b.row-(a?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:c,top:d}},this.update=function(a){this.position&&(this.config=a,this.pixelPos=this.getPixelPosition(!0),this.cursor.style.left=this.pixelPos.left+"px",this.cursor.style.top=this.pixelPos.top+"px",this.cursor.style.width=a.characterWidth+"px",this.cursor.style.height=a.lineHeight+"px",this.isVisible&&this.element.appendChild(this.cursor),this.restartTimer())}}).call(e.prototype),b.Cursor=e}),__ace_shadowed__.define("ace/scrollbar",function(a,b,c){var d=a("pilot/oop"),e=a("pilot/dom"),f=a("pilot/event"),g=a("pilot/event_emitter").EventEmitter,h=function(a){this.element=document.createElement("div"),this.element.className="ace_sb",this.inner=document.createElement("div"),this.element.appendChild(this.inner),a.appendChild(this.element),this.width=e.scrollbarWidth(),this.element.style.width=this.width,f.addListener(this.element,"scroll",this.onScroll.bind(this))};(function(){d.implement(this,g),this.onScroll=function(){this._dispatchEvent("scroll",{data:this.element.scrollTop})},this.getWidth=function(){return this.width},this.setHeight=function(a){this.element.style.height=Math.max(0,a-this.width)+"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_shadowed__.define("ace/renderloop",function(a,b,c){var d=a("pilot/event"),e=function(a){this.onRender=a,this.pending=!1,this.changes=0};(function(){this.schedule=function(a){this.changes=this.changes|a;if(!this.pending){this.pending=!0;var b=this;this.setTimeoutZero(function(){b.pending=!1;var a=b.changes;b.changes=0,b.onRender(a)})}},window.postMessage?(this.messageName="zero-timeout-message",this.setTimeoutZero=function(a){if(!this.attached){var b=this;d.addListener(window,"message",function(a){b.callback&&a.data==b.messageName&&(d.stopPropagation(a),b.callback())}),this.attached=!0}this.callback=a,window.postMessage(this.messageName,"*")}):this.setTimeoutZero=function(a){setTimeout(a,0)}}).call(e.prototype),b.RenderLoop=e}),__ace_shadowed__.define("text!ace/css/editor.css",'.ace_editor { position: absolute; overflow: hidden; font-family: "Menlo", "Monaco", "Courier New", monospace; font-size: 12px; }.ace_scroller { position: absolute; overflow-x: scroll; overflow-y: hidden; }.ace_content { position: absolute; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;}.ace_composition { position: absolute; background: #555; color: #DDD; z-index: 4;}.ace_gutter { position: absolute; overflow-x: hidden; overflow-y: hidden; height: 100%;}.ace_gutter-cell.ace_error { 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"); background-repeat: no-repeat; background-position: 4px center;}.ace_gutter-cell.ace_warning { 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"); background-repeat: no-repeat; background-position: 4px center;}.ace_editor .ace_sb { position: absolute; overflow-x: hidden; overflow-y: scroll; right: 0;}.ace_editor .ace_sb div { position: absolute; width: 1px; left: 0;}.ace_editor .ace_print_margin_layer { z-index: 0; position: absolute; overflow: hidden; margin: 0; left: 0; height: 100%; width: 100%;}.ace_editor .ace_print_margin { position: absolute; height: 100%;}.ace_editor textarea { position: fixed; z-index: -1; width: 10px; height: 30px; opacity: 0; background: transparent; appearance: none; border: none; resize: none; outline: none; overflow: hidden;}.ace_layer { z-index: 1; position: absolute; overflow: hidden; white-space: nowrap; height: 100%; width: 100%;}.ace_text-layer { font-family: Monaco, "Courier New", monospace; color: black;}.ace_cjk { display: inline-block; text-align: center;}.ace_cursor-layer { z-index: 4; cursor: text; pointer-events: none;}.ace_cursor { z-index: 4; position: absolute;}.ace_line { white-space: nowrap;}.ace_marker-layer { cursor: text;}.ace_marker-layer .ace_step { position: absolute; z-index: 3;}.ace_marker-layer .ace_selection { position: absolute; z-index: 4;}.ace_marker-layer .ace_bracket { position: absolute; z-index: 5;}.ace_marker-layer .ace_active_line { position: absolute; z-index: 2;}.ace_marker-layer .ace_selected_word { position: absolute; z-index: 6; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;}'),function(){var a=window.__ace_shadowed__.require,b=["pilot/fixoldbrowsers","pilot/index","pilot/plugin_manager","pilot/environment","ace/editor","ace/edit_session","ace/virtual_renderer","ace/undomanager","ace/theme/textmate"];a(b,function(){function n(a,b,c,d){function i(a,b,c,d){a.push("")}var e={"true":!0,"false":!1},f={mode:"Mode:",gutter:"Display Gutter:",theme:"Theme:",fontSize:"Font Size:",softWrap:"Soft Wrap:",showPrintMargin:"Show Print Margin:"},g={mode:{text:"Plain",javascript:"JavaScript",coffee:"CoffeeScript",html:"HTML",css:"CSS",c_cpp:"C++",php:"PHP",ruby:"Ruby",python:"Python"},theme:{textmate:"Textmate",eclipse:"Eclipse",clouds:"Clouds",clouds_midnight:"Clouds Midnight",cobalt:"Cobalt",dawn:"Dawn",idle_fingers:"Idle Fingers",kr_theme:"Kr Theme",mono_industrial:"Mono Industrial",monokai:"Monokai",pastel_on_dark:"Pastel On Dark",twilight:"Twilight"},gutter:e,fontSize:{"10px":"10px","11px":"11px","12px":"12px","14px":"14px","16px":"16px"},softWrap:{off:"Off",40:"40",80:"80",free:"Free"},showPrintMargin:e},h=[];h.push("");for(var j in d)h.push(""),h.push("");h.push("
    SettingValue
    ",f[j],""),i(h,j,g[j],d[j]),h.push("
    "),a.innerHTML=h.join("");var k=a.getElementsByTagName("select");for(var l=0;l"},{token:"keyword",regex:"(?:#include|#pragma|#line|#define|#undef|#ifdef|#else|#elif|#endif|#ifndef)"},{token:function(a){return a=="this"?"variable.language":b.hasOwnProperty(a)?"keyword":c.hasOwnProperty(a)?"constant.language":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]},this.addRules(a.getRules(),"doc-"),this.$rules["doc-start"][0].next="start"};d.inherits(h,g),b.c_cppHighlightRules=h}),__ace_shadowed__.define("ace/mode/doc_comment_highlight_rules",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc",regex:"\\*\\/",next:"start"},{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",regex:"s+"},{token:"comment.doc",regex:"TODO"},{token:"comment.doc",regex:"[^@\\*]+"},{token:"comment.doc",regex:"."}]}};d.inherits(f,e),function(){this.getStartRule=function(a){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:a}}}.call(f.prototype),b.DocCommentHighlightRules=f}) \ No newline at end of file diff --git a/build/textarea/src/mode-coffee.js b/build/textarea/src/mode-coffee.js deleted file mode 100644 index a2ad2919..00000000 --- a/build/textarea/src/mode-coffee.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/mode/coffee",function(a,b,c){function j(){this.$tokenizer=new d((new e).getRules()),this.$outdent=new f}var d=a("ace/tokenizer").Tokenizer,e=a("ace/mode/coffee_highlight_rules").CoffeeHighlightRules,f=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,g=a("ace/range").Range,h=a("ace/mode/text").Mode,i=a("pilot/oop");i.inherits(j,h);var k=j.prototype,l=/(?:[({[=:]|[-=]>|\b(?:else|switch|try|catch(?:\s*[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)?|finally))\s*$/,m=/^(\s*)#/,n=/^\s*###(?!#)/,o=/^\s*/;k.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a).tokens;(!e.length||e[e.length-1].type!=="comment")&&a==="start"&&l.test(b)&&(d+=c);return d},k.toggleCommentLines=function(a,b,c,d){console.log("toggle");var e=new g(0,0,0,0);for(var f=c;f<=d;++f){var h=b.getLine(f);if(n.test(h))continue;m.test(h)?h=h.replace(m,"$1"):h=h.replace(o,"$&#"),e.end.row=e.start.row=f,e.end.column=h.length+1,b.replace(e,h)}},k.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},k.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)},b.Mode=j}),__ace_shadowed__.define("ace/mode/coffee_highlight_rules",function(a,b,c){function d(){var a="[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*",b="(?![$\\w]|\\s*:)",c={token:"string",regex:".+"};this.$rules={start:[{token:"identifier",regex:"(?:@|(?:\\.|::)\\s*)"+a},{token:"keyword",regex:"(?:t(?:h(?:is|row|en)|ry|ypeof)|s(?:uper|witch)|return|b(?:reak|y)|c(?:ontinue|atch|lass)|i(?:n(?:stanceof)?|s(?:nt)?|f)|e(?:lse|xtends)|f(?:or (?:own)?|inally|unction)|wh(?:ile|en)|n(?:ew|ot?)|d(?:e(?:lete|bugger)|o)|loop|o(?:ff?|[rn])|un(?:less|til)|and|yes)"+b},{token:"constant.language",regex:"(?:true|false|null|undefined)"+b},{token:"invalid.illegal",regex:"(?:c(?:ase|onst)|default|function|v(?:ar|oid)|with|e(?:num|xport)|i(?:mplements|nterface)|let|p(?:ackage|r(?:ivate|otected)|ublic)|static|yield|__(?:hasProp|extends|slice|bind|indexOf))"+b},{token:"language.support.class",regex:"(?:Array|Boolean|Date|Function|Number|Object|R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|TypeError|URIError)"+b},{token:"language.support.function",regex:"(?:Math|JSON|is(?:NaN|Finite)|parse(?:Int|Float)|encodeURI(?:Component)?|decodeURI(?:Component)?)"+b},{token:"identifier",regex:a},{token:"constant.numeric",regex:"(?:0x[\\da-fA-F]+|(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:[eE][+-]?\\d+)?)"},{token:"string",regex:"'''",next:"qdoc"},{token:"string",regex:'"""',next:"qqdoc"},{token:"string",regex:"'",next:"qstring"},{token:"string",regex:'"',next:"qqstring"},{token:"string",regex:"`",next:"js"},{token:"string.regex",regex:"///",next:"heregex"},{token:"string.regex",regex:"/(?!\\s)[^[/\\n\\\\]*(?: (?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[/\\n\\\\]*)*/[imgy]{0,4}(?!\\w)"},{token:"comment",regex:"###(?!#)",next:"comment"},{token:"comment",regex:"#.*"},{token:"lparen",regex:"[({[]"},{token:"rparen",regex:"[\\]})]"},{token:"keyword.operator",regex:"\\S+"},{token:"text",regex:"\\s+"}],qdoc:[{token:"string",regex:".*?'''",next:"start"},c],qqdoc:[{token:"string",regex:'.*?"""',next:"start"},c],qstring:[{token:"string",regex:"[^\\\\']*(?:\\\\.[^\\\\']*)*'",next:"start"},c],qqstring:[{token:"string",regex:'[^\\\\"]*(?:\\\\.[^\\\\"]*)*"',next:"start"},c],js:[{token:"string",regex:"[^\\\\`]*(?:\\\\.[^\\\\`]*)*`",next:"start"},c],heregex:[{token:"string.regex",regex:".*?///[imgy]{0,4}",next:"start"},{token:"comment.regex",regex:"\\s+(?:#.*)?"},{token:"string.regex",regex:"\\S+"}],comment:[{token:"comment",regex:".*?###",next:"start"},{token:"comment",regex:".+"}]}}a("pilot/oop").inherits(d,a("ace/mode/text_highlight_rules").TextHighlightRules),b.CoffeeHighlightRules=d}) \ No newline at end of file diff --git a/build/textarea/src/mode-css.js b/build/textarea/src/mode-css.js deleted file mode 100644 index df1343eb..00000000 --- a/build/textarea/src/mode-css.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/mode/css",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/css_highlight_rules").CssHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(i,e),function(){this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a).tokens;if(e.length&&e[e.length-1].type=="comment")return d;var f=b.match(/^.*\{\s*$/);f&&(d+=c);return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)}}.call(i.prototype),b.Mode=i}),__ace_shadowed__.define("ace/mode/css_highlight_rules",function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/text_highlight_rules").TextHighlightRules,g=function(){function g(a){var b=[],c=a.split("");for(var d=0;d=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]},this.addRules(a.getRules(),"doc-"),this.$rules["doc-start"][0].next="start"};d.inherits(h,g),b.JavaScriptHighlightRules=h}),__ace_shadowed__.define("ace/mode/doc_comment_highlight_rules",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc",regex:"\\*\\/",next:"start"},{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",regex:"s+"},{token:"comment.doc",regex:"TODO"},{token:"comment.doc",regex:"[^@\\*]+"},{token:"comment.doc",regex:"."}]}};d.inherits(f,e),function(){this.getStartRule=function(a){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:a}}}.call(f.prototype),b.DocCommentHighlightRules=f}),__ace_shadowed__.define("ace/worker/worker_client",function(a,b,c){var d=a("pilot/oop"),e=a("pilot/event_emitter").EventEmitter,f=function(b,c,d,e){this.callbacks=[];if(a.packaged)var f=this.$guessBasePath(),g=this.$worker=new Worker(f+c);else{var h=a.nameToUrl("ace/worker/worker",null,"_"),g=this.$worker=new Worker(h),i={};for(var j=0;j"},{token:"comment",regex:"<\\!--",next:"comment"},{token:"text",regex:"<(?=s*script)",next:"script"},{token:"text",regex:"<(?=s*style)",next:"css"},{token:"text",regex:"<\\/?",next:"tag"},{token:"text",regex:"\\s+"},{token:"text",regex:"[^<]+"}],script:[{token:"text",regex:">",next:"js-start"},{token:"keyword",regex:"[-_a-zA-Z0-9:]+"},{token:"text",regex:"\\s+"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"}],css:[{token:"text",regex:">",next:"css-start"},{token:"keyword",regex:"[-_a-zA-Z0-9:]+"},{token:"text",regex:"\\s+"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"}],tag:[{token:"text",regex:">",next:"start"},{token:"keyword",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:".+"}]};var a=(new f).getRules();this.addRules(a,"js-"),this.$rules["js-start"].unshift({token:"comment",regex:"\\/\\/.*(?=<\\/script>)",next:"tag"},{token:"text",regex:"<\\/(?=script)",next:"tag"});var b=(new e).getRules();this.addRules(b,"css-"),this.$rules["css-start"].unshift({token:"text",regex:"<\\/(?=style)",next:"tag"})};d.inherits(h,g),b.HtmlHighlightRules=h}) \ No newline at end of file diff --git a/build/textarea/src/mode-java.js b/build/textarea/src/mode-java.js deleted file mode 100644 index 5ee32234..00000000 --- a/build/textarea/src/mode-java.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/mode/java",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/javascript").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/java_highlight_rules").JavaHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(i,e),function(){this.createWorker=function(a){return null}}.call(i.prototype),b.Mode=i}),__ace_shadowed__.define("ace/mode/javascript",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/javascript_highlight_rules").JavaScriptHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=a("ace/worker/worker_client").WorkerClient,k=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(k,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)\/\//;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,"//")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[]\s*$/);h&&(d+=c)}else if(a=="doc-start"){if(g=="start")return"";var h=b.match(/^\s*(\/?)\*/);h&&(h[1]&&(d+=" "),d+="* ")}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)},this.createWorker=function(a){var b=a.getDocument(),c=new j(["ace","pilot"],"worker-javascript.js","ace/mode/javascript_worker","JavaScriptWorker");c.call("setValue",[b.getValue()]),b.on("change",function(a){a.range={start:a.data.range.start,end:a.data.range.end},c.emit("change",a)}),c.on("jslint",function(b){var c=[];for(var d=0;d=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]},this.addRules(a.getRules(),"doc-"),this.$rules["doc-start"][0].next="start"};d.inherits(h,g),b.JavaScriptHighlightRules=h}),__ace_shadowed__.define("ace/mode/doc_comment_highlight_rules",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc",regex:"\\*\\/",next:"start"},{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",regex:"s+"},{token:"comment.doc",regex:"TODO"},{token:"comment.doc",regex:"[^@\\*]+"},{token:"comment.doc",regex:"."}]}};d.inherits(f,e),function(){this.getStartRule=function(a){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:a}}}.call(f.prototype),b.DocCommentHighlightRules=f}),__ace_shadowed__.define("ace/worker/worker_client",function(a,b,c){var d=a("pilot/oop"),e=a("pilot/event_emitter").EventEmitter,f=function(b,c,d,e){this.callbacks=[];if(a.packaged)var f=this.$guessBasePath(),g=this.$worker=new Worker(f+c);else{var h=a.nameToUrl("ace/worker/worker",null,"_"),g=this.$worker=new Worker(h),i={};for(var j=0;j=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]},this.addRules(a.getRules(),"doc-"),this.$rules["doc-start"][0].next="start"};d.inherits(h,g),b.JavaHighlightRules=h}) \ No newline at end of file diff --git a/build/textarea/src/mode-javascript.js b/build/textarea/src/mode-javascript.js deleted file mode 100644 index 04cc2c93..00000000 --- a/build/textarea/src/mode-javascript.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/mode/javascript",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/javascript_highlight_rules").JavaScriptHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=a("ace/worker/worker_client").WorkerClient,k=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(k,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)\/\//;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,"//")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[]\s*$/);h&&(d+=c)}else if(a=="doc-start"){if(g=="start")return"";var h=b.match(/^\s*(\/?)\*/);h&&(h[1]&&(d+=" "),d+="* ")}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)},this.createWorker=function(a){var b=a.getDocument(),c=new j(["ace","pilot"],"worker-javascript.js","ace/mode/javascript_worker","JavaScriptWorker");c.call("setValue",[b.getValue()]),b.on("change",function(a){a.range={start:a.data.range.start,end:a.data.range.end},c.emit("change",a)}),c.on("jslint",function(b){var c=[];for(var d=0;d=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]},this.addRules(a.getRules(),"doc-"),this.$rules["doc-start"][0].next="start"};d.inherits(h,g),b.JavaScriptHighlightRules=h}),__ace_shadowed__.define("ace/mode/doc_comment_highlight_rules",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc",regex:"\\*\\/",next:"start"},{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",regex:"s+"},{token:"comment.doc",regex:"TODO"},{token:"comment.doc",regex:"[^@\\*]+"},{token:"comment.doc",regex:"."}]}};d.inherits(f,e),function(){this.getStartRule=function(a){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:a}}}.call(f.prototype),b.DocCommentHighlightRules=f}),__ace_shadowed__.define("ace/worker/worker_client",function(a,b,c){var d=a("pilot/oop"),e=a("pilot/event_emitter").EventEmitter,f=function(b,c,d,e){this.callbacks=[];if(a.packaged)var f=this.$guessBasePath(),g=this.$worker=new Worker(f+c);else{var h=a.nameToUrl("ace/worker/worker",null,"_"),g=this.$worker=new Worker(h),i={};for(var j=0;j>=|<<=|<=>|&&=|=>|!~|\\^=|&=|\\|=|\\.=|x=|%=|\\/=|\\*=|\\-=|\\+=|=~|\\*\\*|\\-\\-|\\.\\.|\\|\\||&&|\\+\\+|\\->|!=|==|>=|<=|>>|<<|,|=|\\?\\:|\\^|\\||x|%|\\/|\\*|<|&|\\\\|~|!|>|\\.|\\-|\\+|\\-C|\\-b|\\-S|\\-u|\\-t|\\-p|\\-l|\\-d|\\-f|\\-g|\\-s|\\-z|\\-k|\\-e|\\-O|\\-T|\\-B|\\-M|\\-A|\\-X|\\-W|\\-c|\\-R|\\-o|\\-x|\\-w|\\-r|\\b(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|xor)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]}};d.inherits(g,f),b.PerlHighlightRules=g}) \ No newline at end of file diff --git a/build/textarea/src/mode-php.js b/build/textarea/src/mode-php.js deleted file mode 100644 index 8b8f1daf..00000000 --- a/build/textarea/src/mode-php.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/mode/php",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/php_highlight_rules").PhpHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(j,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)#/;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,"#")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[\:]\s*$/);h&&(d+=c)}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)}}.call(j.prototype),b.Mode=j}),__ace_shadowed__.define("ace/mode/php_highlight_rules",function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/doc_comment_highlight_rules").DocCommentHighlightRules,g=a("ace/mode/text_highlight_rules").TextHighlightRules,h=function(){var a=new f,b=e.arrayToMap("abs|acos|acosh|addcslashes|addslashes|aggregate|aggregate_info|aggregate_methods|aggregate_methods_by_list|aggregate_methods_by_regexp|aggregate_properties|aggregate_properties_by_list|aggregate_properties_by_regexp|aggregation_info|apache_child_terminate|apache_get_modules|apache_get_version|apache_getenv|apache_lookup_uri|apache_note|apache_request_headers|apache_response_headers|apache_setenv|array|array_change_key_case|array_chunk|array_combine|array_count_values|array_diff|array_diff_assoc|array_diff_uassoc|array_fill|array_filter|array_flip|array_intersect|array_intersect_assoc|array_key_exists|array_keys|array_map|array_merge|array_merge_recursive|array_multisort|array_pad|array_pop|array_push|array_rand|array_reduce|array_reverse|array_search|array_shift|array_slice|array_splice|array_sum|array_udiff|array_udiff_assoc|array_udiff_uassoc|array_unique|array_unshift|array_values|array_walk|arsort|ascii2ebcdic|asin|asinh|asort|aspell_check|aspell_check_raw|aspell_new|aspell_suggest|assert|assert_options|atan|atan2|atanh|base64_decode|base64_encode|base_convert|basename|bcadd|bccomp|bcdiv|bcmod|bcmul|bcpow|bcpowmod|bcscale|bcsqrt|bcsub|bin2hex|bind_textdomain_codeset|bindec|bindtextdomain|bzclose|bzcompress|bzdecompress|bzerrno|bzerror|bzerrstr|bzflush|bzopen|bzread|bzwrite|cal_days_in_month|cal_from_jd|cal_info|cal_to_jd|call_user_func|call_user_func_array|call_user_method|call_user_method_array|ccvs_add|ccvs_auth|ccvs_command|ccvs_count|ccvs_delete|ccvs_done|ccvs_init|ccvs_lookup|ccvs_new|ccvs_report|ccvs_return|ccvs_reverse|ccvs_sale|ccvs_status|ccvs_textvalue|ccvs_void|ceil|chdir|checkdate|checkdnsrr|chgrp|chmod|chop|chown|chr|chroot|chunk_split|class_exists|clearstatcache|closedir|closelog|com|com_addref|com_get|com_invoke|com_isenum|com_load|com_load_typelib|com_propget|com_propput|com_propset|com_release|com_set|compact|connection_aborted|connection_status|connection_timeout|constant|convert_cyr_string|copy|cos|cosh|count|count_chars|cpdf_add_annotation|cpdf_add_outline|cpdf_arc|cpdf_begin_text|cpdf_circle|cpdf_clip|cpdf_close|cpdf_closepath|cpdf_closepath_fill_stroke|cpdf_closepath_stroke|cpdf_continue_text|cpdf_curveto|cpdf_end_text|cpdf_fill|cpdf_fill_stroke|cpdf_finalize|cpdf_finalize_page|cpdf_global_set_document_limits|cpdf_import_jpeg|cpdf_lineto|cpdf_moveto|cpdf_newpath|cpdf_open|cpdf_output_buffer|cpdf_page_init|cpdf_place_inline_image|cpdf_rect|cpdf_restore|cpdf_rlineto|cpdf_rmoveto|cpdf_rotate|cpdf_rotate_text|cpdf_save|cpdf_save_to_file|cpdf_scale|cpdf_set_action_url|cpdf_set_char_spacing|cpdf_set_creator|cpdf_set_current_page|cpdf_set_font|cpdf_set_font_directories|cpdf_set_font_map_file|cpdf_set_horiz_scaling|cpdf_set_keywords|cpdf_set_leading|cpdf_set_page_animation|cpdf_set_subject|cpdf_set_text_matrix|cpdf_set_text_pos|cpdf_set_text_rendering|cpdf_set_text_rise|cpdf_set_title|cpdf_set_viewer_preferences|cpdf_set_word_spacing|cpdf_setdash|cpdf_setflat|cpdf_setgray|cpdf_setgray_fill|cpdf_setgray_stroke|cpdf_setlinecap|cpdf_setlinejoin|cpdf_setlinewidth|cpdf_setmiterlimit|cpdf_setrgbcolor|cpdf_setrgbcolor_fill|cpdf_setrgbcolor_stroke|cpdf_show|cpdf_show_xy|cpdf_stringwidth|cpdf_stroke|cpdf_text|cpdf_translate|crack_check|crack_closedict|crack_getlastmessage|crack_opendict|crc32|create_function|crypt|ctype_alnum|ctype_alpha|ctype_cntrl|ctype_digit|ctype_graph|ctype_lower|ctype_print|ctype_punct|ctype_space|ctype_upper|ctype_xdigit|curl_close|curl_errno|curl_error|curl_exec|curl_getinfo|curl_init|curl_multi_add_handle|curl_multi_close|curl_multi_exec|curl_multi_getcontent|curl_multi_info_read|curl_multi_init|curl_multi_remove_handle|curl_multi_select|curl_setopt|curl_version|current|cybercash_base64_decode|cybercash_base64_encode|cybercash_decr|cybercash_encr|cyrus_authenticate|cyrus_bind|cyrus_close|cyrus_connect|cyrus_query|cyrus_unbind|date|dba_close|dba_delete|dba_exists|dba_fetch|dba_firstkey|dba_handlers|dba_insert|dba_key_split|dba_list|dba_nextkey|dba_open|dba_optimize|dba_popen|dba_replace|dba_sync|dbase_add_record|dbase_close|dbase_create|dbase_delete_record|dbase_get_header_info|dbase_get_record|dbase_get_record_with_names|dbase_numfields|dbase_numrecords|dbase_open|dbase_pack|dbase_replace_record|dblist|dbmclose|dbmdelete|dbmexists|dbmfetch|dbmfirstkey|dbminsert|dbmnextkey|dbmopen|dbmreplace|dbplus_add|dbplus_aql|dbplus_chdir|dbplus_close|dbplus_curr|dbplus_errcode|dbplus_errno|dbplus_find|dbplus_first|dbplus_flush|dbplus_freealllocks|dbplus_freelock|dbplus_freerlocks|dbplus_getlock|dbplus_getunique|dbplus_info|dbplus_last|dbplus_lockrel|dbplus_next|dbplus_open|dbplus_prev|dbplus_rchperm|dbplus_rcreate|dbplus_rcrtexact|dbplus_rcrtlike|dbplus_resolve|dbplus_restorepos|dbplus_rkeys|dbplus_ropen|dbplus_rquery|dbplus_rrename|dbplus_rsecindex|dbplus_runlink|dbplus_rzap|dbplus_savepos|dbplus_setindex|dbplus_setindexbynumber|dbplus_sql|dbplus_tcl|dbplus_tremove|dbplus_undo|dbplus_undoprepare|dbplus_unlockrel|dbplus_unselect|dbplus_update|dbplus_xlockrel|dbplus_xunlockrel|dbx_close|dbx_compare|dbx_connect|dbx_error|dbx_escape_string|dbx_fetch_row|dbx_query|dbx_sort|dcgettext|dcngettext|deaggregate|debug_backtrace|debug_print_backtrace|debugger_off|debugger_on|decbin|dechex|decoct|define|define_syslog_variables|defined|deg2rad|delete|dgettext|die|dio_close|dio_fcntl|dio_open|dio_read|dio_seek|dio_stat|dio_tcsetattr|dio_truncate|dio_write|dir|dirname|disk_free_space|disk_total_space|diskfreespace|dl|dngettext|dns_check_record|dns_get_mx|dns_get_record|domxml_new_doc|domxml_open_file|domxml_open_mem|domxml_version|domxml_xmltree|domxml_xslt_stylesheet|domxml_xslt_stylesheet_doc|domxml_xslt_stylesheet_file|dotnet_load|doubleval|each|easter_date|easter_days|ebcdic2ascii|echo|empty|end|ereg|ereg_replace|eregi|eregi_replace|error_log|error_reporting|escapeshellarg|escapeshellcmd|eval|exec|exif_imagetype|exif_read_data|exif_thumbnail|exit|exp|explode|expm1|extension_loaded|extract|ezmlm_hash|fam_cancel_monitor|fam_close|fam_monitor_collection|fam_monitor_directory|fam_monitor_file|fam_next_event|fam_open|fam_pending|fam_resume_monitor|fam_suspend_monitor|fbsql_affected_rows|fbsql_autocommit|fbsql_blob_size|fbsql_change_user|fbsql_clob_size|fbsql_close|fbsql_commit|fbsql_connect|fbsql_create_blob|fbsql_create_clob|fbsql_create_db|fbsql_data_seek|fbsql_database|fbsql_database_password|fbsql_db_query|fbsql_db_status|fbsql_drop_db|fbsql_errno|fbsql_error|fbsql_fetch_array|fbsql_fetch_assoc|fbsql_fetch_field|fbsql_fetch_lengths|fbsql_fetch_object|fbsql_fetch_row|fbsql_field_flags|fbsql_field_len|fbsql_field_name|fbsql_field_seek|fbsql_field_table|fbsql_field_type|fbsql_free_result|fbsql_get_autostart_info|fbsql_hostname|fbsql_insert_id|fbsql_list_dbs|fbsql_list_fields|fbsql_list_tables|fbsql_next_result|fbsql_num_fields|fbsql_num_rows|fbsql_password|fbsql_pconnect|fbsql_query|fbsql_read_blob|fbsql_read_clob|fbsql_result|fbsql_rollback|fbsql_select_db|fbsql_set_lob_mode|fbsql_set_password|fbsql_set_transaction|fbsql_start_db|fbsql_stop_db|fbsql_tablename|fbsql_username|fbsql_warnings|fclose|fdf_add_doc_javascript|fdf_add_template|fdf_close|fdf_create|fdf_enum_values|fdf_errno|fdf_error|fdf_get_ap|fdf_get_attachment|fdf_get_encoding|fdf_get_file|fdf_get_flags|fdf_get_opt|fdf_get_status|fdf_get_value|fdf_get_version|fdf_header|fdf_next_field_name|fdf_open|fdf_open_string|fdf_remove_item|fdf_save|fdf_save_string|fdf_set_ap|fdf_set_encoding|fdf_set_file|fdf_set_flags|fdf_set_javascript_action|fdf_set_opt|fdf_set_status|fdf_set_submit_form_action|fdf_set_target_frame|fdf_set_value|fdf_set_version|feof|fflush|fgetc|fgetcsv|fgets|fgetss|file|file_exists|file_get_contents|file_put_contents|fileatime|filectime|filegroup|fileinode|filemtime|fileowner|fileperms|filepro|filepro_fieldcount|filepro_fieldname|filepro_fieldtype|filepro_fieldwidth|filepro_retrieve|filepro_rowcount|filesize|filetype|floatval|flock|floor|flush|fmod|fnmatch|fopen|fpassthru|fprintf|fputs|fread|frenchtojd|fribidi_log2vis|fscanf|fseek|fsockopen|fstat|ftell|ftok|ftp_alloc|ftp_cdup|ftp_chdir|ftp_chmod|ftp_close|ftp_connect|ftp_delete|ftp_exec|ftp_fget|ftp_fput|ftp_get|ftp_get_option|ftp_login|ftp_mdtm|ftp_mkdir|ftp_nb_continue|ftp_nb_fget|ftp_nb_fput|ftp_nb_get|ftp_nb_put|ftp_nlist|ftp_pasv|ftp_put|ftp_pwd|ftp_quit|ftp_raw|ftp_rawlist|ftp_rename|ftp_rmdir|ftp_set_option|ftp_site|ftp_size|ftp_ssl_connect|ftp_systype|ftruncate|func_get_arg|func_get_args|func_num_args|function_exists|fwrite|gd_info|get_browser|get_cfg_var|get_class|get_class_methods|get_class_vars|get_current_user|get_declared_classes|get_declared_interfaces|get_defined_constants|get_defined_functions|get_defined_vars|get_extension_funcs|get_headers|get_html_translation_table|get_include_path|get_included_files|get_loaded_extensions|get_magic_quotes_gpc|get_magic_quotes_runtime|get_meta_tags|get_object_vars|get_parent_class|get_required_files|get_resource_type|getallheaders|getcwd|getdate|getenv|gethostbyaddr|gethostbyname|gethostbynamel|getimagesize|getlastmod|getmxrr|getmygid|getmyinode|getmypid|getmyuid|getopt|getprotobyname|getprotobynumber|getrandmax|getrusage|getservbyname|getservbyport|gettext|gettimeofday|gettype|glob|gmdate|gmmktime|gmp_abs|gmp_add|gmp_and|gmp_clrbit|gmp_cmp|gmp_com|gmp_div|gmp_div_q|gmp_div_qr|gmp_div_r|gmp_divexact|gmp_fact|gmp_gcd|gmp_gcdext|gmp_hamdist|gmp_init|gmp_intval|gmp_invert|gmp_jacobi|gmp_legendre|gmp_mod|gmp_mul|gmp_neg|gmp_or|gmp_perfect_square|gmp_popcount|gmp_pow|gmp_powm|gmp_prob_prime|gmp_random|gmp_scan0|gmp_scan1|gmp_setbit|gmp_sign|gmp_sqrt|gmp_sqrtrem|gmp_strval|gmp_sub|gmp_xor|gmstrftime|gregoriantojd|gzclose|gzcompress|gzdeflate|gzencode|gzeof|gzfile|gzgetc|gzgets|gzgetss|gzinflate|gzopen|gzpassthru|gzputs|gzread|gzrewind|gzseek|gztell|gzuncompress|gzwrite|header|headers_list|headers_sent|hebrev|hebrevc|hexdec|highlight_file|highlight_string|html_entity_decode|htmlentities|htmlspecialchars|http_build_query|hw_api_attribute|hw_api_content|hw_api_object|hw_array2objrec|hw_changeobject|hw_children|hw_childrenobj|hw_close|hw_connect|hw_connection_info|hw_cp|hw_deleteobject|hw_docbyanchor|hw_docbyanchorobj|hw_document_attributes|hw_document_bodytag|hw_document_content|hw_document_setcontent|hw_document_size|hw_dummy|hw_edittext|hw_error|hw_errormsg|hw_free_document|hw_getanchors|hw_getanchorsobj|hw_getandlock|hw_getchildcoll|hw_getchildcollobj|hw_getchilddoccoll|hw_getchilddoccollobj|hw_getobject|hw_getobjectbyquery|hw_getobjectbyquerycoll|hw_getobjectbyquerycollobj|hw_getobjectbyqueryobj|hw_getparents|hw_getparentsobj|hw_getrellink|hw_getremote|hw_getremotechildren|hw_getsrcbydestobj|hw_gettext|hw_getusername|hw_identify|hw_incollections|hw_info|hw_inscoll|hw_insdoc|hw_insertanchors|hw_insertdocument|hw_insertobject|hw_mapid|hw_modifyobject|hw_mv|hw_new_document|hw_objrec2array|hw_output_document|hw_pconnect|hw_pipedocument|hw_root|hw_setlinkroot|hw_stat|hw_unlock|hw_who|hwapi_hgcsp|hypot|ibase_add_user|ibase_affected_rows|ibase_backup|ibase_blob_add|ibase_blob_cancel|ibase_blob_close|ibase_blob_create|ibase_blob_echo|ibase_blob_get|ibase_blob_import|ibase_blob_info|ibase_blob_open|ibase_close|ibase_commit|ibase_commit_ret|ibase_connect|ibase_db_info|ibase_delete_user|ibase_drop_db|ibase_errcode|ibase_errmsg|ibase_execute|ibase_fetch_assoc|ibase_fetch_object|ibase_fetch_row|ibase_field_info|ibase_free_event_handler|ibase_free_query|ibase_free_result|ibase_gen_id|ibase_maintain_db|ibase_modify_user|ibase_name_result|ibase_num_fields|ibase_num_params|ibase_param_info|ibase_pconnect|ibase_prepare|ibase_query|ibase_restore|ibase_rollback|ibase_rollback_ret|ibase_server_info|ibase_service_attach|ibase_service_detach|ibase_set_event_handler|ibase_timefmt|ibase_trans|ibase_wait_event|iconv|iconv_get_encoding|iconv_mime_decode|iconv_mime_decode_headers|iconv_mime_encode|iconv_set_encoding|iconv_strlen|iconv_strpos|iconv_strrpos|iconv_substr|idate|ifx_affected_rows|ifx_blobinfile_mode|ifx_byteasvarchar|ifx_close|ifx_connect|ifx_copy_blob|ifx_create_blob|ifx_create_char|ifx_do|ifx_error|ifx_errormsg|ifx_fetch_row|ifx_fieldproperties|ifx_fieldtypes|ifx_free_blob|ifx_free_char|ifx_free_result|ifx_get_blob|ifx_get_char|ifx_getsqlca|ifx_htmltbl_result|ifx_nullformat|ifx_num_fields|ifx_num_rows|ifx_pconnect|ifx_prepare|ifx_query|ifx_textasvarchar|ifx_update_blob|ifx_update_char|ifxus_close_slob|ifxus_create_slob|ifxus_free_slob|ifxus_open_slob|ifxus_read_slob|ifxus_seek_slob|ifxus_tell_slob|ifxus_write_slob|ignore_user_abort|image2wbmp|image_type_to_mime_type|imagealphablending|imageantialias|imagearc|imagechar|imagecharup|imagecolorallocate|imagecolorallocatealpha|imagecolorat|imagecolorclosest|imagecolorclosestalpha|imagecolorclosesthwb|imagecolordeallocate|imagecolorexact|imagecolorexactalpha|imagecolormatch|imagecolorresolve|imagecolorresolvealpha|imagecolorset|imagecolorsforindex|imagecolorstotal|imagecolortransparent|imagecopy|imagecopymerge|imagecopymergegray|imagecopyresampled|imagecopyresized|imagecreate|imagecreatefromgd|imagecreatefromgd2|imagecreatefromgd2part|imagecreatefromgif|imagecreatefromjpeg|imagecreatefrompng|imagecreatefromstring|imagecreatefromwbmp|imagecreatefromxbm|imagecreatefromxpm|imagecreatetruecolor|imagedashedline|imagedestroy|imageellipse|imagefill|imagefilledarc|imagefilledellipse|imagefilledpolygon|imagefilledrectangle|imagefilltoborder|imagefilter|imagefontheight|imagefontwidth|imageftbbox|imagefttext|imagegammacorrect|imagegd|imagegd2|imagegif|imageinterlace|imageistruecolor|imagejpeg|imagelayereffect|imageline|imageloadfont|imagepalettecopy|imagepng|imagepolygon|imagepsbbox|imagepscopyfont|imagepsencodefont|imagepsextendfont|imagepsfreefont|imagepsloadfont|imagepsslantfont|imagepstext|imagerectangle|imagerotate|imagesavealpha|imagesetbrush|imagesetpixel|imagesetstyle|imagesetthickness|imagesettile|imagestring|imagestringup|imagesx|imagesy|imagetruecolortopalette|imagettfbbox|imagettftext|imagetypes|imagewbmp|imagexbm|imap_8bit|imap_alerts|imap_append|imap_base64|imap_binary|imap_body|imap_bodystruct|imap_check|imap_clearflag_full|imap_close|imap_createmailbox|imap_delete|imap_deletemailbox|imap_errors|imap_expunge|imap_fetch_overview|imap_fetchbody|imap_fetchheader|imap_fetchstructure|imap_get_quota|imap_get_quotaroot|imap_getacl|imap_getmailboxes|imap_getsubscribed|imap_header|imap_headerinfo|imap_headers|imap_last_error|imap_list|imap_listmailbox|imap_listscan|imap_listsubscribed|imap_lsub|imap_mail|imap_mail_compose|imap_mail_copy|imap_mail_move|imap_mailboxmsginfo|imap_mime_header_decode|imap_msgno|imap_num_msg|imap_num_recent|imap_open|imap_ping|imap_qprint|imap_renamemailbox|imap_reopen|imap_rfc822_parse_adrlist|imap_rfc822_parse_headers|imap_rfc822_write_address|imap_scanmailbox|imap_search|imap_set_quota|imap_setacl|imap_setflag_full|imap_sort|imap_status|imap_subscribe|imap_thread|imap_timeout|imap_uid|imap_undelete|imap_unsubscribe|imap_utf7_decode|imap_utf7_encode|imap_utf8|implode|import_request_variables|in_array|ingres_autocommit|ingres_close|ingres_commit|ingres_connect|ingres_fetch_array|ingres_fetch_object|ingres_fetch_row|ingres_field_length|ingres_field_name|ingres_field_nullable|ingres_field_precision|ingres_field_scale|ingres_field_type|ingres_num_fields|ingres_num_rows|ingres_pconnect|ingres_query|ingres_rollback|ini_alter|ini_get|ini_get_all|ini_restore|ini_set|intval|ip2long|iptcembed|iptcparse|ircg_channel_mode|ircg_disconnect|ircg_fetch_error_msg|ircg_get_username|ircg_html_encode|ircg_ignore_add|ircg_ignore_del|ircg_invite|ircg_is_conn_alive|ircg_join|ircg_kick|ircg_list|ircg_lookup_format_messages|ircg_lusers|ircg_msg|ircg_nick|ircg_nickname_escape|ircg_nickname_unescape|ircg_notice|ircg_oper|ircg_part|ircg_pconnect|ircg_register_format_messages|ircg_set_current|ircg_set_file|ircg_set_on_die|ircg_topic|ircg_who|ircg_whois|is_a|is_array|is_bool|is_callable|is_dir|is_double|is_executable|is_file|is_finite|is_float|is_infinite|is_int|is_integer|is_link|is_long|is_nan|is_null|is_numeric|is_object|is_readable|is_real|is_resource|is_scalar|is_soap_fault|is_string|is_subclass_of|is_uploaded_file|is_writable|is_writeable|isset|java_last_exception_clear|java_last_exception_get|jddayofweek|jdmonthname|jdtofrench|jdtogregorian|jdtojewish|jdtojulian|jdtounix|jewishtojd|join|jpeg2wbmp|juliantojd|key|krsort|ksort|lcg_value|ldap_8859_to_t61|ldap_add|ldap_bind|ldap_close|ldap_compare|ldap_connect|ldap_count_entries|ldap_delete|ldap_dn2ufn|ldap_err2str|ldap_errno|ldap_error|ldap_explode_dn|ldap_first_attribute|ldap_first_entry|ldap_first_reference|ldap_free_result|ldap_get_attributes|ldap_get_dn|ldap_get_entries|ldap_get_option|ldap_get_values|ldap_get_values_len|ldap_list|ldap_mod_add|ldap_mod_del|ldap_mod_replace|ldap_modify|ldap_next_attribute|ldap_next_entry|ldap_next_reference|ldap_parse_reference|ldap_parse_result|ldap_read|ldap_rename|ldap_search|ldap_set_option|ldap_set_rebind_proc|ldap_sort|ldap_start_tls|ldap_t61_to_8859|ldap_unbind|levenshtein|link|linkinfo|list|localeconv|localtime|log|log10|log1p|long2ip|lstat|ltrim|lzf_compress|lzf_decompress|lzf_optimized_for|mail|mailparse_determine_best_xfer_encoding|mailparse_msg_create|mailparse_msg_extract_part|mailparse_msg_extract_part_file|mailparse_msg_free|mailparse_msg_get_part|mailparse_msg_get_part_data|mailparse_msg_get_structure|mailparse_msg_parse|mailparse_msg_parse_file|mailparse_rfc822_parse_addresses|mailparse_stream_encode|mailparse_uudecode_all|main|max|mb_convert_case|mb_convert_encoding|mb_convert_kana|mb_convert_variables|mb_decode_mimeheader|mb_decode_numericentity|mb_detect_encoding|mb_detect_order|mb_encode_mimeheader|mb_encode_numericentity|mb_ereg|mb_ereg_match|mb_ereg_replace|mb_ereg_search|mb_ereg_search_getpos|mb_ereg_search_getregs|mb_ereg_search_init|mb_ereg_search_pos|mb_ereg_search_regs|mb_ereg_search_setpos|mb_eregi|mb_eregi_replace|mb_get_info|mb_http_input|mb_http_output|mb_internal_encoding|mb_language|mb_output_handler|mb_parse_str|mb_preferred_mime_name|mb_regex_encoding|mb_regex_set_options|mb_send_mail|mb_split|mb_strcut|mb_strimwidth|mb_strlen|mb_strpos|mb_strrpos|mb_strtolower|mb_strtoupper|mb_strwidth|mb_substitute_character|mb_substr|mb_substr_count|mcal_append_event|mcal_close|mcal_create_calendar|mcal_date_compare|mcal_date_valid|mcal_day_of_week|mcal_day_of_year|mcal_days_in_month|mcal_delete_calendar|mcal_delete_event|mcal_event_add_attribute|mcal_event_init|mcal_event_set_alarm|mcal_event_set_category|mcal_event_set_class|mcal_event_set_description|mcal_event_set_end|mcal_event_set_recur_daily|mcal_event_set_recur_monthly_mday|mcal_event_set_recur_monthly_wday|mcal_event_set_recur_none|mcal_event_set_recur_weekly|mcal_event_set_recur_yearly|mcal_event_set_start|mcal_event_set_title|mcal_expunge|mcal_fetch_current_stream_event|mcal_fetch_event|mcal_is_leap_year|mcal_list_alarms|mcal_list_events|mcal_next_recurrence|mcal_open|mcal_popen|mcal_rename_calendar|mcal_reopen|mcal_snooze|mcal_store_event|mcal_time_valid|mcal_week_of_year|mcrypt_cbc|mcrypt_cfb|mcrypt_create_iv|mcrypt_decrypt|mcrypt_ecb|mcrypt_enc_get_algorithms_name|mcrypt_enc_get_block_size|mcrypt_enc_get_iv_size|mcrypt_enc_get_key_size|mcrypt_enc_get_modes_name|mcrypt_enc_get_supported_key_sizes|mcrypt_enc_is_block_algorithm|mcrypt_enc_is_block_algorithm_mode|mcrypt_enc_is_block_mode|mcrypt_enc_self_test|mcrypt_encrypt|mcrypt_generic|mcrypt_generic_deinit|mcrypt_generic_end|mcrypt_generic_init|mcrypt_get_block_size|mcrypt_get_cipher_name|mcrypt_get_iv_size|mcrypt_get_key_size|mcrypt_list_algorithms|mcrypt_list_modes|mcrypt_module_close|mcrypt_module_get_algo_block_size|mcrypt_module_get_algo_key_size|mcrypt_module_get_supported_key_sizes|mcrypt_module_is_block_algorithm|mcrypt_module_is_block_algorithm_mode|mcrypt_module_is_block_mode|mcrypt_module_open|mcrypt_module_self_test|mcrypt_ofb|mcve_adduser|mcve_adduserarg|mcve_bt|mcve_checkstatus|mcve_chkpwd|mcve_chngpwd|mcve_completeauthorizations|mcve_connect|mcve_connectionerror|mcve_deleteresponse|mcve_deletetrans|mcve_deleteusersetup|mcve_deluser|mcve_destroyconn|mcve_destroyengine|mcve_disableuser|mcve_edituser|mcve_enableuser|mcve_force|mcve_getcell|mcve_getcellbynum|mcve_getcommadelimited|mcve_getheader|mcve_getuserarg|mcve_getuserparam|mcve_gft|mcve_gl|mcve_gut|mcve_initconn|mcve_initengine|mcve_initusersetup|mcve_iscommadelimited|mcve_liststats|mcve_listusers|mcve_maxconntimeout|mcve_monitor|mcve_numcolumns|mcve_numrows|mcve_override|mcve_parsecommadelimited|mcve_ping|mcve_preauth|mcve_preauthcompletion|mcve_qc|mcve_responseparam|mcve_return|mcve_returncode|mcve_returnstatus|mcve_sale|mcve_setblocking|mcve_setdropfile|mcve_setip|mcve_setssl|mcve_setssl_files|mcve_settimeout|mcve_settle|mcve_text_avs|mcve_text_code|mcve_text_cv|mcve_transactionauth|mcve_transactionavs|mcve_transactionbatch|mcve_transactioncv|mcve_transactionid|mcve_transactionitem|mcve_transactionssent|mcve_transactiontext|mcve_transinqueue|mcve_transnew|mcve_transparam|mcve_transsend|mcve_ub|mcve_uwait|mcve_verifyconnection|mcve_verifysslcert|mcve_void|md5|md5_file|mdecrypt_generic|memory_get_usage|metaphone|method_exists|mhash|mhash_count|mhash_get_block_size|mhash_get_hash_name|mhash_keygen_s2k|microtime|mime_content_type|min|ming_setcubicthreshold|ming_setscale|ming_useswfversion|mkdir|mktime|money_format|move_uploaded_file|msession_connect|msession_count|msession_create|msession_destroy|msession_disconnect|msession_find|msession_get|msession_get_array|msession_getdata|msession_inc|msession_list|msession_listvar|msession_lock|msession_plugin|msession_randstr|msession_set|msession_set_array|msession_setdata|msession_timeout|msession_uniq|msession_unlock|msg_get_queue|msg_receive|msg_remove_queue|msg_send|msg_set_queue|msg_stat_queue|msql|msql|msql_affected_rows|msql_close|msql_connect|msql_create_db|msql_createdb|msql_data_seek|msql_dbname|msql_drop_db|msql_error|msql_fetch_array|msql_fetch_field|msql_fetch_object|msql_fetch_row|msql_field_flags|msql_field_len|msql_field_name|msql_field_seek|msql_field_table|msql_field_type|msql_fieldflags|msql_fieldlen|msql_fieldname|msql_fieldtable|msql_fieldtype|msql_free_result|msql_list_dbs|msql_list_fields|msql_list_tables|msql_num_fields|msql_num_rows|msql_numfields|msql_numrows|msql_pconnect|msql_query|msql_regcase|msql_result|msql_select_db|msql_tablename|mssql_bind|mssql_close|mssql_connect|mssql_data_seek|mssql_execute|mssql_fetch_array|mssql_fetch_assoc|mssql_fetch_batch|mssql_fetch_field|mssql_fetch_object|mssql_fetch_row|mssql_field_length|mssql_field_name|mssql_field_seek|mssql_field_type|mssql_free_result|mssql_free_statement|mssql_get_last_message|mssql_guid_string|mssql_init|mssql_min_error_severity|mssql_min_message_severity|mssql_next_result|mssql_num_fields|mssql_num_rows|mssql_pconnect|mssql_query|mssql_result|mssql_rows_affected|mssql_select_db|mt_getrandmax|mt_rand|mt_srand|muscat_close|muscat_get|muscat_give|muscat_setup|muscat_setup_net|mysql_affected_rows|mysql_change_user|mysql_client_encoding|mysql_close|mysql_connect|mysql_create_db|mysql_data_seek|mysql_db_name|mysql_db_query|mysql_drop_db|mysql_errno|mysql_error|mysql_escape_string|mysql_fetch_array|mysql_fetch_assoc|mysql_fetch_field|mysql_fetch_lengths|mysql_fetch_object|mysql_fetch_row|mysql_field_flags|mysql_field_len|mysql_field_name|mysql_field_seek|mysql_field_table|mysql_field_type|mysql_free_result|mysql_get_client_info|mysql_get_host_info|mysql_get_proto_info|mysql_get_server_info|mysql_info|mysql_insert_id|mysql_list_dbs|mysql_list_fields|mysql_list_processes|mysql_list_tables|mysql_num_fields|mysql_num_rows|mysql_pconnect|mysql_ping|mysql_query|mysql_real_escape_string|mysql_result|mysql_select_db|mysql_stat|mysql_tablename|mysql_thread_id|mysql_unbuffered_query|mysqli_affected_rows|mysqli_autocommit|mysqli_bind_param|mysqli_bind_result|mysqli_change_user|mysqli_character_set_name|mysqli_client_encoding|mysqli_close|mysqli_commit|mysqli_connect|mysqli_connect_errno|mysqli_connect_error|mysqli_data_seek|mysqli_debug|mysqli_disable_reads_from_master|mysqli_disable_rpl_parse|mysqli_dump_debug_info|mysqli_embedded_connect|mysqli_enable_reads_from_master|mysqli_enable_rpl_parse|mysqli_errno|mysqli_error|mysqli_escape_string|mysqli_execute|mysqli_fetch|mysqli_fetch_array|mysqli_fetch_assoc|mysqli_fetch_field|mysqli_fetch_field_direct|mysqli_fetch_fields|mysqli_fetch_lengths|mysqli_fetch_object|mysqli_fetch_row|mysqli_field_count|mysqli_field_seek|mysqli_field_tell|mysqli_free_result|mysqli_get_client_info|mysqli_get_client_version|mysqli_get_host_info|mysqli_get_metadata|mysqli_get_proto_info|mysqli_get_server_info|mysqli_get_server_version|mysqli_info|mysqli_init|mysqli_insert_id|mysqli_kill|mysqli_master_query|mysqli_more_results|mysqli_multi_query|mysqli_next_result|mysqli_num_fields|mysqli_num_rows|mysqli_options|mysqli_param_count|mysqli_ping|mysqli_prepare|mysqli_query|mysqli_real_connect|mysqli_real_escape_string|mysqli_real_query|mysqli_report|mysqli_rollback|mysqli_rpl_parse_enabled|mysqli_rpl_probe|mysqli_rpl_query_type|mysqli_select_db|mysqli_send_long_data|mysqli_send_query|mysqli_server_end|mysqli_server_init|mysqli_set_opt|mysqli_sqlstate|mysqli_ssl_set|mysqli_stat|mysqli_stmt_init|mysqli_stmt_affected_rows|mysqli_stmt_bind_param|mysqli_stmt_bind_result|mysqli_stmt_close|mysqli_stmt_data_seek|mysqli_stmt_errno|mysqli_stmt_error|mysqli_stmt_execute|mysqli_stmt_fetch|mysqli_stmt_free_result|mysqli_stmt_num_rows|mysqli_stmt_param_count|mysqli_stmt_prepare|mysqli_stmt_result_metadata|mysqli_stmt_send_long_data|mysqli_stmt_sqlstate|mysqli_stmt_store_result|mysqli_store_result|mysqli_thread_id|mysqli_thread_safe|mysqli_use_result|mysqli_warning_count|natcasesort|natsort|ncurses_addch|ncurses_addchnstr|ncurses_addchstr|ncurses_addnstr|ncurses_addstr|ncurses_assume_default_colors|ncurses_attroff|ncurses_attron|ncurses_attrset|ncurses_baudrate|ncurses_beep|ncurses_bkgd|ncurses_bkgdset|ncurses_border|ncurses_bottom_panel|ncurses_can_change_color|ncurses_cbreak|ncurses_clear|ncurses_clrtobot|ncurses_clrtoeol|ncurses_color_content|ncurses_color_set|ncurses_curs_set|ncurses_def_prog_mode|ncurses_def_shell_mode|ncurses_define_key|ncurses_del_panel|ncurses_delay_output|ncurses_delch|ncurses_deleteln|ncurses_delwin|ncurses_doupdate|ncurses_echo|ncurses_echochar|ncurses_end|ncurses_erase|ncurses_erasechar|ncurses_filter|ncurses_flash|ncurses_flushinp|ncurses_getch|ncurses_getmaxyx|ncurses_getmouse|ncurses_getyx|ncurses_halfdelay|ncurses_has_colors|ncurses_has_ic|ncurses_has_il|ncurses_has_key|ncurses_hide_panel|ncurses_hline|ncurses_inch|ncurses_init|ncurses_init_color|ncurses_init_pair|ncurses_insch|ncurses_insdelln|ncurses_insertln|ncurses_insstr|ncurses_instr|ncurses_isendwin|ncurses_keyok|ncurses_keypad|ncurses_killchar|ncurses_longname|ncurses_meta|ncurses_mouse_trafo|ncurses_mouseinterval|ncurses_mousemask|ncurses_move|ncurses_move_panel|ncurses_mvaddch|ncurses_mvaddchnstr|ncurses_mvaddchstr|ncurses_mvaddnstr|ncurses_mvaddstr|ncurses_mvcur|ncurses_mvdelch|ncurses_mvgetch|ncurses_mvhline|ncurses_mvinch|ncurses_mvvline|ncurses_mvwaddstr|ncurses_napms|ncurses_new_panel|ncurses_newpad|ncurses_newwin|ncurses_nl|ncurses_nocbreak|ncurses_noecho|ncurses_nonl|ncurses_noqiflush|ncurses_noraw|ncurses_pair_content|ncurses_panel_above|ncurses_panel_below|ncurses_panel_window|ncurses_pnoutrefresh|ncurses_prefresh|ncurses_putp|ncurses_qiflush|ncurses_raw|ncurses_refresh|ncurses_replace_panel|ncurses_reset_prog_mode|ncurses_reset_shell_mode|ncurses_resetty|ncurses_savetty|ncurses_scr_dump|ncurses_scr_init|ncurses_scr_restore|ncurses_scr_set|ncurses_scrl|ncurses_show_panel|ncurses_slk_attr|ncurses_slk_attroff|ncurses_slk_attron|ncurses_slk_attrset|ncurses_slk_clear|ncurses_slk_color|ncurses_slk_init|ncurses_slk_noutrefresh|ncurses_slk_refresh|ncurses_slk_restore|ncurses_slk_set|ncurses_slk_touch|ncurses_standend|ncurses_standout|ncurses_start_color|ncurses_termattrs|ncurses_termname|ncurses_timeout|ncurses_top_panel|ncurses_typeahead|ncurses_ungetch|ncurses_ungetmouse|ncurses_update_panels|ncurses_use_default_colors|ncurses_use_env|ncurses_use_extended_names|ncurses_vidattr|ncurses_vline|ncurses_waddch|ncurses_waddstr|ncurses_wattroff|ncurses_wattron|ncurses_wattrset|ncurses_wborder|ncurses_wclear|ncurses_wcolor_set|ncurses_werase|ncurses_wgetch|ncurses_whline|ncurses_wmouse_trafo|ncurses_wmove|ncurses_wnoutrefresh|ncurses_wrefresh|ncurses_wstandend|ncurses_wstandout|ncurses_wvline|next|ngettext|nl2br|nl_langinfo|notes_body|notes_copy_db|notes_create_db|notes_create_note|notes_drop_db|notes_find_note|notes_header_info|notes_list_msgs|notes_mark_read|notes_mark_unread|notes_nav_create|notes_search|notes_unread|notes_version|nsapi_request_headers|nsapi_response_headers|nsapi_virtual|number_format|ob_clean|ob_end_clean|ob_end_flush|ob_flush|ob_get_clean|ob_get_contents|ob_get_flush|ob_get_length|ob_get_level|ob_get_status|ob_gzhandler|ob_iconv_handler|ob_implicit_flush|ob_list_handlers|ob_start|ob_tidyhandler|oci_bind_by_name|oci_cancel|oci_close|oci_commit|oci_connect|oci_define_by_name|oci_error|oci_execute|oci_fetch|oci_fetch_all|oci_fetch_array|oci_fetch_assoc|oci_fetch_object|oci_fetch_row|oci_field_is_null|oci_field_name|oci_field_precision|oci_field_scale|oci_field_size|oci_field_type|oci_field_type_raw|oci_free_statement|oci_internal_debug|oci_lob_copy|oci_lob_is_equal|oci_new_collection|oci_new_connect|oci_new_cursor|oci_new_descriptor|oci_num_fields|oci_num_rows|oci_parse|oci_password_change|oci_pconnect|oci_result|oci_rollback|oci_server_version|oci_set_prefetch|oci_statement_type|ocibindbyname|ocicancel|ocicloselob|ocicollappend|ocicollassign|ocicollassignelem|ocicollgetelem|ocicollmax|ocicollsize|ocicolltrim|ocicolumnisnull|ocicolumnname|ocicolumnprecision|ocicolumnscale|ocicolumnsize|ocicolumntype|ocicolumntyperaw|ocicommit|ocidefinebyname|ocierror|ociexecute|ocifetch|ocifetchinto|ocifetchstatement|ocifreecollection|ocifreecursor|ocifreedesc|ocifreestatement|ociinternaldebug|ociloadlob|ocilogoff|ocilogon|ocinewcollection|ocinewcursor|ocinewdescriptor|ocinlogon|ocinumcols|ociparse|ociplogon|ociresult|ocirollback|ocirowcount|ocisavelob|ocisavelobfile|ociserverversion|ocisetprefetch|ocistatementtype|ociwritelobtofile|ociwritetemporarylob|octdec|odbc_autocommit|odbc_binmode|odbc_close|odbc_close_all|odbc_columnprivileges|odbc_columns|odbc_commit|odbc_connect|odbc_cursor|odbc_data_source|odbc_do|odbc_error|odbc_errormsg|odbc_exec|odbc_execute|odbc_fetch_array|odbc_fetch_into|odbc_fetch_object|odbc_fetch_row|odbc_field_len|odbc_field_name|odbc_field_num|odbc_field_precision|odbc_field_scale|odbc_field_type|odbc_foreignkeys|odbc_free_result|odbc_gettypeinfo|odbc_longreadlen|odbc_next_result|odbc_num_fields|odbc_num_rows|odbc_pconnect|odbc_prepare|odbc_primarykeys|odbc_procedurecolumns|odbc_procedures|odbc_result|odbc_result_all|odbc_rollback|odbc_setoption|odbc_specialcolumns|odbc_statistics|odbc_tableprivileges|odbc_tables|opendir|openlog|openssl_csr_export|openssl_csr_export_to_file|openssl_csr_new|openssl_csr_sign|openssl_error_string|openssl_free_key|openssl_get_privatekey|openssl_get_publickey|openssl_open|openssl_pkcs7_decrypt|openssl_pkcs7_encrypt|openssl_pkcs7_sign|openssl_pkcs7_verify|openssl_pkey_export|openssl_pkey_export_to_file|openssl_pkey_get_private|openssl_pkey_get_public|openssl_pkey_new|openssl_private_decrypt|openssl_private_encrypt|openssl_public_decrypt|openssl_public_encrypt|openssl_seal|openssl_sign|openssl_verify|openssl_x509_check_private_key|openssl_x509_checkpurpose|openssl_x509_export|openssl_x509_export_to_file|openssl_x509_free|openssl_x509_parse|openssl_x509_read|ora_bind|ora_close|ora_columnname|ora_columnsize|ora_columntype|ora_commit|ora_commitoff|ora_commiton|ora_do|ora_error|ora_errorcode|ora_exec|ora_fetch|ora_fetch_into|ora_getcolumn|ora_logoff|ora_logon|ora_numcols|ora_numrows|ora_open|ora_parse|ora_plogon|ora_rollback|ord|output_add_rewrite_var|output_reset_rewrite_vars|overload|ovrimos_close|ovrimos_commit|ovrimos_connect|ovrimos_cursor|ovrimos_exec|ovrimos_execute|ovrimos_fetch_into|ovrimos_fetch_row|ovrimos_field_len|ovrimos_field_name|ovrimos_field_num|ovrimos_field_type|ovrimos_free_result|ovrimos_longreadlen|ovrimos_num_fields|ovrimos_num_rows|ovrimos_prepare|ovrimos_result|ovrimos_result_all|ovrimos_rollback|pack|parse_ini_file|parse_str|parse_url|passthru|pathinfo|pclose|pcntl_alarm|pcntl_exec|pcntl_fork|pcntl_getpriority|pcntl_setpriority|pcntl_signal|pcntl_wait|pcntl_waitpid|pcntl_wexitstatus|pcntl_wifexited|pcntl_wifsignaled|pcntl_wifstopped|pcntl_wstopsig|pcntl_wtermsig|pdf_add_annotation|pdf_add_bookmark|pdf_add_launchlink|pdf_add_locallink|pdf_add_note|pdf_add_outline|pdf_add_pdflink|pdf_add_thumbnail|pdf_add_weblink|pdf_arc|pdf_arcn|pdf_attach_file|pdf_begin_page|pdf_begin_pattern|pdf_begin_template|pdf_circle|pdf_clip|pdf_close|pdf_close_image|pdf_close_pdi|pdf_close_pdi_page|pdf_closepath|pdf_closepath_fill_stroke|pdf_closepath_stroke|pdf_concat|pdf_continue_text|pdf_curveto|pdf_delete|pdf_end_page|pdf_end_pattern|pdf_end_template|pdf_endpath|pdf_fill|pdf_fill_stroke|pdf_findfont|pdf_get_buffer|pdf_get_font|pdf_get_fontname|pdf_get_fontsize|pdf_get_image_height|pdf_get_image_width|pdf_get_majorversion|pdf_get_minorversion|pdf_get_parameter|pdf_get_pdi_parameter|pdf_get_pdi_value|pdf_get_value|pdf_initgraphics|pdf_lineto|pdf_makespotcolor|pdf_moveto|pdf_new|pdf_open|pdf_open_ccitt|pdf_open_file|pdf_open_gif|pdf_open_image|pdf_open_image_file|pdf_open_jpeg|pdf_open_memory_image|pdf_open_pdi|pdf_open_pdi_page|pdf_open_png|pdf_open_tiff|pdf_place_image|pdf_place_pdi_page|pdf_rect|pdf_restore|pdf_rotate|pdf_save|pdf_scale|pdf_set_border_color|pdf_set_border_dash|pdf_set_border_style|pdf_set_char_spacing|pdf_set_duration|pdf_set_font|pdf_set_horiz_scaling|pdf_set_info|pdf_set_info_author|pdf_set_info_creator|pdf_set_info_keywords|pdf_set_info_subject|pdf_set_info_title|pdf_set_leading|pdf_set_parameter|pdf_set_text_matrix|pdf_set_text_pos|pdf_set_text_rendering|pdf_set_text_rise|pdf_set_value|pdf_set_word_spacing|pdf_setcolor|pdf_setdash|pdf_setflat|pdf_setfont|pdf_setgray|pdf_setgray_fill|pdf_setgray_stroke|pdf_setlinecap|pdf_setlinejoin|pdf_setlinewidth|pdf_setmatrix|pdf_setmiterlimit|pdf_setpolydash|pdf_setrgbcolor|pdf_setrgbcolor_fill|pdf_setrgbcolor_stroke|pdf_show|pdf_show_boxed|pdf_show_xy|pdf_skew|pdf_stringwidth|pdf_stroke|pdf_translate|pfpro_cleanup|pfpro_init|pfpro_process|pfpro_process_raw|pfpro_version|pfsockopen|pg_affected_rows|pg_cancel_query|pg_client_encoding|pg_close|pg_connect|pg_connection_busy|pg_connection_reset|pg_connection_status|pg_convert|pg_copy_from|pg_copy_to|pg_dbname|pg_delete|pg_end_copy|pg_escape_bytea|pg_escape_string|pg_fetch_all|pg_fetch_array|pg_fetch_assoc|pg_fetch_object|pg_fetch_result|pg_fetch_row|pg_field_is_null|pg_field_name|pg_field_num|pg_field_prtlen|pg_field_size|pg_field_type|pg_free_result|pg_get_notify|pg_get_pid|pg_get_result|pg_host|pg_insert|pg_last_error|pg_last_notice|pg_last_oid|pg_lo_close|pg_lo_create|pg_lo_export|pg_lo_import|pg_lo_open|pg_lo_read|pg_lo_read_all|pg_lo_seek|pg_lo_tell|pg_lo_unlink|pg_lo_write|pg_meta_data|pg_num_fields|pg_num_rows|pg_options|pg_pconnect|pg_ping|pg_port|pg_put_line|pg_query|pg_result_error|pg_result_seek|pg_result_status|pg_select|pg_send_query|pg_set_client_encoding|pg_trace|pg_tty|pg_unescape_bytea|pg_untrace|pg_update|php_ini_scanned_files|php_logo_guid|php_sapi_name|php_uname|phpcredits|phpinfo|phpversion|pi|png2wbmp|popen|pos|posix_ctermid|posix_get_last_error|posix_getcwd|posix_getegid|posix_geteuid|posix_getgid|posix_getgrgid|posix_getgrnam|posix_getgroups|posix_getlogin|posix_getpgid|posix_getpgrp|posix_getpid|posix_getppid|posix_getpwnam|posix_getpwuid|posix_getrlimit|posix_getsid|posix_getuid|posix_isatty|posix_kill|posix_mkfifo|posix_setegid|posix_seteuid|posix_setgid|posix_setpgid|posix_setsid|posix_setuid|posix_strerror|posix_times|posix_ttyname|posix_uname|pow|preg_grep|preg_match|preg_match_all|preg_quote|preg_replace|preg_replace_callback|preg_split|prev|print|print_r|printer_abort|printer_close|printer_create_brush|printer_create_dc|printer_create_font|printer_create_pen|printer_delete_brush|printer_delete_dc|printer_delete_font|printer_delete_pen|printer_draw_bmp|printer_draw_chord|printer_draw_elipse|printer_draw_line|printer_draw_pie|printer_draw_rectangle|printer_draw_roundrect|printer_draw_text|printer_end_doc|printer_end_page|printer_get_option|printer_list|printer_logical_fontheight|printer_open|printer_select_brush|printer_select_font|printer_select_pen|printer_set_option|printer_start_doc|printer_start_page|printer_write|printf|proc_close|proc_get_status|proc_nice|proc_open|proc_terminate|pspell_add_to_personal|pspell_add_to_session|pspell_check|pspell_clear_session|pspell_config_create|pspell_config_ignore|pspell_config_mode|pspell_config_personal|pspell_config_repl|pspell_config_runtogether|pspell_config_save_repl|pspell_new|pspell_new_config|pspell_new_personal|pspell_save_wordlist|pspell_store_replacement|pspell_suggest|putenv|qdom_error|qdom_tree|quoted_printable_decode|quotemeta|rad2deg|rand|range|rawurldecode|rawurlencode|read_exif_data|readdir|readfile|readgzfile|readline|readline_add_history|readline_clear_history|readline_completion_function|readline_info|readline_list_history|readline_read_history|readline_write_history|readlink|realpath|recode|recode_file|recode_string|register_shutdown_function|register_tick_function|rename|reset|restore_error_handler|restore_include_path|rewind|rewinddir|rmdir|round|rsort|rtrim|scandir|sem_acquire|sem_get|sem_release|sem_remove|serialize|sesam_affected_rows|sesam_commit|sesam_connect|sesam_diagnostic|sesam_disconnect|sesam_errormsg|sesam_execimm|sesam_fetch_array|sesam_fetch_result|sesam_fetch_row|sesam_field_array|sesam_field_name|sesam_free_result|sesam_num_fields|sesam_query|sesam_rollback|sesam_seek_row|sesam_settransaction|session_cache_expire|session_cache_limiter|session_commit|session_decode|session_destroy|session_encode|session_get_cookie_params|session_id|session_is_registered|session_module_name|session_name|session_regenerate_id|session_register|session_save_path|session_set_cookie_params|session_set_save_handler|session_start|session_unregister|session_unset|session_write_close|set_error_handler|set_file_buffer|set_include_path|set_magic_quotes_runtime|set_time_limit|setcookie|setlocale|setrawcookie|settype|sha1|sha1_file|shell_exec|shm_attach|shm_detach|shm_get_var|shm_put_var|shm_remove|shm_remove_var|shmop_close|shmop_delete|shmop_open|shmop_read|shmop_size|shmop_write|show_source|shuffle|similar_text|simplexml_import_dom|simplexml_load_file|simplexml_load_string|sin|sinh|sizeof|sleep|snmp_get_quick_print|snmp_set_quick_print|snmpget|snmprealwalk|snmpset|snmpwalk|snmpwalkoid|socket_accept|socket_bind|socket_clear_error|socket_close|socket_connect|socket_create|socket_create_listen|socket_create_pair|socket_get_option|socket_get_status|socket_getpeername|socket_getsockname|socket_iovec_add|socket_iovec_alloc|socket_iovec_delete|socket_iovec_fetch|socket_iovec_free|socket_iovec_set|socket_last_error|socket_listen|socket_read|socket_readv|socket_recv|socket_recvfrom|socket_recvmsg|socket_select|socket_send|socket_sendmsg|socket_sendto|socket_set_block|socket_set_blocking|socket_set_nonblock|socket_set_option|socket_set_timeout|socket_shutdown|socket_strerror|socket_write|socket_writev|sort|soundex|split|spliti|sprintf|sql_regcase|sqlite_array_query|sqlite_busy_timeout|sqlite_changes|sqlite_close|sqlite_column|sqlite_create_aggregate|sqlite_create_function|sqlite_current|sqlite_error_string|sqlite_escape_string|sqlite_fetch_array|sqlite_fetch_single|sqlite_fetch_string|sqlite_field_name|sqlite_has_more|sqlite_last_error|sqlite_last_insert_rowid|sqlite_libencoding|sqlite_libversion|sqlite_next|sqlite_num_fields|sqlite_num_rows|sqlite_open|sqlite_popen|sqlite_query|sqlite_rewind|sqlite_seek|sqlite_udf_decode_binary|sqlite_udf_encode_binary|sqlite_unbuffered_query|sqrt|srand|sscanf|stat|str_ireplace|str_pad|str_repeat|str_replace|str_rot13|str_shuffle|str_split|str_word_count|strcasecmp|strchr|strcmp|strcoll|strcspn|stream_context_create|stream_context_get_options|stream_context_set_option|stream_context_set_params|stream_copy_to_stream|stream_filter_append|stream_filter_prepend|stream_filter_register|stream_get_contents|stream_get_filters|stream_get_line|stream_get_meta_data|stream_get_transports|stream_get_wrappers|stream_register_wrapper|stream_select|stream_set_blocking|stream_set_timeout|stream_set_write_buffer|stream_socket_accept|stream_socket_client|stream_socket_get_name|stream_socket_recvfrom|stream_socket_sendto|stream_socket_server|stream_wrapper_register|strftime|strip_tags|stripcslashes|stripos|stripslashes|stristr|strlen|strnatcasecmp|strnatcmp|strncasecmp|strncmp|strpos|strrchr|strrev|strripos|strrpos|strspn|strstr|strtok|strtolower|strtotime|strtoupper|strtr|strval|substr|substr_compare|substr_count|substr_replace|swf_actiongeturl|swf_actiongotoframe|swf_actiongotolabel|swf_actionnextframe|swf_actionplay|swf_actionprevframe|swf_actionsettarget|swf_actionstop|swf_actiontogglequality|swf_actionwaitforframe|swf_addbuttonrecord|swf_addcolor|swf_closefile|swf_definebitmap|swf_definefont|swf_defineline|swf_definepoly|swf_definerect|swf_definetext|swf_endbutton|swf_enddoaction|swf_endshape|swf_endsymbol|swf_fontsize|swf_fontslant|swf_fonttracking|swf_getbitmapinfo|swf_getfontinfo|swf_getframe|swf_labelframe|swf_lookat|swf_modifyobject|swf_mulcolor|swf_nextid|swf_oncondition|swf_openfile|swf_ortho|swf_ortho2|swf_perspective|swf_placeobject|swf_polarview|swf_popmatrix|swf_posround|swf_pushmatrix|swf_removeobject|swf_rotate|swf_scale|swf_setfont|swf_setframe|swf_shapearc|swf_shapecurveto|swf_shapecurveto3|swf_shapefillbitmapclip|swf_shapefillbitmaptile|swf_shapefilloff|swf_shapefillsolid|swf_shapelinesolid|swf_shapelineto|swf_shapemoveto|swf_showframe|swf_startbutton|swf_startdoaction|swf_startshape|swf_startsymbol|swf_textwidth|swf_translate|swf_viewport|swfaction|swfbitmap|swfbutton|swfbutton_keypress|swfdisplayitem|swffill|swffont|swfgradient|swfmorph|swfmovie|swfshape|swfsprite|swftext|swftextfield|sybase_affected_rows|sybase_close|sybase_connect|sybase_data_seek|sybase_deadlock_retry_count|sybase_fetch_array|sybase_fetch_assoc|sybase_fetch_field|sybase_fetch_object|sybase_fetch_row|sybase_field_seek|sybase_free_result|sybase_get_last_message|sybase_min_client_severity|sybase_min_error_severity|sybase_min_message_severity|sybase_min_server_severity|sybase_num_fields|sybase_num_rows|sybase_pconnect|sybase_query|sybase_result|sybase_select_db|sybase_set_message_handler|sybase_unbuffered_query|symlink|syslog|system|tan|tanh|tcpwrap_check|tempnam|textdomain|tidy_access_count|tidy_clean_repair|tidy_config_count|tidy_diagnose|tidy_error_count|tidy_get_body|tidy_get_config|tidy_get_error_buffer|tidy_get_head|tidy_get_html|tidy_get_html_ver|tidy_get_output|tidy_get_release|tidy_get_root|tidy_get_status|tidy_getopt|tidy_is_xhtml|tidy_is_xml|tidy_load_config|tidy_parse_file|tidy_parse_string|tidy_repair_file|tidy_repair_string|tidy_reset_config|tidy_save_config|tidy_set_encoding|tidy_setopt|tidy_warning_count|time|tmpfile|token_get_all|token_name|touch|trigger_error|trim|uasort|ucfirst|ucwords|udm_add_search_limit|udm_alloc_agent|udm_alloc_agent_array|udm_api_version|udm_cat_list|udm_cat_path|udm_check_charset|udm_check_stored|udm_clear_search_limits|udm_close_stored|udm_crc32|udm_errno|udm_error|udm_find|udm_free_agent|udm_free_ispell_data|udm_free_res|udm_get_doc_count|udm_get_res_field|udm_get_res_param|udm_hash32|udm_load_ispell_data|udm_open_stored|udm_set_agent_param|uksort|umask|uniqid|unixtojd|unlink|unpack|unregister_tick_function|unserialize|unset|urldecode|urlencode|user_error|usleep|usort|utf8_decode|utf8_encode|var_dump|var_export|variant|version_compare|virtual|vpopmail_add_alias_domain|vpopmail_add_alias_domain_ex|vpopmail_add_domain|vpopmail_add_domain_ex|vpopmail_add_user|vpopmail_alias_add|vpopmail_alias_del|vpopmail_alias_del_domain|vpopmail_alias_get|vpopmail_alias_get_all|vpopmail_auth_user|vpopmail_del_domain|vpopmail_del_domain_ex|vpopmail_del_user|vpopmail_error|vpopmail_passwd|vpopmail_set_user_quota|vprintf|vsprintf|w32api_deftype|w32api_init_dtype|w32api_invoke_function|w32api_register_function|w32api_set_call_method|wddx_add_vars|wddx_deserialize|wddx_packet_end|wddx_packet_start|wddx_serialize_value|wddx_serialize_vars|wordwrap|xdiff_file_diff|xdiff_file_diff_binary|xdiff_file_merge3|xdiff_file_patch|xdiff_file_patch_binary|xdiff_string_diff|xdiff_string_diff_binary|xdiff_string_merge3|xdiff_string_patch|xdiff_string_patch_binary|xml_error_string|xml_get_current_byte_index|xml_get_current_column_number|xml_get_current_line_number|xml_get_error_code|xml_parse|xml_parse_into_struct|xml_parser_create|xml_parser_create_ns|xml_parser_free|xml_parser_get_option|xml_parser_set_option|xml_set_character_data_handler|xml_set_default_handler|xml_set_element_handler|xml_set_end_namespace_decl_handler|xml_set_external_entity_ref_handler|xml_set_notation_decl_handler|xml_set_object|xml_set_processing_instruction_handler|xml_set_start_namespace_decl_handler|xml_set_unparsed_entity_decl_handler|xmlrpc_decode|xmlrpc_decode_request|xmlrpc_encode|xmlrpc_encode_request|xmlrpc_get_type|xmlrpc_parse_method_descriptions|xmlrpc_server_add_introspection_data|xmlrpc_server_call_method|xmlrpc_server_create|xmlrpc_server_destroy|xmlrpc_server_register_introspection_callback|xmlrpc_server_register_method|xmlrpc_set_type|xpath_eval|xpath_eval_expression|xpath_new_context|xptr_eval|xptr_new_context|xsl_xsltprocessor_get_parameter|xsl_xsltprocessor_has_exslt_support|xsl_xsltprocessor_import_stylesheet|xsl_xsltprocessor_register_php_functions|xsl_xsltprocessor_remove_parameter|xsl_xsltprocessor_set_parameter|xsl_xsltprocessor_transform_to_doc|xsl_xsltprocessor_transform_to_uri|xsl_xsltprocessor_transform_to_xml|xslt_create|xslt_errno|xslt_error|xslt_free|xslt_process|xslt_set_base|xslt_set_encoding|xslt_set_error_handler|xslt_set_log|xslt_set_sax_handler|xslt_set_sax_handlers|xslt_set_scheme_handler|xslt_set_scheme_handlers|yaz_addinfo|yaz_ccl_conf|yaz_ccl_parse|yaz_close|yaz_connect|yaz_database|yaz_element|yaz_errno|yaz_error|yaz_es_result|yaz_get_option|yaz_hits|yaz_itemorder|yaz_present|yaz_range|yaz_record|yaz_scan|yaz_scan_result|yaz_schema|yaz_search|yaz_set_option|yaz_sort|yaz_syntax|yaz_wait|yp_all|yp_cat|yp_err_string|yp_errno|yp_first|yp_get_default_domain|yp_master|yp_match|yp_next|yp_order|zend_logo_guid|zend_version|zip_close|zip_entry_close|zip_entry_compressedsize|zip_entry_compressionmethod|zip_entry_filesize|zip_entry_name|zip_entry_open|zip_entry_read|zip_open|zip_read|zlib_get_coding_type".split("|")),c=e.arrayToMap("abstract|and|array|as|break|case|catch|cfunction|class|clone|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|final|for|foreach|function|include|include_once|global|goto|if|implements|interface|instanceof|namespace|new|old_function|or|private|protected|public|return|require|require_once|static|switch|throw|try|use|var|while|xor".split("|")),d=e.arrayToMap("true|false|null|__FILE__|__LINE__|__METHOD__|__FUNCTION__|__CLASS__".split("|")),g=e.arrayToMap("$_GLOBALS|$_SERVER|$_GET|$_POST|$_FILES|$_REQUEST|$_SESSION|$_ENV|$_COOKIE|$php_errormsg|$HTTP_RAW_POST_DATA|$http_response_header|$argc|$argv".split("|")),h=e.arrayToMap([]);this.$rules={start:[{token:"support",regex:"<\\?(?:php|\\=)"},{token:"support",regex:"\\?>"},{token:"comment",regex:"\\/\\/.*$"},{token:"comment",regex:"#.*$"},a.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/][gimy]*\\s*(?=[).,;]|$)"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language",regex:"\\b(?:DEFAULT_INCLUDE_PATH|E_(?:ALL|CO(?:MPILE_(?:ERROR|WARNING)|RE_(?:ERROR|WARNING))|ERROR|NOTICE|PARSE|STRICT|USER_(?:ERROR|NOTICE|WARNING)|WARNING)|P(?:EAR_(?:EXTENSION_DIR|INSTALL_DIR)|HP_(?:BINDIR|CONFIG_FILE_(?:PATH|SCAN_DIR)|DATADIR|E(?:OL|XTENSION_DIR)|INT_(?:MAX|SIZE)|L(?:IBDIR|OCALSTATEDIR)|O(?:S|UTPUT_HANDLER_(?:CONT|END|START))|PREFIX|S(?:API|HLIB_SUFFIX|YSCONFDIR)|VERSION))|__COMPILER_HALT_OFFSET__)\\b"},{token:"constant.language",regex:"\\b(?:A(?:B(?:DAY_(?:1|2|3|4|5|6|7)|MON_(?:1(?:0|1|2|)|2|3|4|5|6|7|8|9))|LT_DIGITS|M_STR|SSERT_(?:ACTIVE|BAIL|CALLBACK|QUIET_EVAL|WARNING))|C(?:ASE_(?:LOWER|UPPER)|HAR_MAX|O(?:DESET|NNECTION_(?:ABORTED|NORMAL|TIMEOUT)|UNT_(?:NORMAL|RECURSIVE))|R(?:EDITS_(?:ALL|DOCS|FULLPAGE|G(?:ENERAL|ROUP)|MODULES|QA|SAPI)|NCYSTR|YPT_(?:BLOWFISH|EXT_DES|MD5|S(?:ALT_LENGTH|TD_DES)))|URRENCY_SYMBOL)|D(?:AY_(?:1|2|3|4|5|6|7)|ECIMAL_POINT|IRECTORY_SEPARATOR|_(?:FMT|T_FMT))|E(?:NT_(?:COMPAT|NOQUOTES|QUOTES)|RA(?:_(?:D_(?:FMT|T_FMT)|T_FMT|YEAR)|)|XTR_(?:IF_EXISTS|OVERWRITE|PREFIX_(?:ALL|I(?:F_EXISTS|NVALID)|SAME)|SKIP))|FRAC_DIGITS|GROUPING|HTML_(?:ENTITIES|SPECIALCHARS)|IN(?:FO_(?:ALL|C(?:ONFIGURATION|REDITS)|ENVIRONMENT|GENERAL|LICENSE|MODULES|VARIABLES)|I_(?:ALL|PERDIR|SYSTEM|USER)|T_(?:CURR_SYMBOL|FRAC_DIGITS))|L(?:C_(?:ALL|C(?:OLLATE|TYPE)|M(?:ESSAGES|ONETARY)|NUMERIC|TIME)|O(?:CK_(?:EX|NB|SH|UN)|G_(?:A(?:LERT|UTH(?:PRIV|))|C(?:ONS|R(?:IT|ON))|D(?:AEMON|EBUG)|E(?:MERG|RR)|INFO|KERN|L(?:OCAL(?:0|1|2|3|4|5|6|7)|PR)|MAIL|N(?:DELAY|EWS|O(?:TICE|WAIT))|ODELAY|P(?:ERROR|ID)|SYSLOG|U(?:SER|UCP)|WARNING)))|M(?:ON_(?:1(?:0|1|2|)|2|3|4|5|6|7|8|9|DECIMAL_POINT|GROUPING|THOUSANDS_SEP)|_(?:1_PI|2_(?:PI|SQRTPI)|E|L(?:N(?:10|2)|OG(?:10E|2E))|PI(?:_(?:2|4)|)|SQRT(?:1_2|2)))|N(?:EGATIVE_SIGN|O(?:EXPR|STR)|_(?:CS_PRECEDES|S(?:EP_BY_SPACE|IGN_POSN)))|P(?:ATH(?:INFO_(?:BASENAME|DIRNAME|EXTENSION)|_SEPARATOR)|M_STR|OSITIVE_SIGN|_(?:CS_PRECEDES|S(?:EP_BY_SPACE|IGN_POSN)))|RADIXCHAR|S(?:EEK_(?:CUR|END|SET)|ORT_(?:ASC|DESC|NUMERIC|REGULAR|STRING)|TR_PAD_(?:BOTH|LEFT|RIGHT))|T(?:HOUS(?:ANDS_SEP|EP)|_FMT(?:_AMPM|))|YES(?:EXPR|STR)|STD(?:IN|OUT|ERR))\\b"},{token:function(a){if(c.hasOwnProperty(a))return"keyword";if(d.hasOwnProperty(a))return"constant.language";if(g.hasOwnProperty(a))return"variable.language";if(h.hasOwnProperty(a))return"invalid.illegal";if(b.hasOwnProperty(a))return"support.function";if(a=="debugger")return"invalid.deprecated";if(a.match(/^(\$[a-zA-Z][a-zA-Z0-9_]*|self|parent)$/))return"variable";return"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]},this.addRules(a.getRules(),"doc-"),this.$rules["doc-start"][0].next="start"};d.inherits(h,g),b.PhpHighlightRules=h}),__ace_shadowed__.define("ace/mode/doc_comment_highlight_rules",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc",regex:"\\*\\/",next:"start"},{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",regex:"s+"},{token:"comment.doc",regex:"TODO"},{token:"comment.doc",regex:"[^@\\*]+"},{token:"comment.doc",regex:"."}]}};d.inherits(f,e),function(){this.getStartRule=function(a){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:a}}}.call(f.prototype),b.DocCommentHighlightRules=f}) \ No newline at end of file diff --git a/build/textarea/src/mode-python.js b/build/textarea/src/mode-python.js deleted file mode 100644 index 80970228..00000000 --- a/build/textarea/src/mode-python.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/mode/python",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/python_highlight_rules").PythonHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(j,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)#/;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,"#")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[\:]\s*$/);h&&(d+=c)}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)}}.call(j.prototype),b.Mode=j}),__ace_shadowed__.define("ace/mode/python_highlight_rules",function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/text_highlight_rules").TextHighlightRules,g=function(){var a=e.arrayToMap("and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield".split("|")),b=e.arrayToMap("True|False|None|NotImplemented|Ellipsis|__debug__".split("|")),c=e.arrayToMap("abs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|binfile|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|set|apply|delattr|help|next|setattr|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern".split("|")),d=e.arrayToMap("".split("|")),f="(?:r|u|ur|R|U|UR|Ur|uR)?",g="(?:(?:[1-9]\\d*)|(?:0))",h="(?:0[oO]?[0-7]+)",i="(?:0[xX][\\dA-Fa-f]+)",j="(?:0[bB][01]+)",k="(?:"+g+"|"+h+"|"+i+"|"+j+")",l="(?:[eE][+-]?\\d+)",m="(?:\\.\\d+)",n="(?:\\d+)",o="(?:(?:"+n+"?"+m+")|(?:"+n+"\\.))",p="(?:(?:"+o+"|"+n+")"+l+")",q="(?:"+p+"|"+o+")";this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"string",regex:f+'"{3}(?:[^\\\\]|\\\\.)*?"{3}'},{token:"string",regex:f+'"{3}.*$',next:"qqstring"},{token:"string",regex:f+'"(?:[^\\\\]|\\\\.)*?"'},{token:"string",regex:f+"'{3}(?:[^\\\\]|\\\\.)*?'{3}"},{token:"string",regex:f+"'{3}.*$",next:"qstring"},{token:"string",regex:f+"'(?:[^\\\\]|\\\\.)*?'"},{token:"constant.numeric",regex:"(?:"+q+"|\\d+)[jJ]\\b"},{token:"constant.numeric",regex:q},{token:"constant.numeric",regex:k+"[lL]\\b"},{token:"constant.numeric",regex:k+"\\b"},{token:function(e){return a.hasOwnProperty(e)?"keyword":b.hasOwnProperty(e)?"constant.language":d.hasOwnProperty(e)?"invalid.illegal":c.hasOwnProperty(e)?"support.function":e=="debugger"?"invalid.deprecated":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|%|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"lparen",regex:"[\\[\\(\\{]"},{token:"rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+"}],qqstring:[{token:"string",regex:'(?:[^\\\\]|\\\\.)*?"{3}',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:[^\\\\]|\\\\.)*?'{3}",next:"start"},{token:"string",regex:".+"}]}};d.inherits(g,f),b.PythonHighlightRules=g}) \ No newline at end of file diff --git a/build/textarea/src/mode-ruby.js b/build/textarea/src/mode-ruby.js deleted file mode 100644 index aaddc51f..00000000 --- a/build/textarea/src/mode-ruby.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/mode/ruby",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/ruby_highlight_rules").RubyHighlightRules,h=a("ace/mode/matching_brace_outdent").MatchingBraceOutdent,i=a("ace/range").Range,j=function(){this.$tokenizer=new f((new g).getRules()),this.$outdent=new h};d.inherits(j,e),function(){this.toggleCommentLines=function(a,b,c,d){var e=!0,f=[],g=/^(\s*)#/;for(var h=c;h<=d;h++)if(!g.test(b.getLine(h))){e=!1;break}if(e){var j=new i(0,0,0,0);for(var h=c;h<=d;h++){var k=b.getLine(h),l=k.match(g);j.start.row=h,j.end.row=h,j.end.column=l[0].length,b.replace(j,l[1])}}else b.indentRows(c,d,"#")},this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=this.$tokenizer.getLineTokens(b,a),f=e.tokens,g=e.state;if(f.length&&f[f.length-1].type=="comment")return d;if(a=="start"){var h=b.match(/^.*[\{\(\[]\s*$/);h&&(d+=c)}return d},this.checkOutdent=function(a,b,c){return this.$outdent.checkOutdent(b,c)},this.autoOutdent=function(a,b,c){this.$outdent.autoOutdent(b,c)}}.call(j.prototype),b.Mode=j}),__ace_shadowed__.define("ace/mode/ruby_highlight_rules",function(a,b,c){var d=a("pilot/oop"),e=a("pilot/lang"),f=a("ace/mode/text_highlight_rules").TextHighlightRules,g=function(){var a=e.arrayToMap("abort|Array|at_exit|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|eval|exec|exit|exit!fail|Float|fork|format|gets|global_variables|gsub|gsub!|Integer|lambda|load|local_variables|loop|open|p|print|printf|proc|putc|puts|raise|rand|readline|readlines|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan".split("|")),b=e.arrayToMap("alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|if|in|__LINE__|module|next|not|or|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield".split("|")),c=e.arrayToMap("true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING".split("|")),d=e.arrayToMap("$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE".split("|"));this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment",regex:"^=begin$",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:function(e){return e=="self"?"variable.language":b.hasOwnProperty(e)?"keyword":c.hasOwnProperty(e)?"constant.language":d.hasOwnProperty(e)?"variable.language":a.hasOwnProperty(e)?"support.function":e=="debugger"?"invalid.deprecated":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end$",next:"start"},{token:"comment",regex:".+"}]}};d.inherits(g,f),b.RubyHighlightRules=g}) \ No newline at end of file diff --git a/build/textarea/src/mode-xml.js b/build/textarea/src/mode-xml.js deleted file mode 100644 index 73688bcd..00000000 --- a/build/textarea/src/mode-xml.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/mode/xml",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/xml_highlight_rules").XmlHighlightRules,h=function(){this.$tokenizer=new f((new g).getRules())};d.inherits(h,e),function(){this.getNextLineIndent=function(a,b,c){return this.$getIndent(b)}}.call(h.prototype),b.Mode=h}),__ace_shadowed__.define("ace/mode/xml_highlight_rules",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"text",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:"xml_pe",regex:"<\\?.*?\\?>"},{token:"comment",regex:"<\\!--",next:"comment"},{token:"text",regex:"<\\/?",next:"tag"},{token:"text",regex:"\\s+"},{token:"text",regex:"[^<]+"}],tag:[{token:"text",regex:">",next:"start"},{token:"keyword",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:".+"}]}};d.inherits(f,e),b.XmlHighlightRules=f}) \ No newline at end of file diff --git a/build/textarea/src/theme-clouds.js b/build/textarea/src/theme-clouds.js deleted file mode 100644 index 73dfa943..00000000 --- a/build/textarea/src/theme-clouds.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/theme/clouds",function(a,b,c){var d=a("pilot/dom"),e=".ace-clouds .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-clouds .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-clouds .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-clouds .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-clouds .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-clouds .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-clouds .ace_scroller {\n background-color: #FFFFFF;\n}\n\n.ace-clouds .ace_text-layer {\n cursor: text;\n color: #000000;\n}\n\n.ace-clouds .ace_cursor {\n border-left: 2px solid #000000;\n}\n\n.ace-clouds .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #000000;\n}\n \n.ace-clouds .ace_marker-layer .ace_selection {\n background: #BDD5FC;\n}\n\n.ace-clouds .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-clouds .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid #BFBFBF;\n}\n\n.ace-clouds .ace_marker-layer .ace_active_line {\n background: #FFFBD1;\n}\n\n \n.ace-clouds .ace_invisible {\n color: #BFBFBF;\n}\n\n.ace-clouds .ace_keyword {\n color:#AF956F;\n}\n\n.ace-clouds .ace_keyword.ace_operator {\n color:#484848;\n}\n\n.ace-clouds .ace_constant {\n \n}\n\n.ace-clouds .ace_constant.ace_language {\n color:#39946A;\n}\n\n.ace-clouds .ace_constant.ace_library {\n \n}\n\n.ace-clouds .ace_constant.ace_numeric {\n color:#46A609;\n}\n\n.ace-clouds .ace_invalid {\n background-color:#FF002A;\n}\n\n.ace-clouds .ace_invalid.ace_illegal {\n \n}\n\n.ace-clouds .ace_invalid.ace_deprecated {\n \n}\n\n.ace-clouds .ace_support {\n \n}\n\n.ace-clouds .ace_support.ace_function {\n color:#C52727;\n}\n\n.ace-clouds .ace_function.ace_buildin {\n \n}\n\n.ace-clouds .ace_string {\n color:#5D90CD;\n}\n\n.ace-clouds .ace_string.ace_regexp {\n \n}\n\n.ace-clouds .ace_comment {\n color:#BCC8BA;\n}\n\n.ace-clouds .ace_comment.ace_doc {\n \n}\n\n.ace-clouds .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-clouds .ace_variable {\n \n}\n\n.ace-clouds .ace_variable.ace_language {\n \n}\n\n.ace-clouds .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-clouds"}) \ No newline at end of file diff --git a/build/textarea/src/theme-clouds_midnight.js b/build/textarea/src/theme-clouds_midnight.js deleted file mode 100644 index 090ddb97..00000000 --- a/build/textarea/src/theme-clouds_midnight.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/theme/clouds_midnight",function(a,b,c){var d=a("pilot/dom"),e=".ace-clouds-midnight .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-clouds-midnight .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-clouds-midnight .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-clouds-midnight .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-clouds-midnight .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-clouds-midnight .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-clouds-midnight .ace_scroller {\n background-color: #191919;\n}\n\n.ace-clouds-midnight .ace_text-layer {\n cursor: text;\n color: #929292;\n}\n\n.ace-clouds-midnight .ace_cursor {\n border-left: 2px solid #7DA5DC;\n}\n\n.ace-clouds-midnight .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #7DA5DC;\n}\n \n.ace-clouds-midnight .ace_marker-layer .ace_selection {\n background: #000000;\n}\n\n.ace-clouds-midnight .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-clouds-midnight .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid #BFBFBF;\n}\n\n.ace-clouds-midnight .ace_marker-layer .ace_active_line {\n background: rgba(215, 215, 215, 0.031);\n}\n\n \n.ace-clouds-midnight .ace_invisible {\n color: #BFBFBF;\n}\n\n.ace-clouds-midnight .ace_keyword {\n color:#927C5D;\n}\n\n.ace-clouds-midnight .ace_keyword.ace_operator {\n color:#4B4B4B;\n}\n\n.ace-clouds-midnight .ace_constant {\n \n}\n\n.ace-clouds-midnight .ace_constant.ace_language {\n color:#39946A;\n}\n\n.ace-clouds-midnight .ace_constant.ace_library {\n \n}\n\n.ace-clouds-midnight .ace_constant.ace_numeric {\n color:#46A609;\n}\n\n.ace-clouds-midnight .ace_invalid {\n color:#FFFFFF;\nbackground-color:#E92E2E;\n}\n\n.ace-clouds-midnight .ace_invalid.ace_illegal {\n \n}\n\n.ace-clouds-midnight .ace_invalid.ace_deprecated {\n \n}\n\n.ace-clouds-midnight .ace_support {\n \n}\n\n.ace-clouds-midnight .ace_support.ace_function {\n color:#E92E2E;\n}\n\n.ace-clouds-midnight .ace_function.ace_buildin {\n \n}\n\n.ace-clouds-midnight .ace_string {\n color:#5D90CD;\n}\n\n.ace-clouds-midnight .ace_string.ace_regexp {\n \n}\n\n.ace-clouds-midnight .ace_comment {\n color:#3C403B;\n}\n\n.ace-clouds-midnight .ace_comment.ace_doc {\n \n}\n\n.ace-clouds-midnight .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-clouds-midnight .ace_variable {\n \n}\n\n.ace-clouds-midnight .ace_variable.ace_language {\n \n}\n\n.ace-clouds-midnight .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-clouds-midnight"}) \ No newline at end of file diff --git a/build/textarea/src/theme-cobalt.js b/build/textarea/src/theme-cobalt.js deleted file mode 100644 index cda77f43..00000000 --- a/build/textarea/src/theme-cobalt.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/theme/cobalt",function(a,b,c){var d=a("pilot/dom"),e=".ace-cobalt .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-cobalt .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-cobalt .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-cobalt .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-cobalt .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-cobalt .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-cobalt .ace_scroller {\n background-color: #002240;\n}\n\n.ace-cobalt .ace_text-layer {\n cursor: text;\n color: #FFFFFF;\n}\n\n.ace-cobalt .ace_cursor {\n border-left: 2px solid #FFFFFF;\n}\n\n.ace-cobalt .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #FFFFFF;\n}\n \n.ace-cobalt .ace_marker-layer .ace_selection {\n background: rgba(179, 101, 57, 0.75);\n}\n\n.ace-cobalt .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-cobalt .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(255, 255, 255, 0.15);\n}\n\n.ace-cobalt .ace_marker-layer .ace_active_line {\n background: rgba(0, 0, 0, 0.35);\n}\n\n \n.ace-cobalt .ace_invisible {\n color: rgba(255, 255, 255, 0.15);\n}\n\n.ace-cobalt .ace_keyword {\n color:#FF9D00;\n}\n\n.ace-cobalt .ace_keyword.ace_operator {\n \n}\n\n.ace-cobalt .ace_constant {\n color:#FF628C;\n}\n\n.ace-cobalt .ace_constant.ace_language {\n \n}\n\n.ace-cobalt .ace_constant.ace_library {\n \n}\n\n.ace-cobalt .ace_constant.ace_numeric {\n \n}\n\n.ace-cobalt .ace_invalid {\n color:#F8F8F8;\nbackground-color:#800F00;\n}\n\n.ace-cobalt .ace_invalid.ace_illegal {\n \n}\n\n.ace-cobalt .ace_invalid.ace_deprecated {\n \n}\n\n.ace-cobalt .ace_support {\n color:#80FFBB;\n}\n\n.ace-cobalt .ace_support.ace_function {\n color:#FFB054;\n}\n\n.ace-cobalt .ace_function.ace_buildin {\n \n}\n\n.ace-cobalt .ace_string {\n \n}\n\n.ace-cobalt .ace_string.ace_regexp {\n color:#80FFC2;\n}\n\n.ace-cobalt .ace_comment {\n font-style:italic;\ncolor:#0088FF;\n}\n\n.ace-cobalt .ace_comment.ace_doc {\n \n}\n\n.ace-cobalt .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-cobalt .ace_variable {\n color:#CCCCCC;\n}\n\n.ace-cobalt .ace_variable.ace_language {\n color:#FF80E1;\n}\n\n.ace-cobalt .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-cobalt"}) \ No newline at end of file diff --git a/build/textarea/src/theme-dawn.js b/build/textarea/src/theme-dawn.js deleted file mode 100644 index 811b1e37..00000000 --- a/build/textarea/src/theme-dawn.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/theme/dawn",function(a,b,c){var d=a("pilot/dom"),e=".ace-dawn .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-dawn .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-dawn .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-dawn .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-dawn .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-dawn .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-dawn .ace_scroller {\n background-color: #F9F9F9;\n}\n\n.ace-dawn .ace_text-layer {\n cursor: text;\n color: #080808;\n}\n\n.ace-dawn .ace_cursor {\n border-left: 2px solid #000000;\n}\n\n.ace-dawn .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #000000;\n}\n \n.ace-dawn .ace_marker-layer .ace_selection {\n background: rgba(39, 95, 255, 0.30);\n}\n\n.ace-dawn .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-dawn .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(75, 75, 126, 0.50);\n}\n\n.ace-dawn .ace_marker-layer .ace_active_line {\n background: rgba(36, 99, 180, 0.12);\n}\n\n \n.ace-dawn .ace_invisible {\n color: rgba(75, 75, 126, 0.50);\n}\n\n.ace-dawn .ace_keyword {\n color:#794938;\n}\n\n.ace-dawn .ace_keyword.ace_operator {\n \n}\n\n.ace-dawn .ace_constant {\n color:#811F24;\n}\n\n.ace-dawn .ace_constant.ace_language {\n \n}\n\n.ace-dawn .ace_constant.ace_library {\n \n}\n\n.ace-dawn .ace_constant.ace_numeric {\n \n}\n\n.ace-dawn .ace_invalid {\n \n}\n\n.ace-dawn .ace_invalid.ace_illegal {\n text-decoration:underline;\nfont-style:italic;\ncolor:#F8F8F8;\nbackground-color:#B52A1D;\n}\n\n.ace-dawn .ace_invalid.ace_deprecated {\n text-decoration:underline;\nfont-style:italic;\ncolor:#B52A1D;\n}\n\n.ace-dawn .ace_support {\n color:#691C97;\n}\n\n.ace-dawn .ace_support.ace_function {\n color:#693A17;\n}\n\n.ace-dawn .ace_function.ace_buildin {\n \n}\n\n.ace-dawn .ace_string {\n color:#0B6125;\n}\n\n.ace-dawn .ace_string.ace_regexp {\n color:#CF5628;\n}\n\n.ace-dawn .ace_comment {\n font-style:italic;\ncolor:#5A525F;\n}\n\n.ace-dawn .ace_comment.ace_doc {\n \n}\n\n.ace-dawn .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-dawn .ace_variable {\n color:#234A97;\n}\n\n.ace-dawn .ace_variable.ace_language {\n \n}\n\n.ace-dawn .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-dawn"}) \ No newline at end of file diff --git a/build/textarea/src/theme-eclipse.js b/build/textarea/src/theme-eclipse.js deleted file mode 100644 index 3d167885..00000000 --- a/build/textarea/src/theme-eclipse.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/theme/eclipse",function(a,b,c){var d=a("pilot/dom"),e=".ace-eclipse .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-eclipse .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-eclipse .ace_gutter {\n width: 50px;\n background: rgb(227, 227, 227);\n border-right: 1px solid rgb(159, 159, 159);\t \n color: rgb(136, 136, 136);\n}\n\n.ace-eclipse .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-eclipse .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-eclipse .ace_text-layer {\n cursor: text;\n}\n\n.ace-eclipse .ace_cursor {\n border-left: 1px solid black;\n}\n\n.ace-eclipse .ace_line .ace_keyword, .ace-eclipse .ace_line .ace_variable {\n color: rgb(127, 0, 85);\n}\n\n.ace-eclipse .ace_line .ace_constant.ace_buildin {\n color: rgb(88, 72, 246);\n}\n\n.ace-eclipse .ace_line .ace_constant.ace_library {\n color: rgb(6, 150, 14);\n}\n\n.ace-eclipse .ace_line .ace_function {\n color: rgb(60, 76, 114);\n}\n\n.ace-eclipse .ace_line .ace_string {\n color: rgb(42, 0, 255);\n}\n\n.ace-eclipse .ace_line .ace_comment {\n color: rgb(63, 127, 95);\n}\n\n.ace-eclipse .ace_line .ace_comment.ace_doc {\n color: rgb(63, 95, 191);\n}\n\n.ace-eclipse .ace_line .ace_comment.ace_doc.ace_tag {\n color: rgb(127, 159, 191);\n}\n\n.ace-eclipse .ace_line .ace_constant.ace_numeric {\n}\n\n.ace-eclipse .ace_line .ace_tag {\n\tcolor: rgb(63, 127, 127);\n}\n\n.ace-eclipse .ace_line .ace_xml_pe {\n color: rgb(104, 104, 91);\n}\n\n.ace-eclipse .ace_marker-layer .ace_selection {\n background: rgb(181, 213, 255);\n}\n\n.ace-eclipse .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-eclipse .ace_marker-layer .ace_active_line {\n background: rgb(232, 242, 254);\n}";d.importCssString(e),b.cssClass="ace-eclipse"}) \ No newline at end of file diff --git a/build/textarea/src/theme-idle_fingers.js b/build/textarea/src/theme-idle_fingers.js deleted file mode 100644 index 05810f76..00000000 --- a/build/textarea/src/theme-idle_fingers.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/theme/idle_fingers",function(a,b,c){var d=a("pilot/dom"),e=".ace-idle-fingers .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-idle-fingers .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-idle-fingers .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-idle-fingers .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-idle-fingers .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-idle-fingers .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-idle-fingers .ace_scroller {\n background-color: #323232;\n}\n\n.ace-idle-fingers .ace_text-layer {\n cursor: text;\n color: #FFFFFF;\n}\n\n.ace-idle-fingers .ace_cursor {\n border-left: 2px solid #91FF00;\n}\n\n.ace-idle-fingers .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #91FF00;\n}\n \n.ace-idle-fingers .ace_marker-layer .ace_selection {\n background: rgba(90, 100, 126, 0.88);\n}\n\n.ace-idle-fingers .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-idle-fingers .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid #404040;\n}\n\n.ace-idle-fingers .ace_marker-layer .ace_active_line {\n background: #353637;\n}\n\n \n.ace-idle-fingers .ace_invisible {\n color: #404040;\n}\n\n.ace-idle-fingers .ace_keyword {\n color:#CC7833;\n}\n\n.ace-idle-fingers .ace_keyword.ace_operator {\n \n}\n\n.ace-idle-fingers .ace_constant {\n color:#6C99BB;\n}\n\n.ace-idle-fingers .ace_constant.ace_language {\n \n}\n\n.ace-idle-fingers .ace_constant.ace_library {\n \n}\n\n.ace-idle-fingers .ace_constant.ace_numeric {\n \n}\n\n.ace-idle-fingers .ace_invalid {\n color:#FFFFFF;\nbackground-color:#FF0000;\n}\n\n.ace-idle-fingers .ace_invalid.ace_illegal {\n \n}\n\n.ace-idle-fingers .ace_invalid.ace_deprecated {\n \n}\n\n.ace-idle-fingers .ace_support {\n color:#bc9458;\n}\n\n.ace-idle-fingers .ace_support.ace_function {\n color:#B83426;\n}\n\n.ace-idle-fingers .ace_function.ace_buildin {\n \n}\n\n.ace-idle-fingers .ace_string {\n color:#A5C261;\n}\n\n.ace-idle-fingers .ace_string.ace_regexp {\n color:#CCCC33;\n}\n\n.ace-idle-fingers .ace_comment {\n font-style:italic;\n color:#BC9458;\n}\n\n.ace-idle-fingers .ace_comment.ace_doc {\n \n}\n\n.ace-idle-fingers .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-idle-fingers .ace_variable {\n color:#b7dff8;\n}\n\n.ace-idle-fingers .ace_variable.ace_language {\n color:#b7dff8;\n}\n\n.ace-idle-fingers .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-idle-fingers"}) \ No newline at end of file diff --git a/build/textarea/src/theme-kr_theme.js b/build/textarea/src/theme-kr_theme.js deleted file mode 100644 index f681c880..00000000 --- a/build/textarea/src/theme-kr_theme.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/theme/kr_theme",function(a,b,c){var d=a("pilot/dom"),e=".ace-kr-theme .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-kr-theme .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-kr-theme .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-kr-theme .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-kr-theme .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-kr-theme .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-kr-theme .ace_scroller {\n background-color: #0B0A09;\n}\n\n.ace-kr-theme .ace_text-layer {\n cursor: text;\n color: #FCFFE0;\n}\n\n.ace-kr-theme .ace_cursor {\n border-left: 2px solid #FF9900;\n}\n\n.ace-kr-theme .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #FF9900;\n}\n \n.ace-kr-theme .ace_marker-layer .ace_selection {\n background: rgba(170, 0, 255, 0.45);\n}\n\n.ace-kr-theme .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-kr-theme .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(255, 177, 111, 0.32);\n}\n\n.ace-kr-theme .ace_marker-layer .ace_active_line {\n background: #38403D;\n}\n\n \n.ace-kr-theme .ace_invisible {\n color: rgba(255, 177, 111, 0.32);\n}\n\n.ace-kr-theme .ace_keyword {\n color:#949C8B;\n}\n\n.ace-kr-theme .ace_keyword.ace_operator {\n \n}\n\n.ace-kr-theme .ace_constant {\n color:rgba(210, 117, 24, 0.76);\n}\n\n.ace-kr-theme .ace_constant.ace_language {\n \n}\n\n.ace-kr-theme .ace_constant.ace_library {\n \n}\n\n.ace-kr-theme .ace_constant.ace_numeric {\n \n}\n\n.ace-kr-theme .ace_invalid {\n color:#F8F8F8;\nbackground-color:#A41300;\n}\n\n.ace-kr-theme .ace_invalid.ace_illegal {\n \n}\n\n.ace-kr-theme .ace_invalid.ace_deprecated {\n \n}\n\n.ace-kr-theme .ace_support {\n color:#9FC28A;\n}\n\n.ace-kr-theme .ace_support.ace_function {\n color:#85873A;\n}\n\n.ace-kr-theme .ace_function.ace_buildin {\n \n}\n\n.ace-kr-theme .ace_string {\n \n}\n\n.ace-kr-theme .ace_string.ace_regexp {\n color:rgba(125, 255, 192, 0.65);\n}\n\n.ace-kr-theme .ace_comment {\n font-style:italic;\ncolor:#706D5B;\n}\n\n.ace-kr-theme .ace_comment.ace_doc {\n \n}\n\n.ace-kr-theme .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-kr-theme .ace_variable {\n color:#D1A796;\n}\n\n.ace-kr-theme .ace_variable.ace_language {\n color:#FF80E1;\n}\n\n.ace-kr-theme .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-kr-theme"}) \ No newline at end of file diff --git a/build/textarea/src/theme-mono_industrial.js b/build/textarea/src/theme-mono_industrial.js deleted file mode 100644 index 2e118014..00000000 --- a/build/textarea/src/theme-mono_industrial.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/theme/mono_industrial",function(a,b,c){var d=a("pilot/dom"),e=".ace-mono-industrial .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-mono-industrial .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-mono-industrial .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-mono-industrial .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-mono-industrial .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-mono-industrial .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-mono-industrial .ace_scroller {\n background-color: #222C28;\n}\n\n.ace-mono-industrial .ace_text-layer {\n cursor: text;\n color: #FFFFFF;\n}\n\n.ace-mono-industrial .ace_cursor {\n border-left: 2px solid #FFFFFF;\n}\n\n.ace-mono-industrial .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #FFFFFF;\n}\n \n.ace-mono-industrial .ace_marker-layer .ace_selection {\n background: rgba(145, 153, 148, 0.40);\n}\n\n.ace-mono-industrial .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-mono-industrial .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(102, 108, 104, 0.50);\n}\n\n.ace-mono-industrial .ace_marker-layer .ace_active_line {\n background: rgba(12, 13, 12, 0.25);\n}\n\n \n.ace-mono-industrial .ace_invisible {\n color: rgba(102, 108, 104, 0.50);\n}\n\n.ace-mono-industrial .ace_keyword {\n color:#A39E64;\n}\n\n.ace-mono-industrial .ace_keyword.ace_operator {\n color:#A8B3AB;\n}\n\n.ace-mono-industrial .ace_constant {\n color:#E98800;\n}\n\n.ace-mono-industrial .ace_constant.ace_language {\n \n}\n\n.ace-mono-industrial .ace_constant.ace_library {\n \n}\n\n.ace-mono-industrial .ace_constant.ace_numeric {\n color:#E98800;\n}\n\n.ace-mono-industrial .ace_invalid {\n color:#FFFFFF;\nbackground-color:rgba(153, 0, 0, 0.68);\n}\n\n.ace-mono-industrial .ace_invalid.ace_illegal {\n \n}\n\n.ace-mono-industrial .ace_invalid.ace_deprecated {\n \n}\n\n.ace-mono-industrial .ace_support {\n \n}\n\n.ace-mono-industrial .ace_support.ace_function {\n color:#588E60;\n}\n\n.ace-mono-industrial .ace_function.ace_buildin {\n \n}\n\n.ace-mono-industrial .ace_string {\n \n}\n\n.ace-mono-industrial .ace_string.ace_regexp {\n \n}\n\n.ace-mono-industrial .ace_comment {\n color:#666C68;\nbackground-color:#151C19;\n}\n\n.ace-mono-industrial .ace_comment.ace_doc {\n \n}\n\n.ace-mono-industrial .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-mono-industrial .ace_variable {\n \n}\n\n.ace-mono-industrial .ace_variable.ace_language {\n color:#648BD2;\n}\n\n.ace-mono-industrial .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-mono-industrial"}) \ No newline at end of file diff --git a/build/textarea/src/theme-monokai.js b/build/textarea/src/theme-monokai.js deleted file mode 100644 index 021043c4..00000000 --- a/build/textarea/src/theme-monokai.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/theme/monokai",function(a,b,c){var d=a("pilot/dom"),e=".ace-monokai .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-monokai .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-monokai .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-monokai .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-monokai .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-monokai .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-monokai .ace_scroller {\n background-color: #272822;\n}\n\n.ace-monokai .ace_text-layer {\n cursor: text;\n color: #F8F8F2;\n}\n\n.ace-monokai .ace_cursor {\n border-left: 2px solid #F8F8F0;\n}\n\n.ace-monokai .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #F8F8F0;\n}\n \n.ace-monokai .ace_marker-layer .ace_selection {\n background: #49483E;\n}\n\n.ace-monokai .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-monokai .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid #49483E;\n}\n\n.ace-monokai .ace_marker-layer .ace_active_line {\n background: #49483E;\n}\n\n \n.ace-monokai .ace_invisible {\n color: #49483E;\n}\n\n.ace-monokai .ace_keyword {\n color:#F92672;\n}\n\n.ace-monokai .ace_keyword.ace_operator {\n \n}\n\n.ace-monokai .ace_constant {\n \n}\n\n.ace-monokai .ace_constant.ace_language {\n color:#AE81FF;\n}\n\n.ace-monokai .ace_constant.ace_library {\n \n}\n\n.ace-monokai .ace_constant.ace_numeric {\n color:#AE81FF;\n}\n\n.ace-monokai .ace_invalid {\n color:#F8F8F0;\nbackground-color:#F92672;\n}\n\n.ace-monokai .ace_invalid.ace_illegal {\n \n}\n\n.ace-monokai .ace_invalid.ace_deprecated {\n color:#F8F8F0;\nbackground-color:#AE81FF;\n}\n\n.ace-monokai .ace_support {\n \n}\n\n.ace-monokai .ace_support.ace_function {\n color:#66D9EF;\n}\n\n.ace-monokai .ace_function.ace_buildin {\n \n}\n\n.ace-monokai .ace_string {\n color:#E6DB74;\n}\n\n.ace-monokai .ace_string.ace_regexp {\n \n}\n\n.ace-monokai .ace_comment {\n color:#75715E;\n}\n\n.ace-monokai .ace_comment.ace_doc {\n \n}\n\n.ace-monokai .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-monokai .ace_variable {\n \n}\n\n.ace-monokai .ace_variable.ace_language {\n \n}\n\n.ace-monokai .ace_xml_pe {\n \n}";d.importCssString(e),b.cssClass="ace-monokai"}) \ No newline at end of file diff --git a/build/textarea/src/theme-pastel_on_dark.js b/build/textarea/src/theme-pastel_on_dark.js deleted file mode 100644 index 4fe401ee..00000000 --- a/build/textarea/src/theme-pastel_on_dark.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/theme/pastel_on_dark",function(a,b,c){var d=a("pilot/dom"),e=".ace-pastel-on-dark .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-pastel-on-dark .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-pastel-on-dark .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-pastel-on-dark .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-pastel-on-dark .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-pastel-on-dark .ace_print_margin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-pastel-on-dark .ace_scroller {\n background-color: #2c2828;\n}\n\n.ace-pastel-on-dark .ace_text-layer {\n cursor: text;\n color: #8f938f;\n}\n\n.ace-pastel-on-dark .ace_cursor {\n border-left: 2px solid #A7A7A7;\n}\n\n.ace-pastel-on-dark .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #A7A7A7;\n}\n \n.ace-pastel-on-dark .ace_marker-layer .ace_selection {\n background: rgba(221, 240, 255, 0.20);\n}\n\n.ace-pastel-on-dark .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-pastel-on-dark .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(255, 255, 255, 0.25);\n}\n\n.ace-pastel-on-dark .ace_marker-layer .ace_active_line {\n background: rgba(255, 255, 255, 0.031);\n}\n\n \n.ace-pastel-on-dark .ace_invisible {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.ace-pastel-on-dark .ace_keyword {\n color:#757ad8;\n}\n\n.ace-pastel-on-dark .ace_keyword.ace_operator {\n color:#797878;\n}\n\n.ace-pastel-on-dark .ace_constant {\n color:#4fb7c5;\n}\n\n.ace-pastel-on-dark .ace_constant.ace_language {\n \n}\n\n.ace-pastel-on-dark .ace_constant.ace_library {\n \n}\n\n.ace-pastel-on-dark .ace_constant.ace_numeric {\n \n}\n\n.ace-pastel-on-dark .ace_invalid {\n \n}\n\n.ace-pastel-on-dark .ace_invalid.ace_illegal {\n color:#F8F8F8;\nbackground-color:rgba(86, 45, 86, 0.75);\n}\n\n.ace-pastel-on-dark .ace_invalid.ace_deprecated {\n text-decoration:underline;\nfont-style:italic;\ncolor:#D2A8A1;\n}\n\n.ace-pastel-on-dark .ace_support {\n color:#9a9a9a;\n}\n\n.ace-pastel-on-dark .ace_support.ace_function {\n color:#aeb2f8;\n}\n\n.ace-pastel-on-dark .ace_function.ace_buildin {\n \n}\n\n.ace-pastel-on-dark .ace_string {\n color:#66a968;\n}\n\n.ace-pastel-on-dark .ace_string.ace_regexp {\n color:#E9C062;\n}\n\n.ace-pastel-on-dark .ace_comment {\n color:#656865;\n}\n\n.ace-pastel-on-dark .ace_comment.ace_doc {\n color:A6C6FF;\n}\n\n.ace-pastel-on-dark .ace_comment.ace_doc.ace_tag {\n color:A6C6FF;\n}\n\n.ace-pastel-on-dark .ace_variable {\n color:#bebf55;\n}\n\n.ace-pastel-on-dark .ace_variable.ace_language {\n color:#bebf55;\n}\n\n.ace-pastel-on-dark .ace_xml_pe {\n color:#494949;\n}";d.importCssString(e),b.cssClass="ace-pastel-on-dark"}) \ No newline at end of file diff --git a/build/textarea/src/theme-twilight.js b/build/textarea/src/theme-twilight.js deleted file mode 100644 index 502f97fd..00000000 --- a/build/textarea/src/theme-twilight.js +++ /dev/null @@ -1 +0,0 @@ -__ace_shadowed__.define("ace/theme/twilight",function(a,b,c){var d=a("pilot/dom"),e=".ace-twilight .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-twilight .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-twilight .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-twilight .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-twilight .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-twilight .ace_print_margin {\n border-left: 1px solid #3C3C3C;\n width: 100%;\n background: #242424;\n}\n\n.ace-twilight .ace_scroller {\n background-color: #141414;\n}\n\n.ace-twilight .ace_text-layer {\n cursor: text;\n color: #F8F8F8;\n}\n\n.ace-twilight .ace_cursor {\n border-left: 2px solid #A7A7A7;\n}\n\n.ace-twilight .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid #A7A7A7;\n}\n.ace-twilight.normal-mode .ace_cursor.ace_overwrite {\n border: 1px solid #FFE300;\n background: #766B13;\n}\n.ace-twilight.normal-mode .ace_cursor-layer {\n z-index: 0;\n}\n \n.ace-twilight .ace_marker-layer .ace_selection {\n background: rgba(221, 240, 255, 0.20);\n}\n\n.ace-twilight .ace_marker-layer .ace_step {\n background: rgb(198, 219, 174);\n}\n\n.ace-twilight .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgba(255, 255, 255, 0.25);\n}\n\n.ace-twilight .ace_marker-layer .ace_active_line {\n background: rgba(255, 255, 255, 0.031);\n}\n\n \n.ace-twilight .ace_invisible {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.ace-twilight .ace_keyword {\n color:#CDA869;\n}\n\n.ace-twilight .ace_keyword.ace_operator {\n \n}\n\n.ace-twilight .ace_constant {\n color:#CF6A4C;\n}\n\n.ace-twilight .ace_constant.ace_language {\n \n}\n\n.ace-twilight .ace_constant.ace_library {\n \n}\n\n.ace-twilight .ace_constant.ace_numeric {\n \n}\n\n.ace-twilight .ace_invalid {\n \n}\n\n.ace-twilight .ace_invalid.ace_illegal {\n color:#F8F8F8;\nbackground-color:rgba(86, 45, 86, 0.75);\n}\n\n.ace-twilight .ace_invalid.ace_deprecated {\n text-decoration:underline;\nfont-style:italic;\ncolor:#D2A8A1;\n}\n\n.ace-twilight .ace_support {\n color:#9B859D;\n}\n\n.ace-twilight .ace_support.ace_function {\n color:#DAD085;\n}\n\n.ace-twilight .ace_function.ace_buildin {\n \n}\n\n.ace-twilight .ace_string {\n color:#8F9D6A;\n}\n\n.ace-twilight .ace_string.ace_regexp {\n color:#E9C062;\n}\n\n.ace-twilight .ace_comment {\n font-style:italic;\ncolor:#5F5A60;\n}\n\n.ace-twilight .ace_comment.ace_doc {\n \n}\n\n.ace-twilight .ace_comment.ace_doc.ace_tag {\n \n}\n\n.ace-twilight .ace_variable {\n color:#7587A6;\n}\n\n.ace-twilight .ace_variable.ace_language {\n \n}\n\n.ace-twilight .ace_xml_pe {\n color:#494949;\n}";d.importCssString(e),b.cssClass="ace-twilight"}) \ No newline at end of file diff --git a/build_support/bookmarklet.html b/build_support/bookmarklet.html new file mode 100644 index 00000000..88355f78 --- /dev/null +++ b/build_support/bookmarklet.html @@ -0,0 +1,112 @@ + + + + + + + Ace Bookmarklet Builder + + + +
    + +
    +
    +
    + SourceUrl:
    +
    +
    + +
    +
    +
    +
    +

    Ace Bookmarklet Builder

    + +

    + WARNING: Currently, this is only supported in non IE browsers. +

    + +

    How to use it:

    +
      +
    • Select the options as you want them to be by default.
    • +
    • Enter the "SourceUrl". This has to be the URL pointing to build/textarea/src/ (you can leave the default to server the scripts from GitHub).
    • +
    • Click the "Build Link" button to generate your custom Ace Bookmarklet.
    • +
    • Drag the generated link to your toolbar or store it somewhere else.
    • +
    • Go to a page with a textarea element and click the bookmarklet - wait a little bit till the files are loaded.
    • +
    • Click three times on the textarea you want to replace - Ace will replace it.
    • +
    • To change settings, just click the red icon in the bottom right corner.
    • +
    +
    +
    +
    + + + + + diff --git a/build_support/boot.js b/build_support/boot.js deleted file mode 100644 index 0488fcae..00000000 --- a/build_support/boot.js +++ /dev/null @@ -1,91 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kevin Dangoor (kdangoor@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -var deps = [ - "pilot/fixoldbrowsers", - "pilot/index", - "pilot/plugin_manager", - "pilot/environment", - "ace/editor", - "ace/edit_session", - "ace/virtual_renderer", - "ace/undomanager", - "ace/theme/textmate" -]; - -require(deps, function() { - var catalog = require("pilot/plugin_manager").catalog; - catalog.registerPlugins([ "pilot/index" ]); - - var Dom = require("pilot/dom"); - var Event = require("pilot/event"); - - var Editor = require("ace/editor").Editor; - var EditSession = require("ace/edit_session").EditSession; - var UndoManager = require("ace/undomanager").UndoManager; - var Renderer = require("ace/virtual_renderer").VirtualRenderer; - - window.ace = { - edit: function(el) { - if (typeof(el) == "string") { - el = document.getElementById(el); - } - - var doc = new EditSession(Dom.getInnerText(el)); - doc.setUndoManager(new UndoManager()); - el.innerHTML = ''; - - var editor = new Editor(new Renderer(el, "ace/theme/textmate")); - editor.setSession(doc); - - var env = require("pilot/environment").create(); - catalog.startupPlugins({ env: env }).then(function() { - env.document = doc; - env.editor = editor; - editor.resize(); - Event.addListener(window, "resize", function() { - editor.resize(); - }); - el.env = env; - }); - // Store env on editor such that it can be accessed later on from - // the returned object. - editor.env = env; - return editor; - } - }; -}); diff --git a/build_support/boot_textarea.js b/build_support/boot_textarea.js deleted file mode 100644 index 4d7e7f52..00000000 --- a/build_support/boot_textarea.js +++ /dev/null @@ -1,525 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kevin Dangoor (kdangoor@mozilla.com) - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -(function() { - -var require = window.__ace_shadowed__.require; -var deps = [ - "pilot/fixoldbrowsers", - "pilot/index", - "pilot/plugin_manager", - "pilot/environment", - "ace/editor", - "ace/edit_session", - "ace/virtual_renderer", - "ace/undomanager", - "ace/theme/textmate" -]; - -require(deps, function() { - -var catalog = require("pilot/plugin_manager").catalog; -catalog.registerPlugins([ "pilot/index" ]); - -var Dom = require("pilot/dom"); -var Event = require("pilot/event"); -var UA = require("pilot/useragent") - -var Editor = require("ace/editor").Editor; -var EditSession = require("ace/edit_session").EditSession; -var UndoManager = require("ace/undomanager").UndoManager; -var Renderer = require("ace/virtual_renderer").VirtualRenderer; - -window.__ace_shadowed__.edit = function(el) { - if (typeof(el) == "string") { - el = document.getElementById(el); - } - - var doc = new EditSession(Dom.getInnerText(el)); - doc.setUndoManager(new UndoManager()); - el.innerHTML = ''; - - var editor = new Editor(new Renderer(el, "ace/theme/textmate")); - editor.setSession(doc); - - var env = require("pilot/environment").create(); - catalog.startupPlugins({ env: env }).then(function() { - env.document = doc; - env.editor = env; - editor.resize(); - Event.addListener(window, "resize", function() { - editor.resize(); - }); - el.env = env; - }); - return editor; -} - - -/** - * 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 - * - * If the property can't get computed, is 'auto' or 'intrinsic', the former - * calculated property is uesd (this can happen in cases where the textarea - * is hidden and has no dimension styles). - */ -var getCSSProperty = function(element, container, property) { - var ret = element.style[property]; - - if (!ret) { - if (window.getComputedStyle) { - ret = window.getComputedStyle(element, '').getPropertyValue(property); - } else { - ret = element.currentStyle[property]; - } - } - - if (!ret || ret == 'auto' || ret == 'intrinsic') { - ret = container.style[property]; - } - return ret; -}; - -function applyStyles(elm, styles) { - for (style in styles) { - elm.style[style] = styles[style]; - } -} - -function setupContainer(element, getValue) { - if (element.type != 'textarea') { - throw "Textarea required!"; - } - - var parentNode = element.parentNode; - - // This will hold the editor. - var container = document.createElement('div'); - - // To put Ace in the place of the textarea, we have to copy a few of the - // textarea's style attributes to the div container. - // - // The problem is that the properties have to get computed (they might be - // defined by a CSS file on the page - you can't access such rules that - // apply to an element via elm.style). Computed properties are converted to - // pixels although the dimension might be given as percentage. When the - // window resizes, the dimensions defined by percentages changes, so the - // properties have to get recomputed to get the new/true pixels. - var resizeEvent = function() { - var style = 'position:relative;'; - [ - 'margin-top', 'margin-left', 'margin-right', 'margin-bottom' - ].forEach(function(item) { - style += item + ':' + - getCSSProperty(element, container, item) + ';'; - }); - - // Calculating the width/height of the textarea is somewhat tricky. To - // do it right, you have to include the paddings to the sides as well - // (eg. width = width + padding-left, -right). This works well, as - // long as the width of the element is not set or given in pixels. In - // this case and after the textarea is hidden, getCSSProperty(element, - // container, 'width') will still return pixel value. If the element - // has realtiv dimensions (e.g. width='95') - // getCSSProperty(...) will return pixel values only as long as the - // textarea is visible. After it is hidden getCSSProperty will return - // the relative dimensions as they are set on the element (in the case - // of width, 95). - // Making the sum of pixel vaules (e.g. padding) and realtive values - // (e.g. ) is not possible. As such the padding styles are - // ignored. - - // The complete width is the width of the textarea + the padding - // to the left and right. - var width = getCSSProperty(element, container, 'width') || (element.clientWidth + "px"); - var height = getCSSProperty(element, container, 'height') || (element.clientHeight + "px"); - style += 'height:' + height + ';width:' + width + ';'; - - // Set the display property to 'inline-block'. - style += 'display:inline-block;'; - container.setAttribute('style', style); - }; - Event.addListener(window, 'resize', resizeEvent); - - // Call the resizeEvent once, so that the size of the container is - // calculated. - resizeEvent(); - - // Insert the div container after the element. - if (element.nextSibling) { - parentNode.insertBefore(container, element.nextSibling); - } else { - parentNode.appendChild(container); - } - - // Override the forms onsubmit function. Set the innerHTML and value - // of the textarea before submitting. - while (parentNode !== document) { - if (parentNode.tagName.toUpperCase() === 'FORM') { - var oldSumit = parentNode.onsubmit; - // Override the onsubmit function of the form. - parentNode.onsubmit = function(evt) { - element.value = getValue(); - element.innerHTML = getValue(); - // If there is a onsubmit function already, then call - // it with the current context and pass the event. - if (oldSumit) { - oldSumit.call(this, evt); - } - } - break; - } - parentNode = parentNode.parentNode; - } - return container; -} - -window.__ace_shadowed__.transformTextarea = function(element) { - var session; - var container = setupContainer(element, function() { - return session.getValue(); - }); - - // Hide the element. - element.style.display = 'none'; - container.style.background = 'white'; - - // - var editorDiv = document.createElement("div"); - applyStyles(editorDiv, { - top: "0px", - left: "0px", - right: "0px", - bottom: "0px", - border: "1px solid gray" - }); - container.appendChild(editorDiv); - - var settingOpener = document.createElement("div"); - applyStyles(settingOpener, { - position: "absolute", - width: "15px", - right: "0px", - bottom: "0px", - background: "red", - cursor: "pointer", - textAlign: "center", - fontSize: "12px" - }); - settingOpener.innerHTML = "I"; - - var settingDiv = document.createElement("div"); - var settingDivStyles = { - top: "0px", - left: "0px", - right: "0px", - bottom: "0px", - position: "absolute", - padding: "5px", - zIndex: 100, - color: "white", - display: "none", - overflow: "auto", - fontSize: "14px" - }; - if (!UA.isIE) { - settingDivStyles.backgroundColor = "rgba(0, 0, 0, 0.6)"; - } else { - settingDivStyles.backgroundColor = "#333"; - } - - applyStyles(settingDiv, settingDivStyles); - container.appendChild(settingDiv); - - // Power up ace on the textarea: - var ace = window.__ace_shadowed__; - var require = ace.require; - var define = ace.define; - var options = {}; - - var editor = ace.edit(editorDiv); - session = editor.getSession(); - - session.setValue(element.value || element.innerHTML); - editor.focus(); - - // Add the settingPanel opener to the editor's div. - editorDiv.appendChild(settingOpener); - - // Create the API. - var api = setupApi(editor, editorDiv, settingDiv, ace, options) - - // Create the setting's panel. - setupSettingPanel(settingDiv, settingOpener, api, options); - - return api; -} - -function setupApi(editor, editorDiv, settingDiv, ace, options) { - var session = editor.getSession(); - var renderer = editor.renderer; - - function toBool(value) { - return value == "true"; - } - - var ret = { - setDisplaySettings: function(display) { - settingDiv.style.display = display ? "block" : "none"; - }, - - setOption: function(key, value) { - if (options[key] == value) return; - - var load = window.__ace_shadowed_load__; - - switch (key) { - case "gutter": - renderer.setShowGutter(toBool(value)); - break; - - case "mode": - if (value != "text") { - // Load the required mode file. Files get loaded only once. - load("mode-" + value + ".js", "ace/mode/" + value, function() { - var aceMode = require("ace/mode/" + value).Mode; - session.setMode(new aceMode()); - }); - } else { - session.setMode(new (require("ace/mode/text").Mode)); - } - break; - - case "theme": - if (value != "textmate") { - // Load the required theme file. Files get loaded only once. - load("theme-" + value + ".js", "ace/theme/" + value, function() { - editor.setTheme("ace/theme/" + value); - }); - } else { - editor.setTheme("ace/theme/textmate"); - } - break; - - case "fontSize": - editorDiv.style.fontSize = value; - break; - - case "softWrap": - switch (value) { - case "off": - session.setUseWrapMode(false); - renderer.setPrintMarginColumn(80); - break; - case "40": - session.setUseWrapMode(true); - session.setWrapLimitRange(40, 40); - renderer.setPrintMarginColumn(40); - break; - case "80": - session.setUseWrapMode(true); - session.setWrapLimitRange(80, 80); - renderer.setPrintMarginColumn(80); - break; - case "free": - session.setUseWrapMode(true); - session.setWrapLimitRange(null, null); - renderer.setPrintMarginColumn(80); - break; - } - break; - - case "useSoftTabs": - session.setUseSoftTabs(toBool(value)); - break; - - case "showPrintMargin": - renderer.setShowPrintMargin(toBool(value)); - break - } - - options[key] = value; - }, - - getOption: function(key) { - return options[key]; - }, - - getOptions: function() { - return options; - } - } - - for (option in ace.options) { - ret.setOption(option, ace.options[option]); - } - - return ret; -} - -function setupSettingPanel(settingDiv, settingOpener, api, options) { - var BOOL = { - "true": true, - "false": false - } - - var desc = { - mode: "Mode:", - gutter: "Display Gutter:", - theme: "Theme:", - fontSize: "Font Size:", - softWrap: "Soft Wrap:", - showPrintMargin: "Show Print Margin:", - useSoftTabs: "Use Soft Tabs:" - } - - var optionValues = { - mode: { - text: "Plain", - javascript: "JavaScript", - coffee: "CoffeeScript", - html: "HTML", - css: "CSS", - c_cpp: "C++", - php: "PHP", - ruby: "Ruby", - python: "Python" - - }, - theme: { - textmate: "Textmate", - eclipse: "Eclipse", - clouds: "Clouds", - clouds_midnight: "Clouds Midnight", - cobalt: "Cobalt", - dawn: "Dawn", - idle_fingers: "Idle Fingers", - kr_theme: "Kr Theme", - mono_industrial: "Mono Industrial", - monokai: "Monokai", - pastel_on_dark: "Pastel On Dark", - twilight: "Twilight" - }, - gutter: BOOL, - fontSize: { - "10px": "10px", - "11px": "11px", - "12px": "12px", - "14px": "14px", - "16px": "16px" - }, - softWrap: { - off: "Off", - 40: "40", - 80: "80", - free: "Free" - }, - showPrintMargin: BOOL, - useSoftTabs: BOOL - } - - var table = []; - table.push(""); - - function renderOption(builder, option, obj, cValue) { - builder.push("") - } - - for (var option in options) { - table.push(""); - table.push(""); - } - table.push("
    SettingValue
    ", desc[option], ""); - renderOption(table, option, optionValues[option], options[option]); - table.push("
    "); - settingDiv.innerHTML = table.join(""); - - var selects = settingDiv.getElementsByTagName("select"); - for (var i = 0; i < selects.length; i++) { - var onChange = (function() { - var select = selects[i]; - return function() { - var option = select.title; - var value = select.value; - api.setOption(option, value); - } - })(); - selects[i].onchange = onChange; - } - - var button = document.createElement("input"); - button.type = "button"; - button.value = "Hide"; - button.onclick = function() { - api.setDisplaySettings(false); - } - settingDiv.appendChild(button); - - settingOpener.onclick = function() { - api.setDisplaySettings(true); - } -} - -// Default startup options. -window.__ace_shadowed__.options = { - mode: "text", - theme: "textmate", - gutter: "false", - fontSize: "12px", - softWrap: "off", - showPrintMargin: "false", - useSoftTabs: "true" -} - -}); - -})() diff --git a/build_support/editor.html b/build_support/editor.html index 8f8a7895..1d972cf9 100644 --- a/build_support/editor.html +++ b/build_support/editor.html @@ -8,8 +8,8 @@ body { overflow: hidden; } - - #editor { + + #editor { margin: 0; position: absolute; top: 0; @@ -27,18 +27,12 @@ alert("Ace Rocks " + items[i]); } }
    fragments and .js files.",$),N.fragment?a!=="div"&&bC("ADsafe violation: Wrap the widget in a div.",$):bC("Use the fragment option.",$)),N.browser=!0,by()}function cJ(){var a;while(K.id==="@"){a=bH(),bI("@");if(K.identifier)switch(K.value){case"import":bI(),cB()||(bA("Expected '{a}' and instead saw '{b}'.",K,"url",K.value),bI()),bI(";");break;case"media":bI();for(;;){(!K.identifier||r[K.value]===!0)&&bC("Expected a CSS media type, and instead saw '{a}'.",K,K.id),bI();if(K.id!==",")break;bI(",")}bI("{"),cI(),bI("}");break;default:bA("Expected an at-rule, and instead saw @{a}.",K,K.value)}else bA("Expected an at-rule, and instead saw '{a}'.",K,K.value)}cI()}function cI(){while(K.id!=="":case"+":bI(),cG();break;case":":bI(":");switch(K.value){case"active":case"after":case"before":case"checked":case"disabled":case"empty":case"enabled":case"first-child":case"first-letter":case"first-line":case"first-of-type":case"focus":case"hover":case"last-child":case"last-of-type":case"link":case"only-of-type":case"root":case"target":case"visited":bI();break;case"lang":bI(),bI("("),K.identifier||bA("Expected a lang code, and instead saw :{a}.",K,K.value),bI(")");break;case"nth-child":case"nth-last-child":case"nth-last-of-type":case"nth-of-type":bI(),bI("("),cE(),bI(")");break;case"not":bI(),bI("("),K.id===":"&&bH(0).value==="not"&&bA("Nested not."),cG(),bI(")");break;default:bA("Expected a pseudo, and instead saw :{a}.",K,K.value)}break;case"#":bI("#"),K.identifier||bA("Expected an id, and instead saw #{a}.",K,K.value),bI();break;case"*":bI("*");break;case".":bI("."),K.identifier||bA("Expected a class, and instead saw #.{a}.",K,K.value),bI();break;case"[":bI("["),K.identifier||bA("Expected an attribute, and instead saw [{a}].",K,K.value),bI();if(K.id==="="||K.value==="~="||K.value==="$="||K.value==="|="||K.id==="*="||K.id==="^=")bI(),K.type!=="(string)"&&bA("Expected a string, and instead saw {a}.",K,K.value),bI();bI("]");break;default:bC("Expected a CSS selector, and instead saw {a}.",K,K.value)}}function cF(){var a;for(;;){if(K.id==="}"||K.id==="(end)"||be&&K.id===be)return;while(K.id===";")bA("Misplaced ';'."),bI(";");a=cC(),bI(":"),K.identifier&&K.value==="inherit"?bI():cD(a)||(bA("Unexpected token '{a}'.",K,K.value),bI()),K.id==="!"&&(bI("!"),bK(),K.identifier&&K.value==="important"?bI():bA("Expected '{a}' and instead saw '{b}'.",K,"important",K.value)),K.id==="}"||K.id===be?bA("Missing '{a}'.",K,";"):bI(";")}}function cE(){if(K.id==="(number)")bI(),K.value==="n"&&K.identifier&&(bK(),bI(),K.id==="+"&&(bK(),bI("+"),bK(),bI("(number)")));else{switch(K.value){case"odd":case"even":if(K.identifier){bI();return}}bA("Unexpected token '{a}'.",K,K.value)}}function cD(a){var b=0,c,d,e,f,g=0,h;switch(typeof a){case"function":return a();case"string":if(K.identifier&&K.value===a){bI();return!0}return!1}for(;;){if(b>=a.length)return!1;h=a[b],b+=1;if(h===!0)break;typeof h==="number"?(c=h,h=a[b],b+=1):c=1,e=!1;while(c>0)if(cD(h))e=!0,c-=1;else break;if(e)return!0}g=b,d=[];for(;;){f=!1;for(b=g;b=0&&bA("Bad url string."));b||bA("Missing url."),bI(),N.safe&&bp.test(b)&&bC("ADsafe URL violation."),_.push(b);return!0}return!1}function cA(){var a;if(K.identifier&&K.value==="rect"){bI(),bI("(");for(a=0;a<4;a+=1)if(!ct()){bA("Expected a number and instead saw '{a}'.",K,K.value);break}bI(")");return!0}return!1}function cz(){if(K.identifier&&K.value==="counter"){bI(),bI("("),bI(),K.id===","&&(bR(),K.type!=="(string)"&&bA("Expected a string and instead saw '{a}'.",K,K.value),bI()),bI(")");return!0}if(K.identifier&&K.value==="counters"){bI(),bI("("),K.identifier||bA("Expected a name and instead saw '{a}'.",K,K.value),bI(),K.id===","&&(bR(),K.type!=="(string)"&&bA("Expected a string and instead saw '{a}'.",K,K.value),bI()),K.id===","&&(bR(),K.type!=="(string)"&&bA("Expected a string and instead saw '{a}'.",K,K.value),bI()),bI(")");return!0}return!1}function cy(){while(K.id!==";"){!cp()&&!cr()&&bA("Expected a name and instead saw '{a}'.",K,K.value);if(K.id!==",")return!0;bR()}}function cx(){if(K.identifier&&K.value==="attr"){bI(),bI("("),K.identifier||bA("Expected a name and instead saw '{a}'.",K,K.value),bI(),bI(")");return!0}return!1}function cw(){if(!K.identifier)return ct();if(K.value==="auto"){bI();return!0}}function cv(){if(!K.identifier)return ct();switch(K.value){case"thin":case"medium":case"thick":bI();return!0}}function cu(){K.id==="-"&&(bI("-"),bK());if(K.type==="(number)"){bI(),K.type!=="(string)"&&q[K.value]===!0&&(bK(),bI());return!0}return!1}function ct(){K.id==="-"&&(bI("-"),bK(),bQ());if(K.type==="(number)"){bI(),K.type!=="(string)"&&q[K.value]===!0?(bK(),bI()):+$.value!==0&&bA("Expected a linear unit and instead saw '{a}'.",K,K.value);return!0}return!1}function cs(){var a,b,c;if(K.identifier){c=K.value;if(c==="rgb"||c==="rgba"){bI(),bI("(");for(a=0;a<3;a+=1)a&&bI(","),b=K.value,K.type!=="(number)"||b<0?(bA("Expected a positive number and instead saw '{a}'",K,b),bI()):(bI(),K.id==="%"?(bI("%"),b>100&&bA("Expected a percentage and instead saw '{a}'",$,b)):b>255&&bA("Expected a small number and instead saw '{a}'",$,b));c==="rgba"&&(bI(","),b=+K.value,(K.type!=="(number)"||b<0||b>1)&&bA("Expected a number between 0 and 1 and instead saw '{a}'",K,b),bI(),K.id==="%"&&(bA("Unexpected '%'."),bI("%"))),bI(")");return!0}if(n[K.value]===!0){bI();return!0}}else if(K.type==="(color)"){bI();return!0}return!1}function cr(){if(K.type==="(string)"){bI();return!0}}function cq(){K.id==="-"&&(bI("-"),bK(),bQ());if(K.type==="(number)"){bI("(number)");return!0}}function cp(){if(K.identifier){bI();return!0}}function co(a){var b=a.value,c=a.line,d=B[b];typeof d==="function"&&(d=!1),d?d[d.length-1]!==c&&d.push(c):(d=[c],B[b]=d)}function cn(a){J&&typeof J[a]!=="boolean"&&bA("Unexpected /*member '{a}'.",$,a),typeof I[a]==="number"?I[a]+=1:I[a]=1}function cm(a,b){var c,d=C,e=D,f=X,g=S,h;C=a,S=Object.create(S),bN($,K),h=K;if(K.id==="{"){bI("{");if(K.id!=="}"||$.line!==K.line){D+=N.indent;while(!a&&K.from>D)D+=N.indent;!a&&!ck()&&!f&&N.strict&&v["(context)"]["(global)"]&&bA('Missing "use strict" statement.'),c=cl(),X=f,D-=N.indent,bP()}bI("}",h),D=e}else a?((!b||N.curly)&&bA("Expected '{a}' and instead saw '{b}'.",K,"{",K.value),M=!0,c=[cj()],M=!1):bC("Expected '{a}' and instead saw '{b}'.",K,"{",K.value);v["(verb)"]=null,S=g,C=d,a&&N.noempty&&(!c||c.length===0)&&bA("Empty block.");return c}function cl(c){var d=[],e,f;if(N.adsafe)switch(c){case"script":b||(K.value!=="ADSAFE"||bH(0).id!=="."||bH(1).value!=="id"&&bH(1).value!=="go")&&bC("ADsafe violation: Missing ADSAFE.id or ADSAFE.go.",K),K.value==="ADSAFE"&&bH(0).id==="."&&bH(1).value==="id"&&(b&&bC("ADsafe violation.",K),bI("ADSAFE"),bI("."),bI("id"),bI("("),K.value!==a&&bC("ADsafe violation: id does not match.",K),bI("(string)"),bI(")"),bI(";"),b=!0);break;case"lib":if(K.value==="ADSAFE"){bI("ADSAFE"),bI("."),bI("lib"),bI("("),bI("(string)"),bR(),e=bJ(0),e.id!=="function"&&bC("The second argument to lib must be a function.",e),f=e.funct["(params)"],f=f&&f.join(", "),f&&f!=="lib"&&bC("Expected '{a}' and instead saw '{b}'.",e,"(lib)","("+f+")"),bI(")"),bI(";");return d}bC("ADsafe lib violation.")}while(!K.reach&&K.id!=="(end)")K.id===";"?(bA("Unnecessary semicolon."),bI(";")):d.push(cj());return d}function ck(){if(K.value==="use strict"){X&&bA('Unnecessary "use strict".'),bI(),bI(";"),X=!0,N.newcap=!0,N.undef=!0;return!0}return!1}function cj(a){var b=D,c,d=S,e=K;if(e.id===";")bA("Unnecessary semicolon.",e),bI(";");else{e.identifier&&!e.reserved&&bH().id===":"&&(bI(),bI(":"),S=Object.create(d),bF(e.value,"label"),K.labelled||bA("Label '{a}' on {b} statement.",K,e.value,K.value),bo.test(e.value+":")&&bA("Label '{a}' looks like a javascript url.",e,e.value),K.label=e.value,e=K),a||bP(),c=bJ(0,!0),e.block||(c&&c.exps?N.nonew&&c.id==="("&&c.left.id==="new"&&bA("Do not use 'new' for side effects."):bA("Expected an assignment or function call and instead saw an expression.",$),K.id!==";"?bB("Missing semicolon.",$.line,$.from+$.value.length):(bK($,K),bI(";"),bN($,K))),D=b,S=d;return c}}function ci(a){var b=0,c;if(K.id===";"&&!M)for(;;){c=bH(b);if(c.reach)return;if(c.id!=="(endline)"){if(c.id==="function"){bA("Inner functions should be listed at the top of the outer function.",c);break}bA("Unreachable '{a}' after '{b}'.",c,c.value,a);break}b+=1}}function ch(a){var b=cg(a);if(b)return b;$.id==="function"&&K.id==="("?bA("Missing name in function statement."):bC("Expected an identifier and instead saw '{a}'.",K,K.value)}function cg(a){if(K.identifier){bI(),N.safe&&h[$.value]?bA("ADsafe violation: '{a}'.",$,$.value):$.reserved&&!N.es5&&((!a||$.value!="undefined")&&bA("Expected an identifier and instead saw '{a}' (a reserved word).",$,$.id));return $.value}}function cf(a,b){var c=bS(a,150);c.led=function(a){N.plusplus?bA("Unexpected use of '{a}'.",this,this.id):(!a.identifier||a.reserved)&&a.id!=="."&&a.id!=="["&&bA("Bad operand.",this),this.left=a;return this};return c}function ce(a){bS(a,20).exps=!0;return b_(a,function(a,b){N.bitwise&&bA("Unexpected use of '{a}'.",b,b.id),bN(Q,$),bN($,K);if(a){if(a.id==="."||a.id==="["||a.identifier&&!a.reserved){bJ(19);return b}a===Y["function"]&&bA("Expected an identifier in an assignment, and instead saw a function invocation.",$);return b}bC("Bad assignment.",b)},20)}function cd(a,b,c){var d=bS(a,c);bW(d),d.led=typeof b==="function"?b:function(a){N.bitwise&&bA("Unexpected use of '{a}'.",this,this.id),this.left=a,this.right=bJ(c);return this};return d}function cc(a,b){bS(a,20).exps=!0;return b_(a,function(a,b){var c;b.left=a,O[a.value]===!1&&S[a.value]["(global)"]===!0?bA("Read only.",a):a["function"]&&bA("'{a}' is a function.",a,a.value);if(N.safe){c=a;do typeof O[c.value]==="boolean"&&bA("ADsafe violation.",c),c=c.left;while(c)}if(a){if(a.id==="."||a.id==="["){(!a.left||a.left.value==="arguments")&&bA("Bad assignment.",b),b.right=bJ(19);return b}if(a.identifier&&!a.reserved){v[a.value]==="exception"&&bA("Do not assign to the exception parameter.",a),b.right=bJ(19);return b}a===Y["function"]&&bA("Expected an identifier in an assignment and instead saw a function invocation.",$)}bC("Bad assignment.",b)},20)}function cb(a){return a&&(a.type==="(number)"&&+a.value===0||a.type==="(string)"&&a.value===""||a.type==="null"&&!N.boss||a.type==="true"||a.type==="false"||a.type==="undefined")}function ca(a,b){var c=bS(a,100);c.led=function(a){bO(Q,$),bN($,K);var c=bJ(100);a&&a.id==="NaN"||c&&c.id==="NaN"?bA("Use the isNaN function to compare with NaN.",this):b&&b.apply(this,[a,c]),a.id==="!"&&bA("Confusing use of '{a}'.",a,"!"),c.id==="!"&&bA("Confusing use of '{a}'.",a,"!"),this.left=a,this.right=c;return this};return c}function b_(a,b,c,d){var e=bS(a,c);bW(e),e.led=function(a){d||(bO(Q,$),bN($,K));if(typeof b==="function")return b(a,this);this.left=a,this.right=bJ(c);return this};return e}function b$(a,b){return bZ(a,function(){typeof b==="function"&&b(this);return this})}function bZ(a,b){var c=bY(a,b);c.identifier=c.reserved=!0;return c}function bY(a,b){var c=bT(a);c.type=a,c.nud=b;return c}function bX(a,b){var c=bS(a,150);bW(c),c.nud=typeof b==="function"?b:function(){this.right=bJ(150),this.arity="unary";if(this.id==="++"||this.id==="--")N.plusplus?bA("Unexpected use of '{a}'.",this,this.id):(!this.right.identifier||this.right.reserved)&&this.right.id!=="."&&this.right.id!=="["&&bA("Bad operand.",this);return this};return c}function bW(a){var b=a.id.charAt(0);if(b>="a"&&b<="z"||b>="A"&&b<="Z")a.identifier=a.reserved=!0;return a}function bV(a,b){var c=bU(a,b);c.block=!0;return c}function bU(a,b){var c=bT(a);c.identifier=c.reserved=!0,c.fud=b;return c}function bT(a){return bS(a,0)}function bS(a,b){var c=Y[a];if(!c||typeof c!=="object")Y[a]=c={id:a,lbp:b,value:a};return c}function bR(){$.line!==K.line?N.laxbreak||bA("Bad line breaking before '{a}'.",$,K.id):$.character!==K.from&&N.white&&bA("Unexpected space after '{a}'.",K,$.value),bI(","),bN($,K)}function bQ(a){a=a||$,a.line!==K.line&&bA("Line breaking error '{a}'.",a,a.value)}function bP(a){var b;N.white&&K.id!=="(end)"&&(b=D+(a||0),K.from!==b&&bA("Expected '{a}' to have an indentation at {b} instead at {c}.",K,K.value,b,K.from))}function bO(a,b){a=a||$,b=b||K,N.laxbreak||a.line===b.line?N.white&&(a=a||$,b=b||K,a.character===b.from&&bA("Missing space after '{a}'.",K,a.value)):bA("Bad line breaking before '{a}'.",b,b.id)}function bN(a,b){N.white&&(a=a||$,b=b||K,a.line===b.line&&a.character===b.from&&bA("Missing space after '{a}'.",K,a.value))}function bM(a,b){a=a||$,b=b||K,N.white&&!a.comment&&(a.line===b.line&&bK(a,b))}function bL(a,b){a=a||$,b=b||K,N.white&&(a.character!==b.from||a.line!==b.line)&&bA("Unexpected space before '{a}'.",b,b.value)}function bK(a,b){a=a||$,b=b||K;if(N.white||bd==="styleproperty"||bd==="style")a.character!==b.from&&a.line===b.line&&bA("Unexpected space after '{a}'.",b,a.value)}function bJ(a,b){var c;K.id==="(end)"&&bC("Unexpected early end of program.",$),bI(),N.safe&&typeof O[$.value]==="boolean"&&(K.id!=="("&&K.id!==".")&&bA("ADsafe violation.",$),b&&(e="anonymous",v["(verb)"]=$.value);if(b===!0&&$.fud)c=$.fud();else{if($.nud)c=$.nud();else{if(K.type==="(number)"&&$.id==="."){bA("A leading decimal point can be confused with a dot: '.{a}'.",$,K.value),bI();return $}bC("Expected an identifier and instead saw '{a}'.",$,$.id)}while(a=N.maxerr&&bz("Too many errors.",i,h);return j}function bz(a,b,c){throw{name:"JSHintError",line:b,character:c,message:a+" ("+Math.floor(b/G.length*100)+"% scanned)."}}function by(){N.safe||(N.couch&&bx(O,k),N.rhino&&bx(O,R),N.node&&bx(O,L),N.devel&&bx(O,t),N.browser&&bx(O,j),N.jquery&&bx(O,F),N.windows&&bx(O,bc),N.widget&&bx(O,bb))}function bx(a,b){var c;for(c in b)bw(b,c)&&(a[c]=b[c])}function bw(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function bv(){}"use strict";var a,b,c,e,f,g={"<":!0,"<=":!0,"==":!0,"===":!0,"!==":!0,"!=":!0,">":!0,">=":!0,"+":!0,"-":!0,"*":!0,"/":!0,"%":!0},h={arguments:!0,callee:!0,caller:!0,constructor:!0,eval:!0,prototype:!0,stack:!0,unwatch:!0,valueOf:!0,watch:!0},i={adsafe:!0,bitwise:!0,boss:!0,browser:!0,cap:!0,couch:!0,css:!0,curly:!0,debug:!0,devel:!0,eqeqeq:!0,es5:!0,evil:!0,forin:!0,fragment:!0,immed:!0,jquery:!0,laxbreak:!0,newcap:!0,noarg:!0,node:!0,noempty:!0,nonew:!0,nomen:!0,on:!0,onevar:!0,passfail:!0,plusplus:!0,regexp:!0,rhino:!0,undef:!0,safe:!0,windows:!0,strict:!0,sub:!0,white:!0,widget:!0},j={addEventListener:!1,applicationCache:!1,blur:!1,clearInterval:!1,clearTimeout:!1,close:!1,closed:!1,defaultStatus:!1,document:!1,event:!1,FileReader:!1,focus:!1,frames:!1,getComputedStyle:!1,history:!1,Image:!1,length:!1,localStorage:!1,location:!1,moveBy:!1,moveTo:!1,name:!1,navigator:!1,onbeforeunload:!0,onblur:!0,onerror:!0,onfocus:!0,onload:!0,onresize:!0,onunload:!0,open:!1,openDatabase:!1,opener:!1,Option:!1,parent:!1,print:!1,removeEventListener:!1,resizeBy:!1,resizeTo:!1,screen:!1,scroll:!1,scrollBy:!1,scrollTo:!1,setInterval:!1,setTimeout:!1,status:!1,top:!1,WebSocket:!1,window:!1,Worker:!1,XMLHttpRequest:!1},k={require:!1,respond:!1,getRow:!1,emit:!1,send:!1,start:!1,sum:!1,log:!1,exports:!1,module:!1},l,m,n={aliceblue:!0,antiquewhite:!0,aqua:!0,aquamarine:!0,azure:!0,beige:!0,bisque:!0,black:!0,blanchedalmond:!0,blue:!0,blueviolet:!0,brown:!0,burlywood:!0,cadetblue:!0,chartreuse:!0,chocolate:!0,coral:!0,cornflowerblue:!0,cornsilk:!0,crimson:!0,cyan:!0,darkblue:!0,darkcyan:!0,darkgoldenrod:!0,darkgray:!0,darkgreen:!0,darkkhaki:!0,darkmagenta:!0,darkolivegreen:!0,darkorange:!0,darkorchid:!0,darkred:!0,darksalmon:!0,darkseagreen:!0,darkslateblue:!0,darkslategray:!0,darkturquoise:!0,darkviolet:!0,deeppink:!0,deepskyblue:!0,dimgray:!0,dodgerblue:!0,firebrick:!0,floralwhite:!0,forestgreen:!0,fuchsia:!0,gainsboro:!0,ghostwhite:!0,gold:!0,goldenrod:!0,gray:!0,green:!0,greenyellow:!0,honeydew:!0,hotpink:!0,indianred:!0,indigo:!0,ivory:!0,khaki:!0,lavender:!0,lavenderblush:!0,lawngreen:!0,lemonchiffon:!0,lightblue:!0,lightcoral:!0,lightcyan:!0,lightgoldenrodyellow:!0,lightgreen:!0,lightpink:!0,lightsalmon:!0,lightseagreen:!0,lightskyblue:!0,lightslategray:!0,lightsteelblue:!0,lightyellow:!0,lime:!0,limegreen:!0,linen:!0,magenta:!0,maroon:!0,mediumaquamarine:!0,mediumblue:!0,mediumorchid:!0,mediumpurple:!0,mediumseagreen:!0,mediumslateblue:!0,mediumspringgreen:!0,mediumturquoise:!0,mediumvioletred:!0,midnightblue:!0,mintcream:!0,mistyrose:!0,moccasin:!0,navajowhite:!0,navy:!0,oldlace:!0,olive:!0,olivedrab:!0,orange:!0,orangered:!0,orchid:!0,palegoldenrod:!0,palegreen:!0,paleturquoise:!0,palevioletred:!0,papayawhip:!0,peachpuff:!0,peru:!0,pink:!0,plum:!0,powderblue:!0,purple:!0,red:!0,rosybrown:!0,royalblue:!0,saddlebrown:!0,salmon:!0,sandybrown:!0,seagreen:!0,seashell:!0,sienna:!0,silver:!0,skyblue:!0,slateblue:!0,slategray:!0,snow:!0,springgreen:!0,steelblue:!0,tan:!0,teal:!0,thistle:!0,tomato:!0,turquoise:!0,violet:!0,wheat:!0,white:!0,whitesmoke:!0,yellow:!0,yellowgreen:!0,activeborder:!0,activecaption:!0,appworkspace:!0,background:!0,buttonface:!0,buttonhighlight:!0,buttonshadow:!0,buttontext:!0,captiontext:!0,graytext:!0,highlight:!0,highlighttext:!0,inactiveborder:!0,inactivecaption:!0,inactivecaptiontext:!0,infobackground:!0,infotext:!0,menu:!0,menutext:!0,scrollbar:!0,threeddarkshadow:!0,threedface:!0,threedhighlight:!0,threedlightshadow:!0,threedshadow:!0,window:!0,windowframe:!0,windowtext:!0},o,p,q={"%":!0,cm:!0,em:!0,ex:!0,"in":!0,mm:!0,pc:!0,pt:!0,px:!0},r,s,t={alert:!1,confirm:!1,console:!1,Debug:!1,opera:!1,prompt:!1},u={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"/":"\\/","\\":"\\\\"},v,w=["closure","exception","global","label","outer","unused","var"],x,y,z={a:{},abbr:{},acronym:{},address:{},applet:{},area:{empty:!0,parent:" map "},article:{},aside:{},audio:{},b:{},base:{empty:!0,parent:" head "},bdo:{},big:{},blockquote:{},body:{parent:" html noframes "},br:{empty:!0},button:{},canvas:{parent:" body p div th td "},caption:{parent:" table "},center:{},cite:{},code:{},col:{empty:!0,parent:" table colgroup "},colgroup:{parent:" table "},command:{parent:" menu "},datalist:{},dd:{parent:" dl "},del:{},details:{},dialog:{},dfn:{},dir:{},div:{},dl:{},dt:{parent:" dl "},em:{},embed:{},fieldset:{},figure:{},font:{},footer:{},form:{},frame:{empty:!0,parent:" frameset "},frameset:{parent:" html frameset "},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{parent:" html "},header:{},hgroup:{},hr:{empty:!0},"hta:application":{empty:!0,parent:" head "},html:{parent:"*"},i:{},iframe:{},img:{empty:!0},input:{empty:!0},ins:{},kbd:{},keygen:{},label:{},legend:{parent:" details fieldset figure "},li:{parent:" dir menu ol ul "},link:{empty:!0,parent:" head "},map:{},mark:{},menu:{},meta:{empty:!0,parent:" head noframes noscript "},meter:{},nav:{},noframes:{parent:" html body "},noscript:{parent:" body head noframes "},object:{},ol:{},optgroup:{parent:" select "},option:{parent:" optgroup select "},output:{},p:{},param:{empty:!0,parent:" applet object "},pre:{},progress:{},q:{},rp:{},rt:{},ruby:{},samp:{},script:{empty:!0,parent:" body div frame head iframe p pre span "},section:{},select:{},small:{},span:{},source:{},strong:{},style:{parent:" head ",empty:!0},sub:{},sup:{},table:{},tbody:{parent:" table "},td:{parent:" tr "},textarea:{},tfoot:{parent:" table "},th:{parent:" tr "},thead:{parent:" table "},time:{},title:{parent:" head "},tr:{parent:" table tbody thead tfoot "},tt:{},u:{},ul:{},"var":{},video:{}},A,B,C,D,E,F={$:!1,jQuery:!1},G,H,I,J,K,L={__filename:!1,__dirname:!1,Buffer:!1,GLOBAL:!1,global:!1,module:!1,process:!1,require:!1},M,N,O,P,Q,R={defineClass:!1,deserialize:!1,gc:!1,help:!1,load:!1,loadClass:!1,print:!1,quit:!1,readFile:!1,readUrl:!1,runCommand:!1,seal:!1,serialize:!1,spawn:!1,sync:!1,toint32:!1,version:!1},S,T,U,V={Array:!1,Boolean:!1,Date:!1,decodeURI:!1,decodeURIComponent:!1,encodeURI:!1,encodeURIComponent:!1,Error:!1,eval:!1,EvalError:!1,Function:!1,hasOwnProperty:!1,isFinite:!1,isNaN:!1,JSON:!1,Math:!1,Number:!1,Object:!1,parseInt:!1,parseFloat:!1,RangeError:!1,ReferenceError:!1,RegExp:!1,String:!1,SyntaxError:!1,TypeError:!1,URIError:!1},W={E:!0,LN2:!0,LN10:!0,LOG2E:!0,LOG10E:!0,MAX_VALUE:!0,MIN_VALUE:!0,NEGATIVE_INFINITY:!0,PI:!0,POSITIVE_INFINITY:!0,SQRT1_2:!0,SQRT2:!0},X,Y={},Z,$,_,ba,bb={alert:!0,animator:!0,appleScript:!0,beep:!0,bytesToUIString:!0,Canvas:!0,chooseColor:!0,chooseFile:!0,chooseFolder:!0,closeWidget:!0,COM:!0,convertPathToHFS:!0,convertPathToPlatform:!0,CustomAnimation:!0,escape:!0,FadeAnimation:!0,filesystem:!0,Flash:!0,focusWidget:!0,form:!0,FormField:!0,Frame:!0,HotKey:!0,Image:!0,include:!0,isApplicationRunning:!0,iTunes:!0,konfabulatorVersion:!0,log:!0,md5:!0,MenuItem:!0,MoveAnimation:!0,openURL:!0,play:!0,Point:!0,popupMenu:!0,preferenceGroups:!0,preferences:!0,print:!0,prompt:!0,random:!0,Rectangle:!0,reloadWidget:!0,ResizeAnimation:!0,resolvePath:!0,resumeUpdates:!0,RotateAnimation:!0,runCommand:!0,runCommandInBg:!0,saveAs:!0,savePreferences:!0,screen:!0,ScrollBar:!0,showWidgetPreferences:!0,sleep:!0,speak:!0,Style:!0,suppressUpdates:!0,system:!0,tellWidget:!0,Text:!0,TextArea:!0,Timer:!0,unescape:!0,updateNow:!0,URL:!0,Web:!0,widget:!0,Window:!0,XMLDOM:!0,XMLHttpRequest:!0,yahooCheckLogin:!0,yahooLogin:!0,yahooLogout:!0},bc={ActiveXObject:!1,CScript:!1,Debug:!1,Enumerator:!1,System:!1,VBArray:!1,WScript:!1},bd,be,bf=/@cc|<\/?|script|\]\s*\]|<\s*!|</i,bg=/[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,bh=/^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jshint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,bi=/^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-:]*|[0-9]+|--)/,bj=/[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,bk=/[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,bl=/[>&]|<[\/!]?|--/,bm=/\*\/|\/\*/,bn=/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,bo=/^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,bp=/&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i,bq=/^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/,br=/^\s*([@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/,bs=/[^a-zA-Z0-9+\-_\/ ]/,bt=/[\[\]\/\\"'*<>.&:(){}+=#]/,bu={outer:bi,html:bi,style:bq,styleproperty:br};typeof Array.isArray!=="function"&&(Array.isArray=function(a){return Object.prototype.toString.apply(a)==="[object Array]"}),typeof Object.create!=="function"&&(Object.create=function(a){bv.prototype=a;return new bv}),typeof Object.keys!=="function"&&(Object.keys=function(a){var b=[],c;for(c in a)bw(a,c)&&b.push(c);return b}),typeof String.prototype.entityify!=="function"&&(String.prototype.entityify=function(){return this.replace(/&/g,"&").replace(//g,">")}),typeof String.prototype.isAlpha!=="function"&&(String.prototype.isAlpha=function(){return this>="a"&&this<="z￿"||this>="A"&&this<="Z￿"}),typeof String.prototype.isDigit!=="function"&&(String.prototype.isDigit=function(){return this>="0"&&this<="9"}),typeof String.prototype.supplant!=="function"&&(String.prototype.supplant=function(a){return this.replace(/\{([^{}]*)\}/g,function(b,c){var d=a[c];return typeof d==="string"||typeof d==="number"?d:b})}),typeof String.prototype.name!=="function"&&(String.prototype.name=function(){if(bn.test(this))return this;if(bj.test(this))return'"'+this.replace(bk,function(a){var b=u[a];if(b)return b;return"\\u"+("0000"+a.charCodeAt().toString(16)).slice(-4)})+'"';return'"'+this+'"'});var bE=function bE(){function f(d,e){var f,g;d==="(color)"||d==="(range)"?g={type:d}:d==="(punctuator)"||d==="(identifier)"&&bw(Y,e)?g=Y[e]||Y["(error)"]:g=Y[d],g=Object.create(g);if(d==="(string)"||d==="(range)")bo.test(e)&&bB("Script URL.",c,b);d==="(identifier)"&&(g.identifier=!0,e==="__iterator__"||e==="__proto__"?bD("Reserved name '{a}'.",c,b,e):N.nomen&&(e.charAt(0)==="_"||e.charAt(e.length-1)==="_")&&bB("Unexpected {a} in '{b}'.",c,b,"dangling '_'",e)),g.value=e,g.line=c,g.character=a,g.from=b,f=g.id,f!=="(endline)"&&(P=f&&("(,=:[!&|?{};".indexOf(f.charAt(f.length-1))>=0||f==="return"));return g}function e(){var b;if(c>=G.length)return!1;a=1,d=G[c],c+=1,b=d.search(/ \t/),b>=0&&bB("Mixed spaces and tabs.",c,b+1),d=d.replace(/\t/g,Z),b=d.search(bg),b>=0&&bB("Unsafe character.",c,b),N.maxlen&&N.maxlen=32&&e<=126&&e!==34&&e!==92&&e!==39&&bB("Unnecessary escapement.",c,a),a+=b,h=String.fromCharCode(e)}var h,i,j="";E&&g!=='"'&&bB("Strings must use doublequote.",c,a);if(be===g||bd==="scriptstring"&&!be)return f("(punctuator)",g);i=0;for(;;){while(i>=d.length)i=0,(bd!=="html"||!e())&&bD("Unclosed string.",c,b);h=d.charAt(i);if(h===g){a+=1,d=d.substr(i+1);return f("(string)",j,g)}if(h<" "){if(h==="\n"||h==="\r")break;bB("Control character in string: {a}.",c,a+i,d.slice(0,i))}else if(h===be)bB("Bad HTML string",c,a+i);else if(h==="<")N.safe&&bd==="html"?bB("ADsafe string violation.",c,a+i):d.charAt(i+1)==="/"&&(bd||N.safe)?bB("Expected '<\\/' and instead saw '0){a+=1,d=d.slice(m);break}if(!e())return f("(end)","")}q=r(bu[bd]||bh);if(q){if(h.isAlpha()||h==="_"||h==="$")return f("(identifier)",q);if(h.isDigit()){bd!=="style"&&!isFinite(Number(q))&&bB("Bad number '{a}'.",c,a,q),bd!=="style"&&bd!=="styleproperty"&&d.substr(0,1).isAlpha()&&bB("Missing space after '{a}'.",c,a,q),h==="0"&&(j=q.substr(1,1),j.isDigit()?$.id!=="."&&bd!=="styleproperty"&&bB("Don't use extra leading zeros '{a}'.",c,a,q):E&&(j==="x"||j==="X")&&bB("Avoid 0x-. '{a}'.",c,a,q)),q.substr(q.length-1)==="."&&bB("A trailing decimal point can be confused with a dot '{a}'.",c,a,q);return f("(number)",q)}switch(q){case'"':case"'":return s(q);case"//":T||bd&&bd!=="script"?bB("Unexpected comment.",c,a):bd==="script"&&/<\s*\//i.test(d)?bB("Unexpected =0)break;e()?N.safe&&bf.test(d)&&bB("ADsafe comment violation.",c,a):bD("Unclosed comment.",c,a)}a+=m+2,d.substr(m,1)==="/"&&bD("Nested comment.",c,a),d=d.substr(m+2),$.comment=!0;break;case"/*members":case"/*member":case"/*jshint":case"/*global":case"*/":return{value:q,type:"special",line:c,character:a,from:b};case"":break;case"/":$.id==="/="&&bD("A regular expression literal can be confused with '/='.",c,b);if(P){k=0,i=0,n=0;for(;;){g=!0,h=d.charAt(n),n+=1;switch(h){case"":bD("Unclosed regular expression.",c,b);return;case"/":k>0&&bB("Unescaped '{a}'.",c,b+n,"/"),h=d.substr(0,n-1),p={g:!0,i:!0,m:!0};while(p[d.charAt(n)]===!0)p[d.charAt(n)]=!1,n+=1;a+=n,d=d.substr(n),p=d.charAt(0),(p==="/"||p==="*")&&bD("Confusing regular expression.",c,b);return f("(regexp)",h);case"\\":h=d.charAt(n),h<" "?bB("Unexpected control character in regular expression.",c,b+n):h==="<"&&bB("Unexpected escaped character '{a}' in regular expression.",c,b+n,h),n+=1;break;case"(":k+=1,g=!1;if(d.charAt(n)==="?"){n+=1;switch(d.charAt(n)){case":":case"=":case"!":n+=1;break;default:bB("Expected '{a}' and instead saw '{b}'.",c,b+n,":",d.charAt(n))}}else i+=1;break;case"|":g=!1;break;case")":k===0?bB("Unescaped '{a}'.",c,b+n,")"):k-=1;break;case" ":p=1;while(d.charAt(n)===" ")n+=1,p+=1;p>1&&bB("Spaces are hard to count. Use {{a}}.",c,b+n,p);break;case"[":h=d.charAt(n),h==="^"&&(n+=1,N.regexp?bB("Insecure '{a}'.",c,b+n,h):d.charAt(n)==="]"&&bD("Unescaped '{a}'.",c,b+n,"^")),p=!1,h==="]"&&(bB("Empty class.",c,b+n-1),p=!0);klass:do{h=d.charAt(n),n+=1;switch(h){case"[":case"^":bB("Unescaped '{a}'.",c,b+n,h),p=!0;break;case"-":p?p=!1:(bB("Unescaped '{a}'.",c,b+n,"-"),p=!0);break;case"]":p||bB("Unescaped '{a}'.",c,b+n-1,"-");break klass;case"\\":h=d.charAt(n),h<" "?bB("Unexpected control character in regular expression.",c,b+n):h==="<"&&bB("Unexpected escaped character '{a}' in regular expression.",c,b+n,h),n+=1,p=!0;break;case"/":bB("Unescaped '{a}'.",c,b+n-1,"/"),p=!0;break;case"<":bd==="script"&&(h=d.charAt(n),(h==="!"||h==="/")&&bB("HTML confusion in regular expression '<{a}'.",c,b+n,h)),p=!0;break;default:p=!0}}while(h);break;case".":N.regexp&&bB("Insecure '{a}'.",c,b+n,h);break;case"]":case"?":case"{":case"}":case"+":case"*":bB("Unescaped '{a}'.",c,b+n,h);break;case"<":bd==="script"&&(h=d.charAt(n),(h==="!"||h==="/")&&bB("HTML confusion in regular expression '<{a}'.",c,b+n,h))}if(g)switch(d.charAt(n)){case"?":case"+":case"*":n+=1,d.charAt(n)==="?"&&(n+=1);break;case"{":n+=1,h=d.charAt(n),(h<"0"||h>"9")&&bB("Expected a number and instead saw '{a}'.",c,b+n,h),n+=1,o=+h;for(;;){h=d.charAt(n);if(h<"0"||h>"9")break;n+=1,o=+h+o*10}l=o;if(h===","){n+=1,l=Infinity,h=d.charAt(n);if(h>="0"&&h<="9"){n+=1,l=+h;for(;;){h=d.charAt(n);if(h<"0"||h>"9")break;n+=1,l=+h+l*10}}}d.charAt(n)!=="}"?bB("Expected '{a}' and instead saw '{b}'.",c,b+n,"}",h):n+=1,d.charAt(n)==="?"&&(n+=1),o>l&&bB("'{a}' should not be greater than '{b}'.",c,b+n,o,l)}}h=d.substr(0,n-1),a+=n,d=d.substr(n);return f("(regexp)",h)}return f("(punctuator)",q);case".",c,a),a+=3,d=d.slice(m+3);break;case"#":if(bd==="html"||bd==="styleproperty"){for(;;){h=d.charAt(0);if((h<"0"||h>"9")&&(h<"a"||h>"f")&&(h<"A"||h>"F"))break;a+=1,d=d.substr(1),q+=h}q.length!==4&&q.length!==7&&bB("Bad hex color '{a}'.",c,b+n,q);return f("(color)",q)}return f("(punctuator)",q);default:if(bd==="outer"&&h==="&"){a+=1,d=d.substr(1);for(;;){h=d.charAt(0),a+=1,d=d.substr(1);if(h===";")break;(h<"0"||h>"9")&&(h<"a"||h>"z")&&h!=="#"&&bD("Bad entity",c,b+n,a)}break}return f("(punctuator)",q)}}else{q="",h="";while(d&&d<"!")d=d.substr(1);if(d){if(bd==="html")return f("(error)",d.charAt(0));bD("Unexpected '{a}'.",c,a,d.substr(0,1))}}}}}}();m=[cB,function(){for(;;)if(K.identifier)switch(K.value.toLowerCase()){case"url":cB();break;case"expression":bA("Unexpected expression '{a}'.",K,K.value),bI();break;default:bI()}else{if(K.id===";"||K.id==="!"||K.id==="(end)"||K.id==="}")return!0;bI()}}],o=["none","dashed","dotted","double","groove","hidden","inset","outset","ridge","solid"],p=["auto","always","avoid","left","right"],r={all:!0,braille:!0,embossed:!0,handheld:!0,print:!0,projection:!0,screen:!0,speech:!0,tty:!0,tv:!0},s=["auto","hidden","scroll","visible"],l={background:[!0,"background-attachment","background-color","background-image","background-position","background-repeat"],"background-attachment":["scroll","fixed"],"background-color":["transparent",cs],"background-image":["none",cB],"background-position":[2,[ct,"top","bottom","left","right","center"]],"background-repeat":["repeat","repeat-x","repeat-y","no-repeat"],border:[!0,"border-color","border-style","border-width"],"border-bottom":[!0,"border-bottom-color","border-bottom-style","border-bottom-width"],"border-bottom-color":cs,"border-bottom-style":o,"border-bottom-width":cv,"border-collapse":["collapse","separate"],"border-color":["transparent",4,cs],"border-left":[!0,"border-left-color","border-left-style","border-left-width"],"border-left-color":cs,"border-left-style":o,"border-left-width":cv,"border-right":[!0,"border-right-color","border-right-style","border-right-width"],"border-right-color":cs,"border-right-style":o,"border-right-width":cv,"border-spacing":[2,ct],"border-style":[4,o],"border-top":[!0,"border-top-color","border-top-style","border-top-width"],"border-top-color":cs,"border-top-style":o,"border-top-width":cv,"border-width":[4,cv],bottom:[ct,"auto"],"caption-side":["bottom","left","right","top"],clear:["both","left","none","right"],clip:[cA,"auto"],color:cs,content:["open-quote","close-quote","no-open-quote","no-close-quote",cr,cB,cz,cx],"counter-increment":[cp,"none"],"counter-reset":[cp,"none"],cursor:[cB,"auto","crosshair","default","e-resize","help","move","n-resize","ne-resize","nw-resize","pointer","s-resize","se-resize","sw-resize","w-resize","text","wait"],direction:["ltr","rtl"],display:["block","compact","inline","inline-block","inline-table","list-item","marker","none","run-in","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group"],"empty-cells":["show","hide"],"float":["left","none","right"],font:["caption","icon","menu","message-box","small-caption","status-bar",!0,"font-size","font-style","font-weight","font-family"],"font-family":cy,"font-size":["xx-small","x-small","small","medium","large","x-large","xx-large","larger","smaller",ct],"font-size-adjust":["none",cq],"font-stretch":["normal","wider","narrower","ultra-condensed","extra-condensed","condensed","semi-condensed","semi-expanded","expanded","extra-expanded"],"font-style":["normal","italic","oblique"],"font-variant":["normal","small-caps"],"font-weight":["normal","bold","bolder","lighter",cq],height:[ct,"auto"],left:[ct,"auto"],"letter-spacing":["normal",ct],"line-height":["normal",cu],"list-style":[!0,"list-style-image","list-style-position","list-style-type"],"list-style-image":["none",cB],"list-style-position":["inside","outside"],"list-style-type":["circle","disc","square","decimal","decimal-leading-zero","lower-roman","upper-roman","lower-greek","lower-alpha","lower-latin","upper-alpha","upper-latin","hebrew","katakana","hiragana-iroha","katakana-oroha","none"],margin:[4,cw],"margin-bottom":cw,"margin-left":cw,"margin-right":cw,"margin-top":cw,"marker-offset":[ct,"auto"],"max-height":[ct,"none"],"max-width":[ct,"none"],"min-height":ct,"min-width":ct,opacity:cq,outline:[!0,"outline-color","outline-style","outline-width"],"outline-color":["invert",cs],"outline-style":["dashed","dotted","double","groove","inset","none","outset","ridge","solid"],"outline-width":cv,overflow:s,"overflow-x":s,"overflow-y":s,padding:[4,ct],"padding-bottom":ct,"padding-left":ct,"padding-right":ct,"padding-top":ct,"page-break-after":p,"page-break-before":p,position:["absolute","fixed","relative","static"],quotes:[8,cr],right:[ct,"auto"],"table-layout":["auto","fixed"],"text-align":["center","justify","left","right"],"text-decoration":["none","underline","overline","line-through","blink"],"text-indent":ct,"text-shadow":["none",4,[cs,ct]],"text-transform":["capitalize","uppercase","lowercase","none"],top:[ct,"auto"],"unicode-bidi":["normal","embed","bidi-override"],"vertical-align":["baseline","bottom","sub","super","top","text-top","middle","text-bottom",ct],visibility:["visible","hidden","collapse"],"white-space":["normal","nowrap","pre","pre-line","pre-wrap","inherit"],width:[ct,"auto"],"word-spacing":["normal",ct],"word-wrap":["break-word","normal"],"z-index":["auto",cq]},bY("(number)",function(){return this}),bY("(string)",function(){return this}),Y["(identifier)"]={type:"(identifier)",lbp:0,identifier:!0,nud:function(){var a=this.value,b=S[a],c;typeof b==="function"?b=undefined:typeof b==="boolean"&&(c=v,v=x[0],bF(a,"var"),b=v,v=c);if(v===b)switch(v[a]){case"unused":v[a]="var";break;case"unction":v[a]="function",this["function"]=!0;break;case"function":this["function"]=!0;break;case"label":bA("'{a}' is a statement label.",$,a)}else if(v["(global)"])e!="typeof"&&e!="delete"&&N.undef&&typeof O[a]!=="boolean"&&bA("'{a}' is not defined.",$,a),co($);else switch(v[a]){case"closure":case"function":case"var":case"unused":bA("'{a}' used out of scope.",$,a);break;case"label":bA("'{a}' is a statement label.",$,a);break;case"outer":case"global":break;default:if(b===!0)v[a]=!0;else if(b===null)bA("'{a}' is not allowed.",$,a),co($);else if(typeof b!=="object")e!="typeof"&&e!="delete"&&N.undef?bA("'{a}' is not defined.",$,a):v[a]=!0,co($);else switch(b[a]){case"function":case"unction":this["function"]=!0,b[a]="closure",v[a]=b["(global)"]?"global":"outer";break;case"var":case"unused":b[a]="closure",v[a]=b["(global)"]?"global":"outer";break;case"closure":case"parameter":v[a]=b["(global)"]?"global":"outer";break;case"label":bA("'{a}' is a statement label.",$,a)}}return this},led:function(){bC("Expected an operator and instead saw '{a}'.",K,K.value)}},bY("(regexp)",function(){return this}),bT("(endline)"),bT("(begin)"),bT("(end)").reach=!0,bT(""),bT("(error)").reach=!0,bT("}").reach=!0,bT(")"),bT("]"),bT('"').reach=!0,bT("'").reach=!0,bT(";"),bT(":").reach=!0,bT(","),bT("#"),bT("@"),bZ("else"),bZ("case").reach=!0,bZ("catch"),bZ("default").reach=!0,bZ("finally"),b$("arguments",function(a){X&&v["(global)"]?bA("Strict violation.",a):N.safe&&bA("ADsafe violation.",a)}),b$("eval",function(a){N.safe&&bA("ADsafe violation.",a)}),b$("false"),b$("Infinity"),b$("NaN"),b$("null"),b$("this",function(a){X&&(v["(statement)"]&&v["(name)"].charAt(0)>"Z"||v["(global)"])?bA("Strict violation.",a):N.safe&&bA("ADsafe violation.",a)}),b$("true"),b$("undefined"),cc("=","assign",20),cc("+=","assignadd",20),cc("-=","assignsub",20),cc("*=","assignmult",20),cc("/=","assigndiv",20).nud=function(){bC("A regular expression literal can be confused with '/='.")},cc("%=","assignmod",20),ce("&=","assignbitand",20),ce("|=","assignbitor",20),ce("^=","assignbitxor",20),ce("<<=","assignshiftleft",20),ce(">>=","assignshiftright",20),ce(">>>=","assignshiftrightunsigned",20),b_("?",function(a,b){b.left=a,b.right=bJ(10),bI(":"),b["else"]=bJ(10);return b},30),b_("||","or",40),b_("&&","and",50),cd("|","bitor",70),cd("^","bitxor",80),cd("&","bitand",90),ca("==",function(a,b){N.eqeqeq?bA("Expected '{a}' and instead saw '{b}'.",this,"===","=="):cb(a)?bA("Use '{a}' to compare with '{b}'.",this,"===",a.value):cb(b)&&bA("Use '{a}' to compare with '{b}'.",this,"===",b.value);return this}),ca("==="),ca("!=",function(a,b){N.eqeqeq?bA("Expected '{a}' and instead saw '{b}'.",this,"!==","!="):cb(a)?bA("Use '{a}' to compare with '{b}'.",this,"!==",a.value):cb(b)&&bA("Use '{a}' to compare with '{b}'.",this,"!==",b.value);return this}),ca("!=="),ca("<"),ca(">"),ca("<="),ca(">="),cd("<<","shiftleft",120),cd(">>","shiftright",120),cd(">>>","shiftrightunsigned",120),b_("in","in",120),b_("instanceof","instanceof",120),b_("+",function(a,b){var c=bJ(130);if(a&&c&&a.id==="(string)"&&c.id==="(string)"){a.value+=c.value,a.character=c.character,bo.test(a.value)&&bA("JavaScript URL.",a);return a}b.left=a,b.right=c;return b},130),bX("+","num"),bX("+++",function(){bA("Confusing pluses."),this.right=bJ(150),this.arity="unary";return this}),b_("+++",function(a){bA("Confusing pluses."),this.left=a,this.right=bJ(130);return this},130),b_("-","sub",130),bX("-","neg"),bX("---",function(){bA("Confusing minuses."),this.right=bJ(150),this.arity="unary";return this}),b_("---",function(a){bA("Confusing minuses."),this.left=a,this.right=bJ(130);return this},130),b_("*","mult",140),b_("/","div",140),b_("%","mod",140),cf("++","postinc"),bX("++","preinc"),Y["++"].exps=!0,cf("--","postdec"),bX("--","predec"),Y["--"].exps=!0,bX("delete",function(){var a=bJ(0);(!a||a.id!=="."&&a.id!=="[")&&bA("Variables should not be deleted."),this.first=a;return this}).exps=!0,bX("~",function(){N.bitwise&&bA("Unexpected '{a}'.",this,"~"),bJ(150);return this}),bX("!",function(){this.right=bJ(150),this.arity="unary",g[this.right.id]===!0&&bA("Confusing use of '{a}'.",this,"!");return this}),bX("typeof","typeof"),bX("new",function(){var a=bJ(155),b;if(a&&a.id!=="function")if(a.identifier){a["new"]=!0;switch(a.value){case"Object":bA("Use the object literal notation {}.",$);break;case"Array":K.id!=="("?bA("Use the array literal notation [].",$):(bI("("),K.id===")"&&bA("Use the array literal notation [].",$),bI(")")),this.first=a;return this;case"Number":case"String":case"Boolean":case"Math":case"JSON":bA("Do not use {a} as a constructor.",$,a.value);break;case"Function":N.evil||bA("The Function constructor is eval.");break;case"Date":case"RegExp":break;default:a.id!=="function"&&(b=a.value.substr(0,1),N.newcap&&(b<"A"||b>"Z")&&bA("A constructor name should start with an uppercase letter.",$))}}else a.id!=="."&&a.id!=="["&&a.id!=="("&&bA("Bad constructor.",$);else bA("Weird construction. Delete 'new'.",this);bK($,K),K.id!=="("&&bA("Missing '()' invoking a constructor."),this.first=a;return this}),Y["new"].exps=!0,b_(".",function(d,e){bK(Q,$),bL();var f=ch();typeof f==="string"&&cn(f),e.left=d,e.right=f,N.noarg&&d&&d.value==="arguments"&&(f==="callee"||f==="caller")?bA("Avoid arguments.{a}.",d,f):N.evil||!d||d.value!=="document"||f!=="write"&&f!=="writeln"?N.adsafe&&(d&&d.value==="ADSAFE"&&(f==="id"||f==="lib"?bA("ADsafe violation.",e):f==="go"&&(bd!=="script"?bA("ADsafe violation.",e):(c||K.id!=="("||bH(0).id!=="(string)"||bH(0).value!==a||bH(1).id!==",")&&bC("ADsafe violation: go.",e),c=!0,b=!1))):bA("document.write can be a form of eval.",d);if(N.evil||f!=="eval"&&f!=="execScript"){if(N.safe)for(;;){h[f]===!0&&bA("ADsafe restricted word '{a}'.",$,f);if(typeof O[d.value]!=="boolean"||K.id==="(")break;if(W[f]===!0){K.id==="."&&bA("ADsafe violation.",e);break}if(K.id!=="."){bA("ADsafe violation.",e);break}bI("."),$.left=e,$.right=f,e=$,f=ch(),typeof f==="string"&&cn(f)}}else bA("eval is evil.");return e},160,!0),b_("(",function(a,b){Q.id!=="}"&&Q.id!==")"&&bL(Q,$),bM(),N.immed&&!a.immed&&a.id==="function"&&bA("Wrap an immediate function invocation in parentheses to assist the reader in understanding that the expression is the result of a function, and not the function itself.");var c=0,d=[];a&&(a.type==="(identifier)"?a.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)&&(a.value!=="Number"&&a.value!=="String"&&a.value!=="Boolean"&&a.value!=="Date"&&(a.value==="Math"?bA("Math is not a function.",a):N.newcap&&bA("Missing 'new' prefix when invoking a constructor.",a))):a.id==="."&&(N.safe&&a.left.value==="Math"&&a.right==="random"&&bA("ADsafe violation.",a)));if(K.id!==")")for(;;){d[d.length]=bJ(10),c+=1;if(K.id!==",")break;bR()}bI(")"),bM(Q,$),typeof a==="object"&&(a.value==="parseInt"&&c===1&&bA("Missing radix parameter.",a),N.evil||(a.value==="eval"||a.value==="Function"||a.value==="execScript"?bA("eval is evil.",a):d[0]&&d[0].id==="(string)"&&(a.value==="setTimeout"||a.value==="setInterval")&&bA("Implied eval is evil. Pass a function instead of a string.",a)),!a.identifier&&a.id!=="."&&a.id!=="["&&a.id!=="("&&a.id!=="&&"&&a.id!=="||"&&a.id!=="?"&&bA("Bad invocation.",a)),b.left=a;return b},155,!0).exps=!0,bX("(",function(){bM(),K.id==="function"&&(K.immed=!0);var a=bJ(0);bI(")",this),bM(Q,$),N.immed&&a.id==="function"&&(K.id==="("?bA("Move the invocation into the parens that contain the function.",K):bA("Do not wrap function literals in parens unless they are to be immediately invoked.",this));return a}),b_("[",function(a,b){bL(Q,$),bM();var c=bJ(0),d;if(c&&c.type==="(string)")N.safe&&h[c.value]===!0?bA("ADsafe restricted word '{a}'.",b,c.value):N.evil||c.value!=="eval"&&c.value!=="execScript"?N.safe&&(c.value.charAt(0)==="_"||c.value.charAt(0)==="-")&&bA("ADsafe restricted subscript '{a}'.",b,c.value):bA("eval is evil.",b),cn(c.value),!N.sub&&bn.test(c.value)&&(d=Y[c.value],(!d||!d.reserved)&&bA("['{a}'] is better written in dot notation.",c,c.value));else if(!c||c.type!=="(number)"||c.value<0)N.safe&&bA("ADsafe subscripting.");bI("]",b),bM(Q,$),b.left=a,b.right=c;return b},160,!0),bX("[",function(){var a=$.line!==K.line;this.first=[],a&&(D+=N.indent,K.from===D+N.indent&&(D+=N.indent));while(K.id!=="(end)"){while(K.id===",")bA("Extra comma."),bI(",");if(K.id==="]")break;a&&$.line!==K.line&&bP(),this.first.push(bJ(10));if(K.id!==",")break;bR();if(K.id==="]"&&!N.es5){bA("Extra comma.",$);break}}a&&(D-=N.indent,bP()),bI("]",this);return this},160),function(a){a.nud=function(){var a,b,c,d,e,f={},g;a=$.line!==K.line,a&&(D+=N.indent,K.from===D+N.indent&&(D+=N.indent));for(;;){if(K.id==="}")break;a&&bP();if(K.value==="get"&&bH().id!==":")bI("get"),N.es5||bC("get/set are ES5 features."),c=cP(),c||bC("Missing property name."),g=K,bK($,K),b=cR(c),v["(loopage)"]&&bA("Don't make functions within a loop.",g),e=b["(params)"],e&&bA("Unexpected parameter '{a}' in get {b} function.",g,e[0],c),bK($,K),bI(","),bP(),bI("set"),d=cP(),c!==d&&bC("Expected {a} and instead saw {b}.",$,c,d),g=K,bK($,K),b=cR(c),e=b["(params)"],(!e||e.length!==1||e[0]!=="value")&&bA("Expected (value) in set {a} function.",g,c);else{c=cP();if(typeof c!=="string")break;bI(":"),bN($,K),bJ(10)}f[c]===!0&&bA("Duplicate member '{a}'.",K,c),f[c]=!0,cn(c);if(K.id===",")bR(),K.id===","?bA("Extra comma.",$):K.id==="}"&&!N.es5&&bA("Extra comma.",$);else break}a&&(D-=N.indent,bP()),bI("}",this);return this},a.fud=function(){bC("Expected to see a statement and instead saw a block.",$)}}(bT("{"));var cS=function cS(a){var b,c,d;v["(onevar)"]&&N.onevar?bA("Too many var statements."):v["(global)"]||(v["(onevar)"]=!0),this.first=[];for(;;){bN($,K),b=ch(),v["(global)"]&&O[b]===!1&&bA("Redefinition of '{a}'.",$,b),bF(b,"unused");if(a)break;c=$,this.first.push($),K.id==="="&&(bN($,K),bI("="),bN($,K),K.id==="undefined"&&bA("It is not necessary to initialize '{a}' to 'undefined'.",$,b),bH(0).id==="="&&K.identifier&&bC("Variable {a} was not declared correctly.",K,K.value),d=bJ(0),c.first=d);if(K.id!==",")break;bR()}return this};bU("var",cS).exps=!0,bV("function",function(){C&&bA("Function statements should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.",$);var a=ch();bK($,K),bF(a,"unction"),cR(a,!0),K.id==="("&&K.line===$.line&&bC("Function statements are not invocable. Wrap the whole function invocation in parens.");return this}),bX("function",function(){var a=cg();a?bK($,K):bN($,K),cR(a),v["(loopage)"]&&bA("Don't make functions within a loop.");return this}),bV("if",function(){var a=K;bI("("),bN(this,a),bM(),bJ(20),K.id==="="&&(N.boss||bA("Expected a conditional expression and instead saw an assignment."),bI("="),bJ(20)),bI(")",a),bM(Q,$),cm(!0,!0),K.id==="else"&&(bN($,K),bI("else"),K.id==="if"||K.id==="switch"?cj(!0):cm(!0,!0));return this}),bV("try",function(){var a,b,c;N.adsafe&&bA("ADsafe try violation.",this),cm(!1),K.id==="catch"&&(bI("catch"),bN($,K),bI("("),c=S,S=Object.create(c),b=K.value,K.type!=="(identifier)"?bA("Expected an identifier and instead saw '{a}'.",K,b):bF(b,"exception"),bI(),bI(")"),cm(!1),a=!0,S=c);if(K.id==="finally")bI("finally"),cm(!1);else{a||bC("Expected '{a}' and instead saw '{b}'.",K,"catch",K.value);return this}}),bV("while",function(){var a=K;v["(breakage)"]+=1,v["(loopage)"]+=1,bI("("),bN(this,a),bM(),bJ(20),K.id==="="&&(N.boss||bA("Expected a conditional expression and instead saw an assignment."),bI("="),bJ(20)),bI(")",a),bM(Q,$),cm(!0,!0),v["(breakage)"]-=1,v["(loopage)"]-=1;return this}).labelled=!0,bZ("with"),bV("switch",function(){var a=K,b=!1;v["(breakage)"]+=1,bI("("),bN(this,a),bM(),this.condition=bJ(20),bI(")",a),bM(Q,$),bN($,K),a=K,bI("{"),bN($,K),D+=N.indent,this.cases=[];for(;;)switch(K.id){case"case":switch(v["(verb)"]){case"break":case"case":case"continue":case"return":case"switch":case"throw":break;default:bA("Expected a 'break' statement before 'case'.",$)}bP(-N.indent),bI("case"),this.cases.push(bJ(20)),b=!0,bI(":"),v["(verb)"]="case";break;case"default":switch(v["(verb)"]){case"break":case"continue":case"return":case"throw":break;default:bA("Expected a 'break' statement before 'default'.",$)}bP(-N.indent),bI("default"),b=!0,bI(":");break;case"}":D-=N.indent,bP(),bI("}",a),(this.cases.length===1||this.condition.id==="true"||this.condition.id==="false")&&bA("This 'switch' should be an 'if'.",this),v["(breakage)"]-=1,v["(verb)"]=undefined;return;case"(end)":bC("Missing '{a}'.",K,"}");return;default:if(b)switch($.id){case",":bC("Each value should have its own case label.");return;case":":cl();break;default:bC("Missing ':' on a case clause.",$)}else bC("Expected '{a}' and instead saw '{b}'.",K,"case",K.value)}}).labelled=!0,bU("debugger",function(){N.debug||bA("All 'debugger' statements should be removed.");return this}).exps=!0,function(){var a=bU("do",function(){v["(breakage)"]+=1,v["(loopage)"]+=1,this.first=cm(!0),bI("while");var a=K;bN($,a),bI("("),bM(),bJ(20),K.id==="="&&(N.boss||bA("Expected a conditional expression and instead saw an assignment."),bI("="),bJ(20)),bI(")",a),bM(Q,$),v["(breakage)"]-=1,v["(loopage)"]-=1;return this});a.labelled=!0,a.exps=!0}(),bV("for",function(){var a=N.forin,b,c=K;v["(breakage)"]+=1,v["(loopage)"]+=1,bI("("),bN(this,c),bM();if(bH(K.id==="var"?1:0).id==="in"){if(K.id==="var")bI("var"),cS(!0);else{switch(v[K.value]){case"unused":v[K.value]="var";break;case"var":break;default:bA("Bad for in variable '{a}'.",K,K.value)}bI()}bI("in"),bJ(20),bI(")",c),b=cm(!0,!0),!a&&(b.length>1||typeof b[0]!=="object"||b[0].value!=="if")&&bA("The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.",this),v["(breakage)"]-=1,v["(loopage)"]-=1;return this}if(K.id!==";")if(K.id==="var")bI("var"),cS();else for(;;){bJ(0,"for");if(K.id!==",")break;bR()}bQ($),bI(";"),K.id!==";"&&(bJ(20),K.id==="="&&(N.boss||bA("Expected a conditional expression and instead saw an assignment."),bI("="),bJ(20))),bQ($),bI(";"),K.id===";"&&bC("Expected '{a}' and instead saw '{b}'.",K,")",";");if(K.id!==")")for(;;){bJ(0,"for");if(K.id!==",")break;bR()}bI(")",c),bM(Q,$),cm(!0,!0),v["(breakage)"]-=1,v["(loopage)"]-=1;return this}).labelled=!0,bU("break",function(){var a=K.value;v["(breakage)"]===0&&bA("Unexpected '{a}'.",K,this.value),bQ(this),K.id!==";"&&($.line===K.line&&(v[a]!=="label"?bA("'{a}' is not a statement label.",K,a):S[a]!==v&&bA("'{a}' is out of scope.",K,a),this.first=K,bI())),ci("break");return this}).exps=!0,bU("continue",function(){var a=K.value;v["(breakage)"]===0&&bA("Unexpected '{a}'.",K,this.value),bQ(this),K.id!==";"?$.line===K.line&&(v[a]!=="label"?bA("'{a}' is not a statement label.",K,a):S[a]!==v&&bA("'{a}' is out of scope.",K,a),this.first=K,bI()):v["(loopage)"]||bA("Unexpected '{a}'.",K,this.value),ci("continue");return this}).exps=!0,bU("return",function(){bQ(this),K.id==="(regexp)"&&bA("Wrap the /regexp/ literal in parens to disambiguate the slash operator."),K.id!==";"&&!K.reach&&(bN($,K),this.first=bJ(20)),ci("return");return this}).exps=!0,bU("throw",function(){bQ(this),bN($,K),this.first=bJ(20),ci("throw");return this}).exps=!0,bZ("void"),bZ("class"),bZ("const"),bZ("enum"),bZ("export"),bZ("extends"),bZ("import"),bZ("super"),bZ("let"),bZ("yield"),bZ("implements"),bZ("interface"),bZ("package"),bZ("private"),bZ("protected"),bZ("public"),bZ("static");var cU=function(e,g){var h,i,j;d.errors=[],O=Object.create(V);if(g){h=g.predef;if(h)if(Array.isArray(h))for(i=0;i",K.value),K.value==="use strict"&&(bA('Use the function form of "use strict".'),ck()),cl("lib")}bI("(end)")}catch(k){k&&d.errors.push({reason:k.message,line:k.line||K.line,character:k.character||K.from},null)}return d.errors.length===0};cU.data=function(){var a={functions:[]},b,c,d=[],e,f,g,h=[],i,j=[],k;cU.errors.length&&(a.errors=cU.errors),E&&(a.json=!0);for(i in B)bw(B,i)&&d.push({name:i,line:B[i]});d.length>0&&(a.implieds=d),_.length>0&&(a.urls=_),c=Object.keys(S),c.length>0&&(a.globals=c);for(f=1;f0&&(a.unused=j),h=[];for(i in I)if(typeof I[i]==="number"){a.member=I;break}return a},cU.report=function(a){function o(a,b){var c,d,e;if(b){m.push("
    "+a+" "),b=b.sort();for(d=0;d")}}var b=cU.data(),c=[],d,e,f,g,h,i,j,k="",l,m=[],n;if(b.errors||b.implieds||b.unused){f=!0,m.push("
    Error:");if(b.errors)for(h=0;hProblem"+(isFinite(d.line)?" at line "+d.line+" character "+d.character:"")+": "+d.reason.entityify()+"

    "+(e&&(e.length>80?e.slice(0,77)+"...":e).entityify())+"

    "));if(b.implieds){n=[];for(h=0;h"+b.implieds[h].name+"
     "+b.implieds[h].line+"";m.push("

    Implied global: "+n.join(", ")+"

    ")}if(b.unused){n=[];for(h=0;h"+b.unused[h].name+" "+b.unused[h].line+" "+b.unused[h]["function"]+"";m.push("

    Unused variable: "+n.join(", ")+"

    ")}b.json&&m.push("

    JSON: bad.

    "),m.push("
    ")}if(!a){m.push("
    "),b.urls&&o("URLs
    ",b.urls,"
    "),bd==="style"?m.push("

    CSS.

    "):b.json&&!f?m.push("

    JSON: good.

    "):b.globals?m.push("
    Global "+b.globals.sort().join(", ")+"
    "):m.push("
    No new global variables introduced.
    ");for(h=0;h
    "+g.line+"-"+g.last+" "+(g.name||"")+"("+(g.param?g.param.join(", "):"")+")
    "),o("Unused",g.unused),o("Closure",g.closure),o("Variable",g["var"]),o("Exception",g.exception),o("Outer",g.outer),o("Global",g.global),o("Label",g.label);if(b.member){c=Object.keys(b.member);if(c.length){c=c.sort(),k="
    /*members ",j=10;for(h=0;h72&&(m.push(k+"
    "),k=" ",j=1),j+=l.length+2,b.member[i]===1&&(l=""+l+""),h*/
    ")}m.push("
    ")}}return m.join("")},cU.jshint=cU,cU.edition="2011-02-19";return cU}();typeof b=="object"&&b&&(b.JSHINT=d)}),define("ace/narcissus/jsparse",["require","exports","module","ace/narcissus/jslex","ace/narcissus/jsdefs"],function(require,exports,module){function parseStdin(a,b){for(;;)try{var c=new lexer.Tokenizer(a,"stdin",b.value),d=Script(c,!1);b.value=c.lineno;return d}catch(e){if(!c.unexpectedEOF)throw e;var f=readline();if(!f)throw e;a+="\n"+f}}function parse(a,b,c){var d=new lexer.Tokenizer(a,b,c),e=Script(d,!1);if(!d.done)throw d.newSyntaxError("Syntax error");return e}function PrimaryExpression(a,b){var c,d,e=a.get(!0);switch(e){case FUNCTION:c=FunctionDefinition(a,b,!1,EXPRESSED_FORM);break;case LEFT_BRACKET:c=new Node(a,{type:ARRAY_INIT});while((e=a.peek(!0))!==RIGHT_BRACKET){if(e===COMMA){a.get(),c.push(null);continue}c.push(AssignExpression(a,b));if(e!==COMMA&&!a.match(COMMA))break}c.children.length===1&&a.match(FOR)&&(d=new Node(a,{type:ARRAY_COMP,expression:c.children[0],tail:ComprehensionTail(a,b)}),c=d),a.mustMatch(RIGHT_BRACKET);break;case LEFT_CURLY:var f,g;c=new Node(a,{type:OBJECT_INIT});object_init:if(!a.match(RIGHT_CURLY)){do{e=a.get();if(a.token.value!=="get"&&a.token.value!=="set"||a.peek()!==IDENTIFIER){switch(e){case IDENTIFIER:case NUMBER:case STRING:f=new Node(a,{type:IDENTIFIER});break;case RIGHT_CURLY:if(b.ecma3OnlyMode)throw a.newSyntaxError("Illegal trailing ,");break object_init;default:if(a.token.value in definitions.keywords){f=new Node(a,{type:IDENTIFIER});break}throw a.newSyntaxError("Invalid property name")}if(a.match(COLON))d=new Node(a,{type:PROPERTY_INIT}),d.push(f),d.push(AssignExpression(a,b)),c.push(d);else{if(a.peek()!==COMMA&&a.peek()!==RIGHT_CURLY)throw a.newSyntaxError("missing : after property");c.push(f)}}else{if(b.ecma3OnlyMode)throw a.newSyntaxError("Illegal property accessor");c.push(FunctionDefinition(a,b,!0,EXPRESSED_FORM))}}while(a.match(COMMA));a.mustMatch(RIGHT_CURLY)}break;case LEFT_PAREN:c=ParenExpression(a,b),a.mustMatch(RIGHT_PAREN),c.parenthesized=!0;break;case LET:c=LetBlock(a,b,!1);break;case NULL:case THIS:case TRUE:case FALSE:case IDENTIFIER:case NUMBER:case STRING:case REGEXP:c=new Node(a);break;default:throw a.newSyntaxError("missing operand")}return c}function ArgumentList(a,b){var c,d;c=new Node(a,{type:LIST});if(a.match(RIGHT_PAREN,!0))return c;do{d=AssignExpression(a,b);if(d.type===YIELD&&!d.parenthesized&&a.peek()===COMMA)throw a.newSyntaxError("Yield expression must be parenthesized");if(a.match(FOR)){d=GeneratorExpression(a,b,d);if(c.children.length>1||a.peek(!0)===COMMA)throw a.newSyntaxError("Generator expression must be parenthesized")}c.push(d)}while(a.match(COMMA));a.mustMatch(RIGHT_PAREN);return c}function MemberExpression(a,b,c){var d,e,f,g;a.match(NEW)?(d=new Node(a),d.push(MemberExpression(a,b,!1)),a.match(LEFT_PAREN)&&(d.type=NEW_WITH_ARGS,d.push(ArgumentList(a,b)))):d=PrimaryExpression(a,b);while((g=a.get())!==END){switch(g){case DOT:e=new Node(a),e.push(d),a.mustMatch(IDENTIFIER),e.push(new Node(a));break;case LEFT_BRACKET:e=new Node(a,{type:INDEX}),e.push(d),e.push(Expression(a,b)),a.mustMatch(RIGHT_BRACKET);break;case LEFT_PAREN:if(c){e=new Node(a,{type:CALL}),e.push(d),e.push(ArgumentList(a,b));break};default:a.unget();return d}d=e}return d}function UnaryExpression(a,b){var c,d,e;switch(e=a.get(!0)){case DELETE:case VOID:case TYPEOF:case NOT:case BITWISE_NOT:case PLUS:case MINUS:e===PLUS?c=new Node(a,{type:UNARY_PLUS}):e===MINUS?c=new Node(a,{type:UNARY_MINUS}):c=new Node(a),c.push(UnaryExpression(a,b));break;case INCREMENT:case DECREMENT:c=new Node(a),c.push(MemberExpression(a,b,!0));break;default:a.unget(),c=MemberExpression(a,b,!0);if(a.tokens[a.tokenIndex+a.lookahead-1&3].lineno===a.lineno)if(a.match(INCREMENT)||a.match(DECREMENT))d=new Node(a,{postfix:!0}),d.push(c),c=d}return c}function MultiplyExpression(a,b){var c,d;c=UnaryExpression(a,b);while(a.match(MUL)||a.match(DIV)||a.match(MOD))d=new Node(a),d.push(c),d.push(UnaryExpression(a,b)),c=d;return c}function AddExpression(a,b){var c,d;c=MultiplyExpression(a,b);while(a.match(PLUS)||a.match(MINUS))d=new Node(a),d.push(c),d.push(MultiplyExpression(a,b)),c=d;return c}function ShiftExpression(a,b){var c,d;c=AddExpression(a,b);while(a.match(LSH)||a.match(RSH)||a.match(URSH))d=new Node(a),d.push(c),d.push(AddExpression(a,b)),c=d;return c}function RelationalExpression(a,b){var c,d,e=b.update({inForLoopInit:!1});c=ShiftExpression(a,e);while(a.match(LT)||a.match(LE)||a.match(GE)||a.match(GT)||!b.inForLoopInit&&a.match(IN)||a.match(INSTANCEOF))d=new Node(a),d.push(c),d.push(ShiftExpression(a,e)),c=d;return c}function EqualityExpression(a,b){var c,d;c=RelationalExpression(a,b);while(a.match(EQ)||a.match(NE)||a.match(STRICT_EQ)||a.match(STRICT_NE))d=new Node(a),d.push(c),d.push(RelationalExpression(a,b)),c=d;return c}function BitwiseAndExpression(a,b){var c,d;c=EqualityExpression(a,b);while(a.match(BITWISE_AND))d=new Node(a),d.push(c),d.push(EqualityExpression(a,b)),c=d;return c}function BitwiseXorExpression(a,b){var c,d;c=BitwiseAndExpression(a,b);while(a.match(BITWISE_XOR))d=new Node(a),d.push(c),d.push(BitwiseAndExpression(a,b)),c=d;return c}function BitwiseOrExpression(a,b){var c,d;c=BitwiseXorExpression(a,b);while(a.match(BITWISE_OR))d=new Node(a),d.push(c),d.push(BitwiseXorExpression(a,b)),c=d;return c}function AndExpression(a,b){var c,d;c=BitwiseOrExpression(a,b);while(a.match(AND))d=new Node(a),d.push(c),d.push(BitwiseOrExpression(a,b)),c=d;return c}function OrExpression(a,b){var c,d;c=AndExpression(a,b);while(a.match(OR))d=new Node(a),d.push(c),d.push(AndExpression(a,b)),c=d;return c}function ConditionalExpression(a,b){var c,d;c=OrExpression(a,b);if(a.match(HOOK)){d=c,c=new Node(a,{type:HOOK}),c.push(d),c.push(AssignExpression(a,b.update({inForLoopInit:!1})));if(!a.match(COLON))throw a.newSyntaxError("missing : after ?");c.push(AssignExpression(a,b))}return c}function AssignExpression(a,b){var c,d;if(a.match(YIELD,!0))return ReturnOrYield(a,b);c=new Node(a,{type:ASSIGN}),d=ConditionalExpression(a,b);if(!a.match(ASSIGN))return d;switch(d.type){case OBJECT_INIT:case ARRAY_INIT:d.destructuredNames=checkDestructuring(a,b,d);case IDENTIFIER:case DOT:case INDEX:case CALL:break;default:throw a.newSyntaxError("Bad left-hand side of assignment")}c.assignOp=a.token.assignOp,c.push(d),c.push(AssignExpression(a,b));return c}function Expression(a,b){var c,d;c=AssignExpression(a,b);if(a.match(COMMA)){d=new Node(a,{type:COMMA}),d.push(c),c=d;do{d=c.children[c.children.length-1];if(d.type===YIELD&&!d.parenthesized)throw a.newSyntaxError("Yield expression must be parenthesized");c.push(AssignExpression(a,b))}while(a.match(COMMA))}return c}function ParenExpression(a,b){var c=Expression(a,b.update({inForLoopInit:b.inForLoopInit&&a.token.type===LEFT_PAREN}));if(a.match(FOR)){if(c.type===YIELD&&!c.parenthesized)throw a.newSyntaxError("Yield expression must be parenthesized");if(c.type===COMMA&&!c.parenthesized)throw a.newSyntaxError("Generator expression must be parenthesized");c=GeneratorExpression(a,b,c)}return c}function HeadExpression(a,b){var c=MaybeLeftParen(a,b),d=ParenExpression(a,b);MaybeRightParen(a,c);if(c===END&&!d.parenthesized){var e=a.peek();if(e!==LEFT_CURLY&&!definitions.isStatementStartCode[e])throw a.newSyntaxError("Unparenthesized head followed by unbraced body")}return d}function ComprehensionTail(a,b){var c,d,e,f,g;c=new Node(a,{type:COMP_TAIL});do{d=new Node(a,{type:FOR_IN,isLoop:!0}),a.match(IDENTIFIER)&&(a.token.value==="each"?d.isEach=!0:a.unget()),g=MaybeLeftParen(a,b);switch(a.get()){case LEFT_BRACKET:case LEFT_CURLY:a.unget(),d.iterator=DestructuringExpression(a,b);break;case IDENTIFIER:d.iterator=f=new Node(a,{type:IDENTIFIER}),f.name=f.value,d.varDecl=e=new Node(a,{type:VAR}),e.push(f),b.parentScript.varDecls.push(f);break;default:throw a.newSyntaxError("missing identifier")}a.mustMatch(IN),d.object=Expression(a,b),MaybeRightParen(a,g),c.push(d)}while(a.match(FOR));a.match(IF)&&(c.guard=HeadExpression(a,b));return c}function GeneratorExpression(a,b,c){return new Node(a,{type:GENERATOR,expression:c,tail:ComprehensionTail(a,b)})}function DestructuringExpression(a,b,c){var d=PrimaryExpression(a,b);d.destructuredNames=checkDestructuring(a,b,d,c);return d}function checkDestructuring(a,b,c,d){if(c.type===ARRAY_COMP)throw a.newSyntaxError("Invalid array comprehension left-hand side");if(c.type===ARRAY_INIT||c.type===OBJECT_INIT){var e={},f,g,h,i,j,k=c.children;for(var l=0,m=k.length;l=0)throw a.newSyntaxError("More than one switch default");case CASE:f=new Node(a),j===DEFAULT?e.defaultIndex=e.cases.length:f.caseLabel=Expression(a,l,COLON);break;default:throw a.newSyntaxError("Invalid switch case")}a.mustMatch(COLON),f.statements=new Node(a,blockInit());while((j=a.peek(!0))!==CASE&&j!==DEFAULT&&j!==RIGHT_CURLY)f.statements.push(Statement(a,l));e.cases.push(f)}return e;case FOR:e=new Node(a,LOOP_INIT),a.match(IDENTIFIER)&&(a.token.value==="each"?e.isEach=!0:a.unget()),b.parenFreeMode||a.mustMatch(LEFT_PAREN),l=b.pushTarget(e).nest(NESTING_DEEP),m=b.update({inForLoopInit:!0}),(j=a.peek())!==SEMICOLON&&(j===VAR||j===CONST?(a.get(),f=Variables(a,m)):j===LET?(a.get(),a.peek()===LEFT_PAREN?f=LetBlock(a,m,!1):(m.parentBlock=e,e.varDecls=[],f=Variables(a,m))):f=Expression(a,m));if(f&&a.match(IN)){e.type=FOR_IN,e.object=Expression(a,m);if(f.type===VAR||f.type===LET){h=f.children;if(h.length!==1&&f.destructurings.length!==1)throw new SyntaxError("Invalid for..in left-hand side",a.filename,f.lineno);f.destructurings.length>0?e.iterator=f.destructurings[0]:e.iterator=h[0],e.varDecl=f}else{if(f.type===ARRAY_INIT||f.type===OBJECT_INIT)f.destructuredNames=checkDestructuring(a,m,f);e.iterator=f}}else{e.setup=f,a.mustMatch(SEMICOLON);if(e.isEach)throw a.newSyntaxError("Invalid for each..in loop");e.condition=a.peek()===SEMICOLON?null:Expression(a,m),a.mustMatch(SEMICOLON),k=a.peek(),e.update=(b.parenFreeMode?k===LEFT_CURLY||definitions.isStatementStartCode[k]:k===RIGHT_PAREN)?null:Expression(a,m)}b.parenFreeMode||a.mustMatch(RIGHT_PAREN),e.body=Statement(a,l);return e;case WHILE:e=new Node(a,{isLoop:!0}),e.condition=HeadExpression(a,b),e.body=Statement(a,b.pushTarget(e).nest(NESTING_DEEP));return e;case DO:e=new Node(a,{isLoop:!0}),e.body=Statement(a,b.pushTarget(e).nest(NESTING_DEEP)),a.mustMatch(WHILE),e.condition=HeadExpression(a,b);if(!b.ecmaStrictMode){a.match(SEMICOLON);return e}break;case BREAK:case CONTINUE:e=new Node(a),l=b.pushTarget(e),a.peekOnSameLine()===IDENTIFIER&&(a.get(),e.label=a.token.value),e.target=e.label?l.labeledTargets.find(function(a){return a.labels.has(e.label)}):l.defaultTarget;if(!e.target)throw a.newSyntaxError("Invalid "+(j===BREAK?"break":"continue"));if(!e.target.isLoop&&j===CONTINUE)throw a.newSyntaxError("Invalid continue");break;case TRY:e=new Node(a,{catchClauses:[]}),e.tryBlock=Block(a,b);while(a.match(CATCH)){f=new Node(a),g=MaybeLeftParen(a,b);switch(a.get()){case LEFT_BRACKET:case LEFT_CURLY:a.unget(),f.varName=DestructuringExpression(a,b,!0);break;case IDENTIFIER:f.varName=a.token.value;break;default:throw a.newSyntaxError("missing identifier in catch")}if(a.match(IF)){if(b.ecma3OnlyMode)throw a.newSyntaxError("Illegal catch guard");if(e.catchClauses.length&&!e.catchClauses.top().guard)throw a.newSyntaxError("Guarded catch after unguarded");f.guard=Expression(a,b)}MaybeRightParen(a,g),f.block=Block(a,b),e.catchClauses.push(f)}a.match(FINALLY)&&(e.finallyBlock=Block(a,b));if(!e.catchClauses.length&&!e.finallyBlock)throw a.newSyntaxError("Invalid try statement");return e;case CATCH:case FINALLY:throw a.newSyntaxError(definitions.tokens[j]+" without preceding try");case THROW:e=new Node(a),e.exception=Expression(a,b);break;case RETURN:e=ReturnOrYield(a,b);break;case WITH:e=new Node(a),e.object=HeadExpression(a,b),e.body=Statement(a,b.pushTarget(e).nest(NESTING_DEEP));return e;case VAR:case CONST:e=Variables(a,b);break;case LET:a.peek()===LEFT_PAREN?e=LetBlock(a,b,!0):e=Variables(a,b);break;case DEBUGGER:e=new Node(a);break;case NEWLINE:case SEMICOLON:e=new Node(a,{type:SEMICOLON}),e.expression=null;return e;default:if(j===IDENTIFIER){j=a.peek();if(j===COLON){d=a.token.value;if(b.allLabels.has(d))throw a.newSyntaxError("Duplicate label");a.get(),e=new Node(a,{type:LABEL,label:d}),e.statement=Statement(a,b.pushLabel(d).nest(NESTING_SHALLOW)),e.target=e.statement.type===LABEL?e.statement.target:e.statement;return e}}e=new Node(a,{type:SEMICOLON}),a.unget(),e.expression=Expression(a,b),e.end=e.expression.end}MagicalSemicolon(a);return e}function Block(a,b){a.mustMatch(LEFT_CURLY);var c=new Node(a,blockInit());Statements(a,b.update({parentBlock:c}).pushTarget(c),c),a.mustMatch(RIGHT_CURLY);return c}function Statements(a,b,c){try{while(!a.done&&a.peek(!0)!==RIGHT_CURLY)c.push(Statement(a,b))}catch(d){a.done&&(a.unexpectedEOF=!0);throw d}}function MaybeRightParen(a,b){b===LEFT_PAREN&&a.mustMatch(RIGHT_PAREN)}function MaybeLeftParen(a,b){if(b.parenFreeMode)return a.match(LEFT_PAREN)?LEFT_PAREN:END;return a.mustMatch(LEFT_PAREN).type}function scriptInit(){return{type:SCRIPT,funDecls:[],varDecls:[],modDecls:[],impDecls:[],expDecls:[],loadDeps:[],hasEmptyReturn:!1,hasReturnWithValue:!1,isGenerator:!1}}function blockInit(){return{type:BLOCK,varDecls:[]}}function tokenString(a){var b=definitions.tokens[a];return/^\W/.test(b)?definitions.opTypeNames[b]:b.toUpperCase()}function Node(a,b){var c=a.token;c?(this.type=c.type,this.value=c.value,this.lineno=c.lineno,this.start=c.start,this.end=c.end):this.lineno=a.lineno,this.tokenizer=a,this.children=[];for(var d in b)this[d]=b[d]}function Script(a,b){var c=new Node(a,scriptInit()),d=new StaticContext(c,c,b,!1,NESTING_TOP);Statements(a,d,c);return c}function StaticContext(a,b,c,d,e){this.parentScript=a,this.parentBlock=b,this.inFunction=c,this.inForLoopInit=d,this.nesting=e,this.allLabels=new Stack,this.currentLabels=new Stack,this.labeledTargets=new Stack,this.defaultTarget=null,definitions.options.ecma3OnlyMode&&(this.ecma3OnlyMode=!0),definitions.options.parenFreeMode&&(this.parenFreeMode=!0)}function pushDestructuringVarDecls(a,b){for(var c in a){var d=a[c];d.type===IDENTIFIER?b.varDecls.push(d):pushDestructuringVarDecls(d,b)}}var lexer=require("ace/narcissus/jslex"),definitions=require("ace/narcissus/jsdefs");const StringMap=definitions.StringMap,Stack=definitions.Stack;eval(definitions.consts);const NESTING_TOP=0,NESTING_SHALLOW=1,NESTING_DEEP=2;StaticContext.prototype={ecma3OnlyMode:!1,parenFreeMode:!1,update:function(a){var b={};for(var c in a)b[c]={value:a[c],writable:!0,enumerable:!0,configurable:!0};return Object.create(this,b)},pushLabel:function(a){return this.update({currentLabels:this.currentLabels.push(a),allLabels:this.allLabels.push(a)})},pushTarget:function(a){var b=a.isLoop||a.type===SWITCH;if(this.currentLabels.isEmpty())return b?this.update({defaultTarget:a}):this;a.labels=new StringMap,this.currentLabels.forEach(function(b){a.labels.set(b,!0)});return this.update({currentLabels:new Stack,labeledTargets:this.labeledTargets.push(a),defaultTarget:b?a:this.defaultTarget})},nest:function(a){var b=Math.max(this.nesting,a);return b!==this.nesting?this.update({nesting:b}):this}},definitions.defineProperty(Array.prototype,"top",function(){return this.length&&this[this.length-1]},!1,!1,!0);var Np=Node.prototype={};Np.constructor=Node,Np.toSource=Object.prototype.toSource,Np.push=function(a){a!==null&&(a.start=0)b+=c;return b},!1,!1,!0);const DECLARED_FORM=0,EXPRESSED_FORM=1,STATEMENT_FORM=2;exports.parse=parse,exports.parseStdin=parseStdin,exports.Node=Node,exports.DECLARED_FORM=DECLARED_FORM,exports.EXPRESSED_FORM=EXPRESSED_FORM,exports.STATEMENT_FORM=STATEMENT_FORM,exports.Tokenizer=lexer.Tokenizer,exports.FunctionDefinition=FunctionDefinition}),define("ace/narcissus/jslex",["require","exports","module","ace/narcissus/jsdefs"],function(require,exports,module){function Tokenizer(a,b,c){this.cursor=0,this.source=String(a),this.tokens=[],this.tokenIndex=0,this.lookahead=0,this.scanNewlines=!1,this.unexpectedEOF=!1,this.filename=b||"",this.lineno=c||1}var definitions=require("ace/narcissus/jsdefs");eval(definitions.consts);var opTokens={};for(var op in definitions.opTypeNames){if(op==="\n"||op===".")continue;var node=opTokens;for(var i=0;i"9")throw this.newSyntaxError("Missing exponent");do ch=a[this.cursor++];while(ch>="0"&&ch<="9");this.cursor--;return!0}return!1},lexZeroNumber:function(a){var b=this.token,c=this.source;b.type=NUMBER,a=c[this.cursor++];if(a==="."){do a=c[this.cursor++];while(a>="0"&&a<="9");this.cursor--,this.lexExponent(),b.value=parseFloat(b.start,this.cursor)}else if(a==="x"||a==="X"){do a=c[this.cursor++];while(a>="0"&&a<="9"||a>="a"&&a<="f"||a>="A"&&a<="F");this.cursor--,b.value=parseInt(c.substring(b.start,this.cursor))}else if(a<"0"||a>"7")this.cursor--,this.lexExponent(),b.value=0;else{do a=c[this.cursor++];while(a>="0"&&a<="7");this.cursor--,b.value=parseInt(c.substring(b.start,this.cursor))}},lexNumber:function(a){var b=this.token,c=this.source;b.type=NUMBER;var d=!1;do a=c[this.cursor++],a==="."&&!d&&(d=!0,a=c[this.cursor++]);while(a>="0"&&a<="9");this.cursor--;var e=this.lexExponent();d=d||e;var f=c.substring(b.start,this.cursor);b.value=d?parseFloat(f):parseInt(f)},lexDot:function(a){var b=this.token,c=this.source,d=c[this.cursor];if(d<"0"||d>"9")b.type=DOT,b.assignOp=null,b.value=".";else{do a=c[this.cursor++];while(a>="0"&&a<="9");this.cursor--,this.lexExponent(),b.type=NUMBER,b.value=parseFloat(b.start,this.cursor)}},lexString:function(ch){var token=this.token,input=this.source;token.type=STRING;var hasEscapes=!1,delim=ch;while((ch=input[this.cursor++])!==delim){if(this.cursor==input.length)throw this.newSyntaxError("Unterminated string literal");if(ch==="\\"){hasEscapes=!0;if(++this.cursor==input.length)throw this.newSyntaxError("Unterminated string literal")}}token.value=hasEscapes?eval(input.substring(token.start,this.cursor)):input.substring(token.start+1,this.cursor-1)},lexRegExp:function(ch){var token=this.token,input=this.source;token.type=REGEXP;do{ch=input[this.cursor++];if(ch==="\\")this.cursor++;else if(ch==="["){do{if(ch===undefined)throw this.newSyntaxError("Unterminated character class");ch==="\\"&&this.cursor++,ch=input[this.cursor++]}while(ch!=="]")}else if(ch===undefined)throw this.newSyntaxError("Unterminated regex")}while(ch!=="/");do ch=input[this.cursor++];while(ch>="a"&&ch<="z");this.cursor--,token.value=eval(input.substring(token.start,this.cursor))},lexOp:function(a){var b=this.token,c=this.source,d=opTokens[a],e=c[this.cursor];e in d&&(d=d[e],this.cursor++,e=c[this.cursor],e in d&&(d=d[e],this.cursor++,e=c[this.cursor]));var f=d.op;definitions.assignOps[f]&&c[this.cursor]==="="?(this.cursor++,b.type=ASSIGN,b.assignOp=definitions.tokenIds[definitions.opTypeNames[f]],f+="="):(b.type=definitions.tokenIds[definitions.opTypeNames[f]],b.assignOp=null),b.value=f},lexIdent:function(a){var b=this.token,c=this.source;do a=c[this.cursor++];while(a>="a"&&a<="z"||a>="A"&&a<="Z"||a>="0"&&a<="9"||a==="$"||a==="_");this.cursor--;var d=c.substring(b.start,this.cursor);b.type=definitions.keywords[d]||IDENTIFIER,b.value=d},get:function(a){var b;while(this.lookahead){--this.lookahead,this.tokenIndex=this.tokenIndex+1&3,b=this.tokens[this.tokenIndex];if(b.type!==NEWLINE||this.scanNewlines)return b.type}this.skip(),this.tokenIndex=this.tokenIndex+1&3,b=this.tokens[this.tokenIndex],b||(this.tokens[this.tokenIndex]=b={});var c=this.source;if(this.cursor===c.length)return b.type=END;b.start=this.cursor,b.lineno=this.lineno;var d=c[this.cursor++];if(d>="a"&&d<="z"||d>="A"&&d<="Z"||d==="$"||d==="_")this.lexIdent(d);else if(a&&d==="/")this.lexRegExp(d);else if(d in opTokens)this.lexOp(d);else if(d===".")this.lexDot(d);else if(d<"1"||d>"9")if(d==="0")this.lexZeroNumber(d);else if(d==='"'||d==="'")this.lexString(d);else if(this.scanNewlines&&d==="\n")b.type=NEWLINE,b.value="\n",this.lineno++;else throw this.newSyntaxError("Illegal token");else this.lexNumber(d);b.end=this.cursor;return b.type},unget:function(){if(++this.lookahead===4)throw"PANIC: too much lookahead!";this.tokenIndex=this.tokenIndex-1&3},newSyntaxError:function(a){var b=new SyntaxError(a,this.filename,this.lineno);b.source=this.source,b.lineno=this.lineno,b.cursor=this.lookahead?this.tokens[this.tokenIndex+this.lookahead&3].start:this.cursor;return b}},exports.Tokenizer=Tokenizer}),define("ace/narcissus/jsdefs",["require","exports","module"],function(a,b,c){function y(a){this.elts=a||null}function x(){this.table=Object.create(null,{}),this.size=0}function v(){return undefined}function u(a){return{getOwnPropertyDescriptor:function(b){var c=Object.getOwnPropertyDescriptor(a,b);c.configurable=!0;return c},getPropertyDescriptor:function(b){var c=s(a,b);c.configurable=!0;return c},getOwnPropertyNames:function(){return Object.getOwnPropertyNames(a)},defineProperty:function(b,c){Object.defineProperty(a,b,c)},"delete":function(b){return delete a[b]},fix:function(){if(Object.isFrozen(a))return t(a);return undefined},has:function(b){return b in a},hasOwn:function(b){return({}).hasOwnProperty.call(a,b)},get:function(b,c){return a[c]},set:function(b,c,d){a[c]=d;return!0},enumerate:function(){var b=[];for(m in a)b.push(m);return b},keys:function(){return Object.keys(a)}}}function t(a){var b={};for(var c in Object.getOwnPropertyNames(a))b[c]=Object.getOwnPropertyDescriptor(a,c);return b}function s(a,b){while(a){if(({}).hasOwnProperty.call(a,b))return Object.getOwnPropertyDescriptor(a,b);a=Object.getPrototypeOf(a)}}function r(a){return typeof a==="function"&&a.toString().match(/\[native code\]/)}function q(a,b,c,d,e,f){Object.defineProperty(a,b,{value:c,writable:!e,configurable:!d,enumerable:!f})}function p(a,b,c,d,e){Object.defineProperty(a,b,{get:c,configurable:!d,enumerable:!e})}b.options={version:185},function(){b.hostGlobal=this}();var d=["END","\n",";",",","=","?",":","CONDITIONAL","||","&&","|","^","&","==","!=","===","!==","<","<=",">=",">","<<",">>",">>>","+","-","*","/","%","!","~","UNARY_PLUS","UNARY_MINUS","++","--",".","[","]","{","}","(",")","SCRIPT","BLOCK","LABEL","FOR_IN","CALL","NEW_WITH_ARGS","INDEX","ARRAY_INIT","OBJECT_INIT","PROPERTY_INIT","GETTER","SETTER","GROUP","LIST","LET_BLOCK","ARRAY_COMP","GENERATOR","COMP_TAIL","IDENTIFIER","NUMBER","STRING","REGEXP","break","case","catch","const","continue","debugger","default","delete","do","else","false","finally","for","function","if","in","instanceof","let","new","null","return","switch","this","throw","true","try","typeof","var","void","yield","while","with"],e=["break","const","continue","debugger","do","for","if","return","switch","throw","try","var","yield","while","with"],f={"\n":"NEWLINE",";":"SEMICOLON",",":"COMMA","?":"HOOK",":":"COLON","||":"OR","&&":"AND","|":"BITWISE_OR","^":"BITWISE_XOR","&":"BITWISE_AND","===":"STRICT_EQ","==":"EQ","=":"ASSIGN","!==":"STRICT_NE","!=":"NE","<<":"LSH","<=":"LE","<":"LT",">>>":"URSH",">>":"RSH",">=":"GE",">":"GT","++":"INCREMENT","--":"DECREMENT","+":"PLUS","-":"MINUS","*":"MUL","/":"DIV","%":"MOD","!":"NOT","~":"BITWISE_NOT",".":"DOT","[":"LEFT_BRACKET","]":"RIGHT_BRACKET","{":"LEFT_CURLY","}":"RIGHT_CURLY","(":"LEFT_PAREN",")":"RIGHT_PAREN"},g={"__proto__":null},h={},i="const ";for(var j=0,k=d.length;j0&&(i+=", ");var l=d[j],m;/^[a-z]/.test(l)?(m=l.toUpperCase(),g[l]=j):m=/^\W/.test(l)?f[l]:l,i+=m+" = "+j,h[m]=j,d[l]=j}i+=";";var n={"__proto__":null};for(j=0,k=e.length;j>",">>>","+","-","*","/","%"];for(j=0,k=o.length;j - - - - - Editor - - - -

    Ace Bookmarklet Builder

    - -

    -WARNING: Currently, this is only fully supported in non IE browsers. -

    - -

    -How to use it: -

      -
    • Select the options below as you want them to be by default.
    • -
    • Enter the "SourceUrl" where you placed the source data which you find under build/textarea/src (you can also leave the default to server the scripts from GitHub).
    • -
    • Click the "Build Link" button to generate your custom Ace Bookmarklet.
    • -
    • Drag the generated link to your toolbar or store it somewhere else.
    • -
    • Go to a page with an textarea element and click the bookmarklet - wait a little bit till the files are loaded.
    • -
    • Click 3 times on the textarea you want to replace - Ace will replace it.
    • -
    • To change settings, just click the red icon in the bottom right corner.
    • -
    -

    - -
    -SourceUrl: - -
    - - - - - diff --git a/build/textarea/src/ace-uncompressed.js b/build/textarea/src/ace-uncompressed.js deleted file mode 100644 index 3a919028..00000000 --- a/build/textarea/src/ace-uncompressed.js +++ /dev/null @@ -1,12927 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/** - * Define a module along with a payload - * @param module a name for the payload - * @param payload a function to call with (require, exports, module) params - */ - -(function() { - -var _define = function(module, payload) { - if (typeof module !== 'string') { - if (_define.original) - _define.original.apply(window, arguments); - else { - console.error('dropping module because define wasn\'t a string.'); - console.trace(); - } - return; - } - - if (!_define.modules) - _define.modules = {}; - - _define.modules[module] = payload; -}; - -/** - * Get at functionality __ace_shadowed__.define()ed using the function above - */ -var _require = function(module, callback) { - if (Object.prototype.toString.call(module) === "[object Array]") { - var params = []; - for (var i = 0, l = module.length; i < l; ++i) { - var dep = lookup(module[i]); - if (!dep && _require.original) - return _require.original.apply(window, arguments); - params.push(dep); - }; - if (callback) { - callback.apply(null, params); - } - } - - if (typeof module === 'string') { - var payload = lookup(module); - if (!payload && _require.original) - return _require.original.apply(window, arguments); - - if (callback) { - callback(); - } - - return payload; - }; -} - -_require.packaged = true; -_require.noWorker = true; - -/** - * Internal function to lookup moduleNames and resolve them by calling the - * definition function if needed. - */ -var lookup = function(moduleName) { - var module = _define.modules[moduleName]; - if (module == null) { - console.error('Missing module: ' + moduleName); - return null; - } - - if (typeof module === 'function') { - var exports = {}; - module(_require, exports, { id: moduleName, uri: '' }); - // cache the resulting module object for next time - _define.modules[moduleName] = exports; - return exports; - } - - return module; -}; - -/** - * Expose as "shadowed" object to the outside world. - */ - -window.__ace_shadowed__ = { - require: _require, - define: _define -}; - -})();/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kevin Dangoor (kdangoor@mozilla.com) - * Irakli Gozalishvili (http://jeditoolkit.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/fixoldbrowsers', function(require, exports, module) { - -// Should be the first thing, as we want to use that in this module. -if (!Function.prototype.bind) { - // from MDC - // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind - Function.prototype.bind = function (obj) { - var slice = [].slice; - var args = slice.call(arguments, 1); - var self = this; - var nop = function () {}; - - // optimize common case - if (arguments.length == 1) { - var bound = function() { - return self.apply(this instanceof nop ? this : obj, arguments); - }; - } - else { - var bound = function () { - return self.apply( - this instanceof nop ? this : ( obj || {} ), - args.concat( slice.call(arguments) ) - ); - }; - } - - nop.prototype = self.prototype; - bound.prototype = new nop(); - - // From Narwhal - bound.name = this.name; - bound.displayName = this.displayName; - bound.length = this.length; - bound.unbound = self; - - return bound; - }; -} - - -var F = function() {} -var call = Function.prototype.call; -// Shortcut for `Object.prototype.hasOwnProperty.call`. -var owns = call.bind(Object.prototype.hasOwnProperty); - -// Shortcuts for getter / setter utilities if supported by JS engine. -var getGetter, getSetter, setGetter, setSetter -getGetter = getSetter = setGetter = setSetter = F; - -if (Object.prototype.__lookupGetter__) - getGetter = call.bind(Object.prototype.__lookupGetter__); -if (Object.prototype.__lookupSetter__) - getSetter = call.bind(Object.prototype.__lookupSetter__); -if (Object.prototype.__defineGetter__) - setGetter = call.bind(Object.prototype.__defineGetter__); -if (Object.prototype.__defineSetter__) - setSetter = call.bind(Object.prototype.__defineSetter__); - -/** - * Array detector. - * Firefox 3.5 and Safari 4 have this already. Chrome 4 however ... - * Note to Dojo - your isArray is still broken: instanceof doesn't work with - * Arrays taken from a different frame/window. - */ -// ES5 15.4.3.2 -if (!Array.isArray) { - Array.isArray = function(data) { - return data && Object.prototype.toString.call(data) === "[object Array]"; - }; -} - -// from MDC -// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf -if (!Array.prototype.indexOf) -{ - Array.prototype.indexOf = function(searchElement /*, fromIndex */) - { - if (this === void 0 || this === null) - throw new TypeError(); - - var t = Object(this); - var len = t.length >>> 0; - if (len === 0) - return -1; - - var n = 0, zero = n; - if (arguments.length > 0) { - n = Number(arguments[1]); - if (n !== n) - n = 0; - else if (n !== 0 && n !== (1 / zero) && n !== -(1 / zero)) - n = (n > 0 || -1) * Math.floor(Math.abs(n)); - } - - if (n >= len) - return -1; - - var k = n >= 0 - ? n - : Math.max(len - Math.abs(n), 0); - - for (; k < len; k++) { - if (k in t && t[k] === searchElement) - return k; - } - return -1; - }; -} - -// from MDC -// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf -if (!Array.prototype.lastIndexOf) -{ - Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/) - { - "use strict"; - - if (this === void 0 || this === null) - throw new TypeError(); - - var t = Object(this); - var len = t.length >>> 0; - if (len === 0) - return -1; - - var n = len, zero = false | 0; - if (arguments.length > 0) - { - n = Number(arguments[1]); - if (n !== n) - n = 0; - else if (n !== 0 && n !== (1 / zero) && n !== -(1 / zero)) - n = (n > 0 || -1) * Math.floor(Math.abs(n)); - } - - var k = n >= 0 - ? Math.min(n, len - 1) - : len - Math.abs(n); - - while (k >= 0) - { - if (k in t && t[k] === searchElement) - return k; - } - return -1; - }; -} - -// from MDC -// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map -// ES5 15.4.4.19 -if (!Array.prototype.map) { - Array.prototype.map = function(fun /*, thisp */) { - if (this === void 0 || this === null) - throw new TypeError(); - - var t = Object(this); - var len = t.length >>> 0; - if (typeof fun !== "function") - throw new TypeError(); - - res = new Array(len); - var thisp = arguments[1]; - for (var i = 0; i < len; i++) { - if (i in t) - res[i] = fun.call(thisp, t[i], i, t); - } - - return res; - }; -} - -// from MDC -// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach -// ES5 15.4.4.18 -if (!Array.prototype.forEach) { - Array.prototype.forEach = function(fun /*, thisp */) { - if (this === void 0 || this === null) - throw new TypeError(); - - var t = Object(this); - var len = t.length >>> 0; - if (typeof fun !== "function") - throw new TypeError(); - - var thisp = arguments[1]; - for (var i = 0; i < len; i++) { - if (i in t) - fun.call(thisp, t[i], i, t); - } - }; -} - -// ES5 15.4.4.20 -if (!Array.prototype.filter) { - Array.prototype.filter = function filter(callback, scope) { - var values = [], i, ii; - for (i = 0, ii = this.length; i < ii; i++) { - if (callback.call(scope, this[i])) values.push(this[i]); - } - return values; - }; -} - -// ES5 15.4.4.16 -if (!Array.prototype.every) { - Array.prototype.every = function every(callback, scope) { - var i, ii; - for (i = 0, ii = this.length; i < ii; i++) { - if (!callback.call(scope, this[i])) return false; - } - return true; - }; -} - -// ES5 15.4.4.17 -if (!Array.prototype.some) { - Array.prototype.some = function (callback, scope) { - var i, ii; - for (i = 0, ii = this.length; i < ii; i++) { - if (callback.call(scope, this[i])) return true; - } - return false; - }; -} - -// ES5 15.4.4.21 -// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce -if (!Array.prototype.reduce) { - Array.prototype.reduce = function(fun /*, initial*/) { - var len = this.length >>> 0; - if (typeof fun != "function") - throw new TypeError(); - - // no value to return if no initial value and an empty array - if (len == 0 && arguments.length == 1) - throw new TypeError(); - - var i = 0; - if (arguments.length >= 2) { - var rv = arguments[1]; - } else { - do { - if (i in this) { - rv = this[i++]; - break; - } - - // if array contains no values, no initial value to return - if (++i >= len) - throw new TypeError(); - } while (true); - } - - for (; i < len; i++) { - if (i in this) - rv = fun.call(null, rv, this[i], i, this); - } - - return rv; - }; -} - -// ES5 15.4.4.22 -// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight -if (!Array.prototype.reduceRight) { - Array.prototype.reduceRight = function(fun /*, initial*/) { - var len = this.length >>> 0; - if (typeof fun != "function") - throw new TypeError(); - - // no value to return if no initial value, empty array - if (len == 0 && arguments.length == 1) - throw new TypeError(); - - var i = len - 1; - if (arguments.length >= 2) { - var rv = arguments[1]; - } else { - do { - if (i in this) { - rv = this[i--]; - break; - } - - // if array contains no values, no initial value to return - if (--i < 0) - throw new TypeError(); - } while (true); - } - - for (; i >= 0; i--) { - if (i in this) - rv = fun.call(null, rv, this[i], i, this); - } - - return rv; - }; -} - - -/** - * Retrieves the list of keys on an object. - */ -if (!Object.keys) { - Object.keys = function keys(object) { - var name, names = []; - for (name in object) - if (owns(object, name)) names.push(name); - - return names; - }; -} - -// Can not be implemented so we default to the Object.keys -// ES5 15.2.3.4 -if (!Object.getOwnPropertyNames) { - Object.getOwnPropertyNames = Object.keys; -} - -// ES5 15.2.3.3 -var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a non-object" -if (!Object.getOwnPropertyDescriptor) { - Object.getOwnPropertyDescriptor = - function getOwnPropertyDescriptor(object, name) { - var descriptor, getter, setter; - - if (typeof object !== "object" && typeof object !== "function" - || object === null) throw new TypeError(ERR_NON_OBJECT); - - if (owns(object, name)) { - descriptor = { configurable: true, enumerable: true }; - getter = descriptor.get = getGetter(object, name); - setter = descriptor.set = getSetter(object, name); - // If nor getter nor setter is not defined we default to - // normal value. This can mean that either it's data - // property or js engine does not supports getters / setters. - if (!getter && !setter) { - descriptor.writeable = true; - descriptor.value = object[name] - } - } - return descriptor - } -} - -// Returning `__proto__` of an object or `object.constructor.prototype` for IE. -if (!Object.getPrototypeOf) { - Object.getPrototypeOf = function getPrototypeOf(object) { - return object.__proto__ || object.constructor.prototype; - } -} - -// ES5 15.2.3.5 -if (!Object.create) { - Object.create = function create(prototype, properties) { - var object; - - if (prototype === null) { - object = { __proto__: null }; - } else if (typeof prototype !== "object") { - throw new TypeError(prototype + " is not an object or null"); - } else { - F.prototype = prototype; - object = new F(); - } - - if (typeof properties !== "undefined") - Object.defineProperties(object, properties); - - return object; - }; -} - -// ES5 15.2.3.6 -if (!Object.defineProperty) { - Object.defineProperty = function defineProperty(object, name, descriptor) { - var proto, setter, getter; - - if ("object" !== typeof object && "function" !== typeof object) - throw new TypeError(object + "is not an object"); - if (descriptor && 'object' !== typeof descriptor) - throw new TypeError('Property descriptor map must be an object'); - if ('value' in descriptor) { // if it's a data property - if ('get' in descriptor || 'set' in descriptor) { - throw new TypeError('Invalid property. "value" present on ' - + 'property with getter or setter.'); - } - - // Swapping __proto__ with default one to avoid calling inherited - // getters / setters with this `name`. - if (proto = object.__proto__) object.__proto__ = Object.prototype; - // Delete property cause it may be a setter. - delete object[name]; - object[name] = descriptor.value; - // Return __proto__ back. - if (proto) object.__proto__ = proto; - } else { - if (getter = descriptor.get) setGetter(object, getter); - if (setter = descriptor.set) setSetter(object, setter); - } - return object; - }; -} - -// ES5 15.2.3.7 -if (!Object.defineProperties) { - Object.defineProperties = function defineProperties(object, properties) { - Object.getOwnPropertyNames(properties).forEach(function (name) { - Object.defineProperty(object, name, properties[name]); - }); - return object; - }; -} - -var passThrough = function(object) { return object }; -// ES5 15.2.3.8 -if (!Object.seal) Object.seal = passThrough; - -// ES5 15.2.3.9 -if (!Object.freeze) Object.freeze = passThrough; - -// ES5 15.2.3.10 -if (!Object.preventExtensions) Object.preventExtension = passThrough; - -var no = function() { return false }; -var yes = function() { return true }; - -// ES5 15.2.3.11 -if (!Object.isSealed) Object.isSealed = no; -// ES5 15.2.3.12 -if (!Object.isFrozen) Object.isFrozen = no; -// ES5 15.2.3.13 -if (!Object.isExtensible) Object.isExtensible = yes; - -if (!String.prototype.trim) { - String.prototype.trim = function() { - return this.trimLeft().trimRight(); - } -} - -if (!String.prototype.trimRight) { - String.prototype.trimRight = function() { - return this.replace(/[\t\v\f\s\u00a0\ufeff]+$/, ""); - } -} - -if (!String.prototype.trimLeft) { - String.prototype.trimLeft = function() { - return this.replace(/^[\t\v\f\s\u00a0\ufeff]+/, ""); - } -} - -exports.globalsLoaded = true; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kevin Dangoor (kdangoor@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/index', function(require, exports, module) { - -exports.startup = function(data, reason) { - require('pilot/fixoldbrowsers'); - - require('pilot/types/basic').startup(data, reason); - require('pilot/types/command').startup(data, reason); - require('pilot/types/settings').startup(data, reason); - require('pilot/commands/settings').startup(data, reason); - require('pilot/commands/basic').startup(data, reason); - // require('pilot/commands/history').startup(data, reason); - require('pilot/settings/canon').startup(data, reason); - require('pilot/canon').startup(data, reason); -}; - -exports.shutdown = function(data, reason) { - require('pilot/types/basic').shutdown(data, reason); - require('pilot/types/command').shutdown(data, reason); - require('pilot/types/settings').shutdown(data, reason); - require('pilot/commands/settings').shutdown(data, reason); - require('pilot/commands/basic').shutdown(data, reason); - // require('pilot/commands/history').shutdown(data, reason); - require('pilot/settings/canon').shutdown(data, reason); - require('pilot/canon').shutdown(data, reason); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * Kevin Dangoor (kdangoor@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/types/basic', function(require, exports, module) { - -var types = require("pilot/types"); -var Type = types.Type; -var Conversion = types.Conversion; -var Status = types.Status; - -/** - * These are the basic types that we accept. They are vaguely based on the - * Jetpack settings system (https://wiki.mozilla.org/Labs/Jetpack/JEP/24) - * although clearly more restricted. - * - *

    In addition to these types, Jetpack also accepts range, member, password - * that we are thinking of adding. - * - *

    This module probably should not be accessed directly, but instead used - * through types.js - */ - -/** - * 'text' is the default if no type is given. - */ -var text = new Type(); - -text.stringify = function(value) { - return value; -}; - -text.parse = function(value) { - if (typeof value != 'string') { - throw new Error('non-string passed to text.parse()'); - } - return new Conversion(value); -}; - -text.name = 'text'; - -/** - * We don't currently plan to distinguish between integers and floats - */ -var number = new Type(); - -number.stringify = function(value) { - if (!value) { - return null; - } - return '' + value; -}; - -number.parse = function(value) { - if (typeof value != 'string') { - throw new Error('non-string passed to number.parse()'); - } - - if (value.replace(/\s/g, '').length === 0) { - return new Conversion(null, Status.INCOMPLETE, ''); - } - - var reply = new Conversion(parseInt(value, 10)); - if (isNaN(reply.value)) { - reply.status = Status.INVALID; - reply.message = 'Can\'t convert "' + value + '" to a number.'; - } - - return reply; -}; - -number.decrement = function(value) { - return value - 1; -}; - -number.increment = function(value) { - return value + 1; -}; - -number.name = 'number'; - -/** - * One of a known set of options - */ -function SelectionType(typeSpec) { - if (!Array.isArray(typeSpec.data) && typeof typeSpec.data !== 'function') { - throw new Error('instances of SelectionType need typeSpec.data to be an array or function that returns an array:' + JSON.stringify(typeSpec)); - } - Object.keys(typeSpec).forEach(function(key) { - this[key] = typeSpec[key]; - }, this); -}; - -SelectionType.prototype = new Type(); - -SelectionType.prototype.stringify = function(value) { - return value; -}; - -SelectionType.prototype.parse = function(str) { - if (typeof str != 'string') { - throw new Error('non-string passed to parse()'); - } - if (!this.data) { - throw new Error('Missing data on selection type extension.'); - } - var data = (typeof(this.data) === 'function') ? this.data() : this.data; - - // The matchedValue could be the boolean value false - var hasMatched = false; - var matchedValue; - var completions = []; - data.forEach(function(option) { - if (str == option) { - matchedValue = this.fromString(option); - hasMatched = true; - } - else if (option.indexOf(str) === 0) { - completions.push(this.fromString(option)); - } - }, this); - - if (hasMatched) { - return new Conversion(matchedValue); - } - else { - // This is something of a hack it basically allows us to tell the - // setting type to forget its last setting hack. - if (this.noMatch) { - this.noMatch(); - } - - if (completions.length > 0) { - var msg = 'Possibilities' + - (str.length === 0 ? '' : ' for \'' + str + '\''); - return new Conversion(null, Status.INCOMPLETE, msg, completions); - } - else { - var msg = 'Can\'t use \'' + str + '\'.'; - return new Conversion(null, Status.INVALID, msg, completions); - } - } -}; - -SelectionType.prototype.fromString = function(str) { - return str; -}; - -SelectionType.prototype.decrement = function(value) { - var data = (typeof this.data === 'function') ? this.data() : this.data; - var index; - if (value == null) { - index = data.length - 1; - } - else { - var name = this.stringify(value); - var index = data.indexOf(name); - index = (index === 0 ? data.length - 1 : index - 1); - } - return this.fromString(data[index]); -}; - -SelectionType.prototype.increment = function(value) { - var data = (typeof this.data === 'function') ? this.data() : this.data; - var index; - if (value == null) { - index = 0; - } - else { - var name = this.stringify(value); - var index = data.indexOf(name); - index = (index === data.length - 1 ? 0 : index + 1); - } - return this.fromString(data[index]); -}; - -SelectionType.prototype.name = 'selection'; - -/** - * SelectionType is a base class for other types - */ -exports.SelectionType = SelectionType; - -/** - * true/false values - */ -var bool = new SelectionType({ - name: 'bool', - data: [ 'true', 'false' ], - stringify: function(value) { - return '' + value; - }, - fromString: function(str) { - return str === 'true' ? true : false; - } -}); - - -/** - * A we don't know right now, but hope to soon. - */ -function DeferredType(typeSpec) { - if (typeof typeSpec.defer !== 'function') { - throw new Error('Instances of DeferredType need typeSpec.defer to be a function that returns a type'); - } - Object.keys(typeSpec).forEach(function(key) { - this[key] = typeSpec[key]; - }, this); -}; - -DeferredType.prototype = new Type(); - -DeferredType.prototype.stringify = function(value) { - return this.defer().stringify(value); -}; - -DeferredType.prototype.parse = function(value) { - return this.defer().parse(value); -}; - -DeferredType.prototype.decrement = function(value) { - var deferred = this.defer(); - return (deferred.decrement ? deferred.decrement(value) : undefined); -}; - -DeferredType.prototype.increment = function(value) { - var deferred = this.defer(); - return (deferred.increment ? deferred.increment(value) : undefined); -}; - -DeferredType.prototype.name = 'deferred'; - -/** - * DeferredType is a base class for other types - */ -exports.DeferredType = DeferredType; - - -/** - * A set of objects of the same type - */ -function ArrayType(typeSpec) { - if (typeSpec instanceof Type) { - this.subtype = typeSpec; - } - else if (typeof typeSpec === 'string') { - this.subtype = types.getType(typeSpec); - if (this.subtype == null) { - throw new Error('Unknown array subtype: ' + typeSpec); - } - } - else { - throw new Error('Can\' handle array subtype'); - } -}; - -ArrayType.prototype = new Type(); - -ArrayType.prototype.stringify = function(values) { - // TODO: Check for strings with spaces and add quotes - return values.join(' '); -}; - -ArrayType.prototype.parse = function(value) { - return this.defer().parse(value); -}; - -ArrayType.prototype.name = 'array'; - -/** - * Registration and de-registration. - */ -exports.startup = function() { - types.registerType(text); - types.registerType(number); - types.registerType(bool); - types.registerType(SelectionType); - types.registerType(DeferredType); - types.registerType(ArrayType); -}; - -exports.shutdown = function() { - types.unregisterType(text); - types.unregisterType(number); - types.unregisterType(bool); - types.unregisterType(SelectionType); - types.unregisterType(DeferredType); - types.unregisterType(ArrayType); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/types', function(require, exports, module) { - -/** - * Some types can detect validity, that is to say they can distinguish between - * valid and invalid values. - * TODO: Change these constants to be numbers for more performance? - */ -var Status = { - /** - * The conversion process worked without any problem, and the value is - * valid. There are a number of failure states, so the best way to check - * for failure is (x !== Status.VALID) - */ - VALID: { - toString: function() { return 'VALID'; }, - valueOf: function() { return 0; } - }, - - /** - * A conversion process failed, however it was noted that the string - * provided to 'parse()' could be VALID by the addition of more characters, - * so the typing may not be actually incorrect yet, just unfinished. - * @see Status.INVALID - */ - INCOMPLETE: { - toString: function() { return 'INCOMPLETE'; }, - valueOf: function() { return 1; } - }, - - /** - * The conversion process did not work, the value should be null and a - * reason for failure should have been provided. In addition some completion - * values may be available. - * @see Status.INCOMPLETE - */ - INVALID: { - toString: function() { return 'INVALID'; }, - valueOf: function() { return 2; } - }, - - /** - * A combined status is the worser of the provided statuses - */ - combine: function(statuses) { - var combined = Status.VALID; - for (var i = 0; i < arguments; i++) { - if (arguments[i] > combined) { - combined = arguments[i]; - } - } - return combined; - } -}; -exports.Status = Status; - -/** - * The type.parse() method returns a Conversion to inform the user about not - * only the result of a Conversion but also about what went wrong. - * We could use an exception, and throw if the conversion failed, but that - * seems to violate the idea that exceptions should be exceptional. Typos are - * not. Also in order to store both a status and a message we'd still need - * some sort of exception type... - */ -function Conversion(value, status, message, predictions) { - /** - * The result of the conversion process. Will be null if status != VALID - */ - this.value = value; - - /** - * The status of the conversion. - * @see Status - */ - this.status = status || Status.VALID; - - /** - * A message to go with the conversion. This could be present for any status - * including VALID in the case where we want to note a warning for example. - * I18N: On the one hand this nasty and un-internationalized, however with - * a command line it is hard to know where to start. - */ - this.message = message; - - /** - * A array of strings which are the systems best guess at better inputs than - * the one presented. - * We generally expect there to be about 7 predictions (to match human list - * comprehension ability) however it is valid to provide up to about 20, - * or less. It is the job of the predictor to decide a smart cut-off. - * For example if there are 4 very good matches and 4 very poor ones, - * probably only the 4 very good matches should be presented. - */ - this.predictions = predictions || []; -} -exports.Conversion = Conversion; - -/** - * Most of our types are 'static' e.g. there is only one type of 'text', however - * some types like 'selection' and 'deferred' are customizable. The basic - * Type type isn't useful, but does provide documentation about what types do. - */ -function Type() { -}; -Type.prototype = { - /** - * Convert the given value to a string representation. - * Where possible, there should be round-tripping between values and their - * string representations. - */ - stringify: function(value) { throw new Error("not implemented"); }, - - /** - * Convert the given str to an instance of this type. - * Where possible, there should be round-tripping between values and their - * string representations. - * @return Conversion - */ - parse: function(str) { throw new Error("not implemented"); }, - - /** - * The plug-in system, and other things need to know what this type is - * called. The name alone is not enough to fully specify a type. Types like - * 'selection' and 'deferred' need extra data, however this function returns - * only the name, not the extra data. - *

    In old bespin, equality was based on the name. This may turn out to be - * important in Ace too. - */ - name: undefined, - - /** - * If there is some concept of a higher value, return it, - * otherwise return undefined. - */ - increment: function(value) { - return undefined; - }, - - /** - * If there is some concept of a lower value, return it, - * otherwise return undefined. - */ - decrement: function(value) { - return undefined; - }, - - /** - * There is interesting information (like predictions) in a conversion of - * nothing, the output of this can sometimes be customized. - * @return Conversion - */ - getDefault: function() { - return this.parse(''); - } -}; -exports.Type = Type; - -/** - * Private registry of types - * Invariant: types[name] = type.name - */ -var types = {}; - -/** - * Add a new type to the list available to the system. - * You can pass 2 things to this function - either an instance of Type, in - * which case we return this instance when #getType() is called with a 'name' - * that matches type.name. - * Also you can pass in a constructor (i.e. function) in which case when - * #getType() is called with a 'name' that matches Type.prototype.name we will - * pass the typeSpec into this constructor. See #reconstituteType(). - */ -exports.registerType = function(type) { - if (typeof type === 'object') { - if (type instanceof Type) { - if (!type.name) { - throw new Error('All registered types must have a name'); - } - types[type.name] = type; - } - else { - throw new Error('Can\'t registerType using: ' + type); - } - } - else if (typeof type === 'function') { - if (!type.prototype.name) { - throw new Error('All registered types must have a name'); - } - types[type.prototype.name] = type; - } - else { - throw new Error('Unknown type: ' + type); - } -}; - -exports.registerTypes = function registerTypes(types) { - Object.keys(types).forEach(function (name) { - var type = types[name]; - type.name = name; - exports.registerType(type); - }); -}; - -/** - * Remove a type from the list available to the system - */ -exports.deregisterType = function(type) { - delete types[type.name]; -}; - -/** - * See description of #exports.registerType() - */ -function reconstituteType(name, typeSpec) { - if (name.substr(-2) === '[]') { // i.e. endsWith('[]') - var subtypeName = name.slice(0, -2); - return new types['array'](subtypeName); - } - - var type = types[name]; - if (typeof type === 'function') { - type = new type(typeSpec); - } - return type; -} - -/** - * Find a type, previously registered using #registerType() - */ -exports.getType = function(typeSpec) { - if (typeof typeSpec === 'string') { - return reconstituteType(typeSpec); - } - - if (typeof typeSpec === 'object') { - if (!typeSpec.name) { - throw new Error('Missing \'name\' member to typeSpec'); - } - return reconstituteType(typeSpec.name, typeSpec); - } - - throw new Error('Can\'t extract type from ' + typeSpec); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * Kevin Dangoor (kdangoor@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/types/command', function(require, exports, module) { - -var canon = require("pilot/canon"); -var SelectionType = require("pilot/types/basic").SelectionType; -var types = require("pilot/types"); - - -/** - * Select from the available commands - */ -var command = new SelectionType({ - name: 'command', - data: function() { - return canon.getCommandNames(); - }, - stringify: function(command) { - return command.name; - }, - fromString: function(str) { - return canon.getCommand(str); - } -}); - - -/** - * Registration and de-registration. - */ -exports.startup = function() { - types.registerType(command); -}; - -exports.shutdown = function() { - types.unregisterType(command); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/canon', function(require, exports, module) { - -var console = require('pilot/console'); -var Trace = require('pilot/stacktrace').Trace; -var oop = require('pilot/oop'); -var EventEmitter = require('pilot/event_emitter').EventEmitter; -var catalog = require('pilot/catalog'); -var Status = require('pilot/types').Status; -var types = require('pilot/types'); -var lang = require('pilot/lang'); - -/* -// TODO: this doesn't belong here - or maybe anywhere? -var dimensionsChangedExtensionSpec = { - name: 'dimensionsChanged', - description: 'A dimensionsChanged is a way to be notified of ' + - 'changes to the dimension of Skywriter' -}; -exports.startup = function(data, reason) { - catalog.addExtensionSpec(commandExtensionSpec); -}; -exports.shutdown = function(data, reason) { - catalog.removeExtensionSpec(commandExtensionSpec); -}; -*/ - -var commandExtensionSpec = { - name: 'command', - description: 'A command is a bit of functionality with optional ' + - 'typed arguments which can do something small like moving ' + - 'the cursor around the screen, or large like cloning a ' + - 'project from VCS.', - indexOn: 'name' -}; - -exports.startup = function(data, reason) { - // TODO: this is probably all kinds of evil, but we need something working - catalog.addExtensionSpec(commandExtensionSpec); -}; - -exports.shutdown = function(data, reason) { - catalog.removeExtensionSpec(commandExtensionSpec); -}; - -/** - * Manage a list of commands in the current canon - */ - -/** - * A Command is a discrete action optionally with a set of ways to customize - * how it happens. This is here for documentation purposes. - * TODO: Document better - */ -var thingCommand = { - name: 'thing', - description: 'thing is an example command', - params: [{ - name: 'param1', - description: 'an example parameter', - type: 'text', - defaultValue: null - }], - exec: function(env, args, request) { - thing(); - } -}; - -/** - * A lookup hash of our registered commands - */ -var commands = {}; - -/** - * A sorted list of command names, we regularly want them in order, so pre-sort - */ -var commandNames = []; - -/** - * This registration method isn't like other Ace registration methods because - * it doesn't return a decorated command because there is no functional - * decoration to be done. - * TODO: Are we sure that in the future there will be no such decoration? - */ -function addCommand(command) { - if (!command.name) { - throw new Error('All registered commands must have a name'); - } - if (command.params == null) { - command.params = []; - } - if (!Array.isArray(command.params)) { - throw new Error('command.params must be an array in ' + command.name); - } - // Replace the type - command.params.forEach(function(param) { - if (!param.name) { - throw new Error('In ' + command.name + ': all params must have a name'); - } - upgradeType(command.name, param); - }, this); - commands[command.name] = command; - - commandNames.push(command.name); - commandNames.sort(); -}; - -function upgradeType(name, param) { - var lookup = param.type; - param.type = types.getType(lookup); - if (param.type == null) { - throw new Error('In ' + name + '/' + param.name + - ': can\'t find type for: ' + JSON.stringify(lookup)); - } -} - -function removeCommand(command) { - var name = (typeof command === 'string' ? command : command.name); - delete commands[name]; - lang.arrayRemove(commandNames, name); -}; - -function getCommand(name) { - return commands[name]; -}; - -function getCommandNames() { - return commandNames; -}; - -/** - * Entry point for keyboard accelerators or anything else that knows - * everything it needs to about the command params - * @param command Either a command, or the name of one - */ -function exec(command, env, args, typed) { - if (typeof command === 'string') { - command = commands[command]; - } - if (!command) { - // TODO: Should we complain more than returning false? - return false; - } - - var request = new Request({ - command: command, - args: args, - typed: typed - }); - command.exec(env, args || {}, request); - return true; -}; - -exports.removeCommand = removeCommand; -exports.addCommand = addCommand; -exports.getCommand = getCommand; -exports.getCommandNames = getCommandNames; -exports.exec = exec; -exports.upgradeType = upgradeType; - - -/** - * We publish a 'output' event whenever new command begins output - * TODO: make this more obvious - */ -oop.implement(exports, EventEmitter); - - -/** - * Current requirements are around displaying the command line, and provision - * of a 'history' command and cursor up|down navigation of history. - *

    Future requirements could include: - *

      - *
    • Multiple command lines - *
    • The ability to recall key presses (i.e. requests with no output) which - * will likely be needed for macro recording or similar - *
    • The ability to store the command history either on the server or in the - * browser local storage. - *
    - *

    The execute() command doesn't really live here, except as part of that - * last future requirement, and because it doesn't really have anywhere else to - * live. - */ - -/** - * The array of requests that wish to announce their presence - */ -var requests = []; - -/** - * How many requests do we store? - */ -var maxRequestLength = 100; - -/** - * To create an invocation, you need to do something like this (all the ctor - * args are optional): - *

    - * var request = new Request({
    - *     command: command,
    - *     args: args,
    - *     typed: typed
    - * });
    - * 
    - * @constructor - */ -function Request(options) { - options = options || {}; - - // Will be used in the keyboard case and the cli case - this.command = options.command; - - // Will be used only in the cli case - this.args = options.args; - this.typed = options.typed; - - // Have we been initialized? - this._begunOutput = false; - - this.start = new Date(); - this.end = null; - this.completed = false; - this.error = false; -}; - -oop.implement(Request.prototype, EventEmitter); - -/** - * Lazy init to register with the history should only be done on output. - * init() is expensive, and won't be used in the majority of cases - */ -Request.prototype._beginOutput = function() { - this._begunOutput = true; - this.outputs = []; - - requests.push(this); - // This could probably be optimized with some maths, but 99.99% of the - // time we will only be off by one, and I'm feeling lazy. - while (requests.length > maxRequestLength) { - requests.shiftObject(); - } - - exports._dispatchEvent('output', { requests: requests, request: this }); -}; - -/** - * Sugar for: - *
    request.error = true; request.done(output);
    - */ -Request.prototype.doneWithError = function(content) { - this.error = true; - this.done(content); -}; - -/** - * Declares that this function will not be automatically done when - * the command exits - */ -Request.prototype.async = function() { - if (!this._begunOutput) { - this._beginOutput(); - } -}; - -/** - * Complete the currently executing command with successful output. - * @param output Either DOM node, an SproutCore element or something that - * can be used in the content of a DIV to create a DOM node. - */ -Request.prototype.output = function(content) { - if (!this._begunOutput) { - this._beginOutput(); - } - - if (typeof content !== 'string' && !(content instanceof Node)) { - content = content.toString(); - } - - this.outputs.push(content); - this._dispatchEvent('output', {}); - - return this; -}; - -/** - * All commands that do output must call this to indicate that the command - * has finished execution. - */ -Request.prototype.done = function(content) { - this.completed = true; - this.end = new Date(); - this.duration = this.end.getTime() - this.start.getTime(); - - if (content) { - this.output(content); - } - - this._dispatchEvent('output', {}); -}; -exports.Request = Request; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * Patrick Walton (pwalton@mozilla.com) - * Julian Viereck (jviereck@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -__ace_shadowed__.define('pilot/console', function(require, exports, module) { - -/** - * This object represents a "safe console" object that forwards debugging - * messages appropriately without creating a dependency on Firebug in Firefox. - */ - -var noop = function() {}; - -// These are the functions that are available in Chrome 4/5, Safari 4 -// and Firefox 3.6. Don't add to this list without checking browser support -var NAMES = [ - "assert", "count", "debug", "dir", "dirxml", "error", "group", "groupEnd", - "info", "log", "profile", "profileEnd", "time", "timeEnd", "trace", "warn" -]; - -if (typeof(window) === 'undefined') { - // We're in a web worker. Forward to the main thread so the messages - // will show up. - NAMES.forEach(function(name) { - exports[name] = function() { - var args = Array.prototype.slice.call(arguments); - var msg = { op: 'log', method: name, args: args }; - postMessage(JSON.stringify(msg)); - }; - }); -} else { - // For each of the console functions, copy them if they exist, stub if not - NAMES.forEach(function(name) { - if (window.console && window.console[name]) { - exports[name] = Function.prototype.bind.call(window.console[name], window.console); - } else { - exports[name] = noop; - } - }); -} - -}); -__ace_shadowed__.define('pilot/stacktrace', function(require, exports, module) { - -var ua = require("pilot/useragent"); -var console = require('pilot/console'); - -// Changed to suit the specific needs of running within Skywriter - -// Domain Public by Eric Wendelin http://eriwen.com/ (2008) -// Luke Smith http://lucassmith.name/ (2008) -// Loic Dachary (2008) -// Johan Euphrosine (2008) -// Øyvind Sean Kinsey http://kinsey.no/blog -// -// Information and discussions -// http://jspoker.pokersource.info/skin/test-printstacktrace.html -// http://eriwen.com/javascript/js-stack-trace/ -// http://eriwen.com/javascript/stacktrace-update/ -// http://pastie.org/253058 -// http://browsershots.org/http://jspoker.pokersource.info/skin/test-printstacktrace.html -// - -// -// guessFunctionNameFromLines comes from firebug -// -// Software License Agreement (BSD License) -// -// Copyright (c) 2007, Parakey Inc. -// All rights reserved. -// -// Redistribution and use of this software in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above -// copyright notice, this list of conditions and the -// following disclaimer. -// -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the -// following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// * Neither the name of Parakey Inc. nor the names of its -// contributors may be used to endorse or promote products -// derived from this software without specific prior -// written permission of Parakey Inc. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - -/** - * Different browsers create stack traces in different ways. - * Feature Browser detection baby ;). - */ -var mode = (function() { - - // We use SC's browser detection here to avoid the "break on error" - // functionality provided by Firebug. Firebug tries to do the right - // thing here and break, but it happens every time you load the page. - // bug 554105 - if (ua.isGecko) { - return 'firefox'; - } else if (ua.isOpera) { - return 'opera'; - } else { - return 'other'; - } - - // SC doesn't do any detection of Chrome at this time. - - // this is the original feature detection code that is used as a - // fallback. - try { - (0)(); - } catch (e) { - if (e.arguments) { - return 'chrome'; - } - if (e.stack) { - return 'firefox'; - } - if (window.opera && !('stacktrace' in e)) { //Opera 9- - return 'opera'; - } - } - return 'other'; -})(); - -/** - * - */ -function stringifyArguments(args) { - for (var i = 0; i < args.length; ++i) { - var argument = args[i]; - if (typeof argument == 'object') { - args[i] = '#object'; - } else if (typeof argument == 'function') { - args[i] = '#function'; - } else if (typeof argument == 'string') { - args[i] = '"' + argument + '"'; - } - } - return args.join(','); -} - -/** - * Extract a stack trace from the format emitted by each browser. - */ -var decoders = { - chrome: function(e) { - var stack = e.stack; - if (!stack) { - console.log(e); - return []; - } - return stack.replace(/^.*?\n/, ''). - replace(/^.*?\n/, ''). - replace(/^.*?\n/, ''). - replace(/^[^\(]+?[\n$]/gm, ''). - replace(/^\s+at\s+/gm, ''). - replace(/^Object.\s*\(/gm, '{anonymous}()@'). - split('\n'); - }, - - firefox: function(e) { - var stack = e.stack; - if (!stack) { - console.log(e); - return []; - } - // stack = stack.replace(/^.*?\n/, ''); - stack = stack.replace(/(?:\n@:0)?\s+$/m, ''); - stack = stack.replace(/^\(/gm, '{anonymous}('); - return stack.split('\n'); - }, - - // Opera 7.x and 8.x only! - opera: function(e) { - var lines = e.message.split('\n'), ANON = '{anonymous}', - lineRE = /Line\s+(\d+).*?script\s+(http\S+)(?:.*?in\s+function\s+(\S+))?/i, i, j, len; - - for (i = 4, j = 0, len = lines.length; i < len; i += 2) { - if (lineRE.test(lines[i])) { - lines[j++] = (RegExp.$3 ? RegExp.$3 + '()@' + RegExp.$2 + RegExp.$1 : ANON + '()@' + RegExp.$2 + ':' + RegExp.$1) + - ' -- ' + - lines[i + 1].replace(/^\s+/, ''); - } - } - - lines.splice(j, lines.length - j); - return lines; - }, - - // Safari, Opera 9+, IE, and others - other: function(curr) { - var ANON = '{anonymous}', fnRE = /function\s*([\w\-$]+)?\s*\(/i, stack = [], j = 0, fn, args; - - var maxStackSize = 10; - while (curr && stack.length < maxStackSize) { - fn = fnRE.test(curr.toString()) ? RegExp.$1 || ANON : ANON; - args = Array.prototype.slice.call(curr['arguments']); - stack[j++] = fn + '(' + stringifyArguments(args) + ')'; - - //Opera bug: if curr.caller does not exist, Opera returns curr (WTF) - if (curr === curr.caller && window.opera) { - //TODO: check for same arguments if possible - break; - } - curr = curr.caller; - } - return stack; - } -}; - -/** - * - */ -function NameGuesser() { -} - -NameGuesser.prototype = { - - sourceCache: {}, - - ajax: function(url) { - var req = this.createXMLHTTPObject(); - if (!req) { - return; - } - req.open('GET', url, false); - req.setRequestHeader('User-Agent', 'XMLHTTP/1.0'); - req.send(''); - return req.responseText; - }, - - createXMLHTTPObject: function() { - // Try XHR methods in order and store XHR factory - var xmlhttp, XMLHttpFactories = [ - function() { - return new XMLHttpRequest(); - }, function() { - return new ActiveXObject('Msxml2.XMLHTTP'); - }, function() { - return new ActiveXObject('Msxml3.XMLHTTP'); - }, function() { - return new ActiveXObject('Microsoft.XMLHTTP'); - } - ]; - for (var i = 0; i < XMLHttpFactories.length; i++) { - try { - xmlhttp = XMLHttpFactories[i](); - // Use memoization to cache the factory - this.createXMLHTTPObject = XMLHttpFactories[i]; - return xmlhttp; - } catch (e) {} - } - }, - - getSource: function(url) { - if (!(url in this.sourceCache)) { - this.sourceCache[url] = this.ajax(url).split('\n'); - } - return this.sourceCache[url]; - }, - - guessFunctions: function(stack) { - for (var i = 0; i < stack.length; ++i) { - var reStack = /{anonymous}\(.*\)@(\w+:\/\/([-\w\.]+)+(:\d+)?[^:]+):(\d+):?(\d+)?/; - var frame = stack[i], m = reStack.exec(frame); - if (m) { - var file = m[1], lineno = m[4]; //m[7] is character position in Chrome - if (file && lineno) { - var functionName = this.guessFunctionName(file, lineno); - stack[i] = frame.replace('{anonymous}', functionName); - } - } - } - return stack; - }, - - guessFunctionName: function(url, lineNo) { - try { - return this.guessFunctionNameFromLines(lineNo, this.getSource(url)); - } catch (e) { - return 'getSource failed with url: ' + url + ', exception: ' + e.toString(); - } - }, - - guessFunctionNameFromLines: function(lineNo, source) { - var reFunctionArgNames = /function ([^(]*)\(([^)]*)\)/; - var reGuessFunction = /['"]?([0-9A-Za-z_]+)['"]?\s*[:=]\s*(function|eval|new Function)/; - // Walk backwards from the first line in the function until we find the line which - // matches the pattern above, which is the function definition - var line = '', maxLines = 10; - for (var i = 0; i < maxLines; ++i) { - line = source[lineNo - i] + line; - if (line !== undefined) { - var m = reGuessFunction.exec(line); - if (m) { - return m[1]; - } - else { - m = reFunctionArgNames.exec(line); - } - if (m && m[1]) { - return m[1]; - } - } - } - return '(?)'; - } -}; - -var guesser = new NameGuesser(); - -var frameIgnorePatterns = [ - /http:\/\/localhost:4020\/sproutcore.js:/ -]; - -exports.ignoreFramesMatching = function(regex) { - frameIgnorePatterns.push(regex); -}; - -/** - * Create a stack trace from an exception - * @param ex {Error} The error to create a stacktrace from (optional) - * @param guess {Boolean} If we should try to resolve the names of anonymous functions - */ -exports.Trace = function Trace(ex, guess) { - this._ex = ex; - this._stack = decoders[mode](ex); - - if (guess) { - this._stack = guesser.guessFunctions(this._stack); - } -}; - -/** - * Log to the console a number of lines (default all of them) - * @param lines {number} Maximum number of lines to wrote to console - */ -exports.Trace.prototype.log = function(lines) { - if (lines <= 0) { - // You aren't going to have more lines in your stack trace than this - // and it still fits in a 32bit integer - lines = 999999999; - } - - var printed = 0; - for (var i = 0; i < this._stack.length && printed < lines; i++) { - var frame = this._stack[i]; - var display = true; - frameIgnorePatterns.forEach(function(regex) { - if (regex.test(frame)) { - display = false; - } - }); - if (display) { - console.debug(frame); - printed++; - } - } -}; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/useragent', function(require, exports, module) { - -var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase(); -var ua = navigator.userAgent; -var av = navigator.appVersion; - -/** 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 */ -exports.isMac = (os == "mac"); - -/** Is the user using a browser that identifies itself as Linux */ -exports.isLinux = (os == "linux"); - -exports.isIE = ! + "\v1"; - -/** Is this Firefox or related? */ -exports.isGecko = exports.isMozilla = window.controllers && window.navigator.product === "Gecko"; - -/** oldGecko == rev < 2.0 **/ -exports.isOldGecko = exports.isGecko && /rv\:1/.test(navigator.userAgent); - -/** 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 */ -exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined; - -exports.isAIR = ua.indexOf("AdobeAIR") >= 0; - -exports.isIPad = ua.indexOf("iPad") >= 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. - * - * Take copy as an example, Mac people expect to use CMD or APPLE + C - * Windows folks expect to use CTRL + C - */ -exports.OS = { - LINUX: 'LINUX', - MAC: 'MAC', - WINDOWS: 'WINDOWS' -}; - -/** - * Return an exports.OS constant - */ -exports.getOS = function() { - if (exports.isMac) { - return exports.OS['MAC']; - } else if (exports.isLinux) { - return exports.OS['LINUX']; - } else { - return exports.OS['WINDOWS']; - } -}; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/oop', function(require, exports, module) { - -exports.inherits = (function() { - var tempCtor = function() {}; - return function(ctor, superCtor) { - tempCtor.prototype = superCtor.prototype; - ctor.super_ = superCtor.prototype; - ctor.prototype = new tempCtor(); - ctor.prototype.constructor = ctor; - } -}()); - -exports.mixin = function(obj, mixin) { - for (var key in mixin) { - obj[key] = mixin[key]; - } -}; - -exports.implement = function(proto, mixin) { - exports.mixin(proto, mixin); -}; - -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Irakli Gozalishvili (http://jeditoolkit.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/event_emitter', function(require, exports, module) { - -var EventEmitter = {}; - -EventEmitter._emit = -EventEmitter._dispatchEvent = function(eventName, e) { - this._eventRegistry = this._eventRegistry || {}; - - var listeners = this._eventRegistry[eventName]; - if (!listeners || !listeners.length) return; - - var e = e || {}; - e.type = eventName; - - for (var i=0; i - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/lang', function(require, exports, module) { - -exports.stringReverse = function(string) { - return string.split("").reverse().join(""); -}; - -exports.stringRepeat = function (string, count) { - return new Array(count + 1).join(string); -}; - -exports.copyObject = function(obj) { - var copy = {}; - for (var key in obj) { - copy[key] = obj[key]; - } - return copy; -}; - -exports.arrayToMap = function(arr) { - var map = {}; - for (var i=0; i (http://jeditoolkit.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/settings', function(require, exports, module) { - -/** - * This plug-in manages settings. - */ - -var console = require('pilot/console'); -var oop = require('pilot/oop'); -var types = require('pilot/types'); -var EventEmitter = require('pilot/event_emitter').EventEmitter; -var catalog = require('pilot/catalog'); - -var settingExtensionSpec = { - name: 'setting', - description: 'A setting is something that the application offers as a ' + - 'way to customize how it works', - register: 'env.settings.addSetting', - indexOn: 'name' -}; - -exports.startup = function(data, reason) { - catalog.addExtensionSpec(settingExtensionSpec); -}; - -exports.shutdown = function(data, reason) { - catalog.removeExtensionSpec(settingExtensionSpec); -}; - - -/** - * Create a new setting. - * @param settingSpec An object literal that looks like this: - * { - * name: 'thing', - * description: 'Thing is an example setting', - * type: 'string', - * defaultValue: 'something' - * } - */ -function Setting(settingSpec, settings) { - this._settings = settings; - - Object.keys(settingSpec).forEach(function(key) { - this[key] = settingSpec[key]; - }, this); - - this.type = types.getType(this.type); - if (this.type == null) { - throw new Error('In ' + this.name + - ': can\'t find type for: ' + JSON.stringify(settingSpec.type)); - } - - if (!this.name) { - throw new Error('Setting.name == undefined. Ignoring.', this); - } - - if (!this.defaultValue === undefined) { - throw new Error('Setting.defaultValue == undefined', this); - } - - if (this.onChange) { - this.on('change', this.onChange.bind(this)) - } - - this.set(this.defaultValue); -} -Setting.prototype = { - get: function() { - return this.value; - }, - - set: function(value) { - if (this.value === value) { - return; - } - - this.value = value; - if (this._settings.persister) { - this._settings.persister.persistValue(this._settings, this.name, value); - } - - this._dispatchEvent('change', { setting: this, value: value }); - }, - - /** - * Reset the value of the key setting to it's default - */ - resetValue: function() { - this.set(this.defaultValue); - } -}; -oop.implement(Setting.prototype, EventEmitter); - - -/** - * A base class for all the various methods of storing settings. - *

    Usage: - *

    - * // Create manually, or require 'settings' from the container.
    - * // This is the manual version:
    - * var settings = plugins.catalog.getObject('settings');
    - * // Add a new setting
    - * settings.addSetting({ name:'foo', ... });
    - * // Display the default value
    - * alert(settings.get('foo'));
    - * // Alter the value, which also publishes the change etc.
    - * settings.set('foo', 'bar');
    - * // Reset the value to the default
    - * settings.resetValue('foo');
    - * 
    - * @constructor - */ -function Settings(persister) { - // Storage for deactivated values - this._deactivated = {}; - - // Storage for the active settings - this._settings = {}; - // We often want sorted setting names. Cache - this._settingNames = []; - - if (persister) { - this.setPersister(persister); - } -}; - -Settings.prototype = { - /** - * Function to add to the list of available settings. - *

    Example usage: - *

    -     * var settings = plugins.catalog.getObject('settings');
    -     * settings.addSetting({
    -     *     name: 'tabsize', // For use in settings.get('X')
    -     *     type: 'number',  // To allow value checking.
    -     *     defaultValue: 4  // Default value for use when none is directly set
    -     * });
    -     * 
    - * @param {object} settingSpec Object containing name/type/defaultValue members. - */ - addSetting: function(settingSpec) { - var setting = new Setting(settingSpec, this); - this._settings[setting.name] = setting; - this._settingNames.push(setting.name); - this._settingNames.sort(); - }, - - addSettings: function addSettings(settings) { - Object.keys(settings).forEach(function (name) { - var setting = settings[name]; - if (!('name' in setting)) setting.name = name; - this.addSetting(setting); - }, this); - }, - - removeSetting: function(setting) { - var name = (typeof setting === 'string' ? setting : setting.name); - setting = this._settings[name]; - delete this._settings[name]; - util.arrayRemove(this._settingNames, name); - settings.removeAllListeners('change'); - }, - - removeSettings: function removeSettings(settings) { - Object.keys(settings).forEach(function(name) { - var setting = settings[name]; - if (!('name' in setting)) setting.name = name; - this.removeSettings(setting); - }, this); - }, - - getSettingNames: function() { - return this._settingNames; - }, - - getSetting: function(name) { - return this._settings[name]; - }, - - /** - * A Persister is able to store settings. It is an object that defines - * two functions: - * loadInitialValues(settings) and persistValue(settings, key, value). - */ - setPersister: function(persister) { - this._persister = persister; - if (persister) { - persister.loadInitialValues(this); - } - }, - - resetAll: function() { - this.getSettingNames().forEach(function(key) { - this.resetValue(key); - }, this); - }, - - /** - * Retrieve a list of the known settings and their values - */ - _list: function() { - var reply = []; - this.getSettingNames().forEach(function(setting) { - reply.push({ - 'key': setting, - 'value': this.getSetting(setting).get() - }); - }, this); - return reply; - }, - - /** - * Prime the local cache with the defaults. - */ - _loadDefaultValues: function() { - this._loadFromObject(this._getDefaultValues()); - }, - - /** - * Utility to load settings from an object - */ - _loadFromObject: function(data) { - // We iterate over data rather than keys so we don't forget values - // which don't have a setting yet. - for (var key in data) { - if (data.hasOwnProperty(key)) { - var setting = this._settings[key]; - if (setting) { - var value = setting.type.parse(data[key]); - this.set(key, value); - } else { - this.set(key, data[key]); - } - } - } - }, - - /** - * Utility to grab all the settings and export them into an object - */ - _saveToObject: function() { - return this.getSettingNames().map(function(key) { - return this._settings[key].type.stringify(this.get(key)); - }.bind(this)); - }, - - /** - * The default initial settings - */ - _getDefaultValues: function() { - return this.getSettingNames().map(function(key) { - return this._settings[key].spec.defaultValue; - }.bind(this)); - } -}; -exports.settings = new Settings(); - -/** - * Save the settings in a cookie - * This code has not been tested since reboot - * @constructor - */ -function CookiePersister() { -}; - -CookiePersister.prototype = { - loadInitialValues: function(settings) { - settings._loadDefaultValues(); - var data = cookie.get('settings'); - settings._loadFromObject(JSON.parse(data)); - }, - - persistValue: function(settings, key, value) { - try { - var stringData = JSON.stringify(settings._saveToObject()); - cookie.set('settings', stringData); - } catch (ex) { - console.error('Unable to JSONify the settings! ' + ex); - return; - } - } -}; - -exports.CookiePersister = CookiePersister; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Skywriter Team (skywriter@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/commands/settings', function(require, exports, module) { - - -var setCommandSpec = { - name: 'set', - params: [ - { - name: 'setting', - type: 'setting', - description: 'The name of the setting to display or alter', - defaultValue: null - }, - { - name: 'value', - type: 'settingValue', - description: 'The new value for the chosen setting', - defaultValue: null - } - ], - description: 'define and show settings', - exec: function(env, args, request) { - var html; - if (!args.setting) { - // 'set' by itself lists all the settings - var names = env.settings.getSettingNames(); - html = ''; - // first sort the settingsList based on the name - names.sort(function(name1, name2) { - return name1.localeCompare(name2); - }); - - names.forEach(function(name) { - var setting = env.settings.getSetting(name); - var url = 'https://wiki.mozilla.org/Labs/Skywriter/Settings#' + - setting.name; - html += '' + - setting.name + - ' = ' + - setting.value + - '
    '; - }); - } else { - // set with only a setting, shows the value for that setting - if (args.value === undefined) { - html = '' + setting.name + ' = ' + - setting.get(); - } else { - // Actually change the setting - args.setting.set(args.value); - html = 'Setting: ' + args.setting.name + ' = ' + - args.setting.get(); - } - } - request.done(html); - } -}; - -var unsetCommandSpec = { - name: 'unset', - params: [ - { - name: 'setting', - type: 'setting', - description: 'The name of the setting to return to defaults' - } - ], - description: 'unset a setting entirely', - exec: function(env, args, request) { - var setting = env.settings.get(args.setting); - if (!setting) { - request.doneWithError('No setting with the name ' + - args.setting + '.'); - return; - } - - setting.reset(); - request.done('Reset ' + setting.name + ' to default: ' + - env.settings.get(args.setting)); - } -}; - -var canon = require('pilot/canon'); - -exports.startup = function(data, reason) { - canon.addCommand(setCommandSpec); - canon.addCommand(unsetCommandSpec); -}; - -exports.shutdown = function(data, reason) { - canon.removeCommand(setCommandSpec); - canon.removeCommand(unsetCommandSpec); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Skywriter Team (skywriter@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/commands/basic', function(require, exports, module) { - - -var checks = require("pilot/typecheck"); -var canon = require('pilot/canon'); - -/** - * - */ -var helpMessages = { - plainPrefix: - '

    Welcome to Skywriter - Code in the Cloud

    ', - plainSuffix: - 'For more information, see the Skywriter Wiki.' -}; - -/** - * 'help' command - */ -var helpCommandSpec = { - name: 'help', - params: [ - { - name: 'search', - type: 'text', - description: 'Search string to narrow the output.', - defaultValue: null - } - ], - description: 'Get help on the available commands.', - exec: function(env, args, request) { - var output = []; - - var command = canon.getCommand(args.search); - if (command && command.exec) { - // caught a real command - output.push(command.description ? - command.description : - 'No description for ' + args.search); - } else { - var showHidden = false; - - if (!args.search && helpMessages.plainPrefix) { - output.push(helpMessages.plainPrefix); - } - - if (command) { - // We must be looking at sub-commands - output.push('

    Sub-Commands of ' + command.name + '

    '); - output.push('

    ' + command.description + '

    '); - } - else if (args.search) { - if (args.search == 'hidden') { // sneaky, sneaky. - args.search = ''; - showHidden = true; - } - output.push('

    Commands starting with \'' + args.search + '\':

    '); - } - else { - output.push('

    Available Commands:

    '); - } - - var commandNames = canon.getCommandNames(); - commandNames.sort(); - - output.push(''); - for (var i = 0; i < commandNames.length; i++) { - command = canon.getCommand(commandNames[i]); - if (!showHidden && command.hidden) { - continue; - } - if (command.description === undefined) { - // Ignore editor actions - continue; - } - if (args.search && command.name.indexOf(args.search) !== 0) { - // Filtered out by the user - continue; - } - if (!args.search && command.name.indexOf(' ') != -1) { - // sub command - continue; - } - if (command && command.name == args.search) { - // sub command, and we've already given that help - continue; - } - - // todo add back a column with parameter information, perhaps? - - output.push(''); - output.push(''); - output.push(''); - output.push(''); - } - output.push('
    ' + command.name + '' + command.description + '
    '); - - if (!args.search && helpMessages.plainSuffix) { - output.push(helpMessages.plainSuffix); - } - } - - request.done(output.join('')); - } -}; - -/** - * 'eval' command - */ -var evalCommandSpec = { - name: 'eval', - params: [ - { - name: 'javascript', - type: 'text', - description: 'The JavaScript to evaluate' - } - ], - description: 'evals given js code and show the result', - hidden: true, - exec: function(env, args, request) { - var result; - var javascript = args.javascript; - try { - result = eval(javascript); - } catch (e) { - result = 'Error: ' + e.message + ''; - } - - var msg = ''; - var type = ''; - var x; - - if (checks.isFunction(result)) { - // converts the function to a well formated string - msg = (result + '').replace(/\n/g, '
    ').replace(/ /g, ' '); - type = 'function'; - } else if (checks.isObject(result)) { - if (Array.isArray(result)) { - type = 'array'; - } else { - type = 'object'; - } - - var items = []; - var value; - - for (x in result) { - if (result.hasOwnProperty(x)) { - if (checks.isFunction(result[x])) { - value = '[function]'; - } else if (checks.isObject(result[x])) { - value = '[object]'; - } else { - value = result[x]; - } - - items.push({name: x, value: value}); - } - } - - items.sort(function(a,b) { - return (a.name.toLowerCase() < b.name.toLowerCase()) ? -1 : 1; - }); - - for (x = 0; x < items.length; x++) { - msg += '' + items[x].name + ': ' + items[x].value + '
    '; - } - - } else { - msg = result; - type = typeof result; - } - - request.done('Result for eval \'' + javascript + '\'' + - ' (type: '+ type+'):

    '+ msg); - } -}; - -/** - * 'version' command - */ -var versionCommandSpec = { - name: 'version', - description: 'show the Skywriter version', - hidden: true, - exec: function(env, args, request) { - var version = 'Skywriter ' + skywriter.versionNumber + ' (' + - skywriter.versionCodename + ')'; - request.done(version); - } -}; - -/** - * 'skywriter' command - */ -var skywriterCommandSpec = { - name: 'skywriter', - hidden: true, - exec: function(env, args, request) { - var index = Math.floor(Math.random() * messages.length); - request.done('Skywriter ' + messages[index]); - } -}; -var messages = [ - 'really wants you to trick it out in some way.', - 'is your Web editor.', - 'would love to be like Emacs on the Web.', - 'is written on the Web platform, so you can tweak it.' -]; - - -var canon = require('pilot/canon'); - -exports.startup = function(data, reason) { - canon.addCommand(helpCommandSpec); - canon.addCommand(evalCommandSpec); - // canon.addCommand(versionCommandSpec); - canon.addCommand(skywriterCommandSpec); -}; - -exports.shutdown = function(data, reason) { - canon.removeCommand(helpCommandSpec); - canon.removeCommand(evalCommandSpec); - // canon.removeCommand(versionCommandSpec); - canon.removeCommand(skywriterCommandSpec); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/typecheck', function(require, exports, module) { - -var objectToString = Object.prototype.toString; - -/** - * Return true if it is a String - */ -exports.isString = function(it) { - return it && objectToString.call(it) === "[object String]"; -}; - -/** - * Returns true if it is a Boolean. - */ -exports.isBoolean = function(it) { - return it && objectToString.call(it) === "[object Boolean]"; -}; - -/** - * Returns true if it is a Number. - */ -exports.isNumber = function(it) { - return it && objectToString.call(it) === "[object Number]" && isFinite(it); -}; - -/** - * Hack copied from dojo. - */ -exports.isObject = function(it) { - return it !== undefined && - (it === null || typeof it == "object" || - Array.isArray(it) || exports.isFunction(it)); -}; - -/** - * Is the passed object a function? - * From dojo.isFunction() - */ -exports.isFunction = function(it) { - return it && objectToString.call(it) === "[object Function]"; -}; - -});/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/settings/canon', function(require, exports, module) { - - -var historyLengthSetting = { - name: "historyLength", - description: "How many typed commands do we recall for reference?", - type: "number", - defaultValue: 50 -}; - -exports.startup = function(data, reason) { - data.env.settings.addSetting(historyLengthSetting); -}; - -exports.shutdown = function(data, reason) { - data.env.settings.removeSetting(historyLengthSetting); -}; - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kevin Dangoor (kdangoor@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/plugin_manager', function(require, exports, module) { - -var Promise = require("pilot/promise").Promise; - -exports.REASONS = { - APP_STARTUP: 1, - APP_SHUTDOWN: 2, - PLUGIN_ENABLE: 3, - PLUGIN_DISABLE: 4, - PLUGIN_INSTALL: 5, - PLUGIN_UNINSTALL: 6, - PLUGIN_UPGRADE: 7, - PLUGIN_DOWNGRADE: 8 -}; - -exports.Plugin = function(name) { - this.name = name; - this.status = this.INSTALLED; -}; - -exports.Plugin.prototype = { - /** - * constants for the state - */ - NEW: 0, - INSTALLED: 1, - REGISTERED: 2, - STARTED: 3, - UNREGISTERED: 4, - SHUTDOWN: 5, - - install: function(data, reason) { - var pr = new Promise(); - if (this.status > this.NEW) { - pr.resolve(this); - return pr; - } - require([this.name], function(pluginModule) { - if (pluginModule.install) { - pluginModule.install(data, reason); - } - this.status = this.INSTALLED; - pr.resolve(this); - }.bind(this)); - return pr; - }, - - register: function(data, reason) { - var pr = new Promise(); - if (this.status != this.INSTALLED) { - pr.resolve(this); - return pr; - } - require([this.name], function(pluginModule) { - if (pluginModule.register) { - pluginModule.register(data, reason); - } - this.status = this.REGISTERED; - pr.resolve(this); - }.bind(this)); - return pr; - }, - - startup: function(data, reason) { - reason = reason || exports.REASONS.APP_STARTUP; - var pr = new Promise(); - if (this.status != this.REGISTERED) { - pr.resolve(this); - return pr; - } - require([this.name], function(pluginModule) { - if (pluginModule.startup) { - pluginModule.startup(data, reason); - } - this.status = this.STARTED; - pr.resolve(this); - }.bind(this)); - return pr; - }, - - shutdown: function(data, reason) { - if (this.status != this.STARTED) { - return; - } - pluginModule = require(this.name); - if (pluginModule.shutdown) { - pluginModule.shutdown(data, reason); - } - } -}; - -exports.PluginCatalog = function() { - this.plugins = {}; -}; - -exports.PluginCatalog.prototype = { - registerPlugins: function(pluginList, data, reason) { - var registrationPromises = []; - pluginList.forEach(function(pluginName) { - var plugin = this.plugins[pluginName]; - if (plugin === undefined) { - plugin = new exports.Plugin(pluginName); - this.plugins[pluginName] = plugin; - registrationPromises.push(plugin.register(data, reason)); - } - }.bind(this)); - return Promise.group(registrationPromises); - }, - - startupPlugins: function(data, reason) { - var startupPromises = []; - for (var pluginName in this.plugins) { - var plugin = this.plugins[pluginName]; - startupPromises.push(plugin.startup(data, reason)); - } - return Promise.group(startupPromises); - } -}; - -exports.catalog = new exports.PluginCatalog(); - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/promise', function(require, exports, module) { - -var console = require("pilot/console"); -var Trace = require('pilot/stacktrace').Trace; - -/** - * A promise can be in one of 2 states. - * The ERROR and SUCCESS states are terminal, the PENDING state is the only - * start state. - */ -var ERROR = -1; -var PENDING = 0; -var SUCCESS = 1; - -/** - * We give promises and ID so we can track which are outstanding - */ -var _nextId = 0; - -/** - * Debugging help if 2 things try to complete the same promise. - * This can be slow (especially on chrome due to the stack trace unwinding) so - * we should leave this turned off in normal use. - */ -var _traceCompletion = false; - -/** - * Outstanding promises. Handy list for debugging only. - */ -var _outstanding = []; - -/** - * Recently resolved promises. Also for debugging only. - */ -var _recent = []; - -/** - * Create an unfulfilled promise - */ -Promise = function () { - this._status = PENDING; - this._value = undefined; - this._onSuccessHandlers = []; - this._onErrorHandlers = []; - - // Debugging help - this._id = _nextId++; - //this._createTrace = new Trace(new Error()); - _outstanding[this._id] = this; -}; - -/** - * Yeay for RTTI. - */ -Promise.prototype.isPromise = true; - -/** - * Have we either been resolve()ed or reject()ed? - */ -Promise.prototype.isComplete = function() { - return this._status != PENDING; -}; - -/** - * Have we resolve()ed? - */ -Promise.prototype.isResolved = function() { - return this._status == SUCCESS; -}; - -/** - * Have we reject()ed? - */ -Promise.prototype.isRejected = function() { - return this._status == ERROR; -}; - -/** - * Take the specified action of fulfillment of a promise, and (optionally) - * a different action on promise rejection. - */ -Promise.prototype.then = function(onSuccess, onError) { - if (typeof onSuccess === 'function') { - if (this._status === SUCCESS) { - onSuccess.call(null, this._value); - } else if (this._status === PENDING) { - this._onSuccessHandlers.push(onSuccess); - } - } - - if (typeof onError === 'function') { - if (this._status === ERROR) { - onError.call(null, this._value); - } else if (this._status === PENDING) { - this._onErrorHandlers.push(onError); - } - } - - return this; -}; - -/** - * Like then() except that rather than returning this we return - * a promise which - */ -Promise.prototype.chainPromise = function(onSuccess) { - var chain = new Promise(); - chain._chainedFrom = this; - this.then(function(data) { - try { - chain.resolve(onSuccess(data)); - } catch (ex) { - chain.reject(ex); - } - }, function(ex) { - chain.reject(ex); - }); - return chain; -}; - -/** - * Supply the fulfillment of a promise - */ -Promise.prototype.resolve = function(data) { - return this._complete(this._onSuccessHandlers, SUCCESS, data, 'resolve'); -}; - -/** - * Renege on a promise - */ -Promise.prototype.reject = function(data) { - return this._complete(this._onErrorHandlers, ERROR, data, 'reject'); -}; - -/** - * Internal method to be called on resolve() or reject(). - * @private - */ -Promise.prototype._complete = function(list, status, data, name) { - // Complain if we've already been completed - if (this._status != PENDING) { - console.group('Promise already closed'); - console.error('Attempted ' + name + '() with ', data); - console.error('Previous status = ', this._status, - ', previous value = ', this._value); - console.trace(); - - if (this._completeTrace) { - console.error('Trace of previous completion:'); - this._completeTrace.log(5); - } - console.groupEnd(); - return this; - } - - if (_traceCompletion) { - this._completeTrace = new Trace(new Error()); - } - - this._status = status; - this._value = data; - - // Call all the handlers, and then delete them - list.forEach(function(handler) { - handler.call(null, this._value); - }, this); - this._onSuccessHandlers.length = 0; - this._onErrorHandlers.length = 0; - - // Remove the given {promise} from the _outstanding list, and add it to the - // _recent list, pruning more than 20 recent promises from that list. - delete _outstanding[this._id]; - _recent.push(this); - while (_recent.length > 20) { - _recent.shift(); - } - - return this; -}; - -/** - * Takes an array of promises and returns a promise that that is fulfilled once - * all the promises in the array are fulfilled - * @param group The array of promises - * @return the promise that is fulfilled when all the array is fulfilled - */ -Promise.group = function(promiseList) { - if (!(promiseList instanceof Array)) { - promiseList = Array.prototype.slice.call(arguments); - } - - // If the original array has nothing in it, return now to avoid waiting - if (promiseList.length === 0) { - return new Promise().resolve([]); - } - - var groupPromise = new Promise(); - var results = []; - var fulfilled = 0; - - var onSuccessFactory = function(index) { - return function(data) { - results[index] = data; - fulfilled++; - // If the group has already failed, silently drop extra results - if (groupPromise._status !== ERROR) { - if (fulfilled === promiseList.length) { - groupPromise.resolve(results); - } - } - }; - }; - - promiseList.forEach(function(promise, index) { - var onSuccess = onSuccessFactory(index); - var onError = groupPromise.reject.bind(groupPromise); - promise.then(onSuccess, onError); - }); - - return groupPromise; -}; - -exports.Promise = Promise; -exports._outstanding = _outstanding; -exports._recent = _recent; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is DomTemplate. - * - * The Initial Developer of the Original Code is Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Joe Walker (jwalker@mozilla.com) (original author) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/environment', function(require, exports, module) { - - -var settings = require("pilot/settings").settings; - -/** - * Create an environment object - */ -function create() { - return { - settings: settings - }; -}; - -exports.create = create; - - -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Irakli Gozalishvili (http://jeditoolkit.com) - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/editor', function(require, exports, module) { - -require("pilot/fixoldbrowsers"); - -var oop = require("pilot/oop"); -var event = require("pilot/event"); -var lang = require("pilot/lang"); -var useragent = require("pilot/useragent"); -var TextInput = require("ace/keyboard/textinput").TextInput; -var MouseHandler = require("ace/mouse_handler").MouseHandler; -//var TouchHandler = require("ace/touch_handler").TouchHandler; -var KeyBinding = require("ace/keyboard/keybinding").KeyBinding; -var EditSession = require("ace/edit_session").EditSession; -var Search = require("ace/search").Search; -var BackgroundTokenizer = require("ace/background_tokenizer").BackgroundTokenizer; -var Range = require("ace/range").Range; -var EventEmitter = require("pilot/event_emitter").EventEmitter; - -var Editor =function(renderer, session) { - var container = renderer.getContainerElement(); - this.container = container; - this.renderer = renderer; - - this.textInput = new TextInput(renderer.getTextAreaContainer(), this); - this.keyBinding = new KeyBinding(this); - - // TODO detect touch event support - if (useragent.isIPad) { - //this.$mouseHandler = new TouchHandler(this); - } else { - this.$mouseHandler = new MouseHandler(this); - } - - this.$blockScrolling = 0; - this.$search = new Search().set({ - wrap: true - }); - - this.setSession(session || new EditSession("")); -}; - -(function(){ - - oop.implement(this, EventEmitter); - - this.$forwardEvents = { - gutterclick: 1, - gutterdblclick: 1 - }; - - this.$originalAddEventListener = this.addEventListener; - this.$originalRemoveEventListener = this.removeEventListener; - - this.addEventListener = function(eventName, callback) { - if (this.$forwardEvents[eventName]) { - return this.renderer.addEventListener(eventName, callback); - } else { - return this.$originalAddEventListener(eventName, callback); - } - }; - - this.removeEventListener = function(eventName, callback) { - if (this.$forwardEvents[eventName]) { - return this.renderer.removeEventListener(eventName, callback); - } else { - return this.$originalRemoveEventListener(eventName, callback); - } - }; - - this.setKeyboardHandler = function(keyboardHandler) { - this.keyBinding.setKeyboardHandler(keyboardHandler); - }; - - this.getKeyboardHandler = function() { - return this.keyBinding.getKeyboardHandler(); - } - - this.setSession = function(session) { - if (this.session == session) return; - - if (this.session) { - var oldSession = this.session; - this.session.removeEventListener("change", this.$onDocumentChange); - this.session.removeEventListener("changeMode", this.$onDocumentModeChange); - this.session.removeEventListener("changeTabSize", this.$onDocumentChangeTabSize); - this.session.removeEventListener("changeWrapLimit", this.$onDocumentChangeWrapLimit); - this.session.removeEventListener("changeWrapMode", this.$onDocumentChangeWrapMode); - this.session.removeEventListener("changeFrontMarker", this.$onChangeFrontMarker); - this.session.removeEventListener("changeBackMarker", this.$onChangeBackMarker); - this.session.removeEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint); - this.session.removeEventListener("changeAnnotation", this.$onDocumentChangeAnnotation); - - var selection = this.session.getSelection(); - selection.removeEventListener("changeCursor", this.$onCursorChange); - selection.removeEventListener("changeSelection", this.$onSelectionChange); - - this.session.setScrollTopRow(this.renderer.getScrollTopRow()); - } - - this.session = session; - - this.$onDocumentChange = this.onDocumentChange.bind(this); - session.addEventListener("change", this.$onDocumentChange); - this.renderer.setSession(session); - - this.$onDocumentModeChange = this.onDocumentModeChange.bind(this); - session.addEventListener("changeMode", this.$onDocumentModeChange); - - this.$onDocumentChangeTabSize = this.renderer.updateText.bind(this.renderer); - session.addEventListener("changeTabSize", this.$onDocumentChangeTabSize); - - this.$onDocumentChangeWrapLimit = this.onDocumentChangeWrapLimit.bind(this); - session.addEventListener("changeWrapLimit", this.$onDocumentChangeWrapLimit); - - this.$onDocumentChangeWrapMode = this.onDocumentChangeWrapMode.bind(this); - session.addEventListener("changeWrapMode", this.$onDocumentChangeWrapMode); - - 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.$onDocumentChangeBreakpoint = this.onDocumentChangeBreakpoint.bind(this); - this.session.addEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint); - - this.$onDocumentChangeAnnotation = this.onDocumentChangeAnnotation.bind(this); - this.session.addEventListener("changeAnnotation", this.$onDocumentChangeAnnotation); - - this.selection = session.getSelection(); - - this.$onCursorChange = this.onCursorChange.bind(this); - this.selection.addEventListener("changeCursor", this.$onCursorChange); - - this.$onSelectionChange = this.onSelectionChange.bind(this); - this.selection.addEventListener("changeSelection", this.$onSelectionChange); - - this.onDocumentModeChange(); - this.bgTokenizer.setDocument(session.getDocument()); - this.bgTokenizer.start(0); - - this.onCursorChange(); - this.onSelectionChange(); - this.onChangeFrontMarker(); - this.onChangeBackMarker(); - this.onDocumentChangeBreakpoint(); - this.onDocumentChangeAnnotation(); - this.renderer.scrollToRow(session.getScrollTopRow()); - this.renderer.updateFull(); - - this._dispatchEvent("changeSession", { - session: session, - oldSession: oldSession - }); - }; - - this.getSession = function() { - return this.session; - }; - - this.getSelection = function() { - return this.selection; - }; - - this.resize = function() { - this.renderer.onResize(); - }; - - this.setTheme = function(theme) { - this.renderer.setTheme(theme); - }; - - this.setStyle = function(style) { - this.renderer.setStyle(style) - }; - - this.unsetStyle = function(style) { - this.renderer.unsetStyle(style) - } - - this.$highlightBrackets = function() { - if (this.session.$bracketHighlight) { - this.session.removeMarker(this.session.$bracketHighlight); - this.session.$bracketHighlight = null; - } - - if (this.$highlightPending) { - return; - } - - // perform highlight async to not block the browser during navigation - var self = this; - this.$highlightPending = true; - setTimeout(function() { - self.$highlightPending = false; - - var pos = self.session.findMatchingBracket(self.getCursorPosition()); - if (pos) { - var range = new Range(pos.row, pos.column, pos.row, pos.column+1); - self.session.$bracketHighlight = self.session.addMarker(range, "ace_bracket"); - } - }, 10); - }; - - this.focus = function() { - // Safari need the timeout - // iOS and Firefox need it called immediately - // to be on the save side we do both - var _self = this; - setTimeout(function() { - _self.textInput.focus(); - }); - this.textInput.focus(); - }; - - this.blur = function() { - this.textInput.blur(); - }; - - this.onFocus = function() { - this.renderer.showCursor(); - this.renderer.visualizeFocus(); - this._dispatchEvent("focus"); - }; - - this.onBlur = function() { - this.renderer.hideCursor(); - this.renderer.visualizeBlur(); - this._dispatchEvent("blur"); - }; - - this.onDocumentChange = function(e) { - var delta = e.data; - var range = delta.range; - - this.bgTokenizer.start(range.start.row); - if (range.start.row == range.end.row && delta.action != "insertLines" && delta.action != "removeLines") - var lastRow = range.end.row; - else - lastRow = Infinity; - this.renderer.updateLines(range.start.row, lastRow); - - // update cursor because tab characters can influence the cursor position - this.renderer.updateCursor(this.getCursorPosition(), this.$overwrite); - }; - - this.onTokenizerUpdate = function(e) { - var rows = e.data; - this.renderer.updateLines(rows.first, rows.last); - }; - - this.onCursorChange = function(e) { - this.renderer.updateCursor(this.getCursorPosition(), this.$overwrite); - - 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(); - }; - - this.$updateHighlightActiveLine = function() { - var session = this.getSession(); - - if (session.$highlightLineMarker) { - session.removeMarker(session.$highlightLineMarker); - } - session.$highlightLineMarker = null; - - if (this.getHighlightActiveLine() && (this.getSelectionStyle() != "line" || !this.selection.isMultiLine())) { - var cursor = this.getCursorPosition(); - var range = new Range(cursor.row, 0, cursor.row+1, 0); - session.$highlightLineMarker = session.addMarker(range, "ace_active_line", "line"); - } - }; - - this.onSelectionChange = function(e) { - var session = this.getSession(); - - if (session.$selectionMarker) { - session.removeMarker(session.$selectionMarker); - } - session.$selectionMarker = null; - - if (!this.selection.isEmpty()) { - var range = this.selection.getRange(); - var style = this.getSelectionStyle(); - session.$selectionMarker = session.addMarker(range, "ace_selection", style); - } - - this.onCursorChange(e); - - if (this.$highlightSelectedWord) - this.mode.highlightSelection(this); - }; - - this.onChangeFrontMarker = function() { - this.renderer.updateFrontMarkers(); - }; - - this.onChangeBackMarker = function() { - this.renderer.updateBackMarkers(); - }; - - this.onDocumentChangeBreakpoint = function() { - this.renderer.setBreakpoints(this.session.getBreakpoints()); - }; - - this.onDocumentChangeAnnotation = function() { - this.renderer.setAnnotations(this.session.getAnnotations()); - }; - - this.onDocumentModeChange = function() { - var mode = this.session.getMode(); - if (this.mode == mode) - return; - - this.mode = mode; - var tokenizer = mode.getTokenizer(); - - if (!this.bgTokenizer) { - var onUpdate = this.onTokenizerUpdate.bind(this); - this.bgTokenizer = new BackgroundTokenizer(tokenizer, this); - this.bgTokenizer.addEventListener("update", onUpdate); - } else { - this.bgTokenizer.setTokenizer(tokenizer); - } - - this.renderer.setTokenizer(this.bgTokenizer); - }; - - this.onDocumentChangeWrapLimit = function() { - this.renderer.updateCursor(this.getCursorPosition(), this.$overwrite); - this.renderer.updateFull(); - }; - - this.onDocumentChangeWrapMode = function() { - this.renderer.onResize(true); - }; - - this.getCopyText = function() { - if (!this.selection.isEmpty()) { - return this.session.getTextRange(this.getSelectionRange()); - } - else { - return ""; - } - }; - - this.onCut = function() { - if (this.$readOnly) - return; - - if (!this.selection.isEmpty()) { - this.session.remove(this.getSelectionRange()) - this.clearSelection(); - } - }; - - this.insert = function(text) { - if (this.$readOnly) - return; - - var cursor = this.getCursorPosition(); - text = text.replace("\t", this.session.getTabString()); - - // remove selected text - if (!this.selection.isEmpty()) { - var cursor = this.session.remove(this.getSelectionRange()); - this.clearSelection(); - } else if (this.$overwrite){ - var range = new Range.fromPoints(cursor, cursor); - range.end.column += text.length; - this.session.remove(range); - } - - this.clearSelection(); - - var lineState = this.bgTokenizer.getState(cursor.row); - var shouldOutdent = this.mode.checkOutdent(lineState, this.session.getLine(cursor.row), text); - var line = this.session.getLine(cursor.row); - var lineIndent = this.mode.getNextLineIndent(lineState, line.slice(0, cursor.column), this.session.getTabString()); - var end = this.session.insert(cursor, text); - - this.moveCursorToPosition(end); - - var lineState = this.bgTokenizer.getState(cursor.row); - // multi line insert - if (cursor.row !== end.row) { - var size = this.session.getTabSize(), - minIndent = Number.MAX_VALUE; - - for (var row = cursor.row + 1; row <= end.row; ++row) { - var indent = 0; - - line = this.session.getLine(row); - for (var i = 0; i < line.length; ++i) - if (line.charAt(i) == '\t') - indent += size; - else if (line.charAt(i) == ' ') - indent += 1; - else - break; - if (/[^\s]/.test(line)) - minIndent = Math.min(indent, minIndent); - } - - for (var row = cursor.row + 1; row <= end.row; ++row) { - var outdent = minIndent; - - line = this.session.getLine(row); - for (var i = 0; i < line.length && outdent > 0; ++i) - if (line.charAt(i) == '\t') - outdent -= size; - else if (line.charAt(i) == ' ') - outdent -= 1; - this.session.remove(new Range(row, 0, row, i)); - } - this.session.indentRows(cursor.row + 1, end.row, lineIndent); - } else { - if (shouldOutdent) { - this.mode.autoOutdent(lineState, this.session, cursor.row); - } - }; - } - - this.onTextInput = function(text) { - this.keyBinding.onTextInput(text); - }; - - this.onCommandKey = function(e, hashId, keyCode) { - this.keyBinding.onCommandKey(e, hashId, keyCode); - }; - - this.$overwrite = false; - this.setOverwrite = function(overwrite) { - if (this.$overwrite == overwrite) return; - - this.$overwrite = overwrite; - - this.$blockScrolling += 1; - this.onCursorChange(); - this.$blockScrolling -= 1; - - this._dispatchEvent("changeOverwrite", {data: overwrite}); - }; - - this.getOverwrite = function() { - return this.$overwrite; - }; - - this.toggleOverwrite = function() { - this.setOverwrite(!this.$overwrite); - }; - - this.setScrollSpeed = function(speed) { - this.$mouseHandler.setScrollSpeed(speed); - }; - - this.getScrollSpeed = function() { - return this.$mouseHandler.getScrollSpeed() - }; - - this.$selectionStyle = "line"; - this.setSelectionStyle = function(style) { - if (this.$selectionStyle == style) return; - - this.$selectionStyle = style; - this.onSelectionChange(); - this._dispatchEvent("changeSelectionStyle", {data: style}); - }; - - this.getSelectionStyle = function() { - return this.$selectionStyle; - }; - - this.$highlightActiveLine = true; - this.setHighlightActiveLine = function(shouldHighlight) { - if (this.$highlightActiveLine == shouldHighlight) return; - - this.$highlightActiveLine = shouldHighlight; - this.$updateHighlightActiveLine(); - }; - - this.getHighlightActiveLine = function() { - return this.$highlightActiveLine; - }; - - this.$highlightSelectedWord = true; - this.setHighlightSelectedWord = function(shouldHighlight) { - if (this.$highlightSelectedWord == shouldHighlight) - return; - - this.$highlightSelectedWord = shouldHighlight; - if (shouldHighlight) - this.mode.highlightSelection(this); - else - this.mode.clearSelectionHighlight(this); - }; - - this.getHighlightSelectedWord = function() { - return this.$highlightSelectedWord; - }; - - this.setShowInvisibles = function(showInvisibles) { - if (this.getShowInvisibles() == showInvisibles) - return; - - this.renderer.setShowInvisibles(showInvisibles); - }; - - this.getShowInvisibles = function() { - return this.renderer.getShowInvisibles(); - }; - - this.setShowPrintMargin = function(showPrintMargin) { - this.renderer.setShowPrintMargin(showPrintMargin); - }; - - this.getShowPrintMargin = function() { - return this.renderer.getShowPrintMargin(); - }; - - this.setPrintMarginColumn = function(showPrintMargin) { - this.renderer.setPrintMarginColumn(showPrintMargin); - }; - - this.getPrintMarginColumn = function() { - return this.renderer.getPrintMarginColumn(); - }; - - this.$readOnly = false; - this.setReadOnly = function(readOnly) { - this.$readOnly = readOnly; - }; - - this.getReadOnly = function() { - return this.$readOnly; - }; - - this.removeRight = function() { - if (this.$readOnly) - return; - - if (this.selection.isEmpty()) { - this.selection.selectRight(); - } - this.session.remove(this.getSelectionRange()) - this.clearSelection(); - }; - - this.removeLeft = function() { - if (this.$readOnly) - return; - - if (this.selection.isEmpty()) - this.selection.selectLeft(); - - this.session.remove(this.getSelectionRange()); - this.clearSelection(); - }; - - this.removeWordRight = function() { - if (this.$readOnly) - return; - - if (this.selection.isEmpty()) - this.selection.selectWordRight(); - - this.session.remove(this.getSelectionRange()); - this.clearSelection(); - }; - - this.removeWordLeft = function() { - if (this.$readOnly) - return; - - if (this.selection.isEmpty()) - this.selection.selectWordLeft(); - - this.session.remove(this.getSelectionRange()); - this.clearSelection(); - }; - - this.removeToLineStart = function() { - if (this.$readOnly) - return; - - if (this.selection.isEmpty()) - this.selection.selectLineStart(); - - this.session.remove(this.getSelectionRange()); - this.clearSelection(); - }; - - this.removeToLineEnd = function() { - if (this.$readOnly) - return; - - if (this.selection.isEmpty()) - this.selection.selectLineEnd(); - - this.session.remove(this.getSelectionRange()); - this.clearSelection(); - }; - - this.splitLine = function() { - if (this.$readOnly) - return; - - if (!this.selection.isEmpty()) { - this.session.remove(this.getSelectionRange()); - this.clearSelection(); - } - - var cursor = this.getCursorPosition(); - this.insert("\n"); - this.moveCursorToPosition(cursor); - }; - - this.transposeLetters = function() { - if (this.$readOnly) - return; - - if (!this.selection.isEmpty()) { - return; - } - - var cursor = this.getCursorPosition(); - var column = cursor.column; - if (column == 0) - return; - - var line = this.session.getLine(cursor.row); - if (column < line.length) { - var swap = line.charAt(column) + line.charAt(column-1); - var range = new Range(cursor.row, column-1, cursor.row, column+1) - } - else { - var swap = line.charAt(column-1) + line.charAt(column-2); - var range = new Range(cursor.row, column-2, cursor.row, column) - } - this.session.replace(range, swap); - }; - - this.indent = function() { - if (this.$readOnly) - return; - - var session = this.session; - var range = this.getSelectionRange(); - - if (range.start.row < range.end.row || range.start.column < range.end.column) { - var rows = this.$getSelectedRows(); - session.indentRows(rows.first, rows.last, "\t"); - } else { - var indentString; - - if (this.session.getUseSoftTabs()) { - var size = session.getTabSize(), - position = this.getCursorPosition(), - column = session.documentToScreenColumn(position.row, position.column), - count = (size - column % size); - - indentString = lang.stringRepeat(" ", count); - } else - indentString = "\t"; - return this.onTextInput(indentString); - } - }; - - this.blockOutdent = function() { - if (this.$readOnly) - return; - - var selection = this.session.getSelection(); - this.session.outdentRows(selection.getRange()); - }; - - this.toggleCommentLines = function() { - if (this.$readOnly) - return; - - var state = this.bgTokenizer.getState(this.getCursorPosition().row); - var rows = this.$getSelectedRows() - this.mode.toggleCommentLines(state, this.session, rows.first, rows.last); - }; - - this.removeLines = function() { - if (this.$readOnly) - return; - - var rows = this.$getSelectedRows(); - this.session.remove(new Range(rows.first, 0, rows.last+1, 0)); - this.clearSelection(); - }; - - this.moveLinesDown = function() { - if (this.$readOnly) - return; - - this.$moveLines(function(firstRow, lastRow) { - return this.session.moveLinesDown(firstRow, lastRow); - }); - }; - - this.moveLinesUp = function() { - if (this.$readOnly) - return; - - this.$moveLines(function(firstRow, lastRow) { - return this.session.moveLinesUp(firstRow, lastRow); - }); - }; - - this.copyLinesUp = function() { - if (this.$readOnly) - return; - - this.$moveLines(function(firstRow, lastRow) { - this.session.duplicateLines(firstRow, lastRow); - return 0; - }); - }; - - this.copyLinesDown = function() { - if (this.$readOnly) - return; - - this.$moveLines(function(firstRow, lastRow) { - return this.session.duplicateLines(firstRow, lastRow); - }); - }; - - - this.$moveLines = function(mover) { - var rows = this.$getSelectedRows(); - - var linesMoved = mover.call(this, rows.first, rows.last); - - var selection = this.selection; - selection.setSelectionAnchor(rows.last+linesMoved+1, 0); - selection.$moveSelection(function() { - selection.moveCursorTo(rows.first+linesMoved, 0); - }); - }; - - this.$getSelectedRows = function() { - var range = this.getSelectionRange().collapseRows(); - - return { - first: range.start.row, - last: range.end.row - }; - }; - - this.onCompositionStart = function(text) { - this.renderer.showComposition(this.getCursorPosition()); - }; - - this.onCompositionUpdate = function(text) { - this.renderer.setCompositionText(text); - }; - - this.onCompositionEnd = function() { - this.renderer.hideComposition(); - }; - - - this.getFirstVisibleRow = function() { - return this.renderer.getFirstVisibleRow(); - }; - - this.getLastVisibleRow = function() { - return this.renderer.getLastVisibleRow(); - }; - - this.isRowVisible = function(row) { - return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow()); - }; - - 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.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.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.gotoPageDown = function() { - var row = this.$getPageDownRow(); - var column = this.getCursorPositionScreen().column; - - this.scrollToRow(row); - this.getSelection().moveCursorToScreen(row, column); - }; - - this.gotoPageUp = function() { - var row = this.$getPageUpRow(); - var column = this.getCursorPositionScreen().column; - - this.scrollToRow(row); - this.getSelection().moveCursorToScreen(row, column); - }; - - this.scrollPageDown = function() { - this.scrollToRow(this.$getPageDownRow()); - }; - - this.scrollPageUp = function() { - this.renderer.scrollToRow(this.$getPageUpRow()); - }; - - this.scrollToRow = function(row) { - this.renderer.scrollToRow(row); - }; - - this.scrollToLine = function(line, center) { - this.renderer.scrollToLine(line, center); - }; - - 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); - }; - - 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(row, column) { - this.selection.moveCursorTo(row, column); - }; - - this.moveCursorToPosition = function(pos) { - this.selection.moveCursorToPosition(pos); - }; - - - this.gotoLine = function(lineNumber, row) { - this.selection.clearSelection(); - - this.$blockScrolling += 1; - this.moveCursorTo(lineNumber-1, row || 0); - this.$blockScrolling -= 1; - - if (!this.isRowVisible(this.getCursorPosition().row)) { - this.scrollToLine(lineNumber, true); - } - }, - - this.navigateTo = function(row, column) { - this.clearSelection(); - this.moveCursorTo(row, column); - }; - - this.navigateUp = function(times) { - this.selection.clearSelection(); - times = times || 1; - this.selection.moveCursorBy(-times, 0); - }; - - this.navigateDown = function(times) { - this.selection.clearSelection(); - times = times || 1; - this.selection.moveCursorBy(times, 0); - }; - - this.navigateLeft = function(times) { - if (!this.selection.isEmpty()) { - var selectionStart = this.getSelectionRange().start; - this.moveCursorToPosition(selectionStart); - } - else { - times = times || 1; - while (times--) { - this.selection.moveCursorLeft(); - } - } - this.clearSelection(); - }; - - this.navigateRight = function(times) { - if (!this.selection.isEmpty()) { - var selectionEnd = this.getSelectionRange().end; - this.moveCursorToPosition(selectionEnd); - } - else { - times = times || 1; - while (times--) { - 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(replacement, options) { - if (options) - this.$search.set(options); - - var range = this.$search.find(this.session); - this.$tryReplace(range, replacement); - if (range !== null) - this.selection.setSelectionRange(range); - }, - - this.replaceAll = function(replacement, options) { - if (options) { - this.$search.set(options); - } - - var ranges = this.$search.findAll(this.session); - if (!ranges.length) - return; - - var selection = this.getSelectionRange(); - this.clearSelection(); - this.selection.moveCursorTo(0, 0); - - this.$blockScrolling += 1; - for (var i = ranges.length - 1; i >= 0; --i) - this.$tryReplace(ranges[i], replacement); - - this.selection.setSelectionRange(selection); - this.$blockScrolling -= 1; - }, - - this.$tryReplace = function(range, replacement) { - var input = this.session.getTextRange(range); - var replacement = this.$search.replace(input, replacement); - if (replacement !== null) { - range.end = this.session.replace(range, replacement); - return range; - } else { - return null; - } - }; - - this.getLastSearchOptions = function() { - return this.$search.getOptions(); - }; - - this.find = function(needle, options) { - this.clearSelection(); - options = options || {}; - options.needle = needle; - this.$search.set(options); - this.$find(); - }, - - this.findNext = function(options) { - options = options || {}; - if (typeof options.backwards == "undefined") - options.backwards = false; - this.$search.set(options); - this.$find(); - }; - - this.findPrevious = function(options) { - options = options || {}; - if (typeof options.backwards == "undefined") - options.backwards = true; - this.$search.set(options); - this.$find(); - }; - - this.$find = function(backwards) { - if (!this.selection.isEmpty()) { - this.$search.set({needle: this.session.getTextRange(this.getSelectionRange())}); - } - - if (typeof backwards != "undefined") - this.$search.set({backwards: backwards}); - - var range = this.$search.find(this.session); - if (range) { - this.gotoLine(range.end.row+1, range.end.column); - this.selection.setSelectionRange(range); - } - }; - - this.undo = function() { - this.session.getUndoManager().undo(); - }; - - this.redo = function() { - this.session.getUndoManager().redo(); - }; - -}).call(Editor.prototype); - - -exports.Editor = Editor; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/event', function(require, exports, module) { - -var keys = require("pilot/keys"); -var useragent = require("pilot/useragent"); -var dom = require("pilot/dom"); - -exports.addListener = function(elem, type, callback) { - if (elem.addEventListener) { - return elem.addEventListener(type, callback, false); - } - if (elem.attachEvent) { - var wrapper = function() { - callback(window.event); - }; - callback._wrapper = wrapper; - elem.attachEvent("on" + type, wrapper); - } -}; - -exports.removeListener = function(elem, type, callback) { - if (elem.removeEventListener) { - return elem.removeEventListener(type, callback, false); - } - if (elem.detachEvent) { - elem.detachEvent("on" + type, callback._wrapper || callback); - } -}; - -/** -* Prevents propagation and clobbers the default action of the passed event -*/ -exports.stopEvent = function(e) { - exports.stopPropagation(e); - exports.preventDefault(e); - return false; -}; - -exports.stopPropagation = function(e) { - if (e.stopPropagation) - e.stopPropagation(); - else - e.cancelBubble = true; -}; - -exports.preventDefault = function(e) { - if (e.preventDefault) - e.preventDefault(); - else - 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) { - if (e.type == "dblclick") - return 0; - else if (e.type == "contextmenu") - return 2; - - // DOM Event - if (e.preventDefault) { - return e.button; - } - // old IE - else { - return {1:0, 2:2, 4:1}[e.button]; - } -}; - -if (document.documentElement.setCapture) { - exports.capture = function(el, eventHandler, releaseCaptureHandler) { - function onMouseMove(e) { - eventHandler(e); - return exports.stopPropagation(e); - } - - function onReleaseCapture(e) { - eventHandler && eventHandler(e); - releaseCaptureHandler && releaseCaptureHandler(); - - exports.removeListener(el, "mousemove", eventHandler); - exports.removeListener(el, "mouseup", onReleaseCapture); - exports.removeListener(el, "losecapture", onReleaseCapture); - - el.releaseCapture(); - } - - exports.addListener(el, "mousemove", eventHandler); - exports.addListener(el, "mouseup", onReleaseCapture); - exports.addListener(el, "losecapture", onReleaseCapture); - el.setCapture(); - }; -} -else { - exports.capture = function(el, eventHandler, releaseCaptureHandler) { - function onMouseMove(e) { - eventHandler(e); - e.stopPropagation(); - } - - function onMouseUp(e) { - eventHandler && eventHandler(e); - releaseCaptureHandler && releaseCaptureHandler(); - - document.removeEventListener("mousemove", onMouseMove, true); - document.removeEventListener("mouseup", onMouseUp, true); - - e.stopPropagation(); - } - - document.addEventListener("mousemove", onMouseMove, true); - document.addEventListener("mouseup", onMouseUp, true); - }; -} - -exports.addMouseWheelListener = function(el, callback) { - var listener = function(e) { - if (e.wheelDelta !== undefined) { - if (e.wheelDeltaX !== undefined) { - e.wheelX = -e.wheelDeltaX / 8; - e.wheelY = -e.wheelDeltaY / 8; - } else { - e.wheelX = 0; - e.wheelY = -e.wheelDelta / 8; - } - } - else { - if (e.axis && e.axis == e.HORIZONTAL_AXIS) { - e.wheelX = (e.detail || 0) * 5; - e.wheelY = 0; - } else { - e.wheelX = 0; - e.wheelY = (e.detail || 0) * 5; - } - } - callback(e); - }; - exports.addListener(el, "DOMMouseScroll", listener); - exports.addListener(el, "mousewheel", listener); -}; - -exports.addMultiMouseDownListener = function(el, button, count, timeout, callback) { - var clicks = 0; - var startX, startY; - - var listener = function(e) { - clicks += 1; - if (clicks == 1) { - startX = e.clientX; - startY = e.clientY; - - setTimeout(function() { - clicks = 0; - }, timeout || 600); - } - - if (exports.getButton(e) != button - || Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5) - clicks = 0; - - if (clicks == count) { - clicks = 0; - callback(e); - } - return exports.preventDefault(e); - }; - - exports.addListener(el, "mousedown", listener); - useragent.isIE && exports.addListener(el, "dblclick", listener); -}; - -function normalizeCommandKeys(callback, e, keyCode) { - var hashId = 0; - if (useragent.isOpera && useragent.isMac) { - hashId = 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0) - | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0); - } else { - hashId = 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) - | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0); - } - - if (keyCode in keys.MODIFIER_KEYS) { - switch (keys.MODIFIER_KEYS[keyCode]) { - case "Alt": - hashId = 2; - break; - case "Shift": - hashId = 4; - break - case "Ctrl": - hashId = 1; - break; - default: - hashId = 8; - break; - } - keyCode = 0; - } - - if (hashId & 8 && (keyCode == 91 || keyCode == 93)) { - keyCode = 0; - } - - // If there is no hashID and the keyCode is not a function key, then - // we don't call the callback as we don't handle a command key here - // (it's a normal key/character input). - if (hashId == 0 && !(keyCode in keys.FUNCTION_KEYS)) { - return false; - } - - return callback(e, hashId, keyCode); -} - -exports.addCommandKeyListener = function(el, callback) { - var addListener = exports.addListener; - if (useragent.isOldGecko) { - // Old versions of Gecko aka. Firefox < 4.0 didn't repeat the keydown - // event if the user pressed the key for a longer time. Instead, the - // keydown event was fired once and later on only the keypress event. - // To emulate the 'right' keydown behavior, the keyCode of the initial - // keyDown event is stored and in the following keypress events the - // stores keyCode is used to emulate a keyDown event. - var lastKeyDownKeyCode = null; - addListener(el, "keydown", function(e) { - lastKeyDownKeyCode = e.keyCode; - }); - addListener(el, "keypress", function(e) { - return normalizeCommandKeys(callback, e, lastKeyDownKeyCode); - }); - } else { - var lastDown = null; - - addListener(el, "keydown", function(e) { - lastDown = e.keyIdentifier || e.keyCode; - return normalizeCommandKeys(callback, e, e.keyCode); - }); - - // repeated keys are fired as keypress and not keydown events - if (useragent.isMac && useragent.isOpera) { - addListener(el, "keypress", function(e) { - var keyId = e.keyIdentifier || e.keyCode; - if (lastDown !== keyId) { - return normalizeCommandKeys(callback, e, e.keyCode); - } else { - lastDown = null; - } - }); - } - } -}; - -}); -/*! @license -========================================================================== -SproutCore -- JavaScript Application Framework -copyright 2006-2009, Sprout Systems Inc., Apple Inc. and contributors. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -SproutCore and the SproutCore logo are trademarks of Sprout Systems, Inc. - -For more information about SproutCore, visit http://www.sproutcore.com - - -========================================================================== -@license */ - -// Most of the following code is taken from SproutCore with a few changes. - -__ace_shadowed__.define('pilot/keys', function(require, exports, module) { - -var oop = require("pilot/oop"); - -/** - * Helper functions and hashes for key handling. - */ -var Keys = (function() { - var ret = { - 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", - 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: '\"' - } - }; - - // A reverse map of FUNCTION_KEYS - for (i in ret.FUNCTION_KEYS) { - var name = ret.FUNCTION_KEYS[i].toUpperCase(); - ret[name] = parseInt(i, 10); - } - - // Add the MODIFIER_KEYS, FUNCTION_KEYS and PRINTABLE_KEYS to the KEY - // variables as well. - oop.mixin(ret, ret.MODIFIER_KEYS); - oop.mixin(ret, ret.PRINTABLE_KEYS); - oop.mixin(ret, ret.FUNCTION_KEYS); - - return ret; -})(); -oop.mixin(exports, Keys); - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('pilot/dom', function(require, exports, module) { - -exports.setText = function(elem, text) { - if (elem.innerText !== undefined) { - elem.innerText = text; - } - if (elem.textContent !== undefined) { - elem.textContent = text; - } -}; - -if (!document.documentElement.classList) { - exports.hasCssClass = function(el, name) { - var classes = el.className.split(/\s+/g); - return classes.indexOf(name) !== -1; - }; - - /** - * Add a CSS class to the list of classes on the given node - */ - exports.addCssClass = function(el, name) { - if (!exports.hasCssClass(el, name)) { - el.className += " " + name; - } - }; - - /** - * Remove a CSS class from the list of classes on the given node - */ - exports.removeCssClass = function(el, name) { - var classes = el.className.split(/\s+/g); - while (true) { - var index = classes.indexOf(name); - if (index == -1) { - break; - } - classes.splice(index, 1); - } - el.className = classes.join(" "); - }; - - exports.toggleCssClass = function(el, name) { - var classes = el.className.split(/\s+/g), add = true; - while (true) { - var index = classes.indexOf(name); - if (index == -1) { - break; - } - add = false; - classes.splice(index, 1); - } - if(add) - classes.push(name); - - el.className = classes.join(" "); - return add; - }; -} else { - exports.hasCssClass = function(el, name) { - return el.classList.contains(name); - }; - - exports.addCssClass = function(el, name) { - el.classList.add(name); - }; - - exports.removeCssClass = function(el, name) { - el.classList.remove(name); - }; - - exports.toggleCssClass = function(el, name) { - return el.classList.toggle(name); - }; -} - -/** - * Add or remove a CSS class from the list of classes on the given node - * depending on the value of include - */ -exports.setCssClass = function(node, className, include) { - if (include) { - exports.addCssClass(node, className); - } else { - exports.removeCssClass(node, className); - } -}; - -exports.importCssString = function(cssText, doc){ - doc = doc || document; - - if (doc.createStyleSheet) { - var sheet = doc.createStyleSheet(); - sheet.cssText = cssText; - } - else { - var style = doc.createElement("style"); - style.appendChild(doc.createTextNode(cssText)); - doc.getElementsByTagName("head")[0].appendChild(style); - } -}; - -exports.getInnerWidth = function(element) { - return (parseInt(exports.computedStyle(element, "paddingLeft")) - + parseInt(exports.computedStyle(element, "paddingRight")) + element.clientWidth); -}; - -exports.getInnerHeight = function(element) { - return (parseInt(exports.computedStyle(element, "paddingTop")) - + parseInt(exports.computedStyle(element, "paddingBottom")) + element.clientHeight); -}; - -if (window.pageYOffset !== undefined) { - exports.getPageScrollTop = function() { - return window.pageYOffset; - }; - - exports.getPageScrollLeft = function() { - return window.pageXOffset; - }; -} -else { - exports.getPageScrollTop = function() { - return document.body.scrollTop; - }; - - exports.getPageScrollLeft = function() { - return document.body.scrollLeft; - }; -} - -exports.computedStyle = function(element, style) { - if (window.getComputedStyle) { - return (window.getComputedStyle(element, "") || {})[style] || ""; - } - else { - return element.currentStyle[style]; - } -}; - -exports.scrollbarWidth = function() { - - var inner = document.createElement('p'); - inner.style.width = "100%"; - inner.style.height = "200px"; - - var outer = document.createElement("div"); - var style = outer.style; - - style.position = "absolute"; - style.left = "-10000px"; - style.overflow = "hidden"; - style.width = "200px"; - style.height = "150px"; - - outer.appendChild(inner); - document.body.appendChild(outer); - var noScrollbar = inner.offsetWidth; - - style.overflow = "scroll"; - var withScrollbar = inner.offsetWidth; - - if (noScrollbar == withScrollbar) { - withScrollbar = outer.clientWidth; - } - - document.body.removeChild(outer); - - return noScrollbar-withScrollbar; -}; - -/** - * Optimized set innerHTML. This is faster than plain innerHTML if the element - * already contains a lot of child elements. - * - * See http://blog.stevenlevithan.com/archives/faster-than-innerhtml for details - */ -exports.setInnerHtml = function(el, innerHtml) { - var element = el.cloneNode(false);//document.createElement("div"); - element.innerHTML = innerHtml; - el.parentNode.replaceChild(element, el); - return element; -}; - -exports.setInnerText = function(el, innerText) { - if ("textContent" in document.body) - el.textContent = innerText; - else - el.innerText = innerText; - -}; - -exports.getInnerText = function(el) { - if ("textContent" in document.body) - return el.textContent; - else - return el.innerText; -}; - -exports.getParentWindow = function(document) { - return document.defaultView || document.parentWindow; -}; - -exports.getSelectionStart = function(textarea) { - // TODO IE - var start; - try { - start = textarea.selectionStart || 0; - } catch (e) { - start = 0; - } - return start; -}; - -exports.setSelectionStart = function(textarea, start) { - // TODO IE - return textarea.selectionStart = start; -}; - -exports.getSelectionEnd = function(textarea) { - // TODO IE - var end; - try { - end = textarea.selectionEnd || 0; - } catch (e) { - end = 0; - } - return end; -}; - -exports.setSelectionEnd = function(textarea, end) { - // TODO IE - return textarea.selectionEnd = end; -}; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/keyboard/textinput', function(require, exports, module) { - -var event = require("pilot/event"); -var useragent = require("pilot/useragent"); - -var TextInput = function(parentNode, host) { - - var text = document.createElement("textarea"); - text.style.left = "-10000px"; - parentNode.appendChild(text); - - var PLACEHOLDER = String.fromCharCode(0); - sendText(); - - var inCompostion = false; - var copied = false; - var tempStyle = ''; - - function sendText(valueToSend) { - 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); - } else - host.onTextInput(value); - } - } - copied = false; - - // Safari doesn't fire copy events if no text is selected - text.value = PLACEHOLDER; - text.select(); - } - - var onTextInput = function(e) { - if (useragent.isIE && text.value.charCodeAt(0) > 128) return; - setTimeout(function() { - if (!inCompostion) - sendText(); - }, 0); - }; - - var onCompositionStart = function(e) { - inCompostion = true; - if (!useragent.isIE) { - sendText(); - text.value = ""; - }; - host.onCompositionStart(); - if (!useragent.isGecko) setTimeout(onCompositionUpdate, 0); - }; - - var onCompositionUpdate = function() { - if (!inCompostion) return; - host.onCompositionUpdate(text.value); - }; - - var onCompositionEnd = function() { - inCompostion = false; - host.onCompositionEnd(); - setTimeout(function () { - sendText(); - }, 0); - }; - - var onCopy = function(e) { - copied = true; - var copyText = host.getCopyText(); - if(copyText) - text.value = copyText; - else - e.preventDefault(); - text.select(); - setTimeout(function () { - sendText(); - }, 0); - }; - - var onCut = function(e) { - copied = true; - var copyText = host.getCopyText(); - if(copyText) { - text.value = copyText; - host.onCut(); - } else - e.preventDefault(); - text.select(); - setTimeout(function () { - sendText(); - }, 0); - }; - - event.addCommandKeyListener(text, host.onCommandKey.bind(host)); - event.addListener(text, "keypress", onTextInput); - if (useragent.isIE) { - var keytable = { 13:1, 27:1 }; - event.addListener(text, "keyup", function (e) { - if (inCompostion && (!text.value || keytable[e.keyCode])) - setTimeout(onCompositionEnd, 0); - if ((text.value.charCodeAt(0)|0) < 129) { - return; - }; - inCompostion ? onCompositionUpdate() : onCompositionStart(); - }); - }; - event.addListener(text, "textInput", onTextInput); - event.addListener(text, "paste", function(e) { - // Some browsers support the event.clipboardData API. Use this to get - // the pasted content which increases speed if pasting a lot of lines. - if (e.clipboardData && e.clipboardData.getData) { - sendText(e.clipboardData.getData("text/plain")); - e.preventDefault(); - } else - // If a browser doesn't support any of the things above, use the regular - // method to detect the pasted input. - { - onTextInput(); - } - }); - if (!useragent.isIE) { - event.addListener(text, "propertychange", onTextInput); - }; - - if (useragent.isIE) { - event.addListener(text, "beforecopy", function(e) { - var copyText = host.getCopyText(); - if(copyText) - clipboardData.setData("Text", copyText); - else - e.preventDefault(); - }); - event.addListener(parentNode, "keydown", function(e) { - if (e.ctrlKey && e.keyCode == 88) { - var copyText = host.getCopyText(); - if (copyText) { - clipboardData.setData("Text", copyText); - host.onCut(); - } - event.preventDefault(e) - } - }); - } - else { - event.addListener(text, "copy", onCopy); - event.addListener(text, "cut", onCut); - } - - event.addListener(text, "compositionstart", onCompositionStart); - if (useragent.isGecko) { - event.addListener(text, "text", onCompositionUpdate); - }; - if (useragent.isWebKit) { - event.addListener(text, "keyup", onCompositionUpdate); - }; - event.addListener(text, "compositionend", onCompositionEnd); - - event.addListener(text, "blur", function() { - host.onBlur(); - }); - - event.addListener(text, "focus", function() { - host.onFocus(); - text.select(); - }); - - this.focus = function() { - host.onFocus(); - text.select(); - text.focus(); - }; - - this.blur = function() { - text.blur(); - }; - - this.getElement = function() { - return text; - }; - - this.onContextMenu = function(mousePos, isEmpty){ - if (mousePos) { - if(!tempStyle) - tempStyle = text.style.cssText; - text.style.cssText = 'position:fixed; z-index:1000;' + - 'left:' + (mousePos.x - 2) + 'px; top:' + (mousePos.y - 2) + 'px;' - - } - if (isEmpty) - text.value=''; - } - - this.onContextMenuClose = function(){ - setTimeout(function () { - if (tempStyle) { - text.style.cssText = tempStyle; - tempStyle = ''; - } - sendText(); - }, 0); - } -}; - -exports.TextInput = TextInput; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/mouse_handler', function(require, exports, module) { - -var event = require("pilot/event"); - -var MouseHandler = function(editor) { - this.editor = editor; - event.addListener(editor.container, "mousedown", function(e) { - editor.focus(); - return event.preventDefault(e); - }); - event.addListener(editor.container, "selectstart", function(e) { - return event.preventDefault(e); - }); - - var mouseTarget = editor.renderer.getMouseEventTarget(); - event.addListener(mouseTarget, "mousedown", this.onMouseDown.bind(this)); - event.addMultiMouseDownListener(mouseTarget, 0, 2, 500, this.onMouseDoubleClick.bind(this)); - event.addMultiMouseDownListener(mouseTarget, 0, 3, 600, this.onMouseTripleClick.bind(this)); - event.addMouseWheelListener(mouseTarget, this.onMouseWheel.bind(this)); -}; - -(function() { - - this.$scrollSpeed = 1; - this.setScrollSpeed = function(speed) { - this.$scrollSpeed = speed; - }; - - this.getScrollSpeed = function() { - return this.$scrollSpeed; - }; - - this.onMouseDown = function(e) { - var pageX = event.getDocumentX(e); - var pageY = event.getDocumentY(e); - var editor = this.editor; - - var pos = editor.renderer.screenToTextCoordinates(pageX, pageY); - pos.row = Math.max(0, Math.min(pos.row, editor.session.getLength()-1)); - - var button = event.getButton(e) - if (button != 0) { - var isEmpty = editor.selection.isEmpty() - if (isEmpty) { - editor.moveCursorToPosition(pos); - } - if(button == 2) { - editor.textInput.onContextMenu({x: pageX, y: pageY}, isEmpty); - event.capture(editor.container, function(){}, editor.textInput.onContextMenuClose); - } - return; - } - - if (e.shiftKey) - editor.selection.selectToPosition(pos) - else { - editor.moveCursorToPosition(pos); - if (!editor.$clickSelection) - editor.selection.clearSelection(pos.row, pos.column); - } - - editor.renderer.scrollCursorIntoView(); - - var self = this; - var mousePageX, mousePageY; - - var onMouseSelection = function(e) { - mousePageX = event.getDocumentX(e); - mousePageY = event.getDocumentY(e); - }; - - var onMouseSelectionEnd = function() { - clearInterval(timerId); - self.$clickSelection = null; - }; - - var onSelectionInterval = function() { - if (mousePageX === undefined || mousePageY === undefined) - return; - - var cursor = editor.renderer.screenToTextCoordinates(mousePageX, mousePageY); - cursor.row = Math.max(0, Math.min(cursor.row, editor.session.getLength()-1)); - - 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) { - var anchor = self.$clickSelection.end; - } else { - var anchor = self.$clickSelection.start; - } - editor.selection.setSelectionAnchor(anchor.row, anchor.column); - editor.selection.selectToPosition(cursor); - } - } - else { - editor.selection.selectToPosition(cursor); - } - - editor.renderer.scrollCursorIntoView(); - }; - - event.capture(editor.container, onMouseSelection, onMouseSelectionEnd); - var timerId = setInterval(onSelectionInterval, 20); - - return event.preventDefault(e); - }; - - this.onMouseDoubleClick = function(e) { - this.editor.selection.selectWord(); - this.$clickSelection = this.editor.getSelectionRange(); - }; - - this.onMouseTripleClick = function(e) { - this.editor.selection.selectLine(); - this.$clickSelection = this.editor.getSelectionRange(); - }; - - this.onMouseWheel = function(e) { - var speed = this.$scrollSpeed * 2; - - this.editor.renderer.scrollBy(e.wheelX * speed, e.wheelY * speed); - return event.preventDefault(e); - }; - - -}).call(MouseHandler.prototype); - -exports.MouseHandler = MouseHandler; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/keyboard/keybinding', function(require, exports, module) { - -var useragent = require("pilot/useragent"); -var keyUtil = require("pilot/keys"); -var event = require("pilot/event"); -var settings = require("pilot/settings").settings; -var HashHandler = require("ace/keyboard/hash_handler").HashHandler; -var default_mac = require("ace/keyboard/keybinding/default_mac").bindings; -var default_win = require("ace/keyboard/keybinding/default_win").bindings; -var canon = require("pilot/canon"); -require("ace/commands/default_commands"); - -var KeyBinding = function(editor, config) { - this.$editor = editor; - this.$data = { }; - this.$keyboardHandler = null; - this.$defaulKeyboardHandler = new HashHandler(config || (useragent.isMac - ? default_mac - : default_win)); -}; - -(function() { - this.setKeyboardHandler = function(keyboardHandler) { - if (this.$keyboardHandler != keyboardHandler) { - this.$data = { }; - this.$keyboardHandler = keyboardHandler; - } - }; - - this.getKeyboardHandler = function() { - return this.$keyboardHandler; - }; - - this.$callKeyboardHandler = function (e, hashId, keyOrText, keyCode) { - var toExecute; - if (this.$keyboardHandler) { - toExecute = - this.$keyboardHandler.handleKeyboard(this.$data, hashId, keyOrText, keyCode, e); - } - - // If there is nothing to execute yet, then use the default keymapping. - if (!toExecute || !toExecute.command) { - toExecute = this.$defaulKeyboardHandler. - handleKeyboard(this.$data, hashId, keyOrText, keyCode, e); - } - - if (toExecute) { - var success = canon.exec(toExecute.command, - {editor: this.$editor}, toExecute.args); - if (success) { - return event.stopEvent(e); - } - } - }; - - this.onCommandKey = function(e, hashId, keyCode) { - key = (keyUtil[keyCode] || - String.fromCharCode(keyCode)).toLowerCase(); - - this.$callKeyboardHandler(e, hashId, key, keyCode); - }; - - this.onTextInput = function(text) { - this.$callKeyboardHandler({}, 0, text, 0); - } - -}).call(KeyBinding.prototype); - -exports.KeyBinding = KeyBinding; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck (julian.viereck@gmail.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/keyboard/hash_handler', function(require, exports, module) { - -var keyUtil = require("pilot/keys"); - -function HashHandler(config) { - this.setConfig(config); -} - -(function() { - function splitSafe(s, separator, limit, bLowerCase) { - return (bLowerCase && s.toLowerCase() || s) - .replace(/(?:^\s+|\n|\s+$)/g, "") - .split(new RegExp("[\\s ]*" + separator + "[\\s ]*", "g"), limit || 999); - } - - function parseKeys(keys, val, ret) { - var key, - hashId = 0, - parts = splitSafe(keys, "\\-", null, true), - i = 0, - l = parts.length; - - for (; i < l; ++i) { - if (keyUtil.KEY_MODS[parts[i]]) - hashId = hashId | keyUtil.KEY_MODS[parts[i]]; - else - key = parts[i] || "-"; //when empty, the splitSafe removed a '-' - } - - (ret[hashId] || (ret[hashId] = {}))[key] = val; - return ret; - } - - function objectReverse(obj, keySplit) { - var i, j, l, key, - ret = {}; - for (i in obj) { - key = obj[i]; - if (keySplit && typeof key == "string") { - key = key.split(keySplit); - for (j = 0, l = key.length; j < l; ++j) - parseKeys.call(this, key[j], i, ret); - } - else { - parseKeys.call(this, key, i, ret); - } - } - return ret; - } - - this.setConfig = function(config) { - this.$config = config; - if (typeof this.$config.reverse == "undefined") - this.$config.reverse = objectReverse.call(this, this.$config, "|"); - }; - - /** - * This function is called by keyBinding. - */ - this.handleKeyboard = function(data, hashId, textOrKey, keyCode) { - // Figure out if a commandKey was pressed or just some text was insert. - if (hashId != 0 || keyCode != 0) { - return { - command: (this.$config.reverse[hashId] || {})[textOrKey] - } - } else { - return { - command: "inserttext", - args: { - text: textOrKey - } - } - } - } -}).call(HashHandler.prototype) - -exports.HashHandler = HashHandler; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/keyboard/keybinding/default_mac', function(require, exports, module) { - -exports.bindings = { - "selectall": "Command-A", - "removeline": "Command-D", - "gotoline": "Command-L", - "togglecomment": "Command-7", - "findnext": "Command-K", - "findprevious": "Command-Shift-K", - "find": "Command-F", - "replace": "Command-R", - "undo": "Command-Z", - "redo": "Command-Shift-Z|Command-Y", - "overwrite": "Insert", - "copylinesup": "Command-Option-Up", - "movelinesup": "Option-Up", - "selecttostart": "Command-Shift-Up", - "gotostart": "Command-Home|Command-Up", - "selectup": "Shift-Up", - "golineup": "Up|Ctrl-P", - "copylinesdown": "Command-Option-Down", - "movelinesdown": "Option-Down", - "selecttoend": "Command-Shift-Down", - "gotoend": "Command-End|Command-Down", - "selectdown": "Shift-Down", - "golinedown": "Down|Ctrl-N", - "selectwordleft": "Option-Shift-Left", - "gotowordleft": "Option-Left", - "selecttolinestart": "Command-Shift-Left", - "gotolinestart": "Command-Left|Home|Ctrl-A", - "selectleft": "Shift-Left", - "gotoleft": "Left|Ctrl-B", - "selectwordright": "Option-Shift-Right", - "gotowordright": "Option-Right", - "selecttolineend": "Command-Shift-Right", - "gotolineend": "Command-Right|End|Ctrl-E", - "selectright": "Shift-Right", - "gotoright": "Right|Ctrl-F", - "selectpagedown": "Shift-PageDown", - "pagedown": "PageDown", - "gotopagedown": "Option-PageDown|Ctrl-V", - "selectpageup": "Shift-PageUp", - "pageup": "PageUp", - "gotopageup": "Option-PageUp", - "selectlinestart": "Shift-Home", - "selectlineend": "Shift-End", - "del": "Delete|Ctrl-D", - "backspace": "Ctrl-Backspace|Command-Backspace|Shift-Backspace|Backspace|Ctrl-H", - "removetolineend": "Ctrl-K", - "removetolinestart": "Option-Backspace", - "removewordleft": "Alt-Backspace|Ctrl-Alt-Backspace", - "removewordright": "Alt-Delete", - "outdent": "Shift-Tab", - "indent": "Tab", - "transposeletters": "Ctrl-T", - "splitline": "Ctrl-O", - "centerselection": "Ctrl-L" -}; - -});/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/keyboard/keybinding/default_win', function(require, exports, module) { - -exports.bindings = { - "selectall": "Ctrl-A", - "removeline": "Ctrl-D", - "gotoline": "Ctrl-L", - "togglecomment": "Ctrl-7", - "findnext": "Ctrl-K", - "findprevious": "Ctrl-Shift-K", - "find": "Ctrl-F", - "replace": "Ctrl-R", - "undo": "Ctrl-Z", - "redo": "Ctrl-Shift-Z|Ctrl-Y", - "overwrite": "Insert", - "copylinesup": "Ctrl-Alt-Up", - "movelinesup": "Alt-Up", - "selecttostart": "Alt-Shift-Up", - "gotostart": "Ctrl-Home|Ctrl-Up", - "selectup": "Shift-Up", - "golineup": "Up", - "copylinesdown": "Ctrl-Alt-Down", - "movelinesdown": "Alt-Down", - "selecttoend": "Alt-Shift-Down", - "gotoend": "Ctrl-End|Ctrl-Down", - "selectdown": "Shift-Down", - "golinedown": "Down", - "selectwordleft": "Ctrl-Shift-Left", - "gotowordleft": "Ctrl-Left", - "selecttolinestart": "Alt-Shift-Left", - "gotolinestart": "Alt-Left|Home", - "selectleft": "Shift-Left", - "gotoleft": "Left", - "selectwordright": "Ctrl-Shift-Right", - "gotowordright": "Ctrl-Right", - "selecttolineend": "Alt-Shift-Right", - "gotolineend": "Alt-Right|End", - "selectright": "Shift-Right", - "gotoright": "Right", - "selectpagedown": "Shift-PageDown", - "gotopagedown": "PageDown", - "selectpageup": "Shift-PageUp", - "gotopageup": "PageUp", - "selectlinestart": "Shift-Home", - "selectlineend": "Shift-End", - "del": "Delete", - "backspace": "Ctrl-Backspace|Command-Backspace|Option-Backspace|Shift-Backspace|Backspace", - "outdent": "Shift-Tab", - "indent": "Tab" -}; - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/commands/default_commands', function(require, exports, module) { - -var lang = require("pilot/lang"); -var canon = require("pilot/canon"); - -canon.addCommand({ - name: "null", - exec: function(env, args, request) { } -}); - -canon.addCommand({ - name: "selectall", - exec: function(env, args, request) { env.editor.selectAll(); } -}); -canon.addCommand({ - name: "removeline", - exec: function(env, args, request) { env.editor.removeLines(); } -}); -canon.addCommand({ - name: "gotoline", - exec: function(env, args, request) { - var line = parseInt(prompt("Enter line number:")); - if (!isNaN(line)) { - env.editor.gotoLine(line); - } - } -}); -canon.addCommand({ - name: "togglecomment", - exec: function(env, args, request) { env.editor.toggleCommentLines(); } -}); -canon.addCommand({ - name: "findnext", - exec: function(env, args, request) { env.editor.findNext(); } -}); -canon.addCommand({ - name: "findprevious", - exec: function(env, args, request) { env.editor.findPrevious(); } -}); -canon.addCommand({ - name: "find", - exec: function(env, args, request) { - var needle = prompt("Find:"); - env.editor.find(needle); - } -}); -canon.addCommand({ - name: "undo", - exec: function(env, args, request) { env.editor.undo(); } -}); -canon.addCommand({ - name: "redo", - exec: function(env, args, request) { env.editor.redo(); } -}); -canon.addCommand({ - name: "redo", - exec: function(env, args, request) { env.editor.redo(); } -}); -canon.addCommand({ - name: "overwrite", - exec: function(env, args, request) { env.editor.toggleOverwrite(); } -}); -canon.addCommand({ - name: "copylinesup", - exec: function(env, args, request) { env.editor.copyLinesUp(); } -}); -canon.addCommand({ - name: "movelinesup", - exec: function(env, args, request) { env.editor.moveLinesUp(); } -}); -canon.addCommand({ - name: "selecttostart", - exec: function(env, args, request) { env.editor.getSelection().selectFileStart(); } -}); -canon.addCommand({ - name: "gotostart", - exec: function(env, args, request) { env.editor.navigateFileStart(); } -}); -canon.addCommand({ - name: "selectup", - exec: function(env, args, request) { env.editor.getSelection().selectUp(); } -}); -canon.addCommand({ - name: "golineup", - exec: function(env, args, request) { env.editor.navigateUp(args.times); } -}); -canon.addCommand({ - name: "copylinesdown", - exec: function(env, args, request) { env.editor.copyLinesDown(); } -}); -canon.addCommand({ - name: "movelinesdown", - exec: function(env, args, request) { env.editor.moveLinesDown(); } -}); -canon.addCommand({ - name: "selecttoend", - exec: function(env, args, request) { env.editor.getSelection().selectFileEnd(); } -}); -canon.addCommand({ - name: "gotoend", - exec: function(env, args, request) { env.editor.navigateFileEnd(); } -}); -canon.addCommand({ - name: "selectdown", - exec: function(env, args, request) { env.editor.getSelection().selectDown(); } -}); -canon.addCommand({ - name: "golinedown", - exec: function(env, args, request) { env.editor.navigateDown(args.times); } -}); -canon.addCommand({ - name: "selectwordleft", - exec: function(env, args, request) { env.editor.getSelection().selectWordLeft(); } -}); -canon.addCommand({ - name: "gotowordleft", - exec: function(env, args, request) { env.editor.navigateWordLeft(); } -}); -canon.addCommand({ - name: "selecttolinestart", - exec: function(env, args, request) { env.editor.getSelection().selectLineStart(); } -}); -canon.addCommand({ - name: "gotolinestart", - exec: function(env, args, request) { env.editor.navigateLineStart(); } -}); -canon.addCommand({ - name: "selectleft", - exec: function(env, args, request) { env.editor.getSelection().selectLeft(); } -}); -canon.addCommand({ - name: "gotoleft", - exec: function(env, args, request) { env.editor.navigateLeft(args.times); } -}); -canon.addCommand({ - name: "selectwordright", - exec: function(env, args, request) { env.editor.getSelection().selectWordRight(); } -}); -canon.addCommand({ - name: "gotowordright", - exec: function(env, args, request) { env.editor.navigateWordRight(); } -}); -canon.addCommand({ - name: "selecttolineend", - exec: function(env, args, request) { env.editor.getSelection().selectLineEnd(); } -}); -canon.addCommand({ - name: "gotolineend", - exec: function(env, args, request) { env.editor.navigateLineEnd(); } -}); -canon.addCommand({ - name: "selectright", - exec: function(env, args, request) { env.editor.getSelection().selectRight(); } -}); -canon.addCommand({ - name: "gotoright", - exec: function(env, args, request) { env.editor.navigateRight(args.times); } -}); -canon.addCommand({ - name: "selectpagedown", - exec: function(env, args, request) { env.editor.selectPageDown(); } -}); -canon.addCommand({ - name: "pagedown", - exec: function(env, args, request) { env.editor.scrollPageDown(); } -}); -canon.addCommand({ - name: "gotopagedown", - exec: function(env, args, request) { env.editor.gotoPageDown(); } -}); -canon.addCommand({ - name: "selectpageup", - exec: function(env, args, request) { env.editor.selectPageUp(); } -}); -canon.addCommand({ - name: "pageup", - exec: function(env, args, request) { env.editor.scrollPageUp(); } -}); -canon.addCommand({ - name: "gotopageup", - exec: function(env, args, request) { env.editor.gotoPageUp(); } -}); -canon.addCommand({ - name: "selectlinestart", - exec: function(env, args, request) { env.editor.getSelection().selectLineStart(); } -}); -canon.addCommand({ - name: "gotolinestart", - exec: function(env, args, request) { env.editor.navigateLineStart(); } -}); -canon.addCommand({ - name: "selectlineend", - exec: function(env, args, request) { env.editor.getSelection().selectLineEnd(); } -}); -canon.addCommand({ - name: "gotolineend", - exec: function(env, args, request) { env.editor.navigateLineEnd(); } -}); -canon.addCommand({ - name: "del", - exec: function(env, args, request) { env.editor.removeRight(); } -}); -canon.addCommand({ - name: "backspace", - exec: function(env, args, request) { env.editor.removeLeft(); } -}); -canon.addCommand({ - name: "removetolinestart", - exec: function(env, args, request) { env.editor.removeToLineStart(); } -}); -canon.addCommand({ - name: "removetolineend", - exec: function(env, args, request) { env.editor.removeToLineEnd(); } -}); -canon.addCommand({ - name: "removewordleft", - exec: function(env, args, request) { env.editor.removeWordLeft(); } -}); -canon.addCommand({ - name: "removewordright", - exec: function(env, args, request) { env.editor.removeWordRight(); } -}); -canon.addCommand({ - name: "outdent", - exec: function(env, args, request) { env.editor.blockOutdent(); } -}); -canon.addCommand({ - name: "indent", - exec: function(env, args, request) { env.editor.indent(); } -}); -canon.addCommand({ - name: "inserttext", - exec: function(env, args, request) { - env.editor.insert(lang.stringRepeat(args.text || "", args.times || 1)); - } -}); -canon.addCommand({ - name: "centerselection", - exec: function(env, args, request) { env.editor.centerSelection(); } -}); -canon.addCommand({ - name: "splitline", - exec: function(env, args, request) { env.editor.splitLine(); } -}); -canon.addCommand({ - name: "transposeletters", - exec: function(env, args, request) { env.editor.transposeLetters(); } -}); - - -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/edit_session', function(require, exports, module) { - -var oop = require("pilot/oop"); -var lang = require("pilot/lang"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; -var Selection = require("ace/selection").Selection; -var TextMode = require("ace/mode/text").Mode; -var Range = require("ace/range").Range; -var Document = require("ace/document").Document; - -var NO_CHANGE_DELTAS = {}; - -var EditSession = function(text, mode) { - this.$modified = true; - this.$breakpoints = []; - this.$frontMarkers = {}; - this.$backMarkers = {}; - this.$markerId = 1; - this.$wrapData = []; - this.listeners = []; - - if (text instanceof Document) { - this.setDocument(text); - } else { - this.setDocument(new Document(text)); - } - - this.selection = new Selection(this); - if (mode) - this.setMode(mode); -}; - - -(function() { - - oop.implement(this, EventEmitter); - - this.setDocument = function(doc) { - if (this.doc) - throw new Error("Document is already set"); - - this.doc = doc; - doc.on("change", this.onChange.bind(this)); - }; - - this.getDocument = function() { - return this.doc; - }; - - this.onChange = function(e) { - var delta = e.data; - this.$modified = true; - if (!this.$fromUndo && this.$undoManager) { - this.$deltas.push(delta); - this.$informUndoManager.schedule(); - } - - this.$updateWrapDataOnChange(e); - this._dispatchEvent("change", e); - }; - - this.setValue = function(text) { - this.doc.setValue(text); - this.$deltas = []; - }; - - this.getValue = - this.toString = function() { - return this.doc.getValue(); - }; - - this.getSelection = function() { - return this.selection; - }; - - this.setUndoManager = function(undoManager) { - this.$undoManager = undoManager; - this.$deltas = []; - - if (this.$informUndoManager) { - this.$informUndoManager.cancel(); - } - - if (undoManager) { - var self = this; - this.$informUndoManager = lang.deferredCall(function() { - if (self.$deltas.length > 0) - undoManager.execute({ - action : "aceupdate", - args : [self.$deltas, self] - }); - self.$deltas = []; - }); - } - }; - - this.$defaultUndoManager = { - undo: function() {}, - redo: function() {} - }; - - this.getUndoManager = function() { - return this.$undoManager || this.$defaultUndoManager; - }, - - this.getTabString = function() { - if (this.getUseSoftTabs()) { - return lang.stringRepeat(" ", this.getTabSize()); - } else { - return "\t"; - } - }; - - this.$useSoftTabs = true; - this.setUseSoftTabs = function(useSoftTabs) { - if (this.$useSoftTabs === useSoftTabs) return; - - this.$useSoftTabs = useSoftTabs; - }; - - this.getUseSoftTabs = function() { - return this.$useSoftTabs; - }; - - this.$tabSize = 4; - this.setTabSize = function(tabSize) { - if (isNaN(tabSize) || this.$tabSize === tabSize) return; - - this.$modified = true; - this.$tabSize = tabSize; - this._dispatchEvent("changeTabSize"); - }; - - this.getTabSize = function() { - return this.$tabSize; - }; - - this.isTabStop = function(position) { - return this.$useSoftTabs && (position.column % this.$tabSize == 0); - }; - - this.getBreakpoints = function() { - return this.$breakpoints; - }; - - this.setBreakpoints = function(rows) { - this.$breakpoints = []; - for (var i=0; i 0) { - inToken = !!line.charAt(column - 1).match(this.tokenRe); - } - - if (!inToken) { - inToken = !!line.charAt(column).match(this.tokenRe); - } - - var re = inToken ? this.tokenRe : this.nonTokenRe; - - var start = column; - if (start > 0) { - do { - start--; - } - while (start >= 0 && line.charAt(start).match(re)); - start++; - } - - var end = column; - while (end < line.length && line.charAt(end).match(re)) { - end++; - } - - return new Range(row, start, row, end); - }; - - this.setNewLineMode = function(newLineMode) { - this.doc.setNewLineMode(newLineMode); - }; - - this.getNewLineMode = function() { - return this.doc.getNewLineMode(); - }; - - this.$mode = null; - this.setMode = function(mode) { - if (this.$mode === mode) return; - - if (this.$worker) - this.$worker.terminate(); - - if (window.Worker && !require.noWorker) - this.$worker = mode.createWorker(this); - else - this.$worker = null; - - this.$mode = mode; - this._dispatchEvent("changeMode"); - }; - - this.getMode = function() { - if (!this.$mode) { - this.$mode = new TextMode(); - } - return this.$mode; - }; - - this.$scrollTop = 0; - this.setScrollTopRow = function(scrollTopRow) { - if (this.$scrollTop === scrollTopRow) return; - - this.$scrollTop = scrollTopRow; - this._dispatchEvent("changeScrollTop"); - }; - - this.getScrollTopRow = function() { - return this.$scrollTop; - }; - - this.getWidth = function() { - this.$computeWidth(); - return this.width; - }; - - this.getScreenWidth = function() { - this.$computeWidth(); - return this.screenWidth; - }; - - this.$computeWidth = function(force) { - if (this.$modified || force) { - this.$modified = false; - - var lines = this.doc.getAllLines(); - var longestLine = 0; - var longestScreenLine = 0; - var tabSize = this.getTabSize(); - - for ( var i = 0; i < lines.length; i++) { - var len = lines[i].length; - longestLine = Math.max(longestLine, len); - - lines[i].replace(/\t/g, function(m) { - len += tabSize-1; - return m; - }); - longestScreenLine = Math.max(longestScreenLine, len); - } - this.width = longestLine; - - if (this.$useWrapMode) { - this.screenWidth = this.$wrapLimit; - } else { - this.screenWidth = longestScreenLine; - } - } - }; - - /** - * Get a verbatim copy of the given line as it is in the document - */ - this.getLine = function(row) { - return this.doc.getLine(row); - }; - - /** - * Get a line as it is displayed on screen. Tabs are replaced by spaces. - */ - this.getDisplayLine = function(row) { - var tab = new Array(this.getTabSize()+1).join(" "); - return this.doc.getLine(row).replace(/\t/g, tab); - }; - - this.getLines = function(firstRow, lastRow) { - return this.doc.getLines(firstRow, lastRow); - }; - - this.getLength = function() { - return this.doc.getLength(); - }; - - this.getTextRange = function(range) { - return this.doc.getTextRange(range); - }; - - this.findMatchingBracket = function(position) { - if (position.column == 0) return null; - - var charBeforeCursor = this.getLine(position.row).charAt(position.column-1); - if (charBeforeCursor == "") return null; - - var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/); - if (!match) { - return null; - } - - if (match[1]) { - return this.$findClosingBracket(match[1], position); - } else { - return this.$findOpeningBracket(match[2], position); - } - }; - - this.$brackets = { - ")": "(", - "(": ")", - "]": "[", - "[": "]", - "{": "}", - "}": "{" - }; - - this.$findOpeningBracket = function(bracket, position) { - var openBracket = this.$brackets[bracket]; - - var column = position.column - 2; - var row = position.row; - var depth = 1; - - var line = this.getLine(row); - - while (true) { - while(column >= 0) { - var ch = line.charAt(column); - if (ch == openBracket) { - depth -= 1; - if (depth == 0) { - return {row: row, column: column}; - } - } - else if (ch == bracket) { - depth +=1; - } - column -= 1; - } - row -=1; - if (row < 0) break; - - var line = this.getLine(row); - var column = line.length-1; - } - return null; - }; - - this.$findClosingBracket = function(bracket, position) { - var closingBracket = this.$brackets[bracket]; - - var column = position.column; - var row = position.row; - var depth = 1; - - var line = this.getLine(row); - var lineCount = this.getLength(); - - while (true) { - while(column < line.length) { - var ch = line.charAt(column); - if (ch == closingBracket) { - depth -= 1; - if (depth == 0) { - return {row: row, column: column}; - } - } - else if (ch == bracket) { - depth +=1; - } - column += 1; - } - row +=1; - if (row >= lineCount) break; - - var line = this.getLine(row); - var column = 0; - } - return null; - }; - - this.insert = function(position, text) { - return this.doc.insert(position, text); - }; - - this.remove = function(range) { - return this.doc.remove(range); - }; - - this.undoChanges = function(deltas) { - if (!deltas.length) - return; - - this.$fromUndo = true; - this.doc.revertDeltas(deltas); - this.$fromUndo = false; - - // update the selection - var firstDelta = deltas[0]; - var lastDelta = deltas[deltas.length-1]; - - this.selection.clearSelection(); - if (firstDelta.action == "insertText" || firstDelta.action == "insertLines") - this.selection.moveCursorToPosition(firstDelta.range.start); - if (firstDelta.action == "removeText" || firstDelta.action == "removeLines") - this.selection.setSelectionRange(Range.fromPoints(lastDelta.range.start, firstDelta.range.end)); - }, - - this.redoChanges = function(deltas) { - if (!deltas.length) - return; - - this.$fromUndo = true; - this.doc.applyDeltas(deltas); - this.$fromUndo = false; - - // update the selection - var firstDelta = deltas[0]; - var lastDelta = deltas[deltas.length-1]; - - this.selection.clearSelection(); - if (firstDelta.action == "insertText" || firstDelta.action == "insertLines") - this.selection.setSelectionRange(Range.fromPoints(firstDelta.range.start, lastDelta.range.end)); - if (firstDelta.action == "removeText" || firstDelta.action == "removeLines") - this.selection.moveCursorToPosition(lastDelta.range.start); - }, - - this.replace = function(range, text) { - return this.doc.replace(range, text); - }; - - 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); - } - }; - - this.outdentRows = function (range) { - var rowRange = range.collapseRows(); - var deleteRange = new Range(0, 0, 0, 0); - var size = this.getTabSize(); - - for (var i = rowRange.start.row; i <= rowRange.end.row; ++i) { - var line = this.getLine(i); - - deleteRange.start.row = i; - deleteRange.end.row = i; - for (var j = 0; j < size; ++j) - if (line.charAt(j) != ' ') - break; - if (j < size && line.charAt(j) == '\t') { - deleteRange.start.column = j; - deleteRange.end.column = j + 1; - } else { - deleteRange.start.column = 0; - deleteRange.end.column = j; - } - this.remove(deleteRange); - } - }; - - this.moveLinesUp = function(firstRow, lastRow) { - if (firstRow <= 0) return 0; - - var removed = this.doc.removeLines(firstRow, lastRow); - this.doc.insertLines(firstRow - 1, removed); - return -1; - }; - - this.moveLinesDown = function(firstRow, lastRow) { - if (lastRow >= this.doc.getLength()-1) return 0; - - var removed = this.doc.removeLines(firstRow, lastRow); - this.doc.insertLines(firstRow+1, removed); - return 1; - }; - - this.duplicateLines = function(firstRow, lastRow) { - var firstRow = this.$clipRowToDocument(firstRow); - var lastRow = this.$clipRowToDocument(lastRow); - - var lines = this.getLines(firstRow, lastRow); - this.doc.insertLines(firstRow, lines); - - var addedRows = lastRow - firstRow + 1; - return addedRows; - }; - - this.$clipRowToDocument = function(row) { - return Math.max(0, Math.min(row, this.doc.getLength()-1)); - }; - - // WRAPMODE - this.$wrapLimit = 80; - this.$useWrapMode = false; - this.$wrapLimitRange = { - min : null, - max : null - }; - - this.setUseWrapMode = function(useWrapMode) { - if (useWrapMode != this.$useWrapMode) { - this.$useWrapMode = useWrapMode; - this.$modified = true; - - // If wrapMode is activaed, the wrapData array has to be initialized. - if (useWrapMode) { - var len = this.getLength(); - this.$wrapData = []; - for (i = 0; i < len; i++) { - this.$wrapData.push([]); - } - this.$updateWrapData(0, len - 1); - } - - this._dispatchEvent("changeWrapMode"); - } - }; - - this.getUseWrapMode = function() { - return this.$useWrapMode; - }; - - // Allow the wrap limit to move freely between min and max. Either - // 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. - this.setWrapLimitRange = function(min, max) { - if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) { - this.$wrapLimitRange.min = min; - this.$wrapLimitRange.max = max; - this.$modified = true; - // This will force a recalculation of the wrap limit - this._dispatchEvent("changeWrapMode"); - } - }; - - // 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) { - this.$wrapLimit = wrapLimit; - this.$modified = true; - if (this.$useWrapMode) { - this.$updateWrapData(0, this.getLength() - 1); - this._dispatchEvent("changeWrapLimit"); - } - return true; - } - return false; - }; - - this.$constrainWrapLimit = function(wrapLimit) { - var min = this.$wrapLimitRange.min; - if (min) - wrapLimit = Math.max(min, wrapLimit); - - var max = this.$wrapLimitRange.max; - if (max) - wrapLimit = Math.min(max, wrapLimit); - - // What would a limit of 0 even mean? - return Math.max(1, wrapLimit); - }; - - this.getWrapLimit = function() { - return this.$wrapLimit; - }; - - this.getWrapLimitRange = function() { - // Avoid unexpected mutation by returning a copy - return { - min : this.$wrapLimitRange.min, - max : this.$wrapLimitRange.max - }; - }; - - this.$updateWrapDataOnChange = function(e) { - if (!this.$useWrapMode) { - return; - } - - var len; - var action = e.data.action; - var firstRow = e.data.range.start.row, - lastRow = e.data.range.end.row; - - if (action.indexOf("Lines") != -1) { - if (action == "insertLines") { - lastRow = firstRow + (e.data.lines.length); - } else { - lastRow = firstRow; - } - len = e.data.lines.length; - } else { - len = lastRow - firstRow; - } - - if (len != 0) { - if (action.indexOf("remove") != -1) { - this.$wrapData.splice(firstRow, len); - lastRow = firstRow; - } else { - var args = [firstRow, 0]; - for (var i = 0; i < len; i++) args.push([]); - this.$wrapData.splice.apply(this.$wrapData, args); - } - } - - if (this.$wrapData.length != this.doc.$lines.length) { - console.error("The length of doc.$lines and $wrapData have to be the same!"); - } - - this.$updateWrapData(firstRow, lastRow); - }; - - this.$updateWrapData = function(firstRow, lastRow) { - var lines = this.doc.getAllLines(); - var tabSize = this.getTabSize(); - var wrapData = this.$wrapData; - var wrapLimit = this.$wrapLimit; - - for (var row = firstRow; row <= lastRow; row++) { - wrapData[row] = - this.$computeWrapSplits(lines[row], wrapLimit, tabSize); - } - }; - - // "Tokens" - var CHAR = 1, - CHAR_EXT = 2, - SPACE = 3, - TAB = 4, - TAB_SPACE = 5; - - this.$computeWrapSplits = function(textLine, wrapLimit, tabSize) { - textLine = textLine.trimRight(); - if (textLine.length == 0) { - return []; - } - - var tabSize = this.getTabSize(); - var splits = []; - var tokens = this.$getDisplayTokens(textLine); - var displayLength = tokens.length; - var lastSplit = 0, lastDocSplit = 0; - - function addSplit(screenPos) { - var displayed = tokens.slice(lastSplit, screenPos); - - // The document size is the current size - the extra width for tabs - // and multipleWidth characters. - var len = displayed.length; - displayed.join(""). - // Get all the tabs. - replace(/4/g, function(m) { - len -= tabSize - 1; - }). - // Get all the multipleWidth characters. - replace(/2/g, function(m) { - len -= 1; - }); - - lastDocSplit += len; - splits.push(lastDocSplit); - lastSplit = screenPos; - } - - while (displayLength - lastSplit > wrapLimit) { - // This is, where the split should be. - var split = lastSplit + wrapLimit; - - // If there is a space or tab at this split position. - if (tokens[split] >= SPACE) { - // Include all following spaces + tabs in this split as well. - while (tokens[split] >= SPACE) { - split ++; - } - addSplit(split); - } else { - // Search for the first non space/tab token. - for (split; split != lastSplit - 1; split--) { - if (tokens[split] >= SPACE) { - split++; - break; - } - } - // If we found one, then add the split. - if (split > lastSplit) { - addSplit(split); - } - // No space or tab around? Well, force a split then. - else { - addSplit(lastSplit + wrapLimit); - } - } - } - return splits; - } - - this.$getDisplayTokens = function(str) { - var arr = []; - var tabSize = this.getTabSize(); - - for (var i = 0; i < str.length; i++) { - var c = str.charCodeAt(i); - // Tab - if (c == 9) { - arr.push(TAB); - for (var n = 1; n < tabSize; n++) { - arr.push(TAB_SPACE); - } - } - // Space - else if(c == 32) { - arr.push(SPACE); - } - // CJK characters - else if ( - c >= 0x3040 && c <= 0x309F || // Hiragana - c >= 0x30A0 && c <= 0x30FF || // Katakana - c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs - c >= 0xF900 && c <= 0xFAFF || - c >= 0x3400 && c <= 0x4DBF - ) { - arr.push(CHAR, CHAR_EXT); - } else { - arr.push(CHAR); - } - } - 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 int number of columns for str on screen. - */ - this.$getStringScreenWidth = function(str) { - var screenColumn = 0; - var tabSize = this.getTabSize(); - - for (var i=0; i= 0x3040 && c <= 0x309F || // Hiragana - c >= 0x30A0 && c <= 0x30FF || // Katakana - c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs - c >= 0xF900 && c <= 0xFAFF || - c >= 0x3400 && c <= 0x4DBF - ) { - screenColumn += 2; - } else { - screenColumn += 1; - } - } - - return screenColumn; - } - - this.getRowHeight = function(config, row) { - var rows; - if (!this.$useWrapMode || !this.$wrapData[row]) { - rows = 1; - } else { - rows = this.$wrapData[row].length + 1; - } - - return rows * config.lineHeight; - } - - this.getScreenLastRowColumn = function(screenRow, returnDocPosition) { - if (!this.$useWrapMode) { - return this.$getStringScreenWidth(this.getLine(screenRow)); - } - - var rowData = this.$screenToDocumentRow(screenRow); - var docRow = rowData[0], - row = rowData[1]; - - var start, end; - if (this.$wrapData[docRow][row]) { - start = (this.$wrapData[docRow][row - 1] || 0); - end = this.$wrapData[docRow][row]; - returnDocPosition && end--; - } else { - end = this.getLine(docRow).length; - start = (this.$wrapData[docRow][row - 1] || 0); - } - if (!returnDocPosition) { - return this.$getStringScreenWidth(this.getLine(docRow).substring(start, end)); - } else { - return end; - } - }; - - this.getDocumentLastRowColumn = function(docRow, docColumn) { - if (!this.$useWrapMode) { - return this.getLine(docRow).length; - } - - var screenRow = this.documentToScreenRow(docRow, docColumn); - return this.getScreenLastRowColumn(screenRow, true); - } - - this.getScreenFirstRowColumn = function(screenRow) { - if (!this.$useWrapMode) { - return 0; - } - - var rowData = this.$screenToDocumentRow(screenRow); - var docRow = rowData[0], - row = rowData[1]; - - return this.$wrapData[docRow][row - 1] || 0; - }; - - this.getRowSplitData = function(row) { - if (!this.$useWrapMode) { - return undefined; - } else { - return this.$wrapData[row]; - } - }; - - /** - * - * @returns array - * - array[0]: The documentRow equivalent. - * - array[1]: The screenRowOffset to the first documentRow on the screen. - */ - this.$screenToDocumentRow = function(row) { - if (!this.$useWrapMode) { - return [row, 0]; - } - - var wrapData = this.$wrapData, linesCount = this.getLength(); - var docRow = 0; - while (docRow < linesCount && row >= wrapData[docRow].length + 1) { - row -= wrapData[docRow].length + 1; - docRow ++; - } - - return [docRow, row]; - }; - - this.screenToDocumentRow = function(screenRow) { - return this.$screenToDocumentRow(screenRow)[0]; - }; - - this.screenToDocumentColumn = function(screenRow, screenColumn) { - return this.screenToDocumentPosition(screenRow, screenColumn).column; - }; - - this.screenToDocumentPosition = function(row, column) { - var line; - var docRow; - var docColumn; - var remaining = column; - var linesCount = this.getLength(); - if (!this.$useWrapMode) { - docRow = row >= linesCount? linesCount-1 : (row < 0 ? 0 : row); - row = 0; - docColumn = 0; - line = this.getLine(docRow); - } else { - var wrapData = this.$wrapData; - - var docRow = 0; - while (docRow < linesCount && row >= wrapData[docRow].length + 1) { - row -= wrapData[docRow].length + 1; - docRow ++; - } - - if (docRow >= linesCount) { - docRow = linesCount-1 - row = wrapData[docRow].length; - } - docColumn = wrapData[docRow][row - 1] || 0; - line = this.getLine(docRow).substring(docColumn); - } - - var tabSize = this.getTabSize(); - for(var i = 0; i < line.length; i++) { - var c = line.charCodeAt(i); - - if (remaining > 0) { - docColumn += 1; - // tab - if (c == 9) { - if (remaining >= tabSize) { - remaining -= tabSize; - } else { - remaining = 0; - docColumn -= 1; - } - } - // CJK characters - else if ( - c >= 0x3040 && c <= 0x309F || // Hiragana - c >= 0x30A0 && c <= 0x30FF || // Katakana - c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs - c >= 0xF900 && c <= 0xFAFF || - c >= 0x3400 && c <= 0x4DBF - ) { - if (remaining >= 2) { - remaining -= 2; - } else { - remaining = 0; - docColumn -= 1; - } - } else { - remaining -= 1; - } - } else { - break; - } - } - - // Clamp docColumn. - if (this.$useWrapMode) { - column = wrapData[docRow][row] - if (docColumn >= column) { - // We remove one character at the end such that the docColumn - // position returned is not associated to the next row on the - // screen. - docColumn = column - 1; - } - } else if (line) { - docColumn = Math.min(docColumn, line.length); - } - - return { - row: docRow, - column: docColumn - }; - }; - - this.documentToScreenColumn = function(row, docColumn) { - return this.documentToScreenPosition(row, docColumn).column; - }; - - /** - * - * @return array[2] - * - array[0]: The number of the row on the screen (aka screenRow) - * - array[1]: The number of rows from the first docRow on the screen - * (aka screenRowOffset); - */ - this.$documentToScreenRow = function(docRow, docColumn) { - if (!this.$useWrapMode) { - return [docRow, 0]; - } - - var wrapData = this.$wrapData; - var screenRow = 0; - - // Handle special case where the row is outside of the range of lines. - if (docRow > wrapData.length - 1) { - return [ - this.getScreenLength(), - wrapData.length == 0 ? 0 : (wrapData[wrapData.length - 1].length - 1) - ]; - } - - for (var i = 0; i < docRow; i++) { - screenRow += wrapData[i].length + 1; - } - - var screenRowOffset = 0; - while (docColumn >= wrapData[docRow][screenRowOffset]) { - screenRow ++; - screenRowOffset++; - } - - return [screenRow, screenRowOffset]; - } - - this.documentToScreenRow = function(docRow, docColumn) { - return this.$documentToScreenRow(docRow, docColumn)[0]; - } - - this.documentToScreenPosition = function(pos, column) { - var str; - var tabSize = this.getTabSize(); - - // Normalize the passed in arguments. - var row; - if (column != null) { - row = pos; - } else { - row = pos.row; - column = pos.column; - } - - if (!this.$useWrapMode) { - str = this.getLine(row).substring(0, column); - column = this.$getStringScreenWidth(str); - return { - row: row, - column: column - }; - } - - var rowData = this.$documentToScreenRow(row, column); - var screenRow = rowData[0]; - - if (row >= this.getLength()) { - return { - row: screenRow, - column: 0 - }; - } - - var split; - var wrapRowData = this.$wrapData[row]; - var screenColumn; - var screenRowOffset = rowData[1]; - - str = this.getLine(row).substring( - wrapRowData[screenRowOffset - 1] || 0, column); - screenColumn = this.$getStringScreenWidth(str); - - return { - row: screenRow, - column: screenColumn - }; - }; - - this.getScreenLength = function() { - if (!this.$useWrapMode) { - return this.getLength(); - } - - var screenRows = 0; - for (var row = 0; row < this.$wrapData.length; row++) { - screenRows += this.$wrapData[row].length + 1; - } - return screenRows; - } - -}).call(EditSession.prototype); - -exports.EditSession = EditSession; -});/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/selection', function(require, exports, module) { - -var oop = require("pilot/oop"); -var lang = require("pilot/lang"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; -var Range = require("ace/range").Range; -var Anchor = require("ace/anchor").Anchor; - -var Selection = function(session) { - this.session = session; - this.doc = session.getDocument(); - - this.clearSelection(); - this.selectionLead = new Anchor(this.doc, 0, 0); - this.selectionAnchor = new Anchor(this.doc, 0, 0); - - var _self = this; - this.selectionLead.on("change", function(e) { - _self._dispatchEvent("changeCursor"); - if (!_self.$isEmpty) - _self._dispatchEvent("changeSelection"); - if (e.old.row == e.value.row) - _self.$updateDesiredColumn(); - }); - - this.selectionAnchor.on("change", function() { - if (!_self.$isEmpty) - _self._dispatchEvent("changeSelection"); - }); -}; - -(function() { - - oop.implement(this, EventEmitter); - - this.isEmpty = function() { - return (this.$isEmpty || ( - this.selectionAnchor.row == this.selectionLead.row && - this.selectionAnchor.column == this.selectionLead.column - )); - }; - - this.isMultiLine = function() { - if (this.isEmpty()) { - return false; - } - - return this.getRange().isMultiLine(); - }; - - this.getCursor = function() { - return this.selectionLead.getPosition(); - }; - - this.setSelectionAnchor = function(row, column) { - this.selectionAnchor.setPosition(row, column); - - if (this.$isEmpty) { - this.$isEmpty = false; - this._dispatchEvent("changeSelection"); - } - }; - - this.getSelectionAnchor = function() { - if (this.$isEmpty) - return this.getSelectionLead() - else - return this.selectionAnchor.getPosition(); - }; - - this.getSelectionLead = function() { - return this.selectionLead.getPosition(); - }; - - this.shiftSelection = function(columns) { - if (this.$isEmpty) { - this.moveCursorTo(this.selectionLead.row, this.selectionLead.column + columns); - return; - }; - - var anchor = this.getSelectionAnchor(); - var lead = this.getSelectionLead(); - - var isBackwards = this.isBackwards(); - - if (!isBackwards || anchor.column !== 0) - this.setSelectionAnchor(anchor.row, anchor.column + columns); - - if (isBackwards || lead.column !== 0) { - this.$moveSelection(function() { - this.moveCursorTo(lead.row, lead.column + columns); - }); - } - }; - - this.isBackwards = function() { - var anchor = this.selectionAnchor; - var lead = this.selectionLead; - return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column)); - }; - - this.getRange = function() { - var anchor = this.selectionAnchor; - var lead = this.selectionLead; - - if (this.isEmpty()) - return Range.fromPoints(lead, lead); - - if (this.isBackwards()) { - return Range.fromPoints(lead, anchor); - } - else { - return Range.fromPoints(anchor, lead); - } - }; - - this.clearSelection = function() { - if (!this.$isEmpty) { - this.$isEmpty = true; - this._dispatchEvent("changeSelection"); - } - }; - - this.selectAll = function() { - var lastRow = this.doc.getLength() - 1; - this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length); - this.moveCursorTo(0, 0); - }; - - this.setSelectionRange = function(range, reverse) { - if (reverse) { - this.setSelectionAnchor(range.end.row, range.end.column); - this.selectTo(range.start.row, range.start.column); - } else { - this.setSelectionAnchor(range.start.row, range.start.column); - this.selectTo(range.end.row, range.end.column); - } - this.$updateDesiredColumn(); - }; - - this.$updateDesiredColumn = function() { - var cursor = this.getCursor(); - this.$desiredColumn = this.session.documentToScreenColumn(cursor.row, cursor.column); - }; - - this.$moveSelection = function(mover) { - var lead = this.selectionLead; - if (this.$isEmpty) - this.setSelectionAnchor(lead.row, lead.column); - - mover.call(this); - }; - - this.selectTo = function(row, column) { - this.$moveSelection(function() { - this.moveCursorTo(row, column); - }); - }; - - this.selectToPosition = function(pos) { - this.$moveSelection(function() { - this.moveCursorToPosition(pos); - }); - }; - - 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 cursor = this.getCursor(); - var range = this.session.getWordRange(cursor.row, cursor.column); - this.setSelectionRange(range); - }; - - this.selectLine = function() { - this.setSelectionAnchor(this.selectionLead.row, 0); - this.$moveSelection(function() { - this.moveCursorTo(this.selectionLead.row + 1, 0); - }); - }; - - this.moveCursorUp = function() { - this.moveCursorBy(-1, 0); - }; - - this.moveCursorDown = function() { - this.moveCursorBy(1, 0); - }; - - this.moveCursorLeft = function() { - var cursor = this.selectionLead.getPosition(); - if (cursor.column == 0) { - // cursor is a line (start - if (cursor.row > 0) { - this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length); - } - } - else { - var tabSize = this.session.getTabSize(); - if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column-tabSize, cursor.column).split(" ").length-1 == tabSize) - this.moveCursorBy(0, -tabSize); - else - this.moveCursorBy(0, -1); - } - }; - - this.moveCursorRight = function() { - 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 { - var tabSize = this.session.getTabSize(); - var cursor = this.selectionLead; - 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 - this.moveCursorBy(0, 1); - } - }; - - this.moveCursorLineStart = function() { - var row = this.selectionLead.row; - var column = this.selectionLead.column; - var screenRow = this.session.documentToScreenRow(row, column); - var firstRowColumn = this.session.getScreenFirstRowColumn(screenRow); - var beforeCursor = this.doc.getLine(row).slice(firstRowColumn, column); - var leadingSpace = beforeCursor.match(/^\s*/); - if (leadingSpace[0].length == 0) { - var lastRowColumn = this.session.getDocumentLastRowColumn(row, column); - leadingSpace = this.doc.getLine(row). - substring(firstRowColumn, lastRowColumn). - match(/^\s*/); - this.moveCursorTo(row, firstRowColumn + leadingSpace[0].length); - } else if (leadingSpace[0].length >= column) { - this.moveCursorTo(row, firstRowColumn); - } else { - this.moveCursorTo(row, firstRowColumn + leadingSpace[0].length); - } - }; - - this.moveCursorLineEnd = function() { - var lead = this.selectionLead; - this.moveCursorTo(lead.row, this.session.getDocumentLastRowColumn(lead.row, lead.column)); - }; - - this.moveCursorFileEnd = function() { - var row = this.doc.getLength() - 1; - var column = this.doc.getLine(row).length; - this.moveCursorTo(row, column); - }; - - this.moveCursorFileStart = function() { - this.moveCursorTo(0, 0); - }; - - this.moveCursorWordRight = function() { - var row = this.selectionLead.row; - var column = this.selectionLead.column; - var line = this.doc.getLine(row); - var rightOfCursor = line.substring(column); - - var match; - this.session.nonTokenRe.lastIndex = 0; - this.session.tokenRe.lastIndex = 0; - - if (column == line.length) { - this.moveCursorRight(); - return; - } - else if (match = this.session.nonTokenRe.exec(rightOfCursor)) { - column += this.session.nonTokenRe.lastIndex; - this.session.nonTokenRe.lastIndex = 0; - } - else if (match = this.session.tokenRe.exec(rightOfCursor)) { - column += this.session.tokenRe.lastIndex; - this.session.tokenRe.lastIndex = 0; - } - - this.moveCursorTo(row, column); - }; - - this.moveCursorWordLeft = function() { - var row = this.selectionLead.row; - var column = this.selectionLead.column; - var line = this.doc.getLine(row); - var leftOfCursor = lang.stringReverse(line.substring(0, column)); - - var match; - this.session.nonTokenRe.lastIndex = 0; - this.session.tokenRe.lastIndex = 0; - - if (column == 0) { - this.moveCursorLeft(); - return; - } - else if (match = this.session.nonTokenRe.exec(leftOfCursor)) { - column -= this.session.nonTokenRe.lastIndex; - this.session.nonTokenRe.lastIndex = 0; - } - else if (match = this.session.tokenRe.exec(leftOfCursor)) { - column -= this.session.tokenRe.lastIndex; - this.session.tokenRe.lastIndex = 0; - } - - this.moveCursorTo(row, column); - }; - - this.moveCursorBy = function(rows, chars) { - if (this.session.getUseWrapMode()) { - var screenPos = this.session.documentToScreenPosition( - this.selectionLead.row, - this.selectionLead.column - ); - var screenCol = (chars == 0 && this.$desiredColumn) || screenPos.column; - var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenCol); - - this.moveCursorTo(docPos.row, docPos.column + chars, chars == 0); - } else { - var docColumn = (chars == 0 && this.$desiredColumn) || this.selectionLead.column; - this.moveCursorTo(this.selectionLead.row + rows, docColumn + chars, chars == 0); - } - }; - - this.moveCursorToPosition = function(position) { - this.moveCursorTo(position.row, position.column); - }; - - this.moveCursorTo = function(row, column, preventUpdateDesiredColumn) { - this.selectionLead.setPosition(row, column); - if (!preventUpdateDesiredColumn) - this.$updateDesiredColumn(this.selectionLead.column); - }; - - this.moveCursorToScreen = function(row, column, preventUpdateDesiredColumn) { - if (this.session.getUseWrapMode()) { - var pos = this.session.screenToDocumentPosition(row, column); - row = pos.row; - column = pos.column; - } - this.moveCursorTo(row, column, preventUpdateDesiredColumn); - }; - -}).call(Selection.prototype); - -exports.Selection = Selection; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/range', function(require, exports, module) { - -var Range = function(startRow, startColumn, endRow, endColumn) { - this.start = { - row: startRow, - column: startColumn - }; - - this.end = { - row: endRow, - column: endColumn - }; -}; - -(function() { - - this.toString = function() { - return ("Range: [" + this.start.row + "/" + this.start.column + - "] -> [" + this.end.row + "/" + this.end.column + "]"); - }; - - this.contains = function(row, column) { - return this.compare(row, column) == 0; - }; - - this.compare = function(row, column) { - if (!this.isMultiLine()) { - if (row === this.start.row) { - return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0); - }; - } - - if (row < this.start.row) - return -1; - - if (row > this.end.row) - return 1; - - if (this.start.row === row) - return column >= this.start.column ? 0 : -1; - - if (this.end.row === row) - return column <= this.end.column ? 0 : 1; - - return 0; - }; - - this.clipRows = function(firstRow, lastRow) { - if (this.end.row > lastRow) { - var end = { - row: lastRow+1, - column: 0 - }; - } - - if (this.start.row > lastRow) { - var start = { - row: lastRow+1, - column: 0 - }; - } - - if (this.start.row < firstRow) { - var start = { - row: firstRow, - column: 0 - }; - } - - if (this.end.row < firstRow) { - var end = { - row: firstRow, - column: 0 - }; - } - return Range.fromPoints(start || this.start, end || this.end); - }; - - this.extend = function(row, column) { - var cmp = this.compare(row, column); - - if (cmp == 0) - return this; - else if (cmp == -1) - var start = {row: row, column: column}; - else - var end = {row: row, column: column}; - - return Range.fromPoints(start || this.start, end || this.end); - }; - - this.isEmpty = function() { - return (this.start.row == this.end.row && this.start.column == this.end.column); - }; - - this.isMultiLine = function() { - return (this.start.row !== this.end.row); - }; - - this.clone = function() { - return Range.fromPoints(this.start, this.end); - }; - - 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) - else - return new Range(this.start.row, 0, this.end.row, 0) - }; - - this.toScreenRange = function(session) { - var screenPosStart = - session.documentToScreenPosition(this.start); - var screenPosEnd = - session.documentToScreenPosition(this.end); - return new Range( - screenPosStart.row, screenPosStart.column, - screenPosEnd.row, screenPosEnd.column - ); - }; - -}).call(Range.prototype); - - -Range.fromPoints = function(start, end) { - return new Range(start.row, start.column, end.row, end.column); -}; - -exports.Range = Range; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/anchor', function(require, exports, module) { - -var oop = require("pilot/oop"); -var EventEmitter = require("pilot/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 - */ -var Anchor = exports.Anchor = function(doc, row, column) { - this.document = doc; - - if (typeof column == "undefined") - this.setPosition(row.row, row.column) - else - this.setPosition(row, column); - - this.$onChange = this.onChange.bind(this); - doc.on("change", this.$onChange); -}; - -(function() { - - oop.implement(this, EventEmitter); - - this.getPosition = function() { - return this.$clipPositionToDocument(this.row, this.column); - }; - - this.getDocument = function() { - return this.document; - }; - - this.onChange = function(e) { - var delta = e.data; - var range = delta.range; - - if (range.start.row == range.end.row && range.start.row != this.row) - return; - - if (range.start.row > this.row) - return; - - if (range.start.row == this.row && range.start.column > this.column) - return; - - var row = this.row; - var column = this.column; - - if (delta.action === "insertText") { - if (range.start.row === row && range.start.column <= column) { - if (range.start.row === range.end.row) { - column += range.end.column - range.start.column; - } - else { - column -= range.start.column; - row += range.end.row - range.start.row; - } - } - else if (range.start.row !== range.end.row && range.start.row < row) { - row += range.end.row - range.start.row; - } - } else if (delta.action === "insertLines") { - if (range.start.row <= row) { - row += range.end.row - range.start.row; - } - } - else if (delta.action == "removeText") { - if (range.start.row == row && range.start.column < column) { - if (range.end.column >= column) - column = range.start.column; - else - column = Math.max(0, column - (range.end.column - range.start.column)); - - } else if (range.start.row !== range.end.row && range.start.row < row) { - if (range.end.row == row) { - column = Math.max(0, column - range.end.column) + range.start.column; - } - row -= (range.end.row - range.start.row); - } - else if (range.end.row == row) { - row -= range.end.row - range.start.row; - column = Math.max(0, column - range.end.column) + range.start.column; - } - } else if (delta.action == "removeLines") { - if (range.start.row <= row) { - if (range.end.row <= row) - row -= range.end.row - range.start.row; - else { - row = range.start.row; - column = 0; - } - } - } - - this.setPosition(row, column); - }; - - this.setPosition = function(row, column) { - pos = this.$clipPositionToDocument(row, column); - if (this.row == pos.row && this.column == pos.column) - return; - - var old = { - row: this.row, - column: this.column - }; - - this.row = pos.row; - this.column = pos.column; - this._dispatchEvent("change", { - old: old, - value: pos - }); - }; - - this.detach = function() { - this.document.removeEventListener("change", this.$onChange); - }; - - this.$clipPositionToDocument = function(row, column) { - var pos = {}; - - if (row >= this.document.getLength()) { - pos.row = Math.max(0, this.document.getLength() - 1); - pos.column = this.document.getLine(pos.row).length; - } - else if (row < 0) { - pos.row = 0; - pos.column = 0; - } - else { - pos.row = row; - pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column)); - } - - if (column < 0) - pos.column = 0; - - return pos; - }; - -}).call(Anchor.prototype); - -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Mihai Sucan - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/mode/text', function(require, exports, module) { - -var Tokenizer = require("ace/tokenizer").Tokenizer; -var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; - -var Mode = function() { - this.$tokenizer = new Tokenizer(new TextHighlightRules().getRules()); -}; - -(function() { - - this.getTokenizer = function() { - return this.$tokenizer; - }; - - this.toggleCommentLines = function(state, doc, startRow, endRow) { - }; - - this.getNextLineIndent = function(state, line, tab) { - return ""; - }; - - this.checkOutdent = function(state, line, input) { - return false; - }; - - this.autoOutdent = function(state, doc, row) { - }; - - this.$getIndent = function(line) { - var match = line.match(/^(\s+)/); - if (match) { - return match[1]; - } - - return ""; - }; - - this.createWorker = function(session) { - return null; - }; - - this.highlightSelection = function(editor) { - var session = editor.session; - if (!session.$selectionOccurrences) - session.$selectionOccurrences = []; - - if (session.$selectionOccurrences.length) - this.clearSelectionHighlight(editor); - - var selection = editor.getSelectionRange(); - if (selection.isEmpty() || selection.isMultiLine()) - return; - - var startOuter = selection.start.column - 1; - var endOuter = selection.end.column + 1; - var line = session.getLine(selection.start.row); - var lineCols = line.length - 1; - var needle = line.substring(Math.max(startOuter, 0), - Math.min(endOuter, lineCols)); - - // Make sure the outer characters are not part of the word. - if ((startOuter >= 0 && !/[^\w\d]/.test(needle.charAt(0))) || - (endOuter <= lineCols && !/[^\w\d]/.test(needle.charAt(needle.length - 1)))) - return; - - needle = line.substring(selection.start.column, selection.end.column); - if (!/^[\w\d]+$/.test(needle)) - return; - - var newOptions = { - wrap: true, - wholeWord: true, - needle: needle - }; - - var currentOptions = editor.$search.getOptions(); - editor.$search.set(newOptions); - - var ranges = editor.$search.findAll(session); - session.$selectionOccurrences = []; - ranges.forEach(function(range) { - if (!range.contains(selection.start.row, selection.start.column)) { - var marker = session.addMarker(range, "ace_selected_word"); - session.$selectionOccurrences.push(marker); - } - }); - - editor.$search.set(currentOptions); - }; - - this.clearSelectionHighlight = function(editor) { - if (!editor.session.$selectionOccurrences) - return; - - editor.session.$selectionOccurrences.forEach(function(marker) { - editor.session.removeMarker(marker); - }); - }; - -}).call(Mode.prototype); - -exports.Mode = Mode; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/tokenizer', function(require, exports, module) { - -var Tokenizer = function(rules) { - this.rules = rules; - - this.regExps = {}; - for ( var key in this.rules) { - var state = this.rules[key]; - var ruleRegExps = []; - - for ( var i = 0; i < state.length; i++) { - ruleRegExps.push(state[i].regex); - }; - - this.regExps[key] = new RegExp("(?:(" + ruleRegExps.join(")|(") + ")|(.))", "g"); - } -}; - -(function() { - - this.getLineTokens = function(line, startState) { - var currentState = startState; - var state = this.rules[currentState]; - var re = this.regExps[currentState]; - re.lastIndex = 0; - - var match, tokens = []; - - var lastIndex = 0; - - var token = { - type: null, - value: "" - }; - - while (match = re.exec(line)) { - var type = "text"; - var value = match[0]; - - for ( var i = 0; i < state.length; i++) { - if (match[i + 1]) { - if (typeof state[i].token == "function") { - type = state[i].token(match[0]); - } - else { - type = state[i].token; - } - - if (state[i].next && state[i].next !== currentState) { - currentState = state[i].next; - var state = this.rules[currentState]; - var lastIndex = re.lastIndex; - - var re = this.regExps[currentState]; - re.lastIndex = lastIndex; - } - break; - } - }; - - - if (token.type !== type) { - if (token.type) { - tokens.push(token); - } - token = { - type: type, - value: value - }; - } else { - token.value += value; - } - - if (lastIndex == line.length) { - break; - } - - lastIndex = re.lastIndex; - }; - - if (token.type) { - tokens.push(token); - } - - return { - tokens : tokens, - state : currentState - }; - }; - -}).call(Tokenizer.prototype); - -exports.Tokenizer = Tokenizer; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/mode/text_highlight_rules', function(require, exports, module) { - -var TextHighlightRules = function() { - - // regexp must not have capturing parentheses - // regexps are ordered -> the first match is used - - this.$rules = { - "start" : [ { - token : "empty_line", - regex : '^$' - }, { - token : "text", - regex : ".+" - } ] - }; -}; - -(function() { - - this.addRules = function(rules, prefix) { - for (var key in rules) { - var state = rules[key]; - for (var i=0; i - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/document', function(require, exports, module) { - -var oop = require("pilot/oop"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; -var Range = require("ace/range").Range; - -var Document = function(text) { - this.$lines = []; - - if (Array.isArray(text)) { - this.insertLines(0, text); - } - // There has to be one line at least in the document. If you pass an empty - // string to the insert function, nothing will happen. Workaround. - else if (text.length == 0) { - this.$lines = [""]; - } else { - this.insert({row: 0, column:0}, text); - } -}; - -(function() { - - oop.implement(this, EventEmitter); - - 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); - }; - - this.getValue = function() { - return this.getAllLines().join(this.getNewLineCharacter()); - }; - - // check for IE split bug - if ("aaa".split(/a/).length == 0) - this.$split = function(text) { - return text.replace(/\r\n|\r/g, "\n").split("\n"); - } - else - this.$split = function(text) { - return text.split(/\r\n|\r|\n/); - }; - - - this.$detectNewLine = function(text) { - var match = text.match(/^.*?(\r?\n)/m); - if (match) { - this.$autoNewLine = match[1]; - } else { - this.$autoNewLine = "\n"; - } - }; - - this.getNewLineCharacter = function() { - switch (this.$newLineMode) { - case "windows": - return "\r\n"; - - case "unix": - return "\n"; - - case "auto": - return this.$autoNewLine; - } - }, - - this.$autoNewLine = "\n"; - this.$newLineMode = "auto"; - this.setNewLineMode = function(newLineMode) { - if (this.$newLineMode === newLineMode) return; - - this.$newLineMode = newLineMode; - }; - - this.getNewLineMode = function() { - return this.$newLineMode; - }; - - 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 - */ - this.getLine = function(row) { - return this.getLines(row, row + 1)[0] || ""; - }; - - 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! - */ - this.getAllLines = function() { - return this.getLines(0, this.getLength()); - }; - - this.getLength = function() { - return this.$lines.length; - }; - - 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)); - return lines.join(this.getNewLineCharacter()); - } - }; - - this.$clipPosition = function(position) { - var length = this.getLength(); - if (position.row >= length) { - position.row = Math.max(0, length - 1); - position.column = this.getLine(length-1).length; - } - return position; - } - - this.insert = function(position, text) { - if (text.length == 0) - return position; - - position = this.$clipPosition(position); - - if (this.getLength() <= 1) - this.$detectNewLine(text); - - var newLines = this.$split(text); - - if (this.isNewLine(text)) { - var end = this.insertNewLine(position); - } - else if (newLines.length == 1) { - var end = this.insertInLine(position, text); - } - else { - if (newLines[0].length > 0) { - var end = this.insertInLine(position, newLines[0]); - this.insertNewLine(end); - } - // If we are inserting at the end of the document, we don't need to - // use insertInLine (concorde depends on this optimization!) - if (position.row + 1 == this.getLength()) { - this.insertLines(position.row + 1, - newLines.slice(1, newLines.length)); - var end = { - row: position.row + newLines.length - 1, - column: position.column + newLines[newLines.length - 1].length - }; - } else { - if (newLines.length > 2) - this.insertLines(position.row + 1, - newLines.slice(1, newLines.length - 1)); - var end = this.insertInLine({ - row: position.row + newLines.length - 1, - column: 0 - }, newLines[newLines.length - 1]); - } - } - return end; - }; - - this.insertLines = function(row, lines) { - if (lines.length == 0) - return {row: row, column: 0}; - - var args = [row, 0]; - args.push.apply(args, lines); - this.$lines.splice.apply(this.$lines, args); - - var range = new Range(row, 0, row + lines.length, 0); - var delta = { - action: "insertLines", - range: range, - lines: lines - }; - this._dispatchEvent("change", { data: delta }); - return range.end; - }, - - this.insertNewLine = function(position) { - position = this.$clipPosition(position); - var line = this.$lines[position.row] || ""; - this.$lines[position.row] = line.substring(0, position.column); - this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length)); - - var end = { - row : position.row + 1, - column : 0 - }; - - var delta = { - action: "insertText", - range: Range.fromPoints(position, end), - text: this.getNewLineCharacter() - }; - this._dispatchEvent("change", { data: delta }); - - return end; - }; - - this.insertInLine = function(position, text) { - if (text.length == 0) - return position; - - var line = this.$lines[position.row] || ""; - this.$lines[position.row] = line.substring(0, position.column) + text - + line.substring(position.column); - - var end = { - row : position.row, - column : position.column + text.length - }; - - var delta = { - action: "insertText", - range: Range.fromPoints(position, end), - text: text - }; - this._dispatchEvent("change", { data: delta }); - - return end; - }; - - this.remove = function(range) { - // clip to document - range.start = this.$clipPosition(range.start); - range.end = this.$clipPosition(range.end); - - if (range.isEmpty()) - return range.start; - - var firstRow = range.start.row; - var lastRow = range.end.row; - - if (range.isMultiLine()) { - var firstFullRow = range.start.column == 0 ? firstRow : firstRow + 1; - var lastFullRow = lastRow - 1; - - if (range.end.column > 0) - this.removeInLine(lastRow, 0, range.end.column); - - if (lastFullRow >= firstFullRow) - this.removeLines(firstFullRow, lastFullRow); - - if (firstFullRow != firstRow) { - this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length); - this.removeNewLine(range.start.row); - } - } - else { - this.removeInLine(firstRow, range.start.column, range.end.column); - } - return range.start; - }; - - this.removeInLine = function(row, startColumn, endColumn) { - if (startColumn == endColumn) - return; - - var range = new Range(row, startColumn, row, endColumn); - var line = this.getLine(row); - var removed = line.substring(startColumn, endColumn); - var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length); - this.$lines.splice(row, 1, newLine); - - var delta = { - action: "removeText", - range: range, - text: removed - }; - this._dispatchEvent("change", { data: delta }); - return range.start; - }; - - /** - * 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 - */ - this.removeLines = function(firstRow, lastRow) { - var range = new Range(firstRow, 0, lastRow + 1, 0); - var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1); - - var delta = { - action: "removeLines", - range: range, - nl: this.getNewLineCharacter(), - lines: removed - }; - this._dispatchEvent("change", { data: delta }); - return removed; - }; - - this.removeNewLine = function(row) { - var firstLine = this.getLine(row); - var secondLine = this.getLine(row+1); - - var range = new Range(row, firstLine.length, row+1, 0); - var line = firstLine + secondLine; - - this.$lines.splice(row, 2, line); - - var delta = { - action: "removeText", - range: range, - text: this.getNewLineCharacter() - }; - this._dispatchEvent("change", { data: delta }); - }; - - this.replace = function(range, text) { - if (text.length == 0 && range.isEmpty()) - return range.start; - - // Shortcut: If the text we want to insert is the same as it is already - // in the document, we don't have to replace anything. - if (text == this.getTextRange(range)) - return range.end; - - this.remove(range); - if (text) { - var end = this.insert(range.start, text); - } - else { - end = range.start; - } - - return end; - }; - - this.applyDeltas = function(deltas) { - for (var i=0; i=0; i--) { - var delta = deltas[i]; - var range = Range.fromPoints(delta.range.start, delta.range.end); - - if (delta.action == "insertLines") - this.removeLines(range.start.row, range.end.row - 1) - else if (delta.action == "insertText") - this.remove(range) - else if (delta.action == "removeLines") - this.insertLines(range.start.row, delta.lines) - else if (delta.action == "removeText") - this.insert(range.start, delta.text) - } - }; - -}).call(Document.prototype); - -exports.Document = Document; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/search', function(require, exports, module) { - -var lang = require("pilot/lang"); -var oop = require("pilot/oop"); -var Range = require("ace/range").Range; - -var Search = function() { - this.$options = { - needle: "", - backwards: false, - wrap: false, - caseSensitive: false, - wholeWord: false, - scope: Search.ALL, - regExp: false - }; -}; - -Search.ALL = 1; -Search.SELECTION = 2; - -(function() { - - this.set = function(options) { - oop.mixin(this.$options, options); - return this; - }; - - this.getOptions = function() { - return lang.copyObject(this.$options); - }; - - this.find = function(session) { - if (!this.$options.needle) - return null; - - if (this.$options.backwards) { - var iterator = this.$backwardMatchIterator(session); - } else { - iterator = this.$forwardMatchIterator(session); - } - - var firstRange = null; - iterator.forEach(function(range) { - firstRange = range; - return true; - }); - - return firstRange; - }; - - this.findAll = function(session) { - if (!this.$options.needle) - return []; - - if (this.$options.backwards) { - var iterator = this.$backwardMatchIterator(session); - } else { - iterator = this.$forwardMatchIterator(session); - } - - var ranges = []; - iterator.forEach(function(range) { - ranges.push(range); - }); - - return ranges; - }; - - this.replace = function(input, replacement) { - var re = this.$assembleRegExp(); - var match = re.exec(input); - if (match && match[0].length == input.length) { - if (this.$options.regExp) { - return input.replace(re, replacement); - } else { - return replacement; - } - } else { - return null; - } - }; - - this.$forwardMatchIterator = function(session) { - var re = this.$assembleRegExp(); - var self = this; - - return { - forEach: function(callback) { - self.$forwardLineIterator(session).forEach(function(line, startIndex, row) { - if (startIndex) { - line = line.substring(startIndex); - } - - var matches = []; - - line.replace(re, function(str) { - var offset = arguments[arguments.length-2]; - matches.push({ - str: str, - offset: startIndex + offset - }); - return str; - }); - - for (var i=0; i= 0; i--) { - var match = matches[i]; - var range = self.$rangeFromMatch(row, match.offset, match.str.length); - if (callback(range)) - return true; - } - }); - } - }; - }; - - this.$rangeFromMatch = function(row, column, length) { - return new Range(row, column, row, column+length); - }; - - this.$assembleRegExp = function() { - if (this.$options.regExp) { - var needle = this.$options.needle; - } else { - needle = lang.escapeRegExp(this.$options.needle); - } - - if (this.$options.wholeWord) { - needle = "\\b" + needle + "\\b"; - } - - var modifier = "g"; - if (!this.$options.caseSensitive) { - modifier += "i"; - } - - var re = new RegExp(needle, modifier); - return re; - }; - - this.$forwardLineIterator = function(session) { - var searchSelection = this.$options.scope == Search.SELECTION; - - var range = session.getSelection().getRange(); - var start = session.getSelection().getCursor(); - - var firstRow = searchSelection ? range.start.row : 0; - var firstColumn = searchSelection ? range.start.column : 0; - var lastRow = searchSelection ? range.end.row : session.getLength() - 1; - - var wrap = this.$options.wrap; - - function getLine(row) { - var line = session.getLine(row); - if (searchSelection && row == range.end.row) { - line = line.substring(0, range.end.column); - } - return line; - } - - return { - forEach: function(callback) { - var row = start.row; - - var line = getLine(row); - var startIndex = start.column; - - var stop = false; - - while (!callback(line, startIndex, row)) { - - if (stop) { - return; - } - - row++; - startIndex = 0; - - if (row > lastRow) { - if (wrap) { - row = firstRow; - startIndex = firstColumn; - } else { - return; - } - } - - if (row == start.row) - stop = true; - - line = getLine(row); - } - } - }; - }; - - this.$backwardLineIterator = function(session) { - var searchSelection = this.$options.scope == Search.SELECTION; - - var range = session.getSelection().getRange(); - var start = searchSelection ? range.end : range.start; - - var firstRow = searchSelection ? range.start.row : 0; - var firstColumn = searchSelection ? range.start.column : 0; - var lastRow = searchSelection ? range.end.row : session.getLength() - 1; - - var wrap = this.$options.wrap; - - return { - forEach : function(callback) { - var row = start.row; - - var line = session.getLine(row).substring(0, start.column); - var startIndex = 0; - var stop = false; - - while (!callback(line, startIndex, row)) { - - if (stop) - return; - - row--; - startIndex = 0; - - if (row < firstRow) { - if (wrap) { - row = lastRow; - } else { - return; - } - } - - if (row == start.row) - stop = true; - - line = session.getLine(row); - if (searchSelection) { - if (row == firstRow) - startIndex = firstColumn; - else if (row == lastRow) - line = line.substring(0, range.end.column); - } - } - } - }; - }; - -}).call(Search.prototype); - -exports.Search = Search; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/background_tokenizer', function(require, exports, module) { - -var oop = require("pilot/oop"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; - -var BackgroundTokenizer = function(tokenizer, editor) { - this.running = false; - this.lines = []; - this.currentLine = 0; - this.tokenizer = tokenizer; - - var self = this; - - this.$worker = function() { - if (!self.running) { return; } - - var workerStart = new Date(); - var startLine = self.currentLine; - var doc = self.doc; - - var processedLines = 0; - var lastVisibleRow = editor.getLastVisibleRow(); - - var len = doc.getLength(); - while (self.currentLine < len) { - self.lines[self.currentLine] = self.$tokenizeRows(self.currentLine, self.currentLine)[0]; - self.currentLine++; - - // only check every 5 lines - processedLines += 1; - if ((processedLines % 5 == 0) && (new Date() - workerStart) > 20) { - self.fireUpdateEvent(startLine, self.currentLine-1); - - var timeout = self.currentLine < lastVisibleRow ? 20 : 100; - self.running = setTimeout(self.$worker, timeout); - return; - } - } - - self.running = false; - - self.fireUpdateEvent(startLine, len - 1); - }; -}; - -(function(){ - - oop.implement(this, EventEmitter); - - this.setTokenizer = function(tokenizer) { - this.tokenizer = tokenizer; - this.lines = []; - - this.start(0); - }; - - this.setDocument = function(doc) { - this.doc = doc; - this.lines = []; - - this.stop(); - }; - - this.fireUpdateEvent = function(firstRow, lastRow) { - var data = { - first: firstRow, - last: lastRow - }; - this._dispatchEvent("update", {data: data}); - }; - - this.start = function(startRow) { - this.currentLine = Math.min(startRow || 0, this.currentLine, - this.doc.getLength()); - - // remove all cached items below this line - this.lines.splice(this.currentLine, this.lines.length); - - this.stop(); - // pretty long delay to prevent the tokenizer from interfering with the user - this.running = setTimeout(this.$worker, 700); - }; - - this.stop = function() { - if (this.running) - clearTimeout(this.running); - this.running = false; - }; - - this.getTokens = function(firstRow, lastRow) { - return this.$tokenizeRows(firstRow, lastRow); - }; - - this.getState = function(row) { - return this.$tokenizeRows(row, row)[0].state; - }; - - this.$tokenizeRows = function(firstRow, lastRow) { - if (!this.doc) - return []; - - var rows = []; - - // determine start state - var state = "start"; - var doCache = false; - if (firstRow > 0 && this.lines[firstRow - 1]) { - state = this.lines[firstRow - 1].state; - doCache = true; - } - - var lines = this.doc.getLines(firstRow, lastRow); - for (var row=firstRow; row<=lastRow; row++) { - if (!this.lines[row]) { - var tokens = this.tokenizer.getLineTokens(lines[row-firstRow] || "", state); - var state = tokens.state; - rows.push(tokens); - - if (doCache) { - this.lines[row] = tokens; - } - } - else { - var tokens = this.lines[row]; - state = tokens.state; - rows.push(tokens); - } - } - return rows; - }; - -}).call(BackgroundTokenizer.prototype); - -exports.BackgroundTokenizer = BackgroundTokenizer; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/undomanager', function(require, exports, module) { - -var UndoManager = function() { - this.$undoStack = []; - this.$redoStack = []; -}; - -(function() { - - this.execute = function(options) { - var deltas = options.args[0]; - this.$doc = options.args[1]; - this.$undoStack.push(deltas); - }; - - this.undo = function() { - var deltas = this.$undoStack.pop(); - if (deltas) { - this.$doc.undoChanges(deltas); - this.$redoStack.push(deltas); - } - }; - - this.redo = function() { - var deltas = this.$redoStack.pop(); - if (deltas) { - this.$doc.redoChanges(deltas); - this.$undoStack.push(deltas); - } - }; - -}).call(UndoManager.prototype); - -exports.UndoManager = UndoManager; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/theme/textmate', function(require, exports, module) { - - var dom = require("pilot/dom"); - - var cssText = ".ace-tm .ace_editor {\ - border: 2px solid rgb(159, 159, 159);\ -}\ -\ -.ace-tm .ace_editor.ace_focus {\ - border: 2px solid #327fbd;\ -}\ -\ -.ace-tm .ace_gutter {\ - width: 50px;\ - background: #e8e8e8;\ - color: #333;\ - overflow : hidden;\ -}\ -\ -.ace-tm .ace_gutter-layer {\ - width: 100%;\ - text-align: right;\ -}\ -\ -.ace-tm .ace_gutter-layer .ace_gutter-cell {\ - padding-right: 6px;\ -}\ -\ -.ace-tm .ace_print_margin {\ - width: 1px;\ - background: #e8e8e8;\ -}\ -\ -.ace-tm .ace_text-layer {\ - cursor: text;\ -}\ -\ -.ace-tm .ace_cursor {\ - border-left: 2px solid black;\ -}\ -\ -.ace-tm .ace_cursor.ace_overwrite {\ - border-left: 0px;\ - border-bottom: 1px solid black;\ -}\ - \ -.ace-tm .ace_line .ace_invisible {\ - color: rgb(191, 191, 191);\ -}\ -\ -.ace-tm .ace_line .ace_keyword {\ - color: blue;\ -}\ -\ -.ace-tm .ace_line .ace_constant.ace_buildin {\ - color: rgb(88, 72, 246);\ -}\ -\ -.ace-tm .ace_line .ace_constant.ace_language {\ - color: rgb(88, 92, 246);\ -}\ -\ -.ace-tm .ace_line .ace_constant.ace_library {\ - color: rgb(6, 150, 14);\ -}\ -\ -.ace-tm .ace_line .ace_invalid {\ - background-color: rgb(153, 0, 0);\ - color: white;\ -}\ -\ -.ace-tm .ace_line .ace_support.ace_function {\ - color: rgb(60, 76, 114);\ -}\ -\ -.ace-tm .ace_line .ace_support.ace_constant {\ - color: rgb(6, 150, 14);\ -}\ -\ -.ace-tm .ace_line .ace_support.ace_type,\ -.ace-tm .ace_line .ace_support.ace_class {\ - color: rgb(109, 121, 222);\ -}\ -\ -.ace-tm .ace_line .ace_keyword.ace_operator {\ - color: rgb(104, 118, 135);\ -}\ -\ -.ace-tm .ace_line .ace_string {\ - color: rgb(3, 106, 7);\ -}\ -\ -.ace-tm .ace_line .ace_comment {\ - color: rgb(76, 136, 107);\ -}\ -\ -.ace-tm .ace_line .ace_comment.ace_doc {\ - color: rgb(0, 102, 255);\ -}\ -\ -.ace-tm .ace_line .ace_comment.ace_doc.ace_tag {\ - color: rgb(128, 159, 191);\ -}\ -\ -.ace-tm .ace_line .ace_constant.ace_numeric {\ - color: rgb(0, 0, 205);\ -}\ -\ -.ace-tm .ace_line .ace_variable {\ - color: rgb(49, 132, 149);\ -}\ -\ -.ace-tm .ace_line .ace_xml_pe {\ - color: rgb(104, 104, 91);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_selection {\ - background: rgb(181, 213, 255);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_step {\ - background: rgb(252, 255, 0);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_stack {\ - background: rgb(164, 229, 101);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_bracket {\ - margin: -1px 0 0 -1px;\ - border: 1px solid rgb(192, 192, 192);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_active_line {\ - background: rgb(232, 242, 254);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_selected_word {\ - background: rgb(250, 250, 255);\ - border: 1px solid rgb(200, 200, 250);\ -}\ -\ -.ace-tm .ace_string.ace_regex {\ - color: rgb(255, 0, 0)\ -}"; - - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "ace-tm"; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/mode/matching_brace_outdent', function(require, exports, module) { - -var Range = require("ace/range").Range; - -var MatchingBraceOutdent = function() {}; - -(function() { - - this.checkOutdent = function(line, input) { - if (! /^\s+$/.test(line)) - return false; - - return /^\s*\}/.test(input); - }; - - this.autoOutdent = function(doc, row) { - var line = doc.getLine(row); - var match = line.match(/^(\s*\})/); - - if (!match) return 0; - - var column = match[1].length; - var openBracePos = doc.findMatchingBracket({row: row, column: column}); - - if (!openBracePos || openBracePos.row == row) return 0; - - var indent = this.$getIndent(doc.getLine(openBracePos.row)); - doc.replace(new Range(row, 0, row, column-1), indent); - }; - - this.$getIndent = function(line) { - var match = line.match(/^(\s+)/); - if (match) { - return match[1]; - } - - return ""; - }; - -}).call(MatchingBraceOutdent.prototype); - -exports.MatchingBraceOutdent = MatchingBraceOutdent; -}); -/* vim:ts=4:sts=4:sw=4: - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Irakli Gozalishvili (http://jeditoolkit.com) - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/virtual_renderer', function(require, exports, module) { - -var oop = require("pilot/oop"); -var dom = require("pilot/dom"); -var event = require("pilot/event"); -var useragent = require("pilot/useragent"); -var GutterLayer = require("ace/layer/gutter").Gutter; -var MarkerLayer = require("ace/layer/marker").Marker; -var TextLayer = require("ace/layer/text").Text; -var CursorLayer = require("ace/layer/cursor").Cursor; -var ScrollBar = require("ace/scrollbar").ScrollBar; -var RenderLoop = require("ace/renderloop").RenderLoop; -var EventEmitter = require("pilot/event_emitter").EventEmitter; -var editorCss = require("text!ace/css/editor.css"); - -// import CSS once -dom.importCssString(editorCss); - -var VirtualRenderer = function(container, theme) { - this.container = container; - dom.addCssClass(this.container, "ace_editor"); - - this.setTheme(theme); - - this.$gutter = document.createElement("div"); - this.$gutter.className = "ace_gutter"; - this.container.appendChild(this.$gutter); - - this.scroller = document.createElement("div"); - this.scroller.className = "ace_scroller"; - this.container.appendChild(this.scroller); - - this.content = document.createElement("div"); - this.content.className = "ace_content"; - this.scroller.appendChild(this.content); - - this.$gutterLayer = new GutterLayer(this.$gutter); - this.$markerBack = new MarkerLayer(this.content); - - var textLayer = this.$textLayer = new TextLayer(this.content); - this.canvas = textLayer.element; - - this.$markerFront = new MarkerLayer(this.content); - - this.characterWidth = textLayer.getCharacterWidth(); - this.lineHeight = textLayer.getLineHeight(); - - this.$cursorLayer = new CursorLayer(this.content); - this.$cursorPadding = 8; - - this.scrollBar = new ScrollBar(container); - this.scrollBar.addEventListener("scroll", this.onScroll.bind(this)); - - this.scrollTop = 0; - - this.cursorPos = { - row : 0, - column : 0 - }; - - var _self = this; - this.$textLayer.addEventListener("changeCharaterSize", function() { - _self.characterWidth = textLayer.getCharacterWidth(); - _self.lineHeight = textLayer.getLineHeight(); - _self.$updatePrintMargin(); - _self.onResize(true); - - _self.$loop.schedule(_self.CHANGE_FULL); - }); - event.addListener(this.$gutter, "click", this.$onGutterClick.bind(this)); - event.addListener(this.$gutter, "dblclick", this.$onGutterClick.bind(this)); - - this.$size = { - width: 0, - height: 0, - scrollerHeight: 0, - scrollerWidth: 0 - }; - - this.$loop = new RenderLoop(this.$renderChanges.bind(this)); - this.$loop.schedule(this.CHANGE_FULL); - - this.setPadding(4); - this.$updatePrintMargin(); -}; - -(function() { - this.showGutter = true; - - 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; - - oop.implement(this, EventEmitter); - - this.setSession = function(session) { - this.session = session; - 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 - */ - this.updateLines = function(firstRow, lastRow) { - if (lastRow === undefined) - lastRow = Infinity; - - if (!this.$changedLines) { - this.$changedLines = { - firstRow: firstRow, - lastRow: lastRow - }; - } - else { - if (this.$changedLines.firstRow > firstRow) - this.$changedLines.firstRow = firstRow; - - if (this.$changedLines.lastRow < lastRow) - this.$changedLines.lastRow = lastRow; - } - - this.$loop.schedule(this.CHANGE_LINES); - }; - - /** - * Triggers full update of the text layer - */ - this.updateText = function() { - this.$loop.schedule(this.CHANGE_TEXT); - }; - - /** - * Triggers a full update of all layers - */ - this.updateFull = function() { - this.$loop.schedule(this.CHANGE_FULL); - }; - - /** - * Triggers resize of the editor - */ - this.onResize = function(force) { - var changes = this.CHANGE_SIZE; - - var height = dom.getInnerHeight(this.container); - if (force || this.$size.height != height) { - this.$size.height = height; - - this.scroller.style.height = height + "px"; - this.scrollBar.setHeight(height); - - if (this.session) { - this.scrollToY(this.getScrollTop()); - changes = changes | this.CHANGE_FULL; - } - } - - var width = dom.getInnerWidth(this.container); - if (force || this.$size.width != width) { - this.$size.width = width; - - var gutterWidth = this.showGutter ? this.$gutter.offsetWidth : 0; - this.scroller.style.left = gutterWidth + "px"; - this.scroller.style.width = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()) + "px"; - - if (this.session.getUseWrapMode()) { - var availableWidth = this.scroller.clientWidth - this.$padding * 2; - var limit = Math.floor(availableWidth / this.characterWidth) - 1; - if (this.session.adjustWrapLimit(limit) || force) { - changes = changes | this.CHANGE_FULL; - } - } - } - - this.$size.scrollerWidth = this.scroller.clientWidth; - this.$size.scrollerHeight = this.scroller.clientHeight; - this.$loop.schedule(changes); - }; - - this.setTokenizer = function(tokenizer) { - this.$tokenizer = tokenizer; - this.$textLayer.setTokenizer(tokenizer); - this.$loop.schedule(this.CHANGE_TEXT); - }; - - this.$onGutterClick = function(e) { - var pageX = event.getDocumentX(e); - var pageY = event.getDocumentY(e); - - this._dispatchEvent("gutter" + e.type, { - row: this.screenToTextCoordinates(pageX, pageY).row, - htmlEvent: e - }); - }; - - this.setShowInvisibles = function(showInvisibles) { - if (this.$textLayer.setShowInvisibles(showInvisibles)) - this.$loop.schedule(this.CHANGE_TEXT); - }; - - this.getShowInvisibles = function() { - return this.$textLayer.showInvisibles; - }; - - this.$showPrintMargin = true; - this.setShowPrintMargin = function(showPrintMargin) { - this.$showPrintMargin = showPrintMargin; - this.$updatePrintMargin(); - }; - - this.getShowPrintMargin = function() { - return this.$showPrintMargin; - }; - - this.$printMarginColumn = 80; - this.setPrintMarginColumn = function(showPrintMargin) { - this.$printMarginColumn = showPrintMargin; - this.$updatePrintMargin(); - }; - - this.getPrintMarginColumn = function() { - return this.$printMarginColumn; - }; - - this.setShowGutter = function(show){ - if(this.showGutter === show) - return; - this.$gutter.style.display = show ? "block" : "none"; - this.showGutter = show; - this.onResize(true); - } - - this.$updatePrintMargin = function() { - var containerEl - - if (!this.$showPrintMargin && !this.$printMarginEl) - return; - - if (!this.$printMarginEl) { - containerEl = document.createElement("div"); - containerEl.className = "ace_print_margin_layer"; - this.$printMarginEl = document.createElement("div") - this.$printMarginEl.className = "ace_print_margin"; - containerEl.appendChild(this.$printMarginEl); - this.content.insertBefore(containerEl, this.$textLayer.element); - } - - var style = this.$printMarginEl.style; - style.left = ((this.characterWidth * this.$printMarginColumn) + this.$padding * 2) + "px"; - style.visibility = this.$showPrintMargin ? "visible" : "hidden"; - }; - - this.getContainerElement = function() { - return this.container; - }; - - this.getMouseEventTarget = function() { - return this.content; - }; - - this.getTextAreaContainer = function() { - return this.container; - }; - - this.moveTextAreaToCursor = function(textarea) { - // in IE the native cursor always shines through - if (useragent.isIE) - return; - - var pos = this.$cursorLayer.getPixelPosition(); - if (!pos) - return; - - var bounds = this.content.getBoundingClientRect(); - var offset = (this.layerConfig && this.layerConfig.offset) || 0; - - textarea.style.left = (bounds.left + pos.left + this.$padding) + "px"; - textarea.style.top = (bounds.top + pos.top - this.scrollTop + offset) + "px"; - }; - - this.getFirstVisibleRow = function() { - return (this.layerConfig || {}).firstRow || 0; - }; - - this.getFirstFullyVisibleRow = function(){ - if (!this.layerConfig) - return 0; - - return this.layerConfig.firstRow + (this.layerConfig.offset == 0 ? 0 : 1); - } - - this.getLastFullyVisibleRow = function() { - if (!this.layerConfig) - return 0; - - var flint = Math.floor((this.layerConfig.height + this.layerConfig.offset) / this.layerConfig.lineHeight); - return this.layerConfig.firstRow - 1 + flint; - } - - this.getLastVisibleRow = function() { - return (this.layerConfig || {}).lastRow || 0; - }; - - this.$padding = null; - this.setPadding = function(padding) { - this.$padding = padding; - this.content.style.padding = "0 " + padding + "px"; - this.$loop.schedule(this.CHANGE_FULL); - this.$updatePrintMargin(); - }; - - this.onScroll = function(e) { - this.scrollToY(e.data); - }; - - this.$updateScrollBar = function() { - this.scrollBar.setInnerHeight(this.session.getScreenLength() * this.lineHeight); - this.scrollBar.setScrollTop(this.scrollTop); - }; - - this.$renderChanges = function(changes) { - if (!changes || !this.session || !this.$tokenizer) - return; - - // text, scrolling and resize changes can cause the view port size to change - if (!this.layerConfig || - changes & this.CHANGE_FULL || - changes & this.CHANGE_SIZE || - changes & this.CHANGE_TEXT || - changes & this.CHANGE_LINES || - changes & this.CHANGE_SCROLL - ) - this.$computeLayerConfig(); - - // full - if (changes & this.CHANGE_FULL) { - 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.$updateScrollBar(); - this.scrollCursorIntoView(); - return; - } - - // scrolling - if (changes & this.CHANGE_SCROLL) { - if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES) - this.$textLayer.update(this.layerConfig); - else - 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.$updateScrollBar(); - return; - } - - if (changes & this.CHANGE_TEXT) { - this.$textLayer.update(this.layerConfig); - this.showGutter && this.$gutterLayer.update(this.layerConfig); - } - else if (changes & this.CHANGE_LINES) { - this.$updateLines(); - this.$updateScrollBar(); - this.showGutter && this.$gutterLayer.update(this.layerConfig); - } else if (changes & this.CHANGE_GUTTER) { - this.showGutter && this.$gutterLayer.update(this.layerConfig); - } - - if (changes & this.CHANGE_CURSOR) - this.$cursorLayer.update(this.layerConfig); - - if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) { - this.$markerFront.update(this.layerConfig); - } - - if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) { - this.$markerBack.update(this.layerConfig); - } - - if (changes & this.CHANGE_SIZE) - this.$updateScrollBar(); - }; - - this.$computeLayerConfig = function() { - var session = this.session; - - var offset = this.scrollTop % this.lineHeight; - var minHeight = this.$size.scrollerHeight + this.lineHeight; - - var longestLine = this.$getLongestLine(); - var widthChanged = !this.layerConfig ? true : (this.layerConfig.width != longestLine); - - var lineCount = Math.ceil(minHeight / this.lineHeight) - 1; - var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight)); - var lastRow = firstRow + lineCount; - - // Map lines on the screen to lines in the document. - var firstRowScreen, firstRowHeight; - var lineHeight = { lineHeight: this.lineHeight }; - firstRow = session.screenToDocumentRow(firstRow); - firstRowScreen = session.documentToScreenRow(firstRow); - firstRowHeight = session.getRowHeight(lineHeight, firstRow); - - lastRow = Math.min(session.screenToDocumentRow(lastRow), session.getLength() - 1); - minHeight = this.$size.scrollerHeight + session.getRowHeight(lineHeight, lastRow)+ - firstRowHeight; - - offset = this.scrollTop - firstRowScreen * this.lineHeight; - - var layerConfig = this.layerConfig = { - width : longestLine, - padding : this.$padding, - firstRow : firstRow, - firstRowScreen: firstRowScreen, - lastRow : lastRow, - lineHeight : this.lineHeight, - characterWidth : this.characterWidth, - minHeight : minHeight, - offset : offset, - height : this.$size.scrollerHeight - }; - - this.$gutterLayer.element.style.marginTop = (-offset) + "px"; - this.content.style.marginTop = (-offset) + "px"; - this.content.style.width = longestLine + "px"; - this.content.style.height = minHeight + "px"; - }; - - this.$updateLines = function() { - var firstRow = this.$changedLines.firstRow; - var lastRow = this.$changedLines.lastRow; - this.$changedLines = null; - - var layerConfig = this.layerConfig; - - // if the update changes the width of the document do a full redraw - if (layerConfig.width != this.$getLongestLine()) - return this.$textLayer.update(layerConfig); - - if (firstRow > layerConfig.lastRow + 1) { return; } - if (lastRow < layerConfig.firstRow) { return; } - - // if the last row is unknown -> redraw everything - if (lastRow === Infinity) { - this.showGutter && this.$gutterLayer.update(layerConfig); - this.$textLayer.update(layerConfig); - return; - } - - // else update only the changed rows - this.$textLayer.updateLines(layerConfig, firstRow, lastRow); - }; - - this.$getLongestLine = function() { - var charCount = this.session.getScreenWidth() + 1; - if (this.$textLayer.showInvisibles) - charCount += 1; - - return Math.max(this.$size.scrollerWidth - this.$padding * 2, Math.round(charCount * this.characterWidth)); - }; - - this.updateFrontMarkers = function() { - this.$markerFront.setMarkers(this.session.getMarkers(true)); - this.$loop.schedule(this.CHANGE_MARKER_FRONT); - }; - - this.updateBackMarkers = function() { - this.$markerBack.setMarkers(this.session.getMarkers()); - this.$loop.schedule(this.CHANGE_MARKER_BACK); - }; - - this.addGutterDecoration = function(row, className){ - this.$gutterLayer.addGutterDecoration(row, className); - this.$loop.schedule(this.CHANGE_GUTTER); - } - - this.removeGutterDecoration = function(row, className){ - this.$gutterLayer.removeGutterDecoration(row, className); - this.$loop.schedule(this.CHANGE_GUTTER); - } - - this.setBreakpoints = function(rows) { - this.$gutterLayer.setBreakpoints(rows); - this.$loop.schedule(this.CHANGE_GUTTER); - }; - - this.setAnnotations = function(annotations) { - this.$gutterLayer.setAnnotations(annotations); - this.$loop.schedule(this.CHANGE_GUTTER); - }; - - this.updateCursor = function(position, overwrite) { - this.$cursorLayer.setCursor(position, overwrite); - this.$loop.schedule(this.CHANGE_CURSOR); - }; - - this.hideCursor = function() { - this.$cursorLayer.hideCursor(); - }; - - this.showCursor = function() { - this.$cursorLayer.showCursor(); - }; - - this.scrollCursorIntoView = function() { - var pos = this.$cursorLayer.getPixelPosition(); - - var left = pos.left + this.$padding; - var top = pos.top; - - if (this.getScrollTop() > top) { - this.scrollToY(top); - } - - if (this.getScrollTop() + this.$size.scrollerHeight < top - + this.lineHeight) { - this.scrollToY(top + this.lineHeight - this.$size.scrollerHeight); - } - - if (this.scroller.scrollLeft > left) { - this.scrollToX(left); - } - - if (this.scroller.scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) { - - if (left + this.characterWidth > this.scroller.scrollWidth) - this.$renderChanges(this.CHANGE_SIZE); - - this.scrollToX(Math.round(left + this.characterWidth - this.$size.scrollerWidth)); - } - }, - - this.getScrollTop = function() { - return this.scrollTop; - }; - - this.getScrollLeft = function() { - return this.scroller.scrollLeft; - }; - - this.getScrollTopRow = function() { - return this.scrollTop / this.lineHeight; - }; - - this.getScrollBottomRow = function() { - return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1); - } - - this.scrollToRow = function(row) { - this.scrollToY(row * this.lineHeight); - }; - - this.scrollToLine = function(line, center) { - var lineHeight = { lineHeight: this.lineHeight }; - var offset = 0; - for (var l = 1; l < line; l++) { - offset += this.session.getRowHeight(lineHeight, l-1); - } - - if (center) { - offset -= this.$size.scrollerHeight / 2; - } - this.scrollToY(offset); - }; - - this.scrollToY = function(scrollTop) { - var maxHeight = this.session.getScreenLength() * this.lineHeight - this.$size.scrollerHeight; - var scrollTop = Math.max(0, Math.min(maxHeight, scrollTop)); - - if (this.scrollTop !== scrollTop) { - this.scrollTop = scrollTop; - this.$loop.schedule(this.CHANGE_SCROLL); - } - }; - - this.scrollToX = function(scrollLeft) { - if (scrollLeft <= this.$padding) - scrollLeft = 0; - - this.scroller.scrollLeft = scrollLeft; - }; - - this.scrollBy = function(deltaX, deltaY) { - deltaY && this.scrollToY(this.scrollTop + deltaY); - deltaX && this.scrollToX(this.scroller.scrollLeft + deltaX); - }; - - this.screenToTextCoordinates = function(pageX, pageY) { - var canvasPos = this.scroller.getBoundingClientRect(); - - var col = Math.round((pageX + this.scroller.scrollLeft - canvasPos.left - this.$padding - dom.getPageScrollLeft()) - / this.characterWidth); - var row = Math.floor((pageY + this.scrollTop - canvasPos.top - dom.getPageScrollTop()) - / this.lineHeight); - - return this.session.screenToDocumentPosition(row, Math.max(col, 0)); - }; - - this.textToScreenCoordinates = function(row, column) { - var canvasPos = this.scroller.getBoundingClientRect(); - var pos = this.session.documentToScreenPosition(row, column); - - var x = this.$padding + Math.round(pos.column * this.characterWidth); - var y = pos.row * this.lineHeight; - - return { - pageX: canvasPos.left + x - this.getScrollLeft(), - pageY: canvasPos.top + y - this.getScrollTop() - } - }; - - this.visualizeFocus = function() { - dom.addCssClass(this.container, "ace_focus"); - }; - - this.visualizeBlur = function() { - dom.removeCssClass(this.container, "ace_focus"); - }; - - this.showComposition = function(position) { - if (!this.$composition) { - this.$composition = document.createElement("div"); - this.$composition.className = "ace_composition"; - this.content.appendChild(this.$composition); - } - - this.$composition.innerHTML = " "; - - var pos = this.$cursorLayer.getPixelPosition(); - var style = this.$composition.style; - style.top = pos.top + "px"; - style.left = (pos.left + this.$padding) + "px"; - style.height = this.lineHeight + "px"; - - this.hideCursor(); - }; - - this.setCompositionText = function(text) { - dom.setInnerText(this.$composition, text); - }; - - this.hideComposition = function() { - this.showCursor(); - - if (!this.$composition) - return; - - var style = this.$composition.style; - style.top = "-10000px"; - style.left = "-10000px"; - }; - - this.setTheme = function(theme) { - var _self = this; - if (!theme || typeof theme == "string") { - theme = theme || "ace/theme/textmate"; - require([theme], function(theme) { - afterLoad(theme); - }); - } else { - afterLoad(theme); - } - - var _self = this; - function afterLoad(theme) { - if (_self.$theme) - dom.removeCssClass(_self.container, _self.$theme); - - _self.$theme = theme ? theme.cssClass : null; - - if (_self.$theme) - dom.addCssClass(_self.container, _self.$theme); - - // force re-measure of the gutter width - if (_self.$size) { - _self.$size.width = 0; - _self.onResize(); - } - } - }; - - // Methods allows to add / remove CSS classnames to the editor element. - // This feature can be used by plug-ins to provide a visual indication of - // a certain mode that editor is in. - - this.setStyle = function setStyle(style) { - dom.addCssClass(this.container, style) - }; - - this.unsetStyle = function unsetStyle(style) { - dom.removeCssClass(this.container, style) - }; - -}).call(VirtualRenderer.prototype); - -exports.VirtualRenderer = VirtualRenderer; -}); -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -__ace_shadowed__.define('ace/layer/gutter', function(require, exports, module) { - -var dom = require("pilot/dom"); - -var Gutter = function(parentEl) { - this.element = document.createElement("div"); - this.element.className = "ace_layer ace_gutter-layer"; - parentEl.appendChild(this.element); - - this.$breakpoints = []; - this.$annotations = []; - this.$decorations = []; -}; - -(function() { - - this.setSession = function(session) { - this.session = session; - }; - - this.addGutterDecoration = function(row, className){ - if (!this.$decorations[row]) - this.$decorations[row] = ""; - this.$decorations[row] += " ace_" + className; - } - - this.removeGutterDecoration = function(row, className){ - this.$decorations[row] = this.$decorations[row].replace(" ace_" + className, ""); - }; - - this.setBreakpoints = function(rows) { - this.$breakpoints = rows.concat(); - }; - - this.setAnnotations = function(annotations) { - // iterate over sparse array - this.$annotations = []; - for (var row in annotations) if (annotations.hasOwnProperty(row)) { - var rowAnnotations = annotations[row]; - if (!rowAnnotations) - continue; - - var rowInfo = this.$annotations[row] = { - text: [] - }; - for (var i=0; i", (i+1), "
    "); - html.push("

- - - - + + diff --git a/build_support/editor_textarea.html b/build_support/editor_textarea.html deleted file mode 100644 index c3c9a2b5..00000000 --- a/build_support/editor_textarea.html +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - Editor - - - -

Ace Bookmarklet Builder

- -

-WARNING: Currently, this is only fully supported in non IE browsers. -

- -

-How to use it: -

    -
  • Select the options below as you want them to be by default.
  • -
  • Enter the "SourceUrl" where you placed the source data which you find under build/textarea/src (you can also leave the default to server the scripts from GitHub).
  • -
  • Click the "Build Link" button to generate your custom Ace Bookmarklet.
  • -
  • Drag the generated link to your toolbar or store it somewhere else.
  • -
  • Go to a page with an textarea element and click the bookmarklet - wait a little bit till the files are loaded.
  • -
  • Click 3 times on the textarea you want to replace - Ace will replace it.
  • -
  • To change settings, just click the red icon in the bottom right corner.
  • -
-

- -
-SourceUrl: - -
- - - - - diff --git a/build_support/mini_require.js b/build_support/mini_require.js index a3e01b04..1ecbb78b 100644 --- a/build_support/mini_require.js +++ b/build_support/mini_require.js @@ -1,37 +1,30 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ @@ -40,95 +33,142 @@ * @param module a name for the payload * @param payload a function to call with (require, exports, module) params */ - + (function() { - -if (window.require) { - require.packaged = true; + +var ACE_NAMESPACE = ""; + +var global = (function() { return this; })(); +if (!global && typeof window != "undefined") global = window; // strict mode + + +if (!ACE_NAMESPACE && typeof requirejs !== "undefined") return; -} - -var _define = function(module, deps, payload) { - if (typeof module !== 'string') { - if (_define.original) - _define.original.apply(window, arguments); + + +var define = function(module, deps, payload) { + if (typeof module !== "string") { + if (define.original) + define.original.apply(this, arguments); else { - console.error('dropping module because define wasn\'t a string.'); + console.error("dropping module because define wasn\'t a string."); console.trace(); } return; } - - if (!define.modules) - define.modules = {}; - - define.modules[module] = payload; + if (arguments.length == 2) + payload = deps; + if (!define.modules[module]) { + define.payloads[module] = payload; + define.modules[module] = null; + } }; -if (window.define) - _define.original = window.define; - -window.define = _define; +define.modules = {}; +define.payloads = {}; /** * Get at functionality define()ed using the function above */ -var _require = function(module, callback) { - if (Object.prototype.toString.call(module) === "[object Array]") { +var _require = function(parentId, module, callback) { + if (typeof module === "string") { + var payload = lookup(parentId, module); + if (payload != undefined) { + callback && callback(); + return payload; + } + } else if (Object.prototype.toString.call(module) === "[object Array]") { var params = []; for (var i = 0, l = module.length; i < l; ++i) { - var dep = lookup(module[i]); - if (!dep && _require.original) - return _require.original.apply(window, arguments); + var dep = lookup(parentId, module[i]); + if (dep == undefined && require.original) + return; params.push(dep); } - if (callback) { - callback.apply(null, params); - } - } - else if (typeof module === 'string') { - var payload = lookup(module); - if (!payload && _require.original) - return _require.original.apply(window, arguments); - - if (callback) { - callback(); - } - - return payload; - } - else { - if (_require.original) - return _require.original.apply(window, arguments); + return callback && callback.apply(null, params) || true; } }; -if (window.require) - _require.original = window.require; - -window.require = _require; -require.packaged = true; +var require = function(module, callback) { + var packagedModule = _require("", module, callback); + if (packagedModule == undefined && require.original) + return require.original.apply(this, arguments); + return packagedModule; +}; + +var normalizeModule = function(parentId, moduleName) { + // normalize plugin requires + if (moduleName.indexOf("!") !== -1) { + var chunks = moduleName.split("!"); + return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]); + } + // normalize relative requires + if (moduleName.charAt(0) == ".") { + var base = parentId.split("/").slice(0, -1).join("/"); + moduleName = base + "/" + moduleName; + + while(moduleName.indexOf(".") !== -1 && previous != moduleName) { + var previous = moduleName; + moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, ""); + } + } + return moduleName; +}; /** * Internal function to lookup moduleNames and resolve them by calling the * definition function if needed. */ -var lookup = function(moduleName) { +var lookup = function(parentId, moduleName) { + moduleName = normalizeModule(parentId, moduleName); + var module = define.modules[moduleName]; - if (module == null) { - console.error('Missing module: ' + moduleName); - return null; - } + if (!module) { + module = define.payloads[moduleName]; + if (typeof module === 'function') { + var exports = {}; + var mod = { + id: moduleName, + uri: '', + exports: exports, + packaged: true + }; - if (typeof module === 'function') { - var exports = {}; - module(require, exports, { id: moduleName, uri: '' }); - // cache the resulting module object for next time - define.modules[moduleName] = exports; - return exports; - } + var req = function(module, callback) { + return _require(moduleName, module, callback); + }; + var returnValue = module(req, exports, mod); + exports = returnValue || mod.exports; + define.modules[moduleName] = exports; + delete define.payloads[moduleName]; + } + module = define.modules[moduleName] = exports || module; + } return module; }; -})(); \ No newline at end of file +function exportAce(ns) { + var root = global; + if (ns) { + if (!global[ns]) + global[ns] = {}; + root = global[ns]; + } + + if (!root.define || !root.define.packaged) { + define.original = root.define; + root.define = define; + root.define.packaged = true; + } + + if (!root.require || !root.require.packaged) { + require.original = root.require; + root.require = require; + root.require.packaged = true; + } +} + +exportAce(ACE_NAMESPACE); + +})(); diff --git a/build_support/mini_require_textarea.js b/build_support/mini_require_textarea.js deleted file mode 100644 index be4f40d3..00000000 --- a/build_support/mini_require_textarea.js +++ /dev/null @@ -1,128 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/** - * Define a module along with a payload - * @param module a name for the payload - * @param payload a function to call with (require, exports, module) params - */ - -(function() { - -var _define = function(module, deps, payload) { - if (typeof module !== 'string') { - if (_define.original) - _define.original.apply(window, arguments); - else { - console.error('dropping module because define wasn\'t a string.'); - console.trace(); - } - return; - } - - if (!_define.modules) - _define.modules = {}; - - _define.modules[module] = payload; -}; - -/** - * Get at functionality define()ed using the function above - */ -var _require = function(module, callback) { - if (Object.prototype.toString.call(module) === "[object Array]") { - var params = []; - for (var i = 0, l = module.length; i < l; ++i) { - var dep = lookup(module[i]); - if (!dep && _require.original) - return _require.original.apply(window, arguments); - params.push(dep); - }; - if (callback) { - callback.apply(null, params); - } - } - - if (typeof module === 'string') { - var payload = lookup(module); - if (!payload && _require.original) - return _require.original.apply(window, arguments); - - if (callback) { - callback(); - } - - return payload; - }; -} - -_require.packaged = true; -_require.noWorker = true; - -/** - * Internal function to lookup moduleNames and resolve them by calling the - * definition function if needed. - */ -var lookup = function(moduleName) { - var module = _define.modules[moduleName]; - if (module == null) { - console.error('Missing module: ' + moduleName); - return null; - } - - if (typeof module === 'function') { - var exports = {}; - module(_require, exports, { id: moduleName, uri: '' }); - // cache the resulting module object for next time - _define.modules[moduleName] = exports; - return exports; - } - - return module; -}; - -/** - * Expose as "shadowed" object to the outside world. - */ - -window.__ace_shadowed__ = { - require: _require, - define: _define -}; - -})(); \ No newline at end of file diff --git a/build_support/style.css b/build_support/style.css new file mode 100644 index 00000000..3ca603b1 --- /dev/null +++ b/build_support/style.css @@ -0,0 +1,226 @@ +@import url(//fonts.googleapis.com/css?family=Droid+Sans+Mono); + +body { + margin:0; + padding:0; + background-color:#e6f5fc; + +} + +H2, H3, H4 { + font-family:Trebuchet MS; + font-weight:bold; + margin:0; + padding:0; +} + +H2 { + font-size:28px; + color:#263842; + padding-bottom:6px; +} + +H3 { + font-family:Trebuchet MS; + font-weight:bold; + font-size:22px; + color:#253741; + margin-top:43px; + margin-bottom:8px; +} + +H4 { + font-family:Trebuchet MS; + font-weight:bold; + font-size:21px; + color:#222222; + margin-bottom:4px; +} + +P { + padding:13px 0; + margin:0; + line-height:22px; +} + +UL{ + line-height : 22px; +} + +PRE{ + background : #333; + color : white; + padding : 10px; +} + +#header { + height : 227px; + position:relative; + overflow:hidden; + background: url(images/background.png) repeat-x 0 0; + border-bottom:1px solid #c9e8fa; +} + +#header .content .signature { + font-family:Trebuchet MS; + font-size:11px; + color:#ebe4d6; + position:absolute; + bottom:5px; + right:42px; + letter-spacing : 1px; +} + +.content { + width:970px; + position:relative; + margin:0 auto; +} + +#header .content { + height:184px; + margin-top:22px; +} + +#header .content .logo { + width : 282px; + height : 184px; + background:url(images/logo.png) no-repeat 0 0; + position:absolute; + top:0; + left:0; +} + +#header .content .title { + width : 605px; + height : 58px; + background:url(images/ace.png) no-repeat 0 0; + position:absolute; + top:98px; + left:329px; +} + +#wrapper { + background:url(images/body_background.png) repeat-x 0 0; + min-height:250px; +} + +#wrapper .content { + font-family:Arial; + font-size:14px; + color:#222222; + width:1000px; +} + +#wrapper .content .column1 { + position:relative; + float:left; + width:315px; + margin-right:31px; +} + +#wrapper .content .column2 { + position:relative; + overflow:hidden; + float:left; + width:600px; + padding-top:47px; +} + +.fork_on_github { + width:310px; + height:80px; + background:url(images/fork_on_github.png) no-repeat 0 0; + position:relative; + overflow:hidden; + margin-top:49px; + cursor:pointer; +} + +.fork_on_github:hover { + background-position:0 -80px; +} + +.divider { + height:3px; + background-color:#bedaea; + margin-bottom:3px; +} + +.menu { + padding:23px 0 0 24px; +} + +UL.content-list { + padding:15px; + margin:0; +} + +UL.menu-list { + padding:0; + margin:0 0 20px 0; + list-style-type:none; + line-height : 16px; +} + +UL.menu-list LI { + color:#2557b4; + font-family:Trebuchet MS; + font-size:14px; + padding:7px 0; + border-bottom:1px dotted #d6e2e7; +} + +UL.menu-list LI:last-child { + border-bottom:0; +} + +A { + color:#2557b4; + text-decoration:none; +} + +A:hover { + text-decoration:underline; +} + +P#first{ + background : rgba(255,255,255,0.5); + padding : 20px; + font-size : 16px; + line-height : 24px; + margin : 0 0 20px 0; +} + +#footer { + height:40px; + position:relative; + overflow:hidden; + background:url(images/bottombar.png) repeat-x 0 0; + position:relative; + margin-top:40px; +} + +UL.menu-footer { + padding:0; + margin:8px 11px 0 0; + list-style-type:none; + float:right; +} + +UL.menu-footer LI { + color:white; + font-family:Arial; + font-size:12px; + display:inline-block; + margin:0 1px; +} + +UL.menu-footer LI A { + color:#8dd0ff; + text-decoration:none; +} + +UL.menu-footer LI A:hover { + text-decoration:underline; +} diff --git a/demo/autocompletion.html b/demo/autocompletion.html new file mode 100644 index 00000000..e0de5ef3 --- /dev/null +++ b/demo/autocompletion.html @@ -0,0 +1,45 @@ + + + + + ACE Autocompletion demo + + + + +

+
+
+
+
+
+
+
+
+
+
diff --git a/demo/autoresize.html b/demo/autoresize.html
new file mode 100644
index 00000000..b0464ecd
--- /dev/null
+++ b/demo/autoresize.html
@@ -0,0 +1,68 @@
+
+
+
+  
+  
+  Editor
+  
+
+
+
autoresizing editor
+
+
minHeight = 2 lines
+
+

+
+

+
+
+
+
+
+
+
+
diff --git a/demo/boot.js b/demo/boot.js
deleted file mode 100644
index 1fddaf72..00000000
--- a/demo/boot.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ***** 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
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Skywriter.
- *
- * The Initial Developer of the Original Code is
- * Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *      Kevin Dangoor (kdangoor@mozilla.com)
- *
- * 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
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-require({
-    paths: {
-        demo: "../demo",
-        ace: "../lib/ace",
-        cockpit: "../support/cockpit/lib/cockpit",
-        pilot: "../support/pilot/lib/pilot"
-    }
-});
-
-var deps = [ "pilot/fixoldbrowsers", "pilot/plugin_manager", "pilot/settings",
-             "pilot/environment", "demo/demo" ];
-
-var plugins = [ "pilot/index", "cockpit/index", "ace/defaults" ];
-require(deps, function() {
-    var catalog = require("pilot/plugin_manager").catalog;
-    catalog.registerPlugins(plugins).then(function() {
-        var env = require("pilot/environment").create();
-        catalog.startupPlugins({ env: env }).then(function() {
-            require("demo/demo").launch(env);
-        });
-    });
-});
\ No newline at end of file
diff --git a/demo/chromevox.html b/demo/chromevox.html
new file mode 100644
index 00000000..9aa65bae
--- /dev/null
+++ b/demo/chromevox.html
@@ -0,0 +1,39 @@
+
+
+
+  
+  ACE ChromeVox demo
+  
+
+
+
+

+
+
+
+
+
+
+
+
+
+
diff --git a/demo/demo.js b/demo/demo.js
deleted file mode 100644
index 3e342ae4..00000000
--- a/demo/demo.js
+++ /dev/null
@@ -1,379 +0,0 @@
-/* ***** 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
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Skywriter.
- *
- * The Initial Developer of the Original Code is
- * Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *      Fabian Jakobs 
- *      Kevin Dangoor (kdangoor@mozilla.com)
- *
- * 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
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-
-define(function(require, exports, module) {
-
-exports.launch = function(env) {
-
-    var event = require("pilot/event");
-    var Editor = require("ace/editor").Editor;
-    var Renderer = require("ace/virtual_renderer").VirtualRenderer;
-    var theme = require("ace/theme/textmate");
-    var EditSession = require("ace/edit_session").EditSession;
-
-    var JavaScriptMode = require("ace/mode/javascript").Mode;
-    var CssMode = require("ace/mode/css").Mode;
-    var HtmlMode = require("ace/mode/html").Mode;
-    var XmlMode = require("ace/mode/xml").Mode;
-    var PythonMode = require("ace/mode/python").Mode;
-    var PhpMode = require("ace/mode/php").Mode;
-    var JavaMode = require("ace/mode/java").Mode;
-    var CSharpMode = require("ace/mode/csharp").Mode;
-    var RubyMode = require("ace/mode/ruby").Mode;
-    var CCPPMode = require("ace/mode/c_cpp").Mode;
-    var CoffeeMode = require("ace/mode/coffee").Mode;
-    var PerlMode = require("ace/mode/perl").Mode;
-    var TextileMode = require("ace/mode/textile").Mode;
-    var TextMode = require("ace/mode/text").Mode;
-    var UndoManager = require("ace/undomanager").UndoManager;
-
-    var vim = require("ace/keyboard/keybinding/vim").Vim;
-    var emacs = require("ace/keyboard/keybinding/emacs").Emacs;
-    var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
-
-    var keybindings = {
-      // Null = use "default" keymapping
-      ace: null,
-      vim: vim,
-      emacs: emacs,
-      // This is a way to define simple keyboard remappings
-      custom: new HashHandler({
-          "gotoright": "Tab"
-      })
-    }
-
-    var docs = {};
-
-    // Make the lorem ipsum text a little bit longer.
-    var loreIpsum = document.getElementById("plaintext").innerHTML;
-    for (var i = 0; i < 5; i++) {
-        loreIpsum += loreIpsum;
-    }
-    docs.plain = new EditSession(loreIpsum);
-    docs.plain.setUseWrapMode(true);
-    docs.plain.setWrapLimitRange(80, 80)
-    docs.plain.setMode(new TextMode());
-    docs.plain.setUndoManager(new UndoManager());
-
-    docs.js = new EditSession(document.getElementById("jstext").innerHTML);
-    docs.js.setMode(new JavaScriptMode());
-    docs.js.setUndoManager(new UndoManager());
-
-    docs.css = new EditSession(document.getElementById("csstext").innerHTML);
-    docs.css.setMode(new CssMode());
-    docs.css.setUndoManager(new UndoManager());
-
-    docs.html = new EditSession(document.getElementById("htmltext").innerHTML);
-    docs.html.setMode(new HtmlMode());
-    docs.html.setUndoManager(new UndoManager());
-
-    docs.python = new EditSession(document.getElementById("pythontext").innerHTML);
-    docs.python.setMode(new PythonMode());
-    docs.python.setUndoManager(new UndoManager());
-
-    docs.php = new EditSession(document.getElementById("phptext").innerHTML);
-    docs.php.setMode(new PhpMode());
-    docs.php.setUndoManager(new UndoManager());
-
-    docs.java = new EditSession(document.getElementById("javatext").innerHTML);
-    docs.java.setMode(new JavaMode());
-    docs.java.setUndoManager(new UndoManager());
-
-    docs.ruby = new EditSession(document.getElementById("rubytext").innerHTML);
-    docs.ruby.setMode(new RubyMode());
-    docs.ruby.setUndoManager(new UndoManager());
-
-    docs.csharp = new EditSession(document.getElementById("csharptext").innerHTML);
-    docs.csharp.setMode(new CSharpMode());
-    docs.csharp.setUndoManager(new UndoManager());
-
-    docs.c_cpp = new EditSession(document.getElementById("cpptext").innerHTML);
-    docs.c_cpp.setMode(new CCPPMode());
-    docs.c_cpp.setUndoManager(new UndoManager());
-
-    docs.coffee = new EditSession(document.getElementById("coffeetext").innerHTML);
-    docs.coffee.setMode(new CoffeeMode());
-    docs.coffee.setUndoManager(new UndoManager());
-
-    docs.perl = new EditSession(document.getElementById("perltext").innerHTML);
-    docs.perl.setMode(new PerlMode());
-    docs.perl.setUndoManager(new UndoManager());
-
-    docs.textile = new EditSession(document.getElementById("textiletext").innerHTML);
-    docs.textile.setMode(new TextileMode());
-    docs.textile.setUndoManager(new UndoManager());
-
-    var container = document.getElementById("editor");
-    env.editor = new Editor(new Renderer(container, theme));
-
-    var modes = {
-        text: new TextMode(),
-        textile: new TextileMode(),
-        xml: new XmlMode(),
-        html: new HtmlMode(),
-        css: new CssMode(),
-        javascript: new JavaScriptMode(),
-        python: new PythonMode(),
-        php: new PhpMode(),
-        java: new JavaMode(),
-        ruby: new RubyMode(),
-        c_cpp: new CCPPMode(),
-        coffee: new CoffeeMode(),
-        perl: new PerlMode(),
-				csharp: new CSharpMode()
-    };
-
-    function getMode() {
-        return modes[modeEl.value];
-    }
-
-    var modeEl = document.getElementById("mode");
-    var wrapModeEl = document.getElementById("soft_wrap");
-
-    bindDropdown("doc", function(value) {
-        var doc = docs[value];
-        env.editor.setSession(doc);
-
-        var mode = doc.getMode();
-        if (mode instanceof JavaScriptMode) {
-            modeEl.value = "javascript";
-        }
-        else if (mode instanceof CssMode) {
-            modeEl.value = "css";
-        }
-        else if (mode instanceof HtmlMode) {
-            modeEl.value = "html";
-        }
-        else if (mode instanceof XmlMode) {
-            modeEl.value = "xml";
-        }
-        else if (mode instanceof PythonMode) {
-            modeEl.value = "python";
-        }
-        else if (mode instanceof PhpMode) {
-            modeEl.value = "php";
-        }
-        else if (mode instanceof JavaMode) {
-            modeEl.value = "java";
-        }
-        else if (mode instanceof RubyMode) {
-            modeEl.value = "ruby";
-        }
-        else if (mode instanceof CCPPMode) {
-            modeEl.value = "c_cpp";
-        }
-        else if (mode instanceof CoffeeMode) {
-            modeEl.value = "coffee";
-        }
-        else if (mode instanceof PerlMode) {
-            modeEl.value = "perl";
-        }
-        else if (mode instanceof CSharpMode) {
-            modeEl.value = "csharp";
-        }
-        else if (mode instanceof TextileMode) {
-            modeEl.value = "textile";
-        }
-        else {
-            modeEl.value = "text";
-        }
-
-        if (!doc.getUseWrapMode()) {
-            wrapModeEl.value = "off";
-        } else {
-            wrapModeEl.value = doc.getWrapLimitRange().min || "free";
-        }
-        env.editor.focus();
-    });
-
-    bindDropdown("mode", function(value) {
-        env.editor.getSession().setMode(modes[value] || modes.text);
-    });
-
-    bindDropdown("theme", function(value) {
-        env.editor.setTheme(value);
-    });
-
-    bindDropdown("keybinding", function(value) {
-        env.editor.setKeyboardHandler(keybindings[value]);
-    });
-
-    bindDropdown("fontsize", function(value) {
-        document.getElementById("editor").style.fontSize = value;
-    });
-
-    bindDropdown("soft_wrap", function(value) {
-        var session = env.editor.getSession();
-        var renderer = env.editor.renderer;
-        switch (value) {
-            case "off":
-                session.setUseWrapMode(false);
-                renderer.setPrintMarginColumn(80);
-                break;
-            case "40":
-                session.setUseWrapMode(true);
-                session.setWrapLimitRange(40, 40);
-                renderer.setPrintMarginColumn(40);
-                break;
-            case "80":
-                session.setUseWrapMode(true);
-                session.setWrapLimitRange(80, 80);
-                renderer.setPrintMarginColumn(80);
-                break;
-            case "free":
-                session.setUseWrapMode(true);
-                session.setWrapLimitRange(null, null);
-                renderer.setPrintMarginColumn(80);
-                break;
-        }
-    });
-
-    bindCheckbox("select_style", function(checked) {
-        env.editor.setSelectionStyle(checked ? "line" : "text");
-    });
-
-    bindCheckbox("highlight_active", function(checked) {
-        env.editor.setHighlightActiveLine(checked);
-    });
-
-    bindCheckbox("show_hidden", function(checked) {
-        env.editor.setShowInvisibles(checked);
-    });
-
-    bindCheckbox("show_gutter", function(checked) {
-        env.editor.renderer.setShowGutter(checked);
-    });
-
-    bindCheckbox("show_print_margin", function(checked) {
-        env.editor.renderer.setShowPrintMargin(checked);
-    });
-
-    bindCheckbox("highlight_selected_word", function(checked) {
-        env.editor.setHighlightSelectedWord(checked);
-    });
-
-    bindCheckbox("show_hscroll", function(checked) {
-        env.editor.renderer.setHScrollBarAlwaysVisible(checked);
-    });
-
-    function bindCheckbox(id, callback) {
-        var el = document.getElementById(id);
-        var onCheck = function() {
-            callback(!!el.checked);
-        };
-        el.onclick = onCheck;
-        onCheck();
-    }
-
-    function bindDropdown(id, callback) {
-        var el = document.getElementById(id);
-        var onChange = function() {
-            callback(el.value);
-        };
-        el.onchange = onChange;
-        onChange();
-    }
-
-    function onResize() {
-        container.style.width = (document.documentElement.clientWidth) + "px";
-        container.style.height = (document.documentElement.clientHeight - 60 - 22) + "px";
-        env.editor.resize();
-    };
-
-    window.onresize = onResize;
-    onResize();
-
-    event.addListener(container, "dragover", function(e) {
-        return event.preventDefault(e);
-    });
-
-    event.addListener(container, "drop", function(e) {
-        try {
-            var file = e.dataTransfer.files[0];
-        } catch(e) {
-            return event.stopEvent();
-        }
-
-        if (window.FileReader) {
-            var reader = new FileReader();
-            reader.onload = function(e) {
-                env.editor.getSelection().selectAll();
-
-                var mode = "text";
-                if (/^.*\.js$/i.test(file.name)) {
-                    mode = "javascript";
-                } else if (/^.*\.xml$/i.test(file.name)) {
-                    mode = "xml";
-                } else if (/^.*\.html$/i.test(file.name)) {
-                    mode = "html";
-                } else if (/^.*\.css$/i.test(file.name)) {
-                    mode = "css";
-                } else if (/^.*\.py$/i.test(file.name)) {
-                    mode = "python";
-                } else if (/^.*\.php$/i.test(file.name)) {
-                    mode = "php";
-	              } else if (/^.*\.cs$/i.test(file.name)) {
-	                  mode = "csharp";
-                } else if (/^.*\.java$/i.test(file.name)) {
-                    mode = "java";
-                } else if (/^.*\.rb$/i.test(file.name)) {
-                    mode = "ruby";
-                } else if (/^.*\.(c|cpp|h|hpp|cxx)$/i.test(file.name)) {
-                    mode = "c_cpp";
-                } else if (/^.*\.coffee$/i.test(file.name)) {
-                    mode = "coffee";
-                } else if (/^.*\.(pl|pm)$/i.test(file.name)) {
-                    mode = "perl";
-                }
-
-                env.editor.onTextInput(reader.result);
-
-                modeEl.value = mode;
-                env.editor.getSession().setMode(modes[mode]);
-            };
-            reader.readAsText(file);
-        }
-
-        return event.preventDefault(e);
-    });
-
-    window.env = env;
-};
-
-});
diff --git a/demo/emmet.html b/demo/emmet.html
new file mode 100644
index 00000000..bd0d4abe
--- /dev/null
+++ b/demo/emmet.html
@@ -0,0 +1,43 @@
+
+
+
+  
+  ACE Emmet demo
+  
+
+
+
+

+
+
+
+
+
+
+
+
+
+
diff --git a/demo/ie7.html b/demo/ie7.html
new file mode 100644
index 00000000..f5db8667
--- /dev/null
+++ b/demo/ie7.html
@@ -0,0 +1,44 @@
+
+
+
+  
+  
+  ACE Editor StatusBar Demo
+  
+
+
+
+
+require("ace/ext/old_ie");
+// now ace will work even on ie7!
+var editor = ace.edit("editor");
+
+ + + + + + + + diff --git a/demo/keyboard_shortcuts.html b/demo/keyboard_shortcuts.html new file mode 100644 index 00000000..3d01f559 --- /dev/null +++ b/demo/keyboard_shortcuts.html @@ -0,0 +1,51 @@ + + + + + + Editor + + + + +

+    
+
+
+
+
+
+
diff --git a/demo/kitchen-sink/demo.js b/demo/kitchen-sink/demo.js
new file mode 100644
index 00000000..33b2dbc0
--- /dev/null
+++ b/demo/kitchen-sink/demo.js
@@ -0,0 +1,585 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2010, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Ajax.org B.V. nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+define(function(require, exports, module) {
+"use strict";
+
+require("ace/lib/fixoldbrowsers");
+
+require("ace/multi_select");
+require("ace/ext/spellcheck");
+require("./inline_editor");
+require("./dev_util");
+require("./file_drop");
+
+var config = require("ace/config");
+config.init();
+var env = {};
+
+var dom = require("ace/lib/dom");
+var net = require("ace/lib/net");
+var lang = require("ace/lib/lang");
+var useragent = require("ace/lib/useragent");
+
+var event = require("ace/lib/event");
+var theme = require("ace/theme/textmate");
+var EditSession = require("ace/edit_session").EditSession;
+var UndoManager = require("ace/undomanager").UndoManager;
+
+var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
+
+var Renderer = require("ace/virtual_renderer").VirtualRenderer;
+var Editor = require("ace/editor").Editor;
+
+var whitespace = require("ace/ext/whitespace");
+
+
+
+var doclist = require("./doclist");
+var modelist = require("ace/ext/modelist");
+var themelist = require("ace/ext/themelist");
+var layout = require("./layout");
+var TokenTooltip = require("./token_tooltip").TokenTooltip;
+var util = require("./util");
+var saveOption = util.saveOption;
+var fillDropdown = util.fillDropdown;
+var bindCheckbox = util.bindCheckbox;
+var bindDropdown = util.bindDropdown;
+
+var ElasticTabstopsLite = require("ace/ext/elastic_tabstops_lite").ElasticTabstopsLite;
+
+var IncrementalSearch = require("ace/incremental_search").IncrementalSearch;
+
+
+var workerModule = require("ace/worker/worker_client");
+if (location.href.indexOf("noworker") !== -1) {
+    workerModule.WorkerClient = workerModule.UIWorkerClient;
+}
+
+/*********** create editor ***************************/
+var container = document.getElementById("editor-container");
+
+// Splitting.
+var Split = require("ace/split").Split;
+var split = new Split(container, theme, 1);
+env.editor = split.getEditor(0);
+split.on("focus", function(editor) {
+    env.editor = editor;
+    updateUIEditorOptions();
+});
+env.split = split;
+window.env = env;
+
+
+var consoleEl = dom.createElement("div");
+container.parentNode.appendChild(consoleEl);
+consoleEl.style.cssText = "position:fixed; bottom:1px; right:0;\
+border:1px solid #baf; z-index:100";
+
+var cmdLine = new layout.singleLineEditor(consoleEl);
+cmdLine.editor = env.editor;
+env.editor.cmdLine = cmdLine;
+
+env.editor.showCommandLine = function(val) {
+    this.cmdLine.focus();
+    if (typeof val == "string")
+        this.cmdLine.setValue(val, 1);
+};
+
+/**
+ * This demonstrates how you can define commands and bind shortcuts to them.
+ */
+env.editor.commands.addCommands([{
+    name: "gotoline",
+    bindKey: {win: "Ctrl-L", mac: "Command-L"},
+    exec: function(editor, line) {
+        if (typeof line == "object") {
+            var arg = this.name + " " + editor.getCursorPosition().row;
+            editor.cmdLine.setValue(arg, 1);
+            editor.cmdLine.focus();
+            return;
+        }
+        line = parseInt(line, 10);
+        if (!isNaN(line))
+            editor.gotoLine(line);
+    },
+    readOnly: true
+}, {
+    name: "snippet",
+    bindKey: {win: "Alt-C", mac: "Command-Alt-C"},
+    exec: function(editor, needle) {
+        if (typeof needle == "object") {
+            editor.cmdLine.setValue("snippet ", 1);
+            editor.cmdLine.focus();
+            return;
+        }
+        var s = snippetManager.getSnippetByName(needle, editor);
+        if (s)
+            snippetManager.insertSnippet(editor, s.content);
+    },
+    readOnly: true
+}, {
+    name: "focusCommandLine",
+    bindKey: "shift-esc|ctrl-`",
+    exec: function(editor, needle) { editor.cmdLine.focus(); },
+    readOnly: true
+}, {
+    name: "nextFile",
+    bindKey: "Ctrl-tab",
+    exec: function(editor) { doclist.cycleOpen(editor, 1); },
+    readOnly: true
+}, {
+    name: "previousFile",
+    bindKey: "Ctrl-shift-tab",
+    exec: function(editor) { doclist.cycleOpen(editor, -1); },
+    readOnly: true
+}, {
+    name: "execute",
+    bindKey: "ctrl+enter",
+    exec: function(editor) {
+        try {
+            var r = window.eval(editor.getCopyText() || editor.getValue());
+        } catch(e) {
+            r = e;
+        }
+        editor.cmdLine.setValue(r + "");
+    },
+    readOnly: true
+}, {
+    name: "showKeyboardShortcuts",
+    bindKey: {win: "Ctrl-Alt-h", mac: "Command-Alt-h"},
+    exec: function(editor) {
+        config.loadModule("ace/ext/keybinding_menu", function(module) {
+            module.init(editor);
+            editor.showKeyboardShortcuts();
+        });
+    }
+}, {
+    name: "increaseFontSize",
+    bindKey: "Ctrl-=|Ctrl-+",
+    exec: function(editor) {
+        var size = parseInt(editor.getFontSize(), 10) || 12;
+        editor.setFontSize(size + 1);
+    }
+}, {
+    name: "decreaseFontSize",
+    bindKey: "Ctrl+-|Ctrl-_",
+    exec: function(editor) {
+        var size = parseInt(editor.getFontSize(), 10) || 12;
+        editor.setFontSize(Math.max(size - 1 || 1));
+    }
+}, {
+    name: "resetFontSize",
+    bindKey: "Ctrl+0|Ctrl-Numpad0",
+    exec: function(editor) {
+        editor.setFontSize(12);
+    }
+}]);
+
+
+env.editor.commands.addCommands(whitespace.commands);
+
+cmdLine.commands.bindKeys({
+    "Shift-Return|Ctrl-Return|Alt-Return": function(cmdLine) { cmdLine.insert("\n"); },
+    "Esc|Shift-Esc": function(cmdLine){ cmdLine.editor.focus(); },
+    "Return": function(cmdLine){
+        var command = cmdLine.getValue().split(/\s+/);
+        var editor = cmdLine.editor;
+        editor.commands.exec(command[0], editor, command[1]);
+        editor.focus();
+    }
+});
+
+cmdLine.commands.removeCommands(["find", "gotoline", "findall", "replace", "replaceall"]);
+
+var commands = env.editor.commands;
+commands.addCommand({
+    name: "save",
+    bindKey: {win: "Ctrl-S", mac: "Command-S"},
+    exec: function(arg) {
+        var session = env.editor.session;
+        var name = session.name.match(/[^\/]+$/);
+        localStorage.setItem(
+            "saved_file:" + name,
+            session.getValue()
+        );
+        env.editor.cmdLine.setValue("saved "+ name);
+    }
+});
+
+commands.addCommand({
+    name: "load",
+    bindKey: {win: "Ctrl-O", mac: "Command-O"},
+    exec: function(arg) {
+        var session = env.editor.session;
+        var name = session.name.match(/[^\/]+$/);
+        var value = localStorage.getItem("saved_file:" + name);
+        if (typeof value == "string") {
+            session.setValue(value);
+            env.editor.cmdLine.setValue("loaded "+ name);
+        } else {
+            env.editor.cmdLine.setValue("no previuos value saved for "+ name);
+        }
+    }
+});
+
+var keybindings = {
+    ace: null, // Null = use "default" keymapping
+    vim: require("ace/keyboard/vim").handler,
+    emacs: "ace/keyboard/emacs",
+    // This is a way to define simple keyboard remappings
+    custom: new HashHandler({
+        "gotoright":      "Tab",
+        "indent":         "]",
+        "outdent":        "[",
+        "gotolinestart":  "^",
+        "gotolineend":    "$"
+    })
+};
+
+
+
+/*********** manage layout ***************************/
+var consoleHeight = 20;
+function onResize() {
+    var left = env.split.$container.offsetLeft;
+    var width = document.documentElement.clientWidth - left;
+    container.style.width = width + "px";
+    container.style.height = document.documentElement.clientHeight - consoleHeight + "px";
+    env.split.resize();
+
+    consoleEl.style.width = width + "px";
+    cmdLine.resize();
+}
+
+window.onresize = onResize;
+onResize();
+
+/*********** options panel ***************************/
+var docEl = document.getElementById("doc");
+var modeEl = document.getElementById("mode");
+var wrapModeEl = document.getElementById("soft_wrap");
+var themeEl = document.getElementById("theme");
+var foldingEl = document.getElementById("folding");
+var selectStyleEl = document.getElementById("select_style");
+var highlightActiveEl = document.getElementById("highlight_active");
+var showHiddenEl = document.getElementById("show_hidden");
+var showGutterEl = document.getElementById("show_gutter");
+var showPrintMarginEl = document.getElementById("show_print_margin");
+var highlightSelectedWordE = document.getElementById("highlight_selected_word");
+var showHScrollEl = document.getElementById("show_hscroll");
+var showVScrollEl = document.getElementById("show_vscroll");
+var animateScrollEl = document.getElementById("animate_scroll");
+var softTabEl = document.getElementById("soft_tab");
+var behavioursEl = document.getElementById("enable_behaviours");
+
+fillDropdown(docEl, doclist.all);
+
+fillDropdown(modeEl, modelist.modes);
+var modesByName = modelist.modesByName;
+bindDropdown("mode", function(value) {
+    env.editor.session.setMode(modesByName[value].mode || modesByName.text.mode);
+    env.editor.session.modeName = value;
+});
+
+doclist.history = doclist.docs.map(function(doc) {
+    return doc.name;
+});
+doclist.history.index = 0;
+doclist.cycleOpen = function(editor, dir) {
+    var h = this.history;
+    h.index += dir;
+    if (h.index >= h.length)
+        h.index = 0;
+    else if (h.index <= 0)
+        h.index = h.length - 1;
+    var s = h[h.index];
+    docEl.value = s;
+    docEl.onchange();
+};
+doclist.addToHistory = function(name) {
+    var h = this.history;
+    var i = h.indexOf(name);
+    if (i != h.index) {
+        if (i != -1)
+            h.splice(i, 1);
+        h.index = h.push(name);
+    }
+};
+
+bindDropdown("doc", function(name) {
+    doclist.loadDoc(name, function(session) {
+        if (!session)
+            return;
+        doclist.addToHistory(session.name);
+        session = env.split.setSession(session);
+        whitespace.detectIndentation(session);
+        updateUIEditorOptions();
+        env.editor.focus();
+    });
+});
+
+
+function updateUIEditorOptions() {
+    var editor = env.editor;
+    var session = editor.session;
+
+    session.setFoldStyle(foldingEl.value);
+
+    saveOption(docEl, session.name);
+    saveOption(modeEl, session.modeName || "text");
+    saveOption(wrapModeEl, session.getUseWrapMode() ? session.getWrapLimitRange().min || "free" : "off");
+
+    saveOption(selectStyleEl, editor.getSelectionStyle() == "line");
+    saveOption(themeEl, editor.getTheme());
+    saveOption(highlightActiveEl, editor.getHighlightActiveLine());
+    saveOption(showHiddenEl, editor.getShowInvisibles());
+    saveOption(showGutterEl, editor.renderer.getShowGutter());
+    saveOption(showPrintMarginEl, editor.renderer.getShowPrintMargin());
+    saveOption(highlightSelectedWordE, editor.getHighlightSelectedWord());
+    saveOption(showHScrollEl, editor.renderer.getHScrollBarAlwaysVisible());
+    saveOption(animateScrollEl, editor.getAnimatedScroll());
+    saveOption(softTabEl, session.getUseSoftTabs());
+    saveOption(behavioursEl, editor.getBehavioursEnabled());
+}
+
+themelist.themes.forEach(function(x){ x.value = x.theme });
+fillDropdown(themeEl, {
+    Bright: themelist.themes.filter(function(x){return !x.isDark}),
+    Dark: themelist.themes.filter(function(x){return x.isDark}),
+});
+
+event.addListener(themeEl, "mouseover", function(e){
+    themeEl.desiredValue = e.target.value;
+    if (!themeEl.$timer)
+        themeEl.$timer = setTimeout(themeEl.updateTheme);
+});
+
+event.addListener(themeEl, "mouseout", function(e){
+    themeEl.desiredValue = null;
+    if (!themeEl.$timer)
+        themeEl.$timer = setTimeout(themeEl.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) {
+    env.editor.setKeyboardHandler(keybindings[value]);
+});
+
+bindDropdown("fontsize", function(value) {
+    env.split.setFontSize(value);
+});
+
+bindDropdown("folding", function(value) {
+    env.editor.session.setFoldStyle(value);
+    env.editor.setShowFoldWidgets(value !== "manual");
+});
+
+bindDropdown("soft_wrap", function(value) {
+    env.editor.setOption("wrap", value);
+});
+
+bindCheckbox("select_style", function(checked) {
+    env.editor.setOption("selectionStyle", checked ? "line" : "text");
+});
+
+bindCheckbox("highlight_active", function(checked) {
+    env.editor.setHighlightActiveLine(checked);
+});
+
+bindCheckbox("show_hidden", function(checked) {
+    env.editor.setShowInvisibles(checked);
+});
+
+bindCheckbox("display_indent_guides", function(checked) {
+    env.editor.setDisplayIndentGuides(checked);
+});
+
+bindCheckbox("show_gutter", function(checked) {
+    env.editor.renderer.setShowGutter(checked);
+});
+
+bindCheckbox("show_print_margin", function(checked) {
+    env.editor.renderer.setShowPrintMargin(checked);
+});
+
+bindCheckbox("highlight_selected_word", function(checked) {
+    env.editor.setHighlightSelectedWord(checked);
+});
+
+bindCheckbox("show_hscroll", function(checked) {
+    env.editor.setOption("hScrollBarAlwaysVisible", checked);
+});
+
+bindCheckbox("show_vscroll", function(checked) {
+    env.editor.setOption("vScrollBarAlwaysVisible", checked);
+});
+
+bindCheckbox("animate_scroll", function(checked) {
+    env.editor.setAnimatedScroll(checked);
+});
+
+bindCheckbox("soft_tab", function(checked) {
+    env.editor.session.setUseSoftTabs(checked);
+});
+
+bindCheckbox("enable_behaviours", function(checked) {
+    env.editor.setBehavioursEnabled(checked);
+});
+
+bindCheckbox("fade_fold_widgets", function(checked) {
+    env.editor.setFadeFoldWidgets(checked);
+});
+bindCheckbox("read_only", function(checked) {
+    env.editor.setReadOnly(checked);
+});
+bindCheckbox("scrollPastEnd", function(checked) {
+    env.editor.setOption("scrollPastEnd", checked);
+});
+
+bindDropdown("split", function(value) {
+    var sp = env.split;
+    if (value == "none") {
+        sp.setSplits(1);
+    } else {
+        var newEditor = (sp.getSplits() == 1);
+        sp.setOrientation(value == "below" ? sp.BELOW : sp.BESIDE);
+        sp.setSplits(2);
+
+        if (newEditor) {
+            var session = sp.getEditor(0).session;
+            var newSession = sp.setSession(session, 1);
+            newSession.name = session.name;
+        }
+    }
+});
+
+
+bindCheckbox("elastic_tabstops", function(checked) {
+    env.editor.setOption("useElasticTabstops", checked);
+});
+
+var iSearchCheckbox = bindCheckbox("isearch", function(checked) {
+    env.editor.setOption("useIncrementalSearch", checked);
+});
+
+env.editor.addEventListener('incrementalSearchSettingChanged', function(event) {
+    iSearchCheckbox.checked = event.isEnabled;
+});
+
+
+function synchroniseScrolling() {
+    var s1 = env.split.$editors[0].session;
+    var s2 = env.split.$editors[1].session;
+    s1.on('changeScrollTop', function(pos) {s2.setScrollTop(pos)});
+    s2.on('changeScrollTop', function(pos) {s1.setScrollTop(pos)});
+    s1.on('changeScrollLeft', function(pos) {s2.setScrollLeft(pos)});
+    s2.on('changeScrollLeft', function(pos) {s1.setScrollLeft(pos)});
+}
+
+bindCheckbox("highlight_token", function(checked) {
+    var editor = env.editor;
+    if (editor.tokenTooltip && !checked) {
+        editor.tokenTooltip.destroy();
+        delete editor.tokenTooltip;
+    } else if (checked) {
+        editor.tokenTooltip = new TokenTooltip(editor);
+    }
+});
+
+var StatusBar = require("ace/ext/statusbar").StatusBar;
+new StatusBar(env.editor, cmdLine.container);
+
+
+var Emmet = require("ace/ext/emmet");
+net.loadScript("https://cloud9ide.github.io/emmet-core/emmet.js", function() {
+    Emmet.setCore(window.emmet);
+    env.editor.setOption("enableEmmet", true);
+});
+
+
+// require("ace/placeholder").PlaceHolder;
+
+var snippetManager = require("ace/snippets").snippetManager;
+
+env.editSnippets = function() {
+    var sp = env.split;
+    if (sp.getSplits() == 2) {
+        sp.setSplits(1);
+        return;
+    }
+    sp.setSplits(1);
+    sp.setSplits(2);
+    sp.setOrientation(sp.BESIDE);
+    var editor = sp.$editors[1];
+    var id = sp.$editors[0].session.$mode.$id || "";
+    var m = snippetManager.files[id];
+    if (!doclist["snippets/" + id]) {
+        var text = m.snippetText;
+        var s = doclist.initDoc(text, "", {});
+        s.setMode("ace/mode/snippets");
+        doclist["snippets/" + id] = s;
+    }
+    editor.on("blur", function() {
+        m.snippetText = editor.getValue();
+        snippetManager.unregister(m.snippets);
+        m.snippets = snippetManager.parseSnippetFile(m.snippetText, m.scope);
+        snippetManager.register(m.snippets);
+    });
+    sp.$editors[0].once("changeMode", function() {
+        sp.setSplits(1);
+    });
+    editor.setSession(doclist["snippets/" + id], 1);
+    editor.focus();
+};
+
+require("ace/ext/language_tools");
+env.editor.setOptions({
+    enableBasicAutocompletion: true,
+    enableLiveAutocompletion: false,
+    enableSnippets: true
+});
+
+var beautify = require("ace/ext/beautify");
+env.editor.commands.addCommands(beautify.commands);
+
+});
diff --git a/demo/kitchen-sink/dev_util.js b/demo/kitchen-sink/dev_util.js
new file mode 100644
index 00000000..f466285d
--- /dev/null
+++ b/demo/kitchen-sink/dev_util.js
@@ -0,0 +1,217 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2010, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Ajax.org B.V. nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+var dom = require("ace/lib/dom");
+var Range = require("ace/range").Range;
+function warn() {
+    var s = (new Error()).stack || "";
+    s = s.split("\n");
+    if (s[1] == "Error") s.shift(); // remove error description on chrome
+    s.shift(); // remove warn
+    s.shift(); // remove the getter
+    s = s.join("\n");
+    // allow easy access to ace in console, but not in ace code
+    if (!/at Object.InjectedScript.|@debugger eval|snippets:\/{3}|\(:\d+:\d+\)/.test(s)) {
+        console.error("trying to access to global variable");
+    }
+}
+function def(o, key, get) {
+    try {
+        Object.defineProperty(o, key, {
+            configurable: true, 
+            get: get,
+            set: function(val) {
+                delete o[key];
+                o[key] = val;
+            }
+        });
+    } catch(e) {
+        console.error(e);
+    }
+}
+def(window, "ace", function(){ warn(); return window.env.editor });
+def(window, "editor", function(){ warn(); return window.env.editor });
+def(window, "session", function(){ warn(); return window.env.editor.session });
+def(window, "split", function(){ warn(); return window.env.split });
+
+
+def(window, "devUtil", function(){ warn(); return exports });
+exports.showTextArea = function(argument) {
+    dom.importCssString("\
+      .ace_text-input {\
+        position: absolute;\
+        z-index: 10!important;\
+        width: 6em!important;\
+        height: 1em;\
+        opacity: 1!important;\
+        background: rgba(0, 92, 255, 0.11);\
+        border: none;\
+        font: inherit;\
+        padding: 0 1px;\
+        margin: 0 -1px;\
+        text-indent: 0em;\
+    }\
+    ");
+};
+
+exports.addGlobals = function() {
+    window.oop = require("ace/lib/oop");
+    window.dom = require("ace/lib/dom");
+    window.Range = require("ace/range").Range;
+    window.Editor = require("ace/editor").Editor;
+    window.assert = require("ace/test/asyncjs/assert");
+    window.asyncjs = require("ace/test/asyncjs/async");
+    window.UndoManager = require("ace/undomanager").UndoManager;
+    window.EditSession = require("ace/edit_session").EditSession;
+    window.MockRenderer = require("ace/test/mockrenderer").MockRenderer;
+    window.EventEmitter = require("ace/lib/event_emitter").EventEmitter;
+    
+    window.getSelection = getSelection;
+    window.setSelection = setSelection;
+    window.testSelection = testSelection;
+};
+
+function getSelection(editor) {
+    var data = editor.multiSelect.toJSON();
+    if (!data.length) data = [data];
+    data = data.map(function(x) {
+        var a, c;
+        if (x.isBackwards) {
+            a = x.end;
+            c = x.start;
+        } else {
+            c = x.end;
+            a = x.start;
+        }
+        return Range.comparePoints(a, c) 
+            ? [a.row, a.column, c.row, c.column]
+            : [a.row, a.column];
+    });
+    return data.length > 1 ? data : data[0];
+}
+function setSelection(editor, data) {
+    if (typeof data[0] == "number")
+        data = [data];
+    editor.selection.fromJSON(data.map(function(x) {
+        var start = {row: x[0], column: x[1]};
+        var end = x.length == 2 ? start : {row: x[2], column: x[3]};
+        var isBackwards = Range.comparePoints(start, end) > 0;
+        return isBackwards ? {
+            start: end,
+            end: start,
+            isBackwards: true
+        } : {
+            start: start,
+            end: end,
+            isBackwards: true
+        };
+    }));
+}
+function testSelection(editor, data) {
+    assert.equal(getSelection(editor) + "", data + "");
+}
+
+exports.recordTestCase = function() {
+    exports.addGlobals();
+    var editor = window.editor;
+    var testcase = window.testcase = [];
+    var assert;
+
+    testcase.push({
+        type: "setValue",
+        data: editor.getValue()
+    }, {
+        type: "setSelection",
+        data: getSelection(editor)
+    });
+    editor.commands.on("afterExec", function(e) {
+        testcase.push({
+            type: "exec",
+            data: e
+        });
+        testcase.push({
+            type: "value",
+            data: editor.getValue()
+        });
+        testcase.push({
+            type: "selection",
+            data: getSelection(editor)
+        });
+    });
+    editor.on("mouseup", function() {
+        testcase.push({
+            type: "setSelection",
+            data: getSelection(editor)
+        });
+    });
+    
+    testcase.toString = function() {
+        var lastValue = "";
+        // var lastSelection = ""
+        var str = this.map(function(x) {
+            var data = x.data;
+            switch (x.type) {
+                case "exec": 
+                    return 'editor.execCommand("' 
+                        + data.command.name
+                        + (data.args ? '", ' + JSON.stringify(data.args) : '"')
+                    + ')';
+                case "setSelection":
+                    return 'setSelection(editor, ' + JSON.stringify(data)  + ')';
+                case "setValue":
+                    if (lastValue != data) {
+                        lastValue = data;
+                        return 'editor.setValue(' + JSON.stringify(data) + ', -1)';
+                    }
+                    return;
+                case "selection":
+                    return 'testSelection(editor, ' + JSON.stringify(data) + ')';
+                case "value":
+                    if (lastValue != data) {
+                        lastValue = data;
+                        return 'assert.equal('
+                            + 'editor.getValue(),'
+                            + JSON.stringify(data)
+                        + ')';
+                    }
+                    return;
+            }
+        }).filter(Boolean).join("\n");
+        
+        return getSelection + "\n"
+            + testSelection + "\n"
+            + setSelection + "\n"
+            + "\n" + str + "\n";
+    };
+};
+
+
+});
diff --git a/demo/kitchen-sink/doclist.js b/demo/kitchen-sink/doclist.js
new file mode 100644
index 00000000..a4848d50
--- /dev/null
+++ b/demo/kitchen-sink/doclist.js
@@ -0,0 +1,218 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2010, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Ajax.org B.V. nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ define(function(require, exports, module) {
+"use strict";
+
+var EditSession = require("ace/edit_session").EditSession;
+var UndoManager = require("ace/undomanager").UndoManager;
+var net = require("ace/lib/net");
+
+var modelist = require("ace/ext/modelist");
+/*********** demo documents ***************************/
+var fileCache = {};
+
+function initDoc(file, path, doc) {
+    if (doc.prepare)
+        file = doc.prepare(file);
+
+    var session = new EditSession(file);
+    session.setUndoManager(new UndoManager());
+    doc.session = session;
+    doc.path = path;
+    session.name = doc.name;
+    if (doc.wrapped) {
+        session.setUseWrapMode(true);
+        session.setWrapLimitRange(80, 80);
+    }
+    var mode = modelist.getModeForPath(path);
+    session.modeName = mode.name;
+    session.setMode(mode.mode);
+    return session;
+}
+
+
+function makeHuge(txt) {
+    for (var i = 0; i < 5; i++)
+        txt += txt;
+    return txt;
+}
+
+var docs = {
+    "docs/javascript.js": {order: 1, name: "JavaScript"},
+
+    "docs/latex.tex": {name: "LaTeX", wrapped: true},
+    "docs/markdown.md": {name: "Markdown", wrapped: true},
+    "docs/mushcode.mc": {name: "MUSHCode", wrapped: true},
+    "docs/pgsql.pgsql": {name: "pgSQL", wrapped: true},
+    "docs/plaintext.txt": {name: "Plain Text", prepare: makeHuge, wrapped: true},
+    "docs/sql.sql": {name: "SQL", wrapped: true},
+
+    "docs/textile.textile": {name: "Textile", wrapped: true},
+
+    "docs/c9search.c9search_results": "C9 Search Results",
+    "docs/mel.mel": "MEL",
+    "docs/Nix.nix": "Nix"
+};
+
+var ownSource = {
+    /* filled from require*/
+};
+
+var hugeDocs = require.toUrl ? {
+    "build/src/ace.js": "",
+    "build/src-min/ace.js": ""
+} : {
+    "src/ace.js": "",
+    "src-min/ace.js": ""
+};
+
+modelist.modes.forEach(function(m) {
+    var ext = m.extensions.split("|")[0];
+    if (ext[0] === "^") {
+        path = ext.substr(1);
+    } else {
+        var path = m.name + "." + ext;
+    }
+    path = "docs/" + path;
+    if (!docs[path]) {
+        docs[path] = {name: m.caption};
+    } else if (typeof docs[path] == "object" && !docs[path].name) {
+        docs[path].name = m.caption;
+    }
+});
+
+
+
+if (window.require && window.require.s) try {
+    for (var path in window.require.s.contexts._.defined) {
+        if (path.indexOf("!") != -1)
+            path = path.split("!").pop();
+        else
+            path = path + ".js";
+        ownSource[path] = "";
+    }
+} catch(e) {}
+
+function sort(list) {
+    return list.sort(function(a, b) {
+        var cmp = (b.order || 0) - (a.order || 0);
+        return cmp || a.name && a.name.localeCompare(b.name);
+    });
+}
+
+function prepareDocList(docs) {
+    var list = [];
+    for (var path in docs) {
+        var doc = docs[path];
+        if (typeof doc != "object")
+            doc = {name: doc || path};
+
+        doc.path = path;
+        doc.desc = doc.name.replace(/^(ace|docs|demo|build)\//, "");
+        if (doc.desc.length > 18)
+            doc.desc = doc.desc.slice(0, 7) + ".." + doc.desc.slice(-9);
+
+        fileCache[doc.name] = doc;
+        list.push(doc);
+    }
+
+    return list;
+}
+
+function loadDoc(name, callback) {
+    var doc = fileCache[name];
+    if (!doc)
+        return callback(null);
+
+    if (doc.session)
+        return callback(doc.session);
+
+    // TODO: show load screen while waiting
+    var path = doc.path;
+    var parts = path.split("/");
+    if (parts[0] == "docs")
+        path = "demo/kitchen-sink/" + path;
+    else if (parts[0] == "ace")
+        path = "lib/" + path;
+
+    net.get(path, function(x) {
+        initDoc(x, path, doc);
+        callback(doc.session);
+    });
+}
+
+function saveDoc(name, callback) {
+    var doc = fileCache[name] || name;
+    if (!doc || !doc.session)
+        return callback("Unknown document: " + name);
+
+    var path = doc.path;
+    var parts = path.split("/");
+    if (parts[0] == "docs")
+        path = "demo/kitchen-sink/" + path;
+    else if (parts[0] == "ace")
+        path = "lib/" + path;
+
+    upload(path, doc.session.getValue(), callback);
+}
+
+function upload(url, data, callback) {
+    url = net.qualifyURL(url);
+    if (!/https?:/.test(url))
+        return callback(new Error("Unsupported url scheme"));
+    var xhr = new XMLHttpRequest();
+    xhr.open("PUT", url, true);
+    xhr.onreadystatechange = function () {
+        if (xhr.readyState === 4) {
+            callback(!/^2../.test(xhr.status));
+        }
+    };
+    xhr.send(data);
+};
+
+
+module.exports = {
+    fileCache: fileCache,
+    docs: sort(prepareDocList(docs)),
+    ownSource: prepareDocList(ownSource),
+    hugeDocs: prepareDocList(hugeDocs),
+    initDoc: initDoc,
+    loadDoc: loadDoc,
+    saveDoc: saveDoc,
+};
+module.exports.all = {
+    "Mode Examples": module.exports.docs,
+    "Huge documents": module.exports.hugeDocs,
+    "own source": module.exports.ownSource
+};
+
+});
+
diff --git a/demo/kitchen-sink/docs/.gitignore b/demo/kitchen-sink/docs/.gitignore
new file mode 100644
index 00000000..56ec8fd9
--- /dev/null
+++ b/demo/kitchen-sink/docs/.gitignore
@@ -0,0 +1,11 @@
+# A sample .gitignore file.
+
+.buildlog
+.DS_Store
+.svn
+
+# Negated patterns:
+!foo.bar
+
+# Also ignore user settings...
+/.settings
diff --git a/demo/kitchen-sink/docs/Dockerfile b/demo/kitchen-sink/docs/Dockerfile
new file mode 100644
index 00000000..70270cbf
--- /dev/null
+++ b/demo/kitchen-sink/docs/Dockerfile
@@ -0,0 +1,53 @@
+#
+# example Dockerfile for http://docs.docker.io/en/latest/examples/postgresql_service/
+#
+
+FROM ubuntu
+MAINTAINER SvenDowideit@docker.com
+
+# Add the PostgreSQL PGP key to verify their Debian packages.
+# It should be the same key as https://www.postgresql.org/media/keys/ACCC4CF8.asc 
+RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8
+
+# Add PostgreSQL's repository. It contains the most recent stable release
+#     of PostgreSQL, ``9.3``.
+RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list
+
+# Update the Ubuntu and PostgreSQL repository indexes
+RUN apt-get update
+
+# Install ``python-software-properties``, ``software-properties-common`` and PostgreSQL 9.3
+#  There are some warnings (in red) that show up during the build. You can hide
+#  them by prefixing each apt-get statement with DEBIAN_FRONTEND=noninteractive
+RUN apt-get -y -q install python-software-properties software-properties-common
+RUN apt-get -y -q install postgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3
+
+# Note: The official Debian and Ubuntu images automatically ``apt-get clean``
+# after each ``apt-get`` 
+
+# Run the rest of the commands as the ``postgres`` user created by the ``postgres-9.3`` package when it was ``apt-get installed``
+USER postgres
+
+# Create a PostgreSQL role named ``docker`` with ``docker`` as the password and
+# then create a database `docker` owned by the ``docker`` role.
+# Note: here we use ``&&\`` to run commands one after the other - the ``\``
+#       allows the RUN command to span multiple lines.
+RUN    /etc/init.d/postgresql start &&\
+    psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" &&\
+    createdb -O docker docker
+
+# Adjust PostgreSQL configuration so that remote connections to the
+# database are possible. 
+RUN echo "host all  all    0.0.0.0/0  md5" >> /etc/postgresql/9.3/main/pg_hba.conf
+
+# And add ``listen_addresses`` to ``/etc/postgresql/9.3/main/postgresql.conf``
+RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf
+
+# Expose the PostgreSQL port
+EXPOSE 5432
+
+# Add VOLUMEs to allow backup of config, logs and databases
+VOLUME	["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]
+
+# Set the default command to run when starting the container
+CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/Haxe.hx b/demo/kitchen-sink/docs/Haxe.hx
new file mode 100644
index 00000000..ab205bba
--- /dev/null
+++ b/demo/kitchen-sink/docs/Haxe.hx
@@ -0,0 +1,17 @@
+class Haxe 
+{
+    public static function main() 
+    {
+        // Say Hello!
+        var greeting:String = "Hello World";
+        trace(greeting);
+        
+        var targets:Array = ["Flash","Javascript","PHP","Neko","C++","iOS","Android","webOS"];
+        trace("Haxe is a great language that can target:");
+        for (target in targets)
+        {
+            trace (" - " + target);
+        }
+        trace("And many more!");
+    }
+}
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/Jack.jack b/demo/kitchen-sink/docs/Jack.jack
new file mode 100644
index 00000000..15acf743
--- /dev/null
+++ b/demo/kitchen-sink/docs/Jack.jack
@@ -0,0 +1,247 @@
+vars it, p
+
+p = {label, value|
+  print("\n" + label)
+  print(inspect(value))
+}
+-- Create an array from 0 to 15
+p("range", i-collect(range(5)))
+
+-- Create an array from 0 to 15 and break up in chunks of 4
+p("chunked range", i-collect(i-chunk(4, range(16))))
+
+-- Check if all or none items in stream pass test.
+p("all < 60 in range(60)", i-all?({i|i<60}, range(60)))
+p("any < 60 in range(60)", i-any?({i|i>60}, range(60)))
+p("all < 60 in range(70)", i-all?({i|i<60}, range(70)))
+p("any < 60 in range(70)", i-any?({i|i>60}, range(70)))
+
+-- Zip three different collections together
+p("zipped", i-collect(i-zip(
+  range(10),
+  [1,2,3,4,5],
+  i-map({i|i*i}, range(10))
+)))
+
+vars names, person, i, doubles, lengths, cubeRange
+names = ["Thorin", "Dwalin", "Balin", "Bifur", "Bofur", "Bombur", "Oin",
+         "Gloin", "Ori", "Nori", "Dori", "Fili", "Kili", "Bilbo", "Gandalf"]
+
+for name in names {
+  if name != "Bilbo" && name != "Gandalf" {
+    print(name)
+  }
+}
+
+person = {name: "Tim", age: 30}
+for key, value in person {
+  print(key + " = " + value)
+}
+
+i = 0
+while i < 10 {
+  i = i + 1
+  print(i)
+}
+
+print("range")
+for i in range(10) {
+  print(i + 1)
+}
+for i in range(10) {
+  print(10 - i)
+}
+
+-- Dynamic object that gives the first 10 doubles
+doubles = {
+  @len: {| 10 }
+  @get: {key|
+    if key is Integer { key * key }
+  }
+}
+print("#doubles", #doubles)
+
+print("Doubles")
+for k, v in doubles {
+  print([k, v])
+}
+
+-- Dynamic object that has names list as keys and string lenth as values
+lengths = {
+  @keys: {| names }
+  @get: {key|
+    if key is String { #key }
+  }
+}
+
+print ("Lengths")
+for k, v in lengths {
+  print([k, v])
+}
+
+
+cubeRange = {n|
+  vars i, v
+  i = 0
+  {
+    @call: {|
+      v = i
+      i = i + 1
+      if v < n { v * v * v }
+    }
+  }
+}
+
+print("Cubes")
+for k, v in cubeRange(5) {
+  print([k, v])
+}
+print("String")
+for k, v in "Hello World" {
+  print([k, v])
+}
+
+
+print([i for i in range(10)])
+print([i for i in range(20) if i % 3])
+
+
+
+-- Example showing how to do parallel work using split..and
+base = {bootstrap, target-dir|
+  split {
+    copy("res", target-dir)
+  } and {
+    if newer("src/*.less", target-dir + "/style.css") {
+      lessc("src/" + bootstrap + ".less", target-dir + "/style.css")
+    }
+  } and {
+    build("src/" + bootstrap + ".js", target-dir + "/app.js")
+  }
+}
+
+
+vars Dragon, pet
+
+Dragon = {name|
+  vars asleep, stuff-in-belly, stuff-in-intestine,
+       feed, walk, put-to-bed, toss, rock,
+       hungry?, poopy?, passage-of-time
+
+  asleep = false
+  stuff-in-belly     = 10 -- He's full.
+  stuff-in-intestine =  0 -- He doesn't need to go.
+
+  print(name + ' is born.')
+
+  feed = {|
+    print('You feed ' + name + '.')
+    stuff-in-belly = 10
+    passage-of-time()
+  }
+
+  walk = {|
+    print('You walk ' + name + ".")
+    stuff-in-intestine = 0
+    passage-of-time
+  }
+
+  put-to-bed = {|
+    print('You put ' + name + ' to bed.')
+    asleep = true
+    for i in range(3) {
+      if asleep {
+        passage-of-time()
+      }
+      if asleep {
+        print(name + ' snores, filling the room with smoke.')
+      }
+    }
+    if asleep {
+      asleep = false
+      print(name + ' wakes up slowly.')
+    }
+  }
+
+  toss = {|
+    print('You toss ' + name + ' up into the air.')
+    print('He giggles, which singes your eyebrows.')
+    passage-of-time()
+  }
+
+  rock = {|
+    print('You rock ' + name + ' gently.')
+    asleep = true
+    print('He briefly dozes off...')
+    passage-of-time()
+    if asleep {
+      asleep = false
+      print('...but wakes when you stop.')
+    }
+  }
+
+  hungry? = {|
+    stuff-in-belly <= 2
+  }
+
+  poopy? = {|
+    stuff-in-intestine >= 8
+  }
+
+  passage-of-time = {|
+    if stuff-in-belly > 0 {
+      -- Move food from belly to intestine
+      stuff-in-belly     = stuff-in-belly     - 1
+      stuff-in-intestine = stuff-in-intestine + 1
+    } else { -- Our dragon is starving!
+      if asleep {
+        asleep = false
+        print('He wakes up suddenly!')
+      }
+      print(name + ' is starving! In desperation, he ate YOU!')
+      abort "died"
+    }
+
+    if stuff-in-intestine >= 10 {
+      stuff-in-intestine = 0
+      print('Whoops! ' + name + ' had an accident...')
+    }
+
+    if hungry?() {
+      if asleep {
+        asleep = false
+        print('He wakes up suddenly!')
+      }
+      print(name + "'s stomach grumbles...")
+    }
+
+    if poopy?() {
+      if asleep {
+        asleep = false
+        print('He wakes up suddenly!')
+      }
+      print(name + ' does the potty dance...')
+    }
+  }
+
+  -- Export the public interface to this closure object.
+  {
+   feed: feed
+   walk: walk
+   put-to-bed: put-to-bed
+   toss: toss
+   rock: rock
+  }
+
+}
+
+pet = Dragon('Norbert')
+pet.feed()
+pet.toss()
+pet.walk()
+pet.put-to-bed()
+pet.rock()
+pet.put-to-bed()
+pet.put-to-bed()
+pet.put-to-bed()
+pet.put-to-bed()
diff --git a/demo/kitchen-sink/docs/Makefile b/demo/kitchen-sink/docs/Makefile
new file mode 100644
index 00000000..9b0b31ac
--- /dev/null
+++ b/demo/kitchen-sink/docs/Makefile
@@ -0,0 +1,122 @@
+.PHONY:    apf ext worker mode theme package test
+
+default: apf worker
+
+update: worker
+
+# packages apf
+
+# This is the first line of a comment \
+and this is still part of the comment \
+as is this, since I keep ending each line \
+with a backslash character
+
+apf:
+    cd node_modules/packager; node package.js projects/apf_cloud9.apr
+	cd node_modules/packager; cat build/apf_release.js | sed 's/\(\/\*FILEHEAD(\).*//g' > ../../plugins-client/lib.apf/www/apf-packaged/apf_release.js
+
+# package debug version of apf
+apfdebug:
+	cd node_modules/packager/projects; cat apf_cloud9.apr | sed 's///g' > apf_cloud9_debug2.apr
+	cd node_modules/packager/projects; cat apf_cloud9_debug2.apr | sed 's/apf_release/apf_debug/g' > apf_cloud9_debug.apr; rm apf_cloud9_debug2.apr
+	cd node_modules/packager; node package.js projects/apf_cloud9_debug.apr
+	cd node_modules/packager; cat build/apf_debug.js | sed 's/\(\/\*FILEHEAD(\).*\/apf\/\(.*\)/\1\2/g' > ../../plugins-client/lib.apf/www/apf-packaged/apf_debug.js
+
+# package_apf--temporary fix for non-workering infra
+pack_apf:
+	mkdir -p build/src
+	mv plugins-client/lib.apf/www/apf-packaged/apf_release.js build/src/apf_release.js
+	node build/r.js -o name=./build/src/apf_release.js out=./plugins-client/lib.apf/www/apf-packaged/apf_release.js baseUrl=.
+
+# makes ace; at the moment, requires dryice@0.4.2
+ace:
+	cd node_modules/ace; make clean pre_build; ./Makefile.dryice.js minimal
+
+
+# packages core
+core: ace
+	mkdir -p build/src
+	node build/r.js -o build/core.build.js
+
+# generates packed template
+helper: 
+	node build/packed_helper.js
+
+helper_clean:
+	mkdir -p build/src
+	node build/packed_helper.js 1
+
+# packages ext
+ext: 
+	node build/r.js -o build/app.build.js
+
+# calls dryice on worker & packages it
+worker: plugins-client/lib.ace/www/worker/worker-language.js
+
+plugins-client/lib.ace/www/worker/worker-language.js plugins-client/lib.ace/www/worker/worker-javascript.js : \
+        $(wildcard node_modules/ace/*) $(wildcard node_modules/ace/*/*) $(wildcard node_modules/ace/*/*/mode/*) \
+        $(wildcard plugins-client/ext.language/*) \
+        $(wildcard plugins-client/ext.language/*/*) \
+        $(wildcard plugins-client/ext.linereport/*) \
+        $(wildcard plugins-client/ext.codecomplete/*) \
+        $(wildcard plugins-client/ext.codecomplete/*/*) \
+        $(wildcard plugins-client/ext.jslanguage/*) \
+        $(wildcard plugins-client/ext.jslanguage/*/*) \
+        $(wildcard plugins-client/ext.csslanguage/*) \
+        $(wildcard plugins-client/ext.csslanguage/*/*) \
+        $(wildcard plugins-client/ext.htmllanguage/*) \
+        $(wildcard plugins-client/ext.htmllanguage/*/*) \
+        $(wildcard plugins-client/ext.jsinfer/*) \
+        $(wildcard plugins-client/ext.jsinfer/*/*) \
+        $(wildcard node_modules/treehugger/lib/*) \
+        $(wildcard node_modules/treehugger/lib/*/*) \
+        $(wildcard node_modules/ace/lib/*) \
+        $(wildcard node_modules/ace/*/*) \
+        Makefile.dryice.js
+	mkdir -p plugins-client/lib.ace/www/worker
+	rm -rf /tmp/c9_worker_build
+	mkdir -p /tmp/c9_worker_build/ext
+	ln -s `pwd`/plugins-client/ext.language /tmp/c9_worker_build/ext/language
+	ln -s `pwd`/plugins-client/ext.codecomplete /tmp/c9_worker_build/ext/codecomplete
+	ln -s `pwd`/plugins-client/ext.jslanguage /tmp/c9_worker_build/ext/jslanguage
+	ln -s `pwd`/plugins-client/ext.csslanguage /tmp/c9_worker_build/ext/csslanguage
+	ln -s `pwd`/plugins-client/ext.htmllanguage /tmp/c9_worker_build/ext/htmllanguage
+	ln -s `pwd`/plugins-client/ext.linereport /tmp/c9_worker_build/ext/linereport
+	ln -s `pwd`/plugins-client/ext.linereport_php /tmp/c9_worker_build/ext/linereport_php
+	node Makefile.dryice.js worker
+	cp node_modules/ace/build/src/worker* plugins-client/lib.ace/www/worker
+
+define 
+
+ifeq
+
+override
+
+# copies built ace modes
+mode:
+	mkdir -p plugins-client/lib.ace/www/mode
+	cp `find node_modules/ace/build/src | grep -E "mode-[a-zA-Z_0-9]+.js"`  plugins-client/lib.ace/www/mode
+
+# copies built ace themes
+theme:
+	mkdir -p plugins-client/lib.ace/www/theme
+	cp `find node_modules/ace/build/src | grep -E "theme-[a-zA-Z_0-9]+.js"` plugins-client/lib.ace/www/theme
+
+gzip_safe:
+	for i in `ls ./plugins-client/lib.packed/www/*.js`; do \
+		gzip -9 -v -c -q -f $$i > $$i.gz ; \
+	done
+
+gzip:
+	for i in `ls ./plugins-client/lib.packed/www/*.js`; do \
+		gzip -9 -v -q -f $$i ; \
+	done
+
+c9core: apf ace core worker mode theme
+    
+package_clean: helper_clean c9core ext
+
+package: helper c9core ext
+
+test check:
+	test/run-tests.sh	
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/Nix.nix b/demo/kitchen-sink/docs/Nix.nix
new file mode 100644
index 00000000..9476db3b
--- /dev/null
+++ b/demo/kitchen-sink/docs/Nix.nix
@@ -0,0 +1,57 @@
+{
+  # Name of our deployment
+  network.description = "HelloWorld";
+  # Enable rolling back to previous versions of our infrastructure
+  network.enableRollback = true;
+
+  # It consists of a single server named 'helloserver'
+  helloserver =
+    # Every server gets passed a few arguments, including a reference
+    # to nixpkgs (pkgs)
+    { config, pkgs, ... }:
+    let
+      # We import our custom packages from ./default passing pkgs as argument
+      packages = import ./default.nix { pkgs = pkgs; };
+      # This is the nodejs version specified in default.nix
+      nodejs   = packages.nodejs;
+      # And this is the application we'd like to deploy
+      app      = packages.app;
+    in
+    {
+      # We'll be running our application on port 8080, because a regular
+      # user cannot bind to port 80
+      # Then, using some iptables magic we'll forward traffic designated to port 80 to 8080
+      networking.firewall.enable = true;
+      # We will open up port 22 (SSH) as well otherwise we're locking ourselves out
+      networking.firewall.allowedTCPPorts = [ 80 8080 22 ];
+      networking.firewall.allowPing = true;
+
+      # Port forwarding using iptables
+      networking.firewall.extraCommands = ''
+        iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
+      '';
+
+      # To run our node.js program we're going to use a systemd service
+      # We can configure the service to automatically start on boot and to restart
+      # the process in case it crashes
+      systemd.services.helloserver = {
+        description = "Hello world application";
+        # Start the service after the network is available
+        after = [ "network.target" ];
+        # We're going to run it on port 8080 in production
+        environment = { PORT = "8080"; };
+        serviceConfig = {
+          # The actual command to run
+          ExecStart = "${nodejs}/bin/node ${app}/server.js";
+          # For security reasons we'll run this process as a special 'nodejs' user
+          User = "nodejs";
+          Restart = "always";
+        };
+      };
+
+      # And lastly we ensure the user we run our application as is created
+      users.extraUsers = {
+        nodejs = { };
+      };
+    };
+}
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/abap.abap b/demo/kitchen-sink/docs/abap.abap
new file mode 100644
index 00000000..f66bfdfa
--- /dev/null
+++ b/demo/kitchen-sink/docs/abap.abap
@@ -0,0 +1,36 @@
+***************************************
+** Program: EXAMPLE                  **
+** Author: Joe Byte, 07-Jul-2007     **
+***************************************
+ 
+REPORT BOOKINGS.
+ 
+* Read flight bookings from the database
+SELECT * FROM FLIGHTINFO
+  WHERE CLASS = 'Y'       "Y = economy
+  OR    CLASS = 'C'.      "C = business
+(...)
+
+REPORT TEST.
+WRITE 'Hello World'.
+
+USERPROMPT = 'Please double-click on a line in the output list ' &
+             'to see the complete details of the transaction.'.
+
+
+DATA LAST_EOM    TYPE D.  "last end-of-month date
+ 
+* Start from today's date
+  LAST_EOM = SY-DATUM.
+* Set characters 6 and 7 (0-relative) of the YYYYMMDD string to "01",
+* giving the first day of the current month
+  LAST_EOM+6(2) = '01'.
+* Subtract one day
+  LAST_EOM = LAST_EOM - 1.
+ 
+  WRITE: 'Last day of previous month was', LAST_EOM.
+  
+DATA : BEGIN OF I_VBRK OCCURS 0,
+         VBELN LIKE VBRK-VBELN,
+         ZUONR LIKE VBRK-ZUONR,
+       END OF I_VBRK.
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/abc.abc b/demo/kitchen-sink/docs/abc.abc
new file mode 100644
index 00000000..d8ac326e
--- /dev/null
+++ b/demo/kitchen-sink/docs/abc.abc
@@ -0,0 +1,171 @@
+%abc-2.1
+H:This file contains some example English tunes
+% note that the comments (like this one) are to highlight usages
+%  and would not normally be included in such detail
+O:England             % the origin of all tunes is England
+
+X:1                   % tune no 1
+T:Dusty Miller, The   % title
+T:Binny's Jig         % an alternative title
+C:Trad.               % traditional
+R:DH                  % double hornpipe
+M:3/4                 % meter
+K:G                   % key
+B>cd BAG|FA Ac BA|B>cd BAG|DG GB AG:|
+Bdd gfg|aA Ac BA|Bdd gfa|gG GB AG:|
+BG G/2G/2G BG|FA Ac BA|BG G/2G/2G BG|DG GB AG:|
+W:Hey, the dusty miller, and his dusty coat;
+W:He will win a shilling, or he spend a groat.
+W:Dusty was the coat, dusty was the colour;
+W:Dusty was the kiss, that I got frae the miller.
+
+X:2
+T:Old Sir Simon the King
+C:Trad.
+S:Offord MSS          % from Offord manuscript
+N:see also Playford   % reference note
+M:9/8
+R:SJ                  % slip jig
+N:originally in C     % transcription note
+K:G
+D|GFG GAG G2D|GFG GAG F2D|EFE EFE EFG|A2G F2E D2:|
+D|GAG GAB d2D|GAG GAB c2D|[1 EFE EFE EFG|[A2G] F2E D2:|\ % no line-break in score
+M:12/8                % change of meter
+[2 E2E EFE E2E EFG|\  % no line-break in score
+M:9/8                 % change of meter
+A2G F2E D2|]
+
+X:3
+T:William and Nancy
+T:New Mown Hay
+T:Legacy, The
+C:Trad.
+O:England; Gloucs; Bledington % place of origin
+B:Sussex Tune Book            % can be found in these books
+B:Mally's Cotswold Morris vol.1 2
+D:Morris On                   % can be heard on this record
+P:(AB)2(AC)2A                 % play the parts in this order
+M:6/8
+K:G                        
+[P:A] D|"G"G2G GBd|"C"e2e "G"dBG|"D7"A2d "G"BAG|"C"E2"D7"F "G"G2:|
+[P:B] d|"G"e2d B2d|"C"gfe "G"d2d| "G"e2d    B2d|"C"gfe    "D7"d2c|
+        "G"B2B Bcd|"C"e2e "G"dBG|"D7"A2d "G"BAG|"C"E2"D7"F "G"G2:|
+% changes of meter, using inline fields
+[T:Slows][M:4/4][L:1/4][P:C]"G"d2|"C"e2 "G"d2|B2 d2|"Em"gf "A7"e2|"D7"d2 "G"d2|\
+       "C"e2 "G"d2|[M:3/8][L:1/8] "G"B2 d |[M:6/8] "C"gfe "D7"d2c|
+        "G"B2B Bcd|"C"e2e "G"dBG|"D7"A2d "G"BAG|"C"E2"D7"F "G"G2:|
+
+X:4
+T:South Downs Jig
+R:jig
+S:Robert Harbron
+M:6/8
+L:1/8
+K:G
+|: d | dcA G3 | EFG AFE | DEF GAB | cde d2d |
+dcA G3 | EFG AFE | DEF GAB | cAF G2 :|
+B | Bcd e2c | d2B c2A | Bcd e2c | [M:9/8]d2B c2B A3 |
+[M:6/8]DGF E3 | cBA FED | DEF GAB |1 cAF G2 :|2 cAF G3 |]
+
+X:5
+T:Atholl Brose
+% in this example, which reproduces Highland Bagpipe gracing,
+%  the large number of grace notes mean that it is more convenient to be specific about
+%  score line-breaks (using the $ symbol), rather than using code line breaks to indicate them
+I:linebreak $
+K:D
+{gcd}c<{e}A {gAGAG}A2 {gef}e>A {gAGAG}Ad|
+{gcd}c<{e}A {gAGAG}A>e {ag}a>f {gef}e>d|
+{gcd}c<{e}A {gAGAG}A2 {gef}e>A {gAGAG}Ad|
+{g}c/d/e {g}G>{d}B {gf}gG {dc}d>B:|$
+{g}ce {ag}a>e {gf}g>e|
+{g}ce {ag}a2 {GdG}a>d|
+{g}ce {ag}a>e {gf}g>f|
+{gef}e>d {gf}g>d {gBd}B<{e}G {dc}d>B|
+{g}ce {ag}a>e {gf}g>e|
+{g}ce {ag}a2 {GdG}ad|
+{g}c<{GdG}e {gf}ga {f}g>e {g}f>d|
+{g}e/f/g {Gdc}d>c {gBd}B<{e}G {dc}d2|]
+
+X:6
+T:Untitled Reel
+C:Trad.
+K:D
+eg|a2ab ageg|agbg agef|g2g2 fgag|f2d2 d2:|\
+ed|cecA B2ed|cAcA E2ed|cecA B2ed|c2A2 A2:|
+K:G
+AB|cdec BcdB|ABAF GFE2|cdec BcdB|c2A2 A2:|
+
+X:7
+T:Kitchen Girl
+C:Trad.
+K:D
+[c4a4] [B4g4]|efed c2cd|e2f2 gaba|g2e2 e2fg|
+a4 g4|efed cdef|g2d2 efed|c2A2 A4:|
+K:G
+ABcA BAGB|ABAG EDEG|A2AB c2d2|e3f edcB|ABcA BAGB|
+ABAG EGAB|cBAc BAG2|A4 A4:|
+
+%abc-2.1
+%%pagewidth      21cm
+%%pageheight     29.7cm
+%%topspace       0.5cm
+%%topmargin      1cm
+%%botmargin      0cm
+%%leftmargin     1cm
+%%rightmargin    1cm
+%%titlespace     0cm
+%%titlefont      Times-Bold 32
+%%subtitlefont   Times-Bold 24
+%%composerfont   Times 16
+%%vocalfont      Times-Roman 14
+%%staffsep       60pt
+%%sysstaffsep    20pt
+%%musicspace     1cm
+%%vocalspace     5pt
+%%measurenb      0
+%%barsperstaff   5
+%%scale          0.7
+X: 1
+T: Canzonetta a tre voci
+C: Claudio Monteverdi (1567-1643)
+M: C
+L: 1/4
+Q: "Andante mosso" 1/4 = 110
+%%score [1 2 3]
+V: 1 clef=treble name="Soprano"sname="A"
+V: 2 clef=treble name="Alto"   sname="T"
+V: 3 clef=bass middle=d name="Tenor"  sname="B"
+%%MIDI program 1 75 % recorder
+%%MIDI program 2 75
+%%MIDI program 3 75
+K: Eb
+% 1 - 4
+[V: 1] |:z4  |z4  |f2ec         |_ddcc        |
+w: Son que-sti~i cre-spi cri-ni~e
+w: Que-sti son gli~oc-chi che mi-
+[V: 2] |:c2BG|AAGc|(F/G/A/B/)c=A|B2AA         |
+w: Son que-sti~i cre-spi cri-ni~e que - - - - sto~il vi-so e
+w: Que-sti son~gli oc-chi che mi-ran - - - - do fi-so mi-
+[V: 3] |:z4  |f2ec|_ddcf        |(B/c/_d/e/)ff|
+w: Son que-sti~i cre-spi cri-ni~e que - - - - sto~il
+w: Que-sti son~gli oc-chi che mi-ran - - - - do
+% 5 - 9
+[V: 1] cAB2     |cAAA |c3B|G2!fermata!Gz ::e4|
+w: que-sto~il vi-so ond' io ri-man-go~uc-ci-so. Deh,
+w: ran-do fi-so, tut-to re-stai con-qui-so.
+[V: 2] AAG2     |AFFF |A3F|=E2!fermata!Ez::c4|
+w: que-sto~il vi-so ond' io ri-man-go~uc-ci-so. Deh,
+w: ran-do fi-so tut-to re-stai con-qui-so.
+[V: 3] (ag/f/e2)|A_ddd|A3B|c2!fermata!cz ::A4|
+w: vi - - - so ond' io ti-man-go~uc-ci-so. Deh,
+w: fi - - - so tut-to re-stai con-qui-so.
+% 10 - 15
+[V: 1] f_dec |B2c2|zAGF  |\
+w: dim-me-lo ben mi-o, che que-sto\
+=EFG2          |1F2z2:|2F8|] % more notes
+w: sol de-si-o_. % more lyrics
+[V: 2] ABGA  |G2AA|GF=EF |(GF3/2=E//D//E)|1F2z2:|2F8|]
+w: dim-me-lo ben mi-o, che que-sto sol de-si - - - - o_.
+[V: 3] _dBc>d|e2AF|=EFc_d|c4             |1F2z2:|2F8|]
+w: dim-me-lo ben mi-o, che que-sto sol de-si-o_.
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/actionscript.as b/demo/kitchen-sink/docs/actionscript.as
new file mode 100644
index 00000000..ffe21fbf
--- /dev/null
+++ b/demo/kitchen-sink/docs/actionscript.as
@@ -0,0 +1,51 @@
+package code
+{
+    /*****************************************
+	 * based on textmate actionscript bundle
+	 ****************************************/
+	 
+	import fl.events.SliderEvent;
+	
+	public class Foo extends MovieClip
+	{
+		//*************************
+		// Properties:
+		
+		public var activeSwatch:MovieClip;
+		
+		// Color offsets
+		public var c1:Number = 0;	// R
+		
+		//*************************
+		// Constructor:
+		
+		public function Foo()
+		{
+			// Respond to mouse events
+			swatch1_btn.addEventListener(MouseEvent.CLICK,swatchHandler,false,0,false);
+			previewBox_btn.addEventListener(MouseEvent.MOUSE_DOWN,dragPressHandler);
+			
+			// Respond to drag events
+			red_slider.addEventListener(SliderEvent.THUMB_DRAG,sliderHandler);
+			
+			// Draw a frame later
+			addEventListener(Event.ENTER_FRAME,draw);
+		}
+        
+		protected function clickHandler(event:MouseEvent):void
+		{
+			car.transform.colorTransform = new ColorTransform(0,0,0,1,c1,c2,c3);
+		}
+		
+		protected function changeRGBHandler(event:Event):void
+		{
+			c1 = Number(c1_txt.text);
+            
+			if(!(c1>=0)){
+				c1 = 0;
+			}			
+			
+			updateSliders();
+		}
+	}
+}
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/ada.ada b/demo/kitchen-sink/docs/ada.ada
new file mode 100644
index 00000000..90e027f0
--- /dev/null
+++ b/demo/kitchen-sink/docs/ada.ada
@@ -0,0 +1,5 @@
+with Ada.Text_IO; use Ada.Text_IO;
+procedure Hello is
+begin
+  Put_Line("Hello, world!");
+end Hello;
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/asciidoc.asciidoc b/demo/kitchen-sink/docs/asciidoc.asciidoc
new file mode 100644
index 00000000..8cddab5d
--- /dev/null
+++ b/demo/kitchen-sink/docs/asciidoc.asciidoc
@@ -0,0 +1,6040 @@
+AsciiDoc User Guide
+===================
+Stuart Rackham 
+:Author Initials: SJR
+:toc:
+:icons:
+:numbered:
+:website: http://www.methods.co.nz/asciidoc/
+
+AsciiDoc is a text document format for writing notes, documentation,
+articles, books, ebooks, slideshows, web pages, blogs and UNIX man
+pages.  AsciiDoc files can be translated to many formats including
+HTML, PDF, EPUB, man page.  AsciiDoc is highly configurable: both the
+AsciiDoc source file syntax and the backend output markups (which can
+be almost any type of SGML/XML markup) can be customized and extended
+by the user.
+
+.This document
+**********************************************************************
+This is an overly large document, it probably needs to be refactored
+into a Tutorial, Quick Reference and Formal Reference.
+
+If you're new to AsciiDoc read this section and the <> section and take a look at the example AsciiDoc (`*.txt`)
+source files in the distribution `doc` directory.
+**********************************************************************
+
+
+Introduction
+------------
+AsciiDoc is a plain text human readable/writable document format that
+can be translated to DocBook or HTML using the asciidoc(1) command.
+You can then either use asciidoc(1) generated HTML directly or run
+asciidoc(1) DocBook output through your favorite DocBook toolchain or
+use the AsciiDoc a2x(1) toolchain wrapper to produce PDF, EPUB, DVI,
+LaTeX, PostScript, man page, HTML and text formats.
+
+The AsciiDoc format is a useful presentation format in its own right:
+AsciiDoc markup is simple, intuitive and as such is easily proofed and
+edited.
+
+AsciiDoc is light weight: it consists of a single Python script and a
+bunch of configuration files. Apart from asciidoc(1) and a Python
+interpreter, no other programs are required to convert AsciiDoc text
+files to DocBook or HTML. See <>
+below.
+
+Text markup conventions tend to be a matter of (often strong) personal
+preference: if the default syntax is not to your liking you can define
+your own by editing the text based asciidoc(1) configuration files.
+You can also create configuration files to translate AsciiDoc
+documents to almost any SGML/XML markup.
+
+asciidoc(1) comes with a set of configuration files to translate
+AsciiDoc articles, books and man pages to HTML or DocBook backend
+formats.
+
+.My AsciiDoc Itch
+**********************************************************************
+DocBook has emerged as the de facto standard Open Source documentation
+format. But DocBook is a complex language, the markup is difficult to
+read and even more difficult to write directly -- I found I was
+spending more time typing markup tags, consulting reference manuals
+and fixing syntax errors, than I was writing the documentation.
+**********************************************************************
+
+
+[[X6]]
+Getting Started
+---------------
+Installing AsciiDoc
+~~~~~~~~~~~~~~~~~~~
+See the `README` and `INSTALL` files for install prerequisites and
+procedures. Packagers take a look at <>.
+
+[[X11]]
+Example AsciiDoc Documents
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+The best way to quickly get a feel for AsciiDoc is to view the
+AsciiDoc web site and/or distributed examples:
+
+- Take a look at the linked examples on the AsciiDoc web site home
+  page {website}.  Press the 'Page Source' sidebar menu item to view
+  corresponding AsciiDoc source.
+- Read the `*.txt` source files in the distribution `./doc` directory
+  along with the corresponding HTML and DocBook XML files.
+
+
+AsciiDoc Document Types
+-----------------------
+There are three types of AsciiDoc documents: article, book and
+manpage. All document types share the same AsciiDoc format with some
+minor variations. If you are familiar with DocBook you will have
+noticed that AsciiDoc document types correspond to the same-named
+DocBook document types.
+
+Use the asciidoc(1) `-d` (`--doctype`) option to specify the AsciiDoc
+document type -- the default document type is 'article'.
+
+By convention the `.txt` file extension is used for AsciiDoc document
+source files.
+
+article
+~~~~~~~
+Used for short documents, articles and general documentation.  See the
+AsciiDoc distribution `./doc/article.txt` example.
+
+AsciiDoc defines standard DocBook article frontmatter and backmatter
+<> (appendix, abstract, bibliography,
+glossary, index).
+
+book
+~~~~
+Books share the same format as articles, with the following
+differences:
+
+- The part titles in multi-part books are <>
+  (same level as book title).
+- Some sections are book specific e.g. preface and colophon.
+
+Book documents will normally be used to produce DocBook output since
+DocBook processors can automatically generate footnotes, table of
+contents, list of tables, list of figures, list of examples and
+indexes.
+
+AsciiDoc defines standard DocBook book frontmatter and backmatter
+<> (appendix, dedication, preface,
+bibliography, glossary, index, colophon).
+
+.Example book documents
+Book::
+  The `./doc/book.txt` file in the AsciiDoc distribution.
+
+Multi-part book::
+  The `./doc/book-multi.txt` file in the AsciiDoc distribution.
+
+manpage
+~~~~~~~
+Used to generate roff format UNIX manual pages.  AsciiDoc manpage
+documents observe special header title and section naming conventions
+-- see the <> section for details.
+
+AsciiDoc defines the 'synopsis' <> to
+generate the DocBook `refsynopsisdiv` section.
+
+See also the asciidoc(1) man page source (`./doc/asciidoc.1.txt`) from
+the AsciiDoc distribution.
+
+
+[[X5]]
+AsciiDoc Backends
+-----------------
+The asciidoc(1) command translates an AsciiDoc formatted file to the
+backend format specified by the `-b` (`--backend`) command-line
+option. asciidoc(1) itself has little intrinsic knowledge of backend
+formats, all translation rules are contained in customizable cascading
+configuration files. Backend specific attributes are listed in the
+<> section.
+
+docbook45::
+  Outputs DocBook XML 4.5 markup.
+
+html4::
+  This backend generates plain HTML 4.01 Transitional markup.
+
+xhtml11::
+  This backend generates XHTML 1.1 markup styled with CSS2. Output
+  files have an `.html` extension.
+
+html5::
+  This backend generates HTML 5 markup, apart from the inclusion of
+  <> it is functionally identical to
+  the 'xhtml11' backend.
+
+slidy::
+  Use this backend to generate self-contained
+  http://www.w3.org/Talks/Tools/Slidy2/[Slidy] HTML slideshows for
+  your web browser from AsciiDoc documents. The Slidy backend is
+  documented in the distribution `doc/slidy.txt` file and
+  {website}slidy.html[online].
+
+wordpress::
+  A minor variant of the 'html4' backend to support
+  http://srackham.wordpress.com/blogpost1/[blogpost].
+
+latex::
+  Experimental LaTeX backend.
+
+Backend Aliases
+~~~~~~~~~~~~~~~
+Backend aliases are alternative names for AsciiDoc backends.  AsciiDoc
+comes with two backend aliases: 'html' (aliased to 'xhtml11') and
+'docbook' (aliased to 'docbook45').
+
+You can assign (or reassign) backend aliases by setting an AsciiDoc
+attribute named like `backend-alias-` to an AsciiDoc backend
+name. For example, the following backend alias attribute definitions
+appear in the `[attributes]` section of the global `asciidoc.conf`
+configuration file:
+
+  backend-alias-html=xhtml11
+  backend-alias-docbook=docbook45
+
+[[X100]]
+Backend Plugins
+~~~~~~~~~~~~~~~
+The asciidoc(1) `--backend` option is also used to install and manage
+backend <>.
+
+- A backend plugin is used just like the built-in backends.
+- Backend plugins <> over built-in backends with
+  the same name.
+- You can use the `{asciidoc-confdir}` <> to
+  refer to the built-in backend configuration file location from
+  backend plugin configuration files.
+- You can use the `{backend-confdir}` <> to
+  refer to the backend plugin configuration file location.
+- By default backends plugins are installed in
+  `$HOME/.asciidoc/backends/` where `` is the
+  backend name.
+
+
+DocBook
+-------
+AsciiDoc generates 'article', 'book' and 'refentry'
+http://www.docbook.org/[DocBook] documents (corresponding to the
+AsciiDoc 'article', 'book' and 'manpage' document types).
+
+Most Linux distributions come with conversion tools (collectively
+called a toolchain) for <> to
+presentation formats such as Postscript, HTML, PDF, EPUB, DVI,
+PostScript, LaTeX, roff (the native man page format), HTMLHelp,
+JavaHelp and text.  There are also programs that allow you to view
+DocBook files directly, for example http://live.gnome.org/Yelp[Yelp]
+(the GNOME help viewer).
+
+[[X12]]
+Converting DocBook to other file formats
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+DocBook files are validated, parsed and translated various
+presentation file formats using a combination of applications
+collectively called a DocBook 'tool chain'. The function of a tool
+chain is to read the DocBook markup (produced by AsciiDoc) and
+transform it to a presentation format (for example HTML, PDF, HTML
+Help, EPUB, DVI, PostScript, LaTeX).
+
+A wide range of user output format requirements coupled with a choice
+of available tools and stylesheets results in many valid tool chain
+combinations.
+
+[[X43]]
+a2x Toolchain Wrapper
+~~~~~~~~~~~~~~~~~~~~~
+One of the biggest hurdles for new users is installing, configuring
+and using a DocBook XML toolchain. `a2x(1)` can help -- it's a
+toolchain wrapper command that will generate XHTML (chunked and
+unchunked), PDF, EPUB, DVI, PS, LaTeX, man page, HTML Help and text
+file outputs from an AsciiDoc text file.  `a2x(1)` does all the grunt
+work associated with generating and sequencing the toolchain commands
+and managing intermediate and output files.  `a2x(1)` also optionally
+deploys admonition and navigation icons and a CSS stylesheet. See the
+`a2x(1)` man page for more details. In addition to `asciidoc(1)` you
+also need <>, <> and
+optionally: <> or <> (to generate PDF);
+`w3m(1)` or `lynx(1)` (to generate text).
+
+The following examples generate `doc/source-highlight-filter.pdf` from
+the AsciiDoc `doc/source-highlight-filter.txt` source file. The first
+example uses `dblatex(1)` (the default PDF generator) the second
+example forces FOP to be used:
+
+  $ a2x -f pdf doc/source-highlight-filter.txt
+  $ a2x -f pdf --fop doc/source-highlight-filter.txt
+
+See the `a2x(1)` man page for details.
+
+TIP: Use the `--verbose` command-line option to view executed
+toolchain commands.
+
+HTML generation
+~~~~~~~~~~~~~~~
+AsciiDoc produces nicely styled HTML directly without requiring a
+DocBook toolchain but there are also advantages in going the DocBook
+route:
+
+- HTML from DocBook can optionally include automatically generated
+  indexes, tables of contents, footnotes, lists of figures and tables.
+- DocBook toolchains can also (optionally) generate separate (chunked)
+  linked HTML pages for each document section.
+- Toolchain processing performs link and document validity checks.
+- If the DocBook 'lang' attribute is set then things like table of
+  contents, figure and table captions and admonition captions will be
+  output in the specified language (setting the AsciiDoc 'lang'
+  attribute sets the DocBook 'lang' attribute).
+
+On the other hand, HTML output directly from AsciiDoc is much faster,
+is easily customized and can be used in situations where there is no
+suitable DocBook toolchain (for example, see the {website}[AsciiDoc
+website]).
+
+PDF generation
+~~~~~~~~~~~~~~
+There are two commonly used tools to generate PDFs from DocBook,
+<> and <>.
+
+.dblatex or FOP?
+- 'dblatex' is easier to install, there's zero configuration
+  required and no Java VM to install -- it just works out of the box.
+- 'dblatex' source code highlighting and numbering is superb.
+- 'dblatex' is easier to use as it converts DocBook directly to PDF
+  whereas before using 'FOP' you have to convert DocBook to XML-FO
+  using <>.
+- 'FOP' is more feature complete (for example, callouts are processed
+  inside literal layouts) and arguably produces nicer looking output.
+
+HTML Help generation
+~~~~~~~~~~~~~~~~~~~~
+. Convert DocBook XML documents to HTML Help compiler source files
+  using <> and <>.
+. Convert the HTML Help source (`.hhp` and `.html`) files to HTML Help
+  (`.chm`) files using the <>.
+
+Toolchain components summary
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+AsciiDoc::
+    Converts AsciiDoc (`.txt`) files to DocBook XML (`.xml`) files.
+
+[[X13]]http://docbook.sourceforge.net/projects/xsl/[DocBook XSL Stylesheets]::
+  These are a set of XSL stylesheets containing rules for converting
+  DocBook XML documents to HTML, XSL-FO, manpage and HTML Help files.
+  The stylesheets are used in conjunction with an XML parser such as
+  <>.
+
+[[X40]]http://www.xmlsoft.org[xsltproc]::
+  An XML parser for applying XSLT stylesheets (in our case the
+  <>) to XML documents.
+
+[[X31]]http://dblatex.sourceforge.net/[dblatex]::
+  Generates PDF, DVI, PostScript and LaTeX formats directly from
+  DocBook source via the intermediate LaTeX typesetting language --
+  uses <>, <> and
+  `latex(1)`.
+
+[[X14]]http://xml.apache.org/fop/[FOP]::
+  The Apache Formatting Objects Processor converts XSL-FO (`.fo`)
+  files to PDF files.  The XSL-FO files are generated from DocBook
+  source files using <> and
+  <>.
+
+[[X67]]Microsoft Help Compiler::
+  The Microsoft HTML Help Compiler (`hhc.exe`) is a command-line tool
+  that converts HTML Help source files to a single HTML Help (`.chm`)
+  file. It runs on MS Windows platforms and can be downloaded from
+  http://www.microsoft.com.
+
+AsciiDoc dblatex configuration files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The AsciiDoc distribution `./dblatex` directory contains
+`asciidoc-dblatex.xsl` (customized XSL parameter settings) and
+`asciidoc-dblatex.sty` (customized LaTeX settings). These are examples
+of optional <> output customization and are used by
+<>.
+
+AsciiDoc DocBook XSL Stylesheets drivers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+You will have noticed that the distributed HTML and HTML Help
+documentation files (for example `./doc/asciidoc.html`) are not the
+plain outputs produced using the default 'DocBook XSL Stylesheets'
+configuration.  This is because they have been processed using
+customized DocBook XSL Stylesheets along with (in the case of HTML
+outputs) the custom `./stylesheets/docbook-xsl.css` CSS stylesheet.
+
+You'll find the customized DocBook XSL drivers along with additional
+documentation in the distribution `./docbook-xsl` directory. The
+examples that follow are executed from the distribution documentation
+(`./doc`) directory. These drivers are also used by <>.
+
+`common.xsl`::
+    Shared driver parameters.  This file is not used directly but is
+    included in all the following drivers.
+
+`chunked.xsl`::
+    Generate chunked XHTML (separate HTML pages for each document
+    section) in the `./doc/chunked` directory. For example:
+
+    $ python ../asciidoc.py -b docbook asciidoc.txt
+    $ xsltproc --nonet ../docbook-xsl/chunked.xsl asciidoc.xml
+
+`epub.xsl`::
+    Used by <> to generate EPUB formatted documents.
+
+`fo.xsl`::
+    Generate XSL Formatting Object (`.fo`) files for subsequent PDF
+    file generation using FOP. For example:
+
+    $ python ../asciidoc.py -b docbook article.txt
+    $ xsltproc --nonet ../docbook-xsl/fo.xsl article.xml > article.fo
+    $ fop article.fo article.pdf
+
+`htmlhelp.xsl`::
+    Generate Microsoft HTML Help source files for the MS HTML Help
+    Compiler in the `./doc/htmlhelp` directory. This example is run on
+    MS Windows from a Cygwin shell prompt:
+
+    $ python ../asciidoc.py -b docbook asciidoc.txt
+    $ xsltproc --nonet ../docbook-xsl/htmlhelp.xsl asciidoc.xml
+    $ c:/Program\ Files/HTML\ Help\ Workshop/hhc.exe htmlhelp.hhp
+
+`manpage.xsl`::
+    Generate a `roff(1)` format UNIX man page from a DocBook XML
+    'refentry' document. This example generates an `asciidoc.1` man
+    page file:
+
+    $ python ../asciidoc.py -d manpage -b docbook asciidoc.1.txt
+    $ xsltproc --nonet ../docbook-xsl/manpage.xsl asciidoc.1.xml
+
+`xhtml.xsl`::
+    Convert a DocBook XML file to a single XHTML file. For example:
+
+    $ python ../asciidoc.py -b docbook asciidoc.txt
+    $ xsltproc --nonet ../docbook-xsl/xhtml.xsl asciidoc.xml > asciidoc.html
+
+If you want to see how the complete documentation set is processed
+take a look at the A-A-P script `./doc/main.aap`.
+
+
+Generating Plain Text Files
+---------------------------
+AsciiDoc does not have a text backend (for most purposes AsciiDoc
+source text is fine), however you can convert AsciiDoc text files to
+formatted text using the AsciiDoc <> toolchain wrapper
+utility.
+
+
+[[X35]]
+HTML5 and XHTML 1.1
+-------------------
+The 'xhtml11' and 'html5' backends embed or link CSS and JavaScript
+files in their outputs, there is also a <> plugin
+framework.
+
+- If the AsciiDoc 'linkcss' attribute is defined then CSS and
+  JavaScript files are linked to the output document, otherwise they
+  are embedded (the default behavior).
+- The default locations for CSS and JavaScript files can be changed by
+  setting the AsciiDoc 'stylesdir' and 'scriptsdir' attributes
+  respectively.
+- The default locations for embedded and linked files differ and are
+  calculated at different times -- embedded files are loaded when
+  asciidoc(1) generates the output document, linked files are loaded
+  by the browser when the user views the output document.
+- Embedded files are automatically inserted in the output files but
+  you need to manually copy linked CSS and Javascript files from
+  AsciiDoc <> to the correct location
+  relative to the output document.
+
+.Stylesheet file locations
+[cols="3*",frame="topbot",options="header"]
+|====================================================================
+|'stylesdir' attribute
+|Linked location ('linkcss' attribute defined)
+|Embedded location ('linkcss' attribute undefined)
+
+|Undefined (default).
+|Same directory as the output document.
+|`stylesheets` subdirectory in the AsciiDoc configuration directory
+(the directory containing the backend conf file).
+
+|Absolute or relative directory name.
+|Absolute or relative to the output document.
+|Absolute or relative to the AsciiDoc configuration directory (the
+directory containing the backend conf file).
+
+|====================================================================
+
+.JavaScript file locations
+[cols="3*",frame="topbot",options="header"]
+|====================================================================
+|'scriptsdir' attribute
+|Linked location ('linkcss' attribute defined)
+|Embedded location ('linkcss' attribute undefined)
+
+|Undefined (default).
+|Same directory as the output document.
+|`javascripts` subdirectory in the AsciiDoc configuration directory
+(the directory containing the backend conf file).
+
+|Absolute or relative directory name.
+|Absolute or relative to the output document.
+|Absolute or relative to the AsciiDoc configuration directory (the
+directory containing the backend conf file).
+
+|====================================================================
+
+[[X99]]
+Themes
+~~~~~~
+The AsciiDoc 'theme' attribute is used to select an alternative CSS
+stylesheet and to optionally include additional JavaScript code.
+
+- Theme files reside in an AsciiDoc <>
+  named `themes//` (where `` is the the theme name set
+  by the 'theme' attribute). asciidoc(1) sets the 'themedir' attribute
+  to the theme directory path name.
+- The 'theme' attribute can also be set using the asciidoc(1)
+  `--theme` option, the `--theme` option can also be used to manage
+  theme <>.
+- AsciiDoc ships with two themes: 'flask' and 'volnitsky'.
+- The `.css` file replaces the default `asciidoc.css` CSS file.
+- The `.js` file is included in addition to the default
+  `asciidoc.js` JavaScript file.
+- If the <> attribute is defined then icons are loaded
+  from the theme `icons` sub-directory if it exists (i.e.  the
+  'iconsdir' attribute is set to theme `icons` sub-directory path).
+- Embedded theme files are automatically inserted in the output files
+  but you need to manually copy linked CSS and Javascript files to the
+  location of the output documents.
+- Linked CSS and JavaScript theme files are linked to the same linked
+  locations as <>.
+
+For example, the command-line option `--theme foo` (or `--attribute
+theme=foo`) will cause asciidoc(1) to search <<"X27","configuration
+file locations 1, 2 and 3">> for a sub-directory called `themes/foo`
+containing the stylesheet `foo.css` and optionally a JavaScript file
+name `foo.js`.
+
+
+Document Structure
+------------------
+An AsciiDoc document consists of a series of <>
+starting with an optional document Header, followed by an optional
+Preamble, followed by zero or more document Sections.
+
+Almost any combination of zero or more elements constitutes a valid
+AsciiDoc document: documents can range from a single sentence to a
+multi-part book.
+
+Block Elements
+~~~~~~~~~~~~~~
+Block elements consist of one or more lines of text and may contain
+other block elements.
+
+The AsciiDoc block structure can be informally summarized as follows
+footnote:[This is a rough structural guide, not a rigorous syntax
+definition]:
+
+  Document      ::= (Header?,Preamble?,Section*)
+  Header        ::= (Title,(AuthorInfo,RevisionInfo?)?)
+  AuthorInfo    ::= (FirstName,(MiddleName?,LastName)?,EmailAddress?)
+  RevisionInfo  ::= (RevisionNumber?,RevisionDate,RevisionRemark?)
+  Preamble      ::= (SectionBody)
+  Section       ::= (Title,SectionBody?,(Section)*)
+  SectionBody   ::= ((BlockTitle?,Block)|BlockMacro)+
+  Block         ::= (Paragraph|DelimitedBlock|List|Table)
+  List          ::= (BulletedList|NumberedList|LabeledList|CalloutList)
+  BulletedList  ::= (ListItem)+
+  NumberedList  ::= (ListItem)+
+  CalloutList   ::= (ListItem)+
+  LabeledList   ::= (ListEntry)+
+  ListEntry     ::= (ListLabel,ListItem)
+  ListLabel     ::= (ListTerm+)
+  ListItem      ::= (ItemText,(List|ListParagraph|ListContinuation)*)
+
+Where:
+
+- '?' implies zero or one occurrence, '+' implies one or more
+  occurrences, '*' implies zero or more occurrences.
+- All block elements are separated by line boundaries.
+- `BlockId`, `AttributeEntry` and `AttributeList` block elements (not
+  shown) can occur almost anywhere.
+- There are a number of document type and backend specific
+  restrictions imposed on the block syntax.
+- The following elements cannot contain blank lines: Header, Title,
+  Paragraph, ItemText.
+- A ListParagraph is a Paragraph with its 'listelement' option set.
+- A ListContinuation is a <>.
+
+[[X95]]
+Header
+~~~~~~
+The Header contains document meta-data, typically title plus optional
+authorship and revision information:
+
+- The Header is optional, but if it is used it must start with a
+  document <>.
+- Optional Author and Revision information immediately follows the
+  header title.
+- The document header must be separated from the remainder of the
+  document by one or more blank lines and cannot contain blank lines.
+- The header can include comments.
+- The header can include <>, typically
+  'doctype', 'lang', 'encoding', 'icons', 'data-uri', 'toc',
+  'numbered'.
+- Header attributes are overridden by command-line attributes.
+- If the header contains non-UTF-8 characters then the 'encoding' must
+  precede the header (either in the document or on the command-line).
+
+Here's an example AsciiDoc document header:
+
+  Writing Documentation using AsciiDoc
+  ====================================
+  Joe Bloggs 
+  v2.0, February 2003:
+  Rewritten for version 2 release.
+
+The author information line contains the author's name optionally
+followed by the author's email address. The author's name is formatted
+like:
+
+  firstname[ [middlename ]lastname][ ]]
+
+i.e. a first name followed by optional middle and last names followed
+by an email address in that order.  Multi-word first, middle and last
+names can be entered using the underscore as a word separator.  The
+email address comes last and must be enclosed in angle <> brackets.
+Here a some examples of author information lines:
+
+  Joe Bloggs 
+  Joe Bloggs
+  Vincent Willem van_Gogh
+
+If the author line does not match the above specification then the
+entire author line is treated as the first name.
+
+The optional revision information line follows the author information
+line. The revision information can be one of two formats:
+
+. An optional document revision number followed by an optional
+  revision date followed by an optional revision remark:
++
+--
+  * If the revision number is specified it must be followed by a
+    comma.
+  * The revision number must contain at least one numeric character.
+  * Any non-numeric characters preceding the first numeric character
+    will be dropped.
+  * If a revision remark is specified it must be preceded by a colon.
+    The revision remark extends from the colon up to the next blank
+    line, attribute entry or comment and is subject to normal text
+    substitutions.
+  * If a revision number or remark has been set but the revision date
+    has not been set then the revision date is set to the value of the
+    'docdate' attribute.
+
+Examples:
+
+  v2.0, February 2003
+  February 2003
+  v2.0,
+  v2.0, February 2003: Rewritten for version 2 release.
+  February 2003: Rewritten for version 2 release.
+  v2.0,: Rewritten for version 2 release.
+  :Rewritten for version 2 release.
+--
+
+. The revision information line can also be an RCS/CVS/SVN $Id$
+  marker:
++
+--
+  * AsciiDoc extracts the 'revnumber', 'revdate', and 'author'
+    attributes from the $Id$ revision marker and displays them in the
+    document header.
+  * If an $Id$ revision marker is used the header author line can be
+    omitted.
+
+Example:
+
+  $Id: mydoc.txt,v 1.5 2009/05/17 17:58:44 jbloggs Exp $
+--
+
+You can override or set header parameters by passing 'revnumber',
+'revremark', 'revdate', 'email', 'author', 'authorinitials',
+'firstname' and 'lastname' attributes using the asciidoc(1) `-a`
+(`--attribute`) command-line option. For example:
+
+  $ asciidoc -a revdate=2004/07/27 article.txt
+
+Attribute entries can also be added to the header for substitution in
+the header template with <> elements.
+
+The 'title' element in HTML outputs is set to the AsciiDoc document
+title, you can set it to a different value by including a 'title'
+attribute entry in the document header.
+
+[[X87]]
+Additional document header information
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+AsciiDoc has two mechanisms for optionally including additional
+meta-data in the header of the output document:
+
+'docinfo' configuration file sections::
+If a <> section named 'docinfo' has been loaded
+then it will be included in the document header. Typically the
+'docinfo' section name will be prefixed with a '+' character so that it
+is appended to (rather than replace) other 'docinfo' sections.
+
+'docinfo' files::
+Two docinfo files are recognized: one named `docinfo` and a second
+named like the AsciiDoc source file with a `-docinfo` suffix.  For
+example, if the source document is called `mydoc.txt` then the
+document information files would be `docinfo.xml` and
+`mydoc-docinfo.xml` (for DocBook outputs) and `docinfo.html` and
+`mydoc-docinfo.html` (for HTML outputs).  The <> attributes control which docinfo files are included in
+the output files.
+
+The contents docinfo templates and files is dependent on the type of
+output:
+
+HTML::
+  Valid 'head' child elements. Typically 'style' and 'script' elements
+  for CSS and JavaScript inclusion.
+
+DocBook::
+  Valid 'articleinfo' or 'bookinfo' child elements.  DocBook defines
+  numerous elements for document meta-data, for example: copyrights,
+  document history and authorship information.  See the DocBook
+  `./doc/article-docinfo.xml` example that comes with the AsciiDoc
+  distribution.  The rendering of meta-data elements (or not) is
+  DocBook processor dependent.
+
+
+[[X86]]
+Preamble
+~~~~~~~~
+The Preamble is an optional untitled section body between the document
+Header and the first Section title.
+
+Sections
+~~~~~~~~
+In addition to the document title (level 0), AsciiDoc supports four
+section levels: 1 (top) to 4 (bottom).  Section levels are delimited
+by section <>.  Sections are translated using
+configuration file <>. AsciiDoc
+generates the following <> specifically for
+use in section markup templates:
+
+level::
+The `level` attribute is the section level number, it is normally just
+the <> level number (1..4). However, if the `leveloffset`
+attribute is defined it will be added to the `level` attribute. The
+`leveloffset` attribute is useful for <>.
+
+sectnum::
+The `-n` (`--section-numbers`) command-line option generates the
+`sectnum` (section number) attribute.  The `sectnum` attribute is used
+for section numbers in HTML outputs (DocBook section numbering are
+handled automatically by the DocBook toolchain commands).
+
+[[X93]]
+Section markup templates
+^^^^^^^^^^^^^^^^^^^^^^^^
+Section markup templates specify output markup and are defined in
+AsciiDoc configuration files.  Section markup template names are
+derived as follows (in order of precedence):
+
+1. From the title's first positional attribute or 'template'
+   attribute. For example, the following three section titles are
+   functionally equivalent:
++
+.....................................................................
+[[terms]]
+[glossary]
+List of Terms
+-------------
+
+["glossary",id="terms"]
+List of Terms
+-------------
+
+[template="glossary",id="terms"]
+List of Terms
+-------------
+.....................................................................
+
+2. When the title text matches a configuration file
+   <> entry.
+3. If neither of the above the default `sect` template is used
+   (where `` is a number from 1 to 4).
+
+In addition to the normal section template names ('sect1', 'sect2',
+'sect3', 'sect4') AsciiDoc has the following templates for
+frontmatter, backmatter and other special sections: 'abstract',
+'preface', 'colophon', 'dedication', 'glossary', 'bibliography',
+'synopsis', 'appendix', 'index'.  These special section templates
+generate the corresponding Docbook elements; for HTML outputs they
+default to the 'sect1' section template.
+
+Section IDs
+^^^^^^^^^^^
+If no explicit section ID is specified an ID will be synthesised from
+the section title.  The primary purpose of this feature is to ensure
+persistence of table of contents links (permalinks): the missing
+section IDs are generated dynamically by the JavaScript TOC generator
+*after* the page is loaded. If you link to a dynamically generated TOC
+address the page will load but the browser will ignore the (as yet
+ungenerated) section ID.
+
+The IDs are generated by the following algorithm:
+
+- Replace all non-alphanumeric title characters with underscores.
+- Strip leading or trailing underscores.
+- Convert to lowercase.
+- Prepend the `idprefix` attribute (so there's no possibility of name
+  clashes with existing document IDs). Prepend an underscore if the
+  `idprefix` attribute is not defined.
+- A numbered suffix (`_2`, `_3` ...) is added if a same named
+  auto-generated section ID exists.
+- If the `ascii-ids` attribute is defined then non-ASCII characters
+  are replaced with ASCII equivalents. This attribute may be
+  deprecated in future releases and *should be avoided*, it's sole
+  purpose is to accommodate deficient downstream applications that
+  cannot process non-ASCII ID attributes.
+
+Example: the title 'Jim's House' would generate the ID `_jim_s_house`.
+
+Section ID synthesis can be disabled by undefining the `sectids`
+attribute.
+
+[[X16]]
+Special Section Titles
+^^^^^^^^^^^^^^^^^^^^^^
+AsciiDoc has a mechanism for mapping predefined section titles
+auto-magically to specific markup templates. For example a title
+'Appendix A: Code Reference' will automatically use the 'appendix'
+<>. The mappings from title to template
+name are specified in `[specialsections]` sections in the Asciidoc
+language configuration files (`lang-*.conf`).  Section entries are
+formatted like:
+
+  =<template>
+
+`<title>` is a Python regular expression and `<template>` is the name
+of a configuration file markup template section. If the `<title>`
+matches an AsciiDoc document section title then the backend output is
+marked up using the `<template>` markup template (instead of the
+default `sect<level>` section template). The `{title}` attribute value
+is set to the value of the matched regular expression group named
+'title', if there is no 'title' group `{title}` defaults to the whole
+of the AsciiDoc section title. If `<template>` is blank then any
+existing entry with the same `<title>` will be deleted.
+
+.Special section titles vs. explicit template names
+*********************************************************************
+AsciiDoc has two mechanisms for specifying non-default section markup
+templates: you can specify the template name explicitly (using the
+'template' attribute) or indirectly (using 'special section titles').
+Specifying a <<X93,section template>> attribute explicitly is
+preferred.  Auto-magical 'special section titles' have the following
+drawbacks:
+
+- They are non-obvious, you have to know the exact matching
+  title for each special section on a language by language basis.
+- Section titles are predefined and can only be customised with a
+  configuration change.
+- The implementation is complicated by multiple languages: every
+  special section title has to be defined for each language (in each
+  of the `lang-*.conf` files).
+
+Specifying special section template names explicitly does add more
+noise to the source document (the 'template' attribute declaration),
+but the intention is obvious and the syntax is consistent with other
+AsciiDoc elements c.f.  bibliographic, Q&A and glossary lists.
+
+Special section titles have been deprecated but are retained for
+backward compatibility.
+
+*********************************************************************
+
+Inline Elements
+~~~~~~~~~~~~~~~
+<<X34,Inline document elements>> are used to format text and to
+perform various types of text substitution. Inline elements and inline
+element syntax is defined in the asciidoc(1) configuration files.
+
+Here is a list of AsciiDoc inline elements in the (default) order in
+which they are processed:
+
+Special characters::
+        These character sequences escape special characters used by
+        the backend markup (typically `<`, `>`, and `&` characters).
+        See `[specialcharacters]` configuration file sections.
+
+Quotes::
+        Elements that markup words and phrases; usually for character
+        formatting. See `[quotes]` configuration file sections.
+
+Special Words::
+        Word or word phrase patterns singled out for markup without
+        the need for further annotation.  See `[specialwords]`
+        configuration file sections.
+
+Replacements::
+        Each replacement defines a word or word phrase pattern to
+        search for along with corresponding replacement text. See
+        `[replacements]` configuration file sections.
+
+Attribute references::
+        Document attribute names enclosed in braces are replaced by
+        the corresponding attribute value.
+
+Inline Macros::
+        Inline macros are replaced by the contents of parametrized
+        configuration file sections.
+
+
+Document Processing
+-------------------
+The AsciiDoc source document is read and processed as follows:
+
+1. The document 'Header' is parsed, header parameter values are
+   substituted into the configuration file `[header]` template section
+   which is then written to the output file.
+2. Each document 'Section' is processed and its constituent elements
+   translated to the output file.
+3. The configuration file `[footer]` template section is substituted
+   and written to the output file.
+
+When a block element is encountered asciidoc(1) determines the type of
+block by checking in the following order (first to last): (section)
+Titles, BlockMacros, Lists, DelimitedBlocks, Tables, AttributeEntrys,
+AttributeLists, BlockTitles, Paragraphs.
+
+The default paragraph definition `[paradef-default]` is last element
+to be checked.
+
+Knowing the parsing order will help you devise unambiguous macro, list
+and block syntax rules.
+
+Inline substitutions within block elements are performed in the
+following default order:
+
+1. Special characters
+2. Quotes
+3. Special words
+4. Replacements
+5. Attributes
+6. Inline Macros
+7. Replacements2
+
+The substitutions and substitution order performed on
+Title, Paragraph and DelimitedBlock elements is determined by
+configuration file parameters.
+
+
+Text Formatting
+---------------
+[[X51]]
+Quoted Text
+~~~~~~~~~~~
+Words and phrases can be formatted by enclosing inline text with
+quote characters:
+
+_Emphasized text_::
+        Word phrases \'enclosed in single quote characters' (acute
+        accents) or \_underline characters_ are emphasized.
+
+*Strong text*::
+        Word phrases \*enclosed in asterisk characters* are rendered
+        in a strong font (usually bold).
+
+[[X81]]+Monospaced text+::
+        Word phrases \+enclosed in plus characters+ are rendered in a
+        monospaced font. Word phrases \`enclosed in backtick
+        characters` (grave accents) are also rendered in a monospaced
+        font but in this case the enclosed text is rendered literally
+        and is not subject to further expansion (see <<X80,inline
+        literal passthrough>>).
+
+`Single quoted text'::
+        Phrases enclosed with a \`single grave accent to the left and
+        a single acute accent to the right' are rendered in single
+        quotation marks.
+
+``Double quoted text''::
+        Phrases enclosed with \\``two grave accents to the left and
+        two acute accents to the right'' are rendered in quotation
+        marks.
+
+#Unquoted text#::
+        Placing \#hashes around text# does nothing, it is a mechanism
+        to allow inline attributes to be applied to otherwise
+        unformatted text.
+
+New quote types can be defined by editing asciidoc(1) configuration
+files. See the <<X7,Configuration Files>> section for details.
+
+.Quoted text behavior
+- Quoting cannot be overlapped.
+- Different quoting types can be nested.
+- To suppress quoted text formatting place a backslash character
+  immediately in front of the leading quote character(s). In the case
+  of ambiguity between escaped and non-escaped text you will need to
+  escape both leading and trailing quotes, in the case of
+  multi-character quotes you may even need to escape individual
+  characters.
+
+[[X96]]
+Quoted text attributes
+^^^^^^^^^^^^^^^^^^^^^^
+Quoted text can be prefixed with an <<X21,attribute list>>.  The first
+positional attribute ('role' attribute) is translated by AsciiDoc to
+an HTML 'span' element 'class' attribute or a DocBook 'phrase' element
+'role' attribute.
+
+DocBook XSL Stylesheets translate DocBook 'phrase' elements with
+'role' attributes to corresponding HTML 'span' elements with the same
+'class' attributes; CSS can then be used
+http://www.sagehill.net/docbookxsl/UsingCSS.html[to style the
+generated HTML].  Thus CSS styling can be applied to both DocBook and
+AsciiDoc generated HTML outputs.  You can also specify multiple class
+names separated by spaces.
+
+CSS rules for text color, text background color, text size and text
+decorators are included in the distributed AsciiDoc CSS files and are
+used in conjunction with AsciiDoc 'xhtml11', 'html5' and 'docbook'
+outputs. The CSS class names are:
+
+- '<color>' (text foreground color).
+- '<color>-background' (text background color).
+- 'big' and 'small' (text size).
+- 'underline', 'overline' and 'line-through' (strike through) text
+  decorators.
+
+Where '<color>' can be any of the
+http://en.wikipedia.org/wiki/Web_colors#HTML_color_names[sixteen HTML
+color names].  Examples:
+
+  [red]#Obvious# and [big red yellow-background]*very obvious*.
+
+  [underline]#Underline text#, [overline]#overline text# and
+  [blue line-through]*bold blue and line-through*.
+
+is rendered as:
+
+[red]#Obvious# and [big red yellow-background]*very obvious*.
+
+[underline]#Underline text#, [overline]#overline text# and
+[bold blue line-through]*bold blue and line-through*.
+
+NOTE: Color and text decorator attributes are rendered for XHTML and
+HTML 5 outputs using CSS stylesheets.  The mechanism to implement
+color and text decorator attributes is provided for DocBook toolchains
+via the DocBook 'phrase' element 'role' attribute, but the actual
+rendering is toolchain specific and is not part of the AsciiDoc
+distribution.
+
+[[X52]]
+Constrained and Unconstrained Quotes
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+There are actually two types of quotes:
+
+Constrained quotes
+++++++++++++++++++
+Quoted must be bounded by white space or commonly adjoining
+punctuation characters. These are the most commonly used type of
+quote.
+
+Unconstrained quotes
+++++++++++++++++++++
+Unconstrained quotes have no boundary constraints and can be placed
+anywhere within inline text. For consistency and to make them easier
+to remember unconstrained quotes are double-ups of the `_`, `*`, `+`
+and `#` constrained quotes:
+
+  __unconstrained emphasized text__
+  **unconstrained strong text**
+  ++unconstrained monospaced text++
+  ##unconstrained unquoted text##
+
+The following example emboldens the letter F:
+
+  **F**ile Open...
+
+Superscripts and Subscripts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Put \^carets on either^ side of the text to be superscripted, put
+\~tildes on either side~ of text to be subscripted.  For example, the
+following line:
+
+  e^πi^+1 = 0. H~2~O and x^10^. Some ^super text^
+  and ~some sub text~
+
+Is rendered like:
+
+e^πi^+1 = 0. H~2~O and x^10^. Some ^super text^
+and ~some sub text~
+
+Superscripts and subscripts are implemented as <<X52,unconstrained
+quotes>> and they can be escaped with a leading backslash and prefixed
+with with an attribute list.
+
+Line Breaks
+~~~~~~~~~~~
+A plus character preceded by at least one space character at the end
+of a non-blank line forces a line break. It generates a line break
+(`br`) tag for HTML outputs and a custom XML `asciidoc-br` processing
+instruction for DocBook outputs. The `asciidoc-br` processing
+instruction is handled by <<X43,a2x(1)>>.
+
+Page Breaks
+~~~~~~~~~~~
+A line of three or more less-than (`<<<`) characters will generate a
+hard page break in DocBook and printed HTML outputs.  It uses the CSS
+`page-break-after` property for HTML outputs and a custom XML
+`asciidoc-pagebreak` processing instruction for DocBook outputs. The
+`asciidoc-pagebreak` processing instruction is handled by
+<<X43,a2x(1)>>. Hard page breaks are sometimes handy but as a general
+rule you should let your page processor generate page breaks for you.
+
+Rulers
+~~~~~~
+A line of three or more apostrophe characters will generate a ruler
+line.  It generates a ruler (`hr`) tag for HTML outputs and a custom
+XML `asciidoc-hr` processing instruction for DocBook outputs. The
+`asciidoc-hr` processing instruction is handled by <<X43,a2x(1)>>.
+
+Tabs
+~~~~
+By default tab characters input files will translated to 8 spaces. Tab
+expansion is set with the 'tabsize' entry in the configuration file
+`[miscellaneous]` section and can be overridden in included files by
+setting a 'tabsize' attribute in the `include` macro's attribute list.
+For example:
+
+  include::addendum.txt[tabsize=2]
+
+The tab size can also be set using the attribute command-line option,
+for example `--attribute tabsize=4`
+
+Replacements
+~~~~~~~~~~~~
+The following replacements are defined in the default AsciiDoc
+configuration:
+
+  (C) copyright, (TM) trademark, (R) registered trademark,
+  -- em dash, ... ellipsis, -> right arrow, <- left arrow, => right
+  double arrow, <= left double arrow.
+
+Which are rendered as:
+
+(C) copyright, (TM) trademark, (R) registered trademark,
+-- em dash, ... ellipsis, -> right arrow, <- left arrow, => right
+double arrow, <= left double arrow.
+
+You can also include arbitrary entity references in the AsciiDoc
+source. Examples:
+
+  ➊ ¶
+
+renders:
+
+➊ ¶
+
+To render a replacement literally escape it with a leading back-slash.
+
+The <<X7,Configuration Files>> section explains how to configure your
+own replacements.
+
+Special Words
+~~~~~~~~~~~~~
+Words defined in `[specialwords]` configuration file sections are
+automatically marked up without having to be explicitly notated.
+
+The <<X7,Configuration Files>> section explains how to add and replace
+special words.
+
+
+[[X17]]
+Titles
+------
+Document and section titles can be in either of two formats:
+
+Two line titles
+~~~~~~~~~~~~~~~
+A two line title consists of a title line, starting hard against the
+left margin, and an underline. Section underlines consist a repeated
+character pairs spanning the width of the preceding title (give or
+take up to two characters):
+
+The default title underlines for each of the document levels are:
+
+
+  Level 0 (top level):     ======================
+  Level 1:                 ----------------------
+  Level 2:                 ~~~~~~~~~~~~~~~~~~~~~~
+  Level 3:                 ^^^^^^^^^^^^^^^^^^^^^^
+  Level 4 (bottom level):  ++++++++++++++++++++++
+
+Examples:
+
+  Level One Section Title
+  -----------------------
+
+  Level 2 Subsection Title
+  ~~~~~~~~~~~~~~~~~~~~~~~~
+
+[[X46]]
+One line titles
+~~~~~~~~~~~~~~~
+One line titles consist of a single line delimited on either side by
+one or more equals characters (the number of equals characters
+corresponds to the section level minus one).  Here are some examples:
+
+  = Document Title (level 0) =
+  == Section title (level 1) ==
+  === Section title (level 2) ===
+  ==== Section title (level 3) ====
+  ===== Section title (level 4) =====
+
+[NOTE]
+=====================================================================
+- One or more spaces must fall between the title and the delimiters.
+- The trailing title delimiter is optional.
+- The one-line title syntax can be changed by editing the
+  configuration file `[titles]` section `sect0`...`sect4` entries.
+=====================================================================
+
+Floating titles
+~~~~~~~~~~~~~~~
+Setting the title's first positional attribute or 'style' attribute to
+'float' generates a free-floating title. A free-floating title is
+rendered just like a normal section title but is not formally
+associated with a text body and is not part of the regular section
+hierarchy so the normal ordering rules do not apply. Floating titles
+can also be used in contexts where section titles are illegal: for
+example sidebar and admonition blocks.  Example:
+
+  [float]
+  The second day
+  ~~~~~~~~~~~~~~
+
+Floating titles do not appear in a document's table of contents.
+
+
+[[X42]]
+Block Titles
+------------
+A 'BlockTitle' element is a single line beginning with a period
+followed by the title text. A BlockTitle is applied to the immediately
+following Paragraph, DelimitedBlock, List, Table or BlockMacro. For
+example:
+
+........................
+.Notes
+- Note 1.
+- Note 2.
+........................
+
+is rendered as:
+
+.Notes
+- Note 1.
+- Note 2.
+
+
+[[X41]]
+BlockId Element
+---------------
+A 'BlockId' is a single line block element containing a unique
+identifier enclosed in double square brackets. It is used to assign an
+identifier to the ensuing block element. For example:
+
+  [[chapter-titles]]
+  Chapter titles can be ...
+
+The preceding example identifies the ensuing paragraph so it can be
+referenced from other locations, for example with
+`<<chapter-titles,chapter titles>>`.
+
+'BlockId' elements can be applied to Title, Paragraph, List,
+DelimitedBlock, Table and BlockMacro elements.  The BlockId element
+sets the `{id}` attribute for substitution in the subsequent block's
+markup template. If a second positional argument is supplied it sets
+the `{reftext}` attribute which is used to set the DocBook `xreflabel`
+attribute.
+
+The 'BlockId' element has the same syntax and serves the same function
+to the <<X30,anchor inline macro>>.
+
+[[X79]]
+AttributeList Element
+---------------------
+An 'AttributeList' block element is an <<X21,attribute list>> on a
+line by itself:
+
+- 'AttributeList' attributes are only applied to the immediately
+  following block element -- the attributes are made available to the
+  block's markup template.
+- Multiple contiguous 'AttributeList' elements are additively combined
+  in the order they appear..
+- The first positional attribute in the list is often used to specify
+  the ensuing element's <<X23,style>>.
+
+Attribute value substitution
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+By default, only substitutions that take place inside attribute list
+values are attribute references, this is because not all attributes
+are destined to be marked up and rendered as text (for example the
+table 'cols' attribute). To perform normal inline text substitutions
+(special characters, quotes, macros, replacements) on an attribute
+value you need to enclose it in single quotes. In the following quote
+block the second attribute value in the AttributeList is quoted to
+ensure the 'http' macro is expanded to a hyperlink.
+
+---------------------------------------------------------------------
+[quote,'http://en.wikipedia.org/wiki/Samuel_Johnson[Samuel Johnson]']
+_____________________________________________________________________
+Sir, a woman's preaching is like a dog's walking on his hind legs. It
+is not done well; but you are surprised to find it done at all.
+_____________________________________________________________________
+---------------------------------------------------------------------
+
+Common attributes
+~~~~~~~~~~~~~~~~~
+Most block elements support the following attributes:
+
+[cols="1e,1,5a",frame="topbot",options="header"]
+|====================================================================
+|Name |Backends |Description
+
+|id |html4, html5, xhtml11, docbook |
+Unique identifier typically serve as link targets.
+Can also be set by the 'BlockId' element.
+
+|role |html4, html5, xhtml11, docbook |
+Role contains a string used to classify or subclassify an element and
+can be applied to AsciiDoc block elements.  The AsciiDoc 'role'
+attribute is translated to the 'role' attribute in DocBook outputs and
+is included in the 'class' attribute in HTML outputs, in this respect
+it behaves like the <<X96,quoted text role attribute>>.
+
+DocBook XSL Stylesheets translate DocBook 'role' attributes to HTML
+'class' attributes; CSS can then be used
+http://www.sagehill.net/docbookxsl/UsingCSS.html[to style the
+generated HTML].
+
+|reftext |docbook |
+'reftext' is used to set the DocBook 'xreflabel' attribute.
+The 'reftext' attribute can an also be set by the 'BlockId' element.
+
+|====================================================================
+
+
+Paragraphs
+----------
+Paragraphs are blocks of text terminated by a blank line, the end of
+file, or the start of a delimited block or a list.  There are three
+paragraph syntaxes: normal, indented (literal) and admonition which
+are rendered, by default, with the corresponding paragraph style.
+
+Each syntax has a default style, but you can explicitly apply any
+paragraph style to any paragraph syntax. You can also apply
+<<X104,delimited block>> styles to single paragraphs.
+
+The built-in paragraph styles are: 'normal', 'literal', 'verse',
+'quote', 'listing', 'TIP', 'NOTE', 'IMPORTANT', 'WARNING', 'CAUTION',
+'abstract', 'partintro', 'comment', 'example', 'sidebar', 'source',
+'music', 'latex', 'graphviz'.
+
+normal paragraph syntax
+~~~~~~~~~~~~~~~~~~~~~~~
+Normal paragraph syntax consists of one or more non-blank lines of
+text. The first line must start hard against the left margin (no
+intervening white space). The default processing expectation is that
+of a normal paragraph of text.
+
+[[X85]]
+literal paragraph syntax
+~~~~~~~~~~~~~~~~~~~~~~~~
+Literal paragraphs are rendered verbatim in a monospaced font without
+any distinguishing background or border.  By default there is no text
+formatting or substitutions within Literal paragraphs apart from
+Special Characters and Callouts.
+
+The 'literal' style is applied implicitly to indented paragraphs i.e.
+where the first line of the paragraph is indented by one or more space
+or tab characters.  For example:
+
+---------------------------------------------------------------------
+  Consul *necessitatibus* per id,
+  consetetur, eu pro everti postulant
+  homero verear ea mea, qui.
+---------------------------------------------------------------------
+
+Renders:
+
+  Consul *necessitatibus* per id,
+  consetetur, eu pro everti postulant
+  homero verear ea mea, qui.
+
+NOTE: Because <<X64,lists>> can be indented it's possible for your
+indented paragraph to be misinterpreted as a list -- in situations
+like this apply the 'literal' style to a normal paragraph.
+
+Instead of using a paragraph indent you could apply the 'literal'
+style explicitly, for example:
+
+---------------------------------------------------------------------
+[literal]
+Consul *necessitatibus* per id,
+consetetur, eu pro everti postulant
+homero verear ea mea, qui.
+---------------------------------------------------------------------
+
+Renders:
+
+[literal]
+Consul *necessitatibus* per id,
+consetetur, eu pro everti postulant
+homero verear ea mea, qui.
+
+[[X94]]
+quote and verse paragraph styles
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The optional 'attribution' and 'citetitle' attributes (positional
+attributes 2 and 3) specify the author and source respectively.
+
+The 'verse' style retains the line breaks, for example:
+
+---------------------------------------------------------------------
+[verse, William Blake, from Auguries of Innocence]
+To see a world in a grain of sand,
+And a heaven in a wild flower,
+Hold infinity in the palm of your hand,
+And eternity in an hour.
+---------------------------------------------------------------------
+
+Which is rendered as:
+
+[verse, William Blake, from Auguries of Innocence]
+To see a world in a grain of sand,
+And a heaven in a wild flower,
+Hold infinity in the palm of your hand,
+And eternity in an hour.
+
+The 'quote' style flows the text at left and right margins, for
+example:
+
+---------------------------------------------------------------------
+[quote, Bertrand Russell, The World of Mathematics (1956)]
+A good notation has subtlety and suggestiveness which at times makes
+it almost seem like a live teacher.
+---------------------------------------------------------------------
+
+Which is rendered as:
+
+[quote, Bertrand Russell, The World of Mathematics (1956)]
+A good notation has subtlety and suggestiveness which at times makes
+it almost seem like a live teacher.
+
+[[X28]]
+Admonition Paragraphs
+~~~~~~~~~~~~~~~~~~~~~
+'TIP', 'NOTE', 'IMPORTANT', 'WARNING' and 'CAUTION' admonishment
+paragraph styles are generated by placing `NOTE:`, `TIP:`,
+`IMPORTANT:`, `WARNING:` or `CAUTION:` as the first word of the
+paragraph. For example:
+
+  NOTE: This is an example note.
+
+Alternatively, you can specify the paragraph admonition style
+explicitly using an <<X79,AttributeList element>>. For example:
+
+  [NOTE]
+  This is an example note.
+
+Renders:
+
+NOTE: This is an example note.
+
+TIP: If your admonition requires more than a single paragraph use an
+<<X22,admonition block>> instead.
+
+[[X47]]
+Admonition Icons and Captions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+NOTE: Admonition customization with `icons`, `iconsdir`, `icon` and
+`caption` attributes does not apply when generating DocBook output. If
+you are going the DocBook route then the <<X43,a2x(1)>> `--no-icons`
+and `--icons-dir` options can be used to set the appropriate XSL
+Stylesheets parameters.
+
+By default the asciidoc(1) HTML backends generate text captions
+instead of admonition icon image links. To generate links to icon
+images define the <<X45,`icons`>> attribute, for example using the `-a
+icons` command-line option.
+
+The <<X44,`iconsdir`>> attribute sets the location of linked icon
+images.
+
+You can override the default icon image using the `icon` attribute to
+specify the path of the linked image. For example:
+
+  [icon="./images/icons/wink.png"]
+  NOTE: What lovely war.
+
+Use the `caption` attribute to customize the admonition captions (not
+applicable to `docbook` backend). The following example suppresses the
+icon image and customizes the caption of a 'NOTE' admonition
+(undefining the `icons` attribute with `icons=None` is only necessary
+if <<X45,admonition icons>> have been enabled):
+
+  [icons=None, caption="My Special Note"]
+  NOTE: This is my special note.
+
+This subsection also applies to <<X22,Admonition Blocks>>.
+
+
+[[X104]]
+Delimited Blocks
+----------------
+Delimited blocks are blocks of text enveloped by leading and trailing
+delimiter lines (normally a series of four or more repeated
+characters). The behavior of Delimited Blocks is specified by entries
+in configuration file `[blockdef-*]` sections.
+
+Predefined Delimited Blocks
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+AsciiDoc ships with a number of predefined DelimitedBlocks (see the
+`asciidoc.conf` configuration file in the asciidoc(1) program
+directory):
+
+Predefined delimited block underlines:
+
+  CommentBlock:     //////////////////////////
+  PassthroughBlock: ++++++++++++++++++++++++++
+  ListingBlock:     --------------------------
+  LiteralBlock:     ..........................
+  SidebarBlock:     **************************
+  QuoteBlock:       __________________________
+  ExampleBlock:     ==========================
+  OpenBlock:        --
+
+.Default DelimitedBlock substitutions
+[cols="2e,7*^",frame="topbot",options="header,autowidth"]
+|=====================================================
+| |Attributes |Callouts |Macros | Quotes |Replacements
+|Special chars |Special words
+
+|PassthroughBlock |Yes |No  |Yes |No  |No  |No  |No
+|ListingBlock     |No  |Yes |No  |No  |No  |Yes |No
+|LiteralBlock     |No  |Yes |No  |No  |No  |Yes |No
+|SidebarBlock     |Yes |No  |Yes |Yes |Yes |Yes |Yes
+|QuoteBlock       |Yes |No  |Yes |Yes |Yes |Yes |Yes
+|ExampleBlock     |Yes |No  |Yes |Yes |Yes |Yes |Yes
+|OpenBlock        |Yes |No  |Yes |Yes |Yes |Yes |Yes
+|=====================================================
+
+Listing Blocks
+~~~~~~~~~~~~~~
+'ListingBlocks' are rendered verbatim in a monospaced font, they
+retain line and whitespace formatting and are often distinguished by a
+background or border. There is no text formatting or substitutions
+within Listing blocks apart from Special Characters and Callouts.
+Listing blocks are often used for computer output and file listings.
+
+Here's an example:
+
+[listing]
+......................................
+--------------------------------------
+#include <stdio.h>
+
+int main() {
+   printf("Hello World!\n");
+   exit(0);
+}
+--------------------------------------
+......................................
+
+Which will be rendered like:
+
+--------------------------------------
+#include <stdio.h>
+
+int main() {
+    printf("Hello World!\n");
+    exit(0);
+}
+--------------------------------------
+
+By convention <<X59,filter blocks>> use the listing block syntax and
+are implemented as distinct listing block styles.
+
+[[X65]]
+Literal Blocks
+~~~~~~~~~~~~~~
+'LiteralBlocks' are rendered just like <<X85,literal paragraphs>>.
+Example:
+
+---------------------------------------------------------------------
+...................................
+Consul *necessitatibus* per id,
+consetetur, eu pro everti postulant
+homero verear ea mea, qui.
+...................................
+---------------------------------------------------------------------
+
+Renders:
+...................................
+Consul *necessitatibus* per id,
+consetetur, eu pro everti postulant
+homero verear ea mea, qui.
+...................................
+
+If the 'listing' style is applied to a LiteralBlock it will be
+rendered as a ListingBlock (this is handy if you have a listing
+containing a ListingBlock).
+
+Sidebar Blocks
+~~~~~~~~~~~~~~
+A sidebar is a short piece of text presented outside the narrative
+flow of the main text. The sidebar is normally presented inside a
+bordered box to set it apart from the main text.
+
+The sidebar body is treated like a normal section body.
+
+Here's an example:
+
+---------------------------------------------------------------------
+.An Example Sidebar
+************************************************
+Any AsciiDoc SectionBody element (apart from
+SidebarBlocks) can be placed inside a sidebar.
+************************************************
+---------------------------------------------------------------------
+
+Which will be rendered like:
+
+.An Example Sidebar
+************************************************
+Any AsciiDoc SectionBody element (apart from
+SidebarBlocks) can be placed inside a sidebar.
+************************************************
+
+[[X26]]
+Comment Blocks
+~~~~~~~~~~~~~~
+The contents of 'CommentBlocks' are not processed; they are useful for
+annotations and for excluding new or outdated content that you don't
+want displayed. CommentBlocks are never written to output files.
+Example:
+
+---------------------------------------------------------------------
+//////////////////////////////////////////
+CommentBlock contents are not processed by
+asciidoc(1).
+//////////////////////////////////////////
+---------------------------------------------------------------------
+
+See also <<X25,Comment Lines>>.
+
+NOTE: System macros are executed inside comment blocks.
+
+[[X76]]
+Passthrough Blocks
+~~~~~~~~~~~~~~~~~~
+By default the block contents is subject only to 'attributes' and
+'macros' substitutions (use an explicit 'subs' attribute to apply
+different substitutions).  PassthroughBlock content will often be
+backend specific. Here's an example:
+
+---------------------------------------------------------------------
+[subs="quotes"]
+++++++++++++++++++++++++++++++++++++++
+<table border="1"><tr>
+  <td>*Cell 1*</td>
+  <td>*Cell 2*</td>
+</tr></table>
+++++++++++++++++++++++++++++++++++++++
+---------------------------------------------------------------------
+
+The following styles can be applied to passthrough blocks:
+
+pass::
+  No substitutions are performed. This is equivalent to `subs="none"`.
+
+asciimath, latexmath::
+  By default no substitutions are performed, the contents are rendered
+  as <<X78,mathematical formulas>>.
+
+Quote Blocks
+~~~~~~~~~~~~
+'QuoteBlocks' are used for quoted passages of text. There are two
+styles: 'quote' and 'verse'. The style behavior is identical to
+<<X94,quote and verse paragraphs>> except that blocks can contain
+multiple paragraphs and, in the case of the 'quote' style, other
+section elements.  The first positional attribute sets the style, if
+no attributes are specified the 'quote' style is used.  The optional
+'attribution' and 'citetitle' attributes (positional attributes 2 and
+3) specify the quote's author and source. For example:
+
+---------------------------------------------------------------------
+[quote, Sir Arthur Conan Doyle, The Adventures of Sherlock Holmes]
+____________________________________________________________________
+As he spoke there was the sharp sound of horses' hoofs and
+grating wheels against the curb, followed by a sharp pull at the
+bell. Holmes whistled.
+
+"A pair, by the sound," said he. "Yes," he continued, glancing
+out of the window. "A nice little brougham and a pair of
+beauties. A hundred and fifty guineas apiece. There's money in
+this case, Watson, if there is nothing else."
+____________________________________________________________________
+---------------------------------------------------------------------
+
+Which is rendered as:
+
+[quote, Sir Arthur Conan Doyle, The Adventures of Sherlock Holmes]
+____________________________________________________________________
+As he spoke there was the sharp sound of horses' hoofs and
+grating wheels against the curb, followed by a sharp pull at the
+bell. Holmes whistled.
+
+"A pair, by the sound," said he. "Yes," he continued, glancing
+out of the window. "A nice little brougham and a pair of
+beauties. A hundred and fifty guineas apiece. There's money in
+this case, Watson, if there is nothing else."
+____________________________________________________________________
+
+[[X48]]
+Example Blocks
+~~~~~~~~~~~~~~
+'ExampleBlocks' encapsulate the DocBook Example element and are used
+for, well, examples.  Example blocks can be titled by preceding them
+with a 'BlockTitle'.  DocBook toolchains will normally automatically
+number examples and generate a 'List of Examples' backmatter section.
+
+Example blocks are delimited by lines of equals characters and can
+contain any block elements apart from Titles, BlockTitles and
+Sidebars) inside an example block. For example:
+
+---------------------------------------------------------------------
+.An example
+=====================================================================
+Qui in magna commodo, est labitur dolorum an. Est ne magna primis
+adolescens.
+=====================================================================
+---------------------------------------------------------------------
+
+Renders:
+
+.An example
+=====================================================================
+Qui in magna commodo, est labitur dolorum an. Est ne magna primis
+adolescens.
+=====================================================================
+
+A title prefix that can be inserted with the `caption` attribute
+(HTML backends). For example:
+
+---------------------------------------------------------------------
+[caption="Example 1: "]
+.An example with a custom caption
+=====================================================================
+Qui in magna commodo, est labitur dolorum an. Est ne magna primis
+adolescens.
+=====================================================================
+---------------------------------------------------------------------
+
+[[X22]]
+Admonition Blocks
+~~~~~~~~~~~~~~~~~
+The 'ExampleBlock' definition includes a set of admonition
+<<X23,styles>> ('NOTE', 'TIP', 'IMPORTANT', 'WARNING', 'CAUTION') for
+generating admonition blocks (admonitions containing more than a
+<<X28,single paragraph>>).  Just precede the 'ExampleBlock' with an
+attribute list specifying the admonition style name. For example:
+
+---------------------------------------------------------------------
+[NOTE]
+.A NOTE admonition block
+=====================================================================
+Qui in magna commodo, est labitur dolorum an. Est ne magna primis
+adolescens.
+
+. Fusce euismod commodo velit.
+. Vivamus fringilla mi eu lacus.
+  .. Fusce euismod commodo velit.
+  .. Vivamus fringilla mi eu lacus.
+. Donec eget arcu bibendum
+  nunc consequat lobortis.
+=====================================================================
+---------------------------------------------------------------------
+
+Renders:
+
+[NOTE]
+.A NOTE admonition block
+=====================================================================
+Qui in magna commodo, est labitur dolorum an. Est ne magna primis
+adolescens.
+
+. Fusce euismod commodo velit.
+. Vivamus fringilla mi eu lacus.
+  .. Fusce euismod commodo velit.
+  .. Vivamus fringilla mi eu lacus.
+. Donec eget arcu bibendum
+  nunc consequat lobortis.
+=====================================================================
+
+See also <<X47,Admonition Icons and Captions>>.
+
+[[X29]]
+Open Blocks
+~~~~~~~~~~~
+Open blocks are special:
+
+- The open block delimiter is line containing two hyphen characters
+  (instead of four or more repeated characters).
+
+- They can be used to group block elements for <<X15,List item
+  continuation>>.
+
+- Open blocks can be styled to behave like any other type of delimited
+  block.  The  following built-in styles can be applied to open
+  blocks: 'literal', 'verse', 'quote', 'listing', 'TIP', 'NOTE',
+  'IMPORTANT', 'WARNING', 'CAUTION', 'abstract', 'partintro',
+  'comment', 'example', 'sidebar', 'source', 'music', 'latex',
+  'graphviz'. For example, the following open block and listing block
+  are functionally identical:
+
+  [listing]
+  --
+  Lorum ipsum ...
+  --
+
+  ---------------
+  Lorum ipsum ...
+  ---------------
+
+- An unstyled open block groups section elements but otherwise does
+  nothing.
+
+Open blocks are used to generate document abstracts and book part
+introductions:
+
+- Apply the 'abstract' style to generate an abstract, for example:
+
+  [abstract]
+  --
+  In this paper we will ...
+  --
+
+. Apply the 'partintro' style to generate a book part introduction for
+  a multi-part book, for example:
+
+  [partintro]
+  .Optional part introduction title
+  --
+  Optional part introduction goes here.
+  --
+
+
+[[X64]]
+Lists
+-----
+.List types
+- Bulleted lists. Also known as itemized or unordered lists.
+- Numbered lists. Also called ordered lists.
+- Labeled lists. Sometimes called variable or definition lists.
+- Callout lists (a list of callout annotations).
+
+.List behavior
+- List item indentation is optional and does not determine nesting,
+  indentation does however make the source more readable.
+- Another list or a literal paragraph immediately following a list
+  item will be implicitly included in the list item; use <<X15, list
+  item continuation>> to explicitly append other block elements to a
+  list item.
+- A comment block or a comment line block macro element will terminate
+  a list -- use inline comment lines to put comments inside lists.
+- The `listindex` <<X60,intrinsic attribute>> is the current list item
+  index (1..). If this attribute is used outside a list then it's value
+  is the number of items in the most recently closed list. Useful for
+  displaying the number of items in a list.
+
+Bulleted Lists
+~~~~~~~~~~~~~~
+Bulleted list items start with a single dash or one to five asterisks
+followed by some white space then some text. Bulleted list syntaxes
+are:
+
+...................
+- List item.
+* List item.
+** List item.
+*** List item.
+**** List item.
+***** List item.
+...................
+
+Numbered Lists
+~~~~~~~~~~~~~~
+List item numbers are explicit or implicit.
+
+.Explicit numbering
+List items begin with a number followed by some white space then the
+item text. The numbers can be decimal (arabic), roman (upper or lower
+case) or alpha (upper or lower case). Decimal and alpha numbers are
+terminated with a period, roman numbers are terminated with a closing
+parenthesis. The different terminators are necessary to ensure 'i',
+'v' and 'x' roman numbers are are distinguishable from 'x', 'v' and
+'x' alpha numbers. Examples:
+
+.....................................................................
+1.   Arabic (decimal) numbered list item.
+a.   Lower case alpha (letter) numbered list item.
+F.   Upper case alpha (letter) numbered list item.
+iii) Lower case roman numbered list item.
+IX)  Upper case roman numbered list item.
+.....................................................................
+
+.Implicit numbering
+List items begin one to five period characters, followed by some white
+space then the item text. Examples:
+
+.....................................................................
+. Arabic (decimal) numbered list item.
+.. Lower case alpha (letter) numbered list item.
+... Lower case roman numbered list item.
+.... Upper case alpha (letter) numbered list item.
+..... Upper case roman numbered list item.
+.....................................................................
+
+You can use the 'style' attribute (also the first positional
+attribute) to specify an alternative numbering style.  The numbered
+list style can be one of the following values: 'arabic', 'loweralpha',
+'upperalpha', 'lowerroman', 'upperroman'.
+
+Here are some examples of bulleted and numbered lists:
+
+---------------------------------------------------------------------
+- Praesent eget purus quis magna eleifend eleifend.
+  1. Fusce euismod commodo velit.
+    a. Fusce euismod commodo velit.
+    b. Vivamus fringilla mi eu lacus.
+    c. Donec eget arcu bibendum nunc consequat lobortis.
+  2. Vivamus fringilla mi eu lacus.
+    i)  Fusce euismod commodo velit.
+    ii) Vivamus fringilla mi eu lacus.
+  3. Donec eget arcu bibendum nunc consequat lobortis.
+  4. Nam fermentum mattis ante.
+- Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+  * Fusce euismod commodo velit.
+  ** Qui in magna commodo, est labitur dolorum an. Est ne magna primis
+     adolescens. Sit munere ponderum dignissim et. Minim luptatum et
+     vel.
+  ** Vivamus fringilla mi eu lacus.
+  * Donec eget arcu bibendum nunc consequat lobortis.
+- Nulla porttitor vulputate libero.
+  . Fusce euismod commodo velit.
+  . Vivamus fringilla mi eu lacus.
+[upperroman]
+    .. Fusce euismod commodo velit.
+    .. Vivamus fringilla mi eu lacus.
+  . Donec eget arcu bibendum nunc consequat lobortis.
+---------------------------------------------------------------------
+
+Which render as:
+
+- Praesent eget purus quis magna eleifend eleifend.
+  1. Fusce euismod commodo velit.
+    a. Fusce euismod commodo velit.
+    b. Vivamus fringilla mi eu lacus.
+    c. Donec eget arcu bibendum nunc consequat lobortis.
+  2. Vivamus fringilla mi eu lacus.
+    i)  Fusce euismod commodo velit.
+    ii) Vivamus fringilla mi eu lacus.
+  3. Donec eget arcu bibendum nunc consequat lobortis.
+  4. Nam fermentum mattis ante.
+- Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+  * Fusce euismod commodo velit.
+  ** Qui in magna commodo, est labitur dolorum an. Est ne magna primis
+     adolescens. Sit munere ponderum dignissim et. Minim luptatum et
+     vel.
+  ** Vivamus fringilla mi eu lacus.
+  * Donec eget arcu bibendum nunc consequat lobortis.
+- Nulla porttitor vulputate libero.
+  . Fusce euismod commodo velit.
+  . Vivamus fringilla mi eu lacus.
+[upperroman]
+    .. Fusce euismod commodo velit.
+    .. Vivamus fringilla mi eu lacus.
+  . Donec eget arcu bibendum nunc consequat lobortis.
+
+A predefined 'compact' option is available to bulleted and numbered
+lists -- this translates to the DocBook 'spacing="compact"' lists
+attribute which may or may not be processed by the DocBook toolchain.
+Example:
+
+  [options="compact"]
+  - Compact list item.
+  - Another compact list item.
+
+TIP: To apply the 'compact' option globally define a document-wide
+'compact-option' attribute, e.g. using the `-a compact-option`
+command-line option.
+
+You can set the list start number using the 'start' attribute (works
+for HTML outputs and DocBook outputs processed by DocBook XSL
+Stylesheets). Example:
+
+  [start=7]
+  . List item 7.
+  . List item 8.
+
+Labeled Lists
+~~~~~~~~~~~~~
+Labeled list items consist of one or more text labels followed by the
+text of the list item.
+
+An item label begins a line with an alphanumeric character hard
+against the left margin and ends with two, three or four colons or two
+semi-colons. A list item can have multiple labels, one per line.
+
+The list item text consists of one or more lines of text starting
+after the last label (either on the same line or a new line) and can
+be followed by nested List or ListParagraph elements. Item text can be
+optionally indented.
+
+Here are some examples:
+
+---------------------------------------------------------------------
+In::
+Lorem::
+  Fusce euismod commodo velit.
+
+  Fusce euismod commodo velit.
+
+Ipsum:: Vivamus fringilla mi eu lacus.
+  * Vivamus fringilla mi eu lacus.
+  * Donec eget arcu bibendum nunc consequat lobortis.
+Dolor::
+  Donec eget arcu bibendum nunc consequat lobortis.
+  Suspendisse;;
+    A massa id sem aliquam auctor.
+  Morbi;;
+    Pretium nulla vel lorem.
+  In;;
+    Dictum mauris in urna.
+    Vivamus::: Fringilla mi eu lacus.
+    Donec:::   Eget arcu bibendum nunc consequat lobortis.
+---------------------------------------------------------------------
+
+Which render as:
+
+In::
+Lorem::
+  Fusce euismod commodo velit.
+
+  Fusce euismod commodo velit.
+
+Ipsum:: Vivamus fringilla mi eu lacus.
+  * Vivamus fringilla mi eu lacus.
+  * Donec eget arcu bibendum nunc consequat lobortis.
+Dolor::
+  Donec eget arcu bibendum nunc consequat lobortis.
+  Suspendisse;;
+    A massa id sem aliquam auctor.
+  Morbi;;
+    Pretium nulla vel lorem.
+  In;;
+    Dictum mauris in urna.
+    Vivamus::: Fringilla mi eu lacus.
+    Donec:::   Eget arcu bibendum nunc consequat lobortis.
+
+Horizontal labeled list style
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The 'horizontal' labeled list style (also the first positional
+attribute) places the list text side-by-side with the label instead of
+under the label. Here is an example:
+
+---------------------------------------------------------------------
+[horizontal]
+*Lorem*:: Fusce euismod commodo velit.  Qui in magna commodo, est
+labitur dolorum an. Est ne magna primis adolescens.
+
+  Fusce euismod commodo velit.
+
+*Ipsum*:: Vivamus fringilla mi eu lacus.
+- Vivamus fringilla mi eu lacus.
+- Donec eget arcu bibendum nunc consequat lobortis.
+
+*Dolor*::
+  - Vivamus fringilla mi eu lacus.
+  - Donec eget arcu bibendum nunc consequat lobortis.
+
+---------------------------------------------------------------------
+
+Which render as:
+
+[horizontal]
+*Lorem*:: Fusce euismod commodo velit.  Qui in magna commodo, est
+labitur dolorum an. Est ne magna primis adolescens.
+
+  Fusce euismod commodo velit.
+
+*Ipsum*:: Vivamus fringilla mi eu lacus.
+- Vivamus fringilla mi eu lacus.
+- Donec eget arcu bibendum nunc consequat lobortis.
+
+*Dolor*::
+  - Vivamus fringilla mi eu lacus.
+  - Donec eget arcu bibendum nunc consequat lobortis.
+
+[NOTE]
+=====================================================================
+- Current PDF toolchains do not make a good job of determining
+  the relative column widths for horizontal labeled lists.
+- Nested horizontal labeled lists will generate DocBook validation
+  errors because the 'DocBook XML V4.2' DTD does not permit nested
+  informal tables (although <<X13,DocBook XSL Stylesheets>> and
+  <<X31,dblatex>> process them correctly).
+- The label width can be set as a percentage of the total width by
+  setting the 'width' attribute e.g. `width="10%"`
+=====================================================================
+
+Question and Answer Lists
+~~~~~~~~~~~~~~~~~~~~~~~~~
+AsciiDoc comes pre-configured with a 'qanda' style labeled list for generating
+DocBook question and answer (Q&A) lists. Example:
+
+---------------------------------------------------------------------
+[qanda]
+Question one::
+        Answer one.
+Question two::
+        Answer two.
+---------------------------------------------------------------------
+
+Renders:
+
+[qanda]
+Question one::
+        Answer one.
+Question two::
+        Answer two.
+
+Glossary Lists
+~~~~~~~~~~~~~~
+AsciiDoc comes pre-configured with a 'glossary' style labeled list for
+generating DocBook glossary lists. Example:
+
+---------------------------------------------------------------------
+[glossary]
+A glossary term::
+    The corresponding definition.
+A second glossary term::
+    The corresponding definition.
+---------------------------------------------------------------------
+
+For working examples see the `article.txt` and `book.txt` documents in
+the AsciiDoc `./doc` distribution directory.
+
+NOTE: To generate valid DocBook output glossary lists must be located
+in a section that uses the 'glossary' <<X93,section markup template>>.
+
+Bibliography Lists
+~~~~~~~~~~~~~~~~~~
+AsciiDoc comes with a predefined 'bibliography' bulleted list style
+generating DocBook bibliography entries. Example:
+
+---------------------------------------------------------------------
+[bibliography]
+.Optional list title
+- [[[taoup]]] Eric Steven Raymond. 'The Art of UNIX
+  Programming'. Addison-Wesley. ISBN 0-13-142901-9.
+- [[[walsh-muellner]]] Norman Walsh & Leonard Muellner.
+  'DocBook - The Definitive Guide'. O'Reilly & Associates.
+  1999. ISBN 1-56592-580-7.
+---------------------------------------------------------------------
+
+The `[[[<reference>]]]` syntax is a bibliography entry anchor, it
+generates an anchor named `<reference>` and additionally displays
+`[<reference>]` at the anchor position. For example `[[[taoup]]]`
+generates an anchor named `taoup` that displays `[taoup]` at the
+anchor position. Cite the reference from elsewhere your document using
+`<<taoup>>`, this displays a hyperlink (`[taoup]`) to the
+corresponding bibliography entry anchor.
+
+For working examples see the `article.txt` and `book.txt` documents in
+the AsciiDoc `./doc` distribution directory.
+
+NOTE: To generate valid DocBook output bibliography lists must be
+located in a <<X93,bibliography section>>.
+
+[[X15]]
+List Item Continuation
+~~~~~~~~~~~~~~~~~~~~~~
+Another list or a literal paragraph immediately following a list item
+is implicitly appended to the list item; to append other block
+elements to a list item you need to explicitly join them to the list
+item with a 'list continuation' (a separator line containing a single
+plus character). Multiple block elements can be appended to a list
+item using list continuations (provided they are legal list item
+children in the backend markup).
+
+Here are some examples of list item continuations: list item one
+contains multiple continuations; list item two is continued with an
+<<X29,OpenBlock>> containing multiple elements:
+
+---------------------------------------------------------------------
+1. List item one.
++
+List item one continued with a second paragraph followed by an
+Indented block.
++
+.................
+$ ls *.sh
+$ mv *.sh ~/tmp
+.................
++
+List item continued with a third paragraph.
+
+2. List item two continued with an open block.
++
+--
+This paragraph is part of the preceding list item.
+
+a. This list is nested and does not require explicit item continuation.
++
+This paragraph is part of the preceding list item.
+
+b. List item b.
+
+This paragraph belongs to item two of the outer list.
+--
+---------------------------------------------------------------------
+
+Renders:
+
+1. List item one.
++
+List item one continued with a second paragraph followed by an
+Indented block.
++
+.................
+$ ls *.sh
+$ mv *.sh ~/tmp
+.................
++
+List item continued with a third paragraph.
+
+2. List item two continued with an open block.
++
+--
+This paragraph is part of the preceding list item.
+
+a. This list is nested and does not require explicit item continuation.
++
+This paragraph is part of the preceding list item.
+
+b. List item b.
+
+This paragraph belongs to item two of the outer list.
+--
+
+
+[[X92]]
+Footnotes
+---------
+The shipped AsciiDoc configuration includes three footnote inline
+macros:
+
+`footnote:[<text>]`::
+  Generates a footnote with text `<text>`.
+
+`footnoteref:[<id>,<text>]`::
+  Generates a footnote with a reference ID `<id>` and text `<text>`.
+
+`footnoteref:[<id>]`::
+  Generates a reference to the footnote with ID `<id>`.
+
+The footnote text can span multiple lines.
+
+The 'xhtml11' and 'html5' backends render footnotes dynamically using
+JavaScript; 'html4' outputs do not use JavaScript and leave the
+footnotes inline; 'docbook' footnotes are processed by the downstream
+DocBook toolchain.
+
+Example footnotes:
+
+  A footnote footnote:[An example footnote.];
+  a second footnote with a reference ID footnoteref:[note2,Second footnote.];
+  finally a reference to the second footnote footnoteref:[note2].
+
+Renders:
+
+A footnote footnote:[An example footnote.];
+a second footnote with a reference ID footnoteref:[note2,Second footnote.];
+finally a reference to the second footnote footnoteref:[note2].
+
+
+Indexes
+-------
+The shipped AsciiDoc configuration includes the inline macros for
+generating DocBook index entries.
+
+`indexterm:[<primary>,<secondary>,<tertiary>]`::
+`(((<primary>,<secondary>,<tertiary>)))`::
+    This inline macro generates an index term (the `<secondary>` and
+    `<tertiary>` positional attributes are optional). Example:
+    `indexterm:[Tigers,Big cats]` (or, using the alternative syntax
+    `(((Tigers,Big cats)))`.  Index terms that have secondary and
+    tertiary entries also generate separate index terms for the
+    secondary and tertiary entries. The index terms appear in the
+    index, not the primary text flow.
+
+`indexterm2:[<primary>]`::
+`((<primary>))`::
+    This inline macro generates an index term that appears in both the
+    index and the primary text flow.  The `<primary>` should not be
+    padded to the left or right with white space characters.
+
+For working examples see the `article.txt` and `book.txt` documents in
+the AsciiDoc `./doc` distribution directory.
+
+NOTE: Index entries only really make sense if you are generating
+DocBook markup -- DocBook conversion programs automatically generate
+an index at the point an 'Index' section appears in source document.
+
+
+[[X105]]
+Callouts
+--------
+Callouts are a mechanism for annotating verbatim text (for example:
+source code, computer output and user input). Callout markers are
+placed inside the annotated text while the actual annotations are
+presented in a callout list after the annotated text. Here's an
+example:
+
+---------------------------------------------------------------------
+ .MS-DOS directory listing
+ -----------------------------------------------------
+ 10/17/97   9:04         <DIR>    bin
+ 10/16/97  14:11         <DIR>    DOS            \<1>
+ 10/16/97  14:40         <DIR>    Program Files
+ 10/16/97  14:46         <DIR>    TEMP
+ 10/17/97   9:04         <DIR>    tmp
+ 10/16/97  14:37         <DIR>    WINNT
+ 10/16/97  14:25             119  AUTOEXEC.BAT   \<2>
+  2/13/94   6:21          54,619  COMMAND.COM    \<2>
+ 10/16/97  14:25             115  CONFIG.SYS     \<2>
+ 11/16/97  17:17      61,865,984  pagefile.sys
+  2/13/94   6:21           9,349  WINA20.386     \<3>
+ -----------------------------------------------------
+
+ \<1> This directory holds MS-DOS.
+ \<2> System startup code for DOS.
+ \<3> Some sort of Windows 3.1 hack.
+---------------------------------------------------------------------
+
+Which renders:
+
+.MS-DOS directory listing
+-----------------------------------------------------
+10/17/97   9:04         <DIR>    bin
+10/16/97  14:11         <DIR>    DOS            <1>
+10/16/97  14:40         <DIR>    Program Files
+10/16/97  14:46         <DIR>    TEMP
+10/17/97   9:04         <DIR>    tmp
+10/16/97  14:37         <DIR>    WINNT
+10/16/97  14:25             119  AUTOEXEC.BAT   <2>
+ 2/13/94   6:21          54,619  COMMAND.COM    <2>
+10/16/97  14:25             115  CONFIG.SYS     <2>
+11/16/97  17:17      61,865,984  pagefile.sys
+ 2/13/94   6:21           9,349  WINA20.386     <3>
+-----------------------------------------------------
+
+<1> This directory holds MS-DOS.
+<2> System startup code for DOS.
+<3> Some sort of Windows 3.1 hack.
+
+.Explanation
+- The callout marks are whole numbers enclosed in angle brackets --
+  they refer to the correspondingly numbered item in the following
+  callout list.
+- By default callout marks are confined to 'LiteralParagraphs',
+  'LiteralBlocks' and 'ListingBlocks' (although this is a
+  configuration file option and can be changed).
+- Callout list item numbering is fairly relaxed -- list items can
+  start with `<n>`, `n>` or `>` where `n` is the optional list item
+  number (in the latter case list items starting with a single `>`
+  character are implicitly numbered starting at one).
+- Callout lists should not be nested.
+- Callout lists start list items hard against the left margin.
+- If you want to present a number inside angle brackets you'll need to
+  escape it with a backslash to prevent it being interpreted as a
+  callout mark.
+
+NOTE: Define the AsciiDoc 'icons' attribute (for example using the `-a
+icons` command-line option) to display callout icons.
+
+Implementation Notes
+~~~~~~~~~~~~~~~~~~~~
+Callout marks are generated by the 'callout' inline macro while
+callout lists are generated using the 'callout' list definition. The
+'callout' macro and 'callout' list are special in that they work
+together. The 'callout' inline macro is not enabled by the normal
+'macros' substitutions option, instead it has its own 'callouts'
+substitution option.
+
+The following attributes are available during inline callout macro
+substitution:
+
+`{index}`::
+    The callout list item index inside the angle brackets.
+`{coid}`::
+    An identifier formatted like `CO<listnumber>-<index>` that
+    uniquely identifies the callout mark. For example `CO2-4`
+    identifies the fourth callout mark in the second set of callout
+    marks.
+
+The `{coids}` attribute can be used during callout list item
+substitution -- it is a space delimited list of callout IDs that refer
+to the explanatory list item.
+
+Including callouts in included code
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+You can annotate working code examples with callouts -- just remember
+to put the callouts inside source code comments. This example displays
+the `test.py` source file (containing a single callout) using the
+'source' (code highlighter) filter:
+
+.AsciiDoc source
+---------------------------------------------------------------------
+ [source,python]
+ -------------------------------------------
+ \include::test.py[]
+ -------------------------------------------
+
+ \<1> Print statement.
+---------------------------------------------------------------------
+
+.Included `test.py` source
+---------------------------------------------------------------------
+print 'Hello World!'   # \<1>
+---------------------------------------------------------------------
+
+
+Macros
+------
+Macros are a mechanism for substituting parametrized text into output
+documents.
+
+Macros have a 'name', a single 'target' argument and an 'attribute
+list'.  The usual syntax is `<name>:<target>[<attrlist>]` (for
+inline macros) and `<name>::<target>[<attrlist>]` (for block
+macros).  Here are some examples:
+
+  http://www.docbook.org/[DocBook.org]
+  include::chapt1.txt[tabsize=2]
+  mailto:srackham@gmail.com[]
+
+.Macro behavior
+- `<name>` is the macro name. It can only contain letters, digits or
+  dash characters and cannot start with a dash.
+- The optional `<target>` cannot contain white space characters.
+- `<attrlist>` is a <<X21,list of attributes>> enclosed in square
+  brackets.
+- `]` characters inside attribute lists must be escaped with a
+  backslash.
+- Expansion of macro references can normally be escaped by prefixing a
+  backslash character (see the AsciiDoc 'FAQ' for examples of
+  exceptions to this rule).
+- Attribute references in block macros are expanded.
+- The substitutions performed prior to Inline macro macro expansion
+  are determined by the inline context.
+- Macros are processed in the order they appear in the configuration
+  file(s).
+- Calls to inline macros can be nested inside different inline macros
+  (an inline macro call cannot contain a nested call to itself).
+- In addition to `<name>`, `<target>` and `<attrlist>` the
+  `<passtext>` and `<subslist>` named groups are available to
+  <<X77,passthrough macros>>. A macro is a passthrough macro if the
+  definition includes a `<passtext>` named group.
+
+Inline Macros
+~~~~~~~~~~~~~
+Inline Macros occur in an inline element context. Predefined Inline
+macros include 'URLs', 'image' and 'link' macros.
+
+URLs
+^^^^
+'http', 'https', 'ftp', 'file', 'mailto' and 'callto' URLs are
+rendered using predefined inline macros.
+
+- If you don't need a custom link caption you can enter the 'http',
+  'https', 'ftp', 'file' URLs and email addresses without any special
+  macro syntax.
+- If the `<attrlist>` is empty the URL is displayed.
+
+Here are some examples:
+
+  http://www.docbook.org/[DocBook.org]
+  http://www.docbook.org/
+  mailto:joe.bloggs@foobar.com[email Joe Bloggs]
+  joe.bloggs@foobar.com
+
+Which are rendered:
+
+http://www.docbook.org/[DocBook.org]
+
+http://www.docbook.org/
+
+mailto:joe.bloggs@foobar.com[email Joe Bloggs]
+
+joe.bloggs@foobar.com
+
+If the `<target>` necessitates space characters use `%20`, for example
+`large%20image.png`.
+
+Internal Cross References
+^^^^^^^^^^^^^^^^^^^^^^^^^
+Two AsciiDoc inline macros are provided for creating hypertext links
+within an AsciiDoc document. You can use either the standard macro
+syntax or the (preferred) alternative.
+
+[[X30]]
+anchor
+++++++
+Used to specify hypertext link targets:
+
+  [[<id>,<xreflabel>]]
+  anchor:<id>[<xreflabel>]
+
+The `<id>` is a unique string that conforms to the output markup's
+anchor syntax. The optional `<xreflabel>` is the text to be displayed
+by captionless 'xref' macros that refer to this anchor. The optional
+`<xreflabel>` is only really useful when generating DocBook output.
+Example anchor:
+
+  [[X1]]
+
+You may have noticed that the syntax of this inline element is the
+same as that of the <<X41,BlockId block element>>, this is no
+coincidence since they are functionally equivalent.
+
+xref
+++++
+Creates a hypertext link to a document anchor.
+
+  <<<id>,<caption>>>
+  xref:<id>[<caption>]
+
+The `<id>` refers to an anchor ID. The optional `<caption>` is the
+link's displayed text. Example:
+
+  <<X21,attribute lists>>
+
+If `<caption>` is not specified then the displayed text is
+auto-generated:
+
+- The AsciiDoc 'xhtml11' and 'html5' backends display the `<id>`
+  enclosed in square brackets.
+- If DocBook is produced the DocBook toolchain is responsible for the
+  displayed text which will normally be the referenced figure, table
+  or section title number followed by the element's title text.
+
+Here is an example:
+
+---------------------------------------------------------------------
+[[tiger_image]]
+.Tyger tyger
+image::tiger.png[]
+
+This can be seen in <<tiger_image>>.
+---------------------------------------------------------------------
+
+Linking to Local Documents
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+Hypertext links to files on the local file system are specified using
+the 'link' inline macro.
+
+  link:<target>[<caption>]
+
+The 'link' macro generates relative URLs. The link macro `<target>` is
+the target file name (relative to the file system location of the
+referring document). The optional `<caption>` is the link's displayed
+text. If `<caption>` is not specified then `<target>` is displayed.
+Example:
+
+  link:downloads/foo.zip[download foo.zip]
+
+You can use the `<filename>#<id>` syntax to refer to an anchor within
+a target document but this usually only makes sense when targeting
+HTML documents.
+
+[[X9]]
+Images
+^^^^^^
+Inline images are inserted into the output document using the 'image'
+macro. The inline syntax is:
+
+  image:<target>[<attributes>]
+
+The contents of the image file `<target>` is displayed. To display the
+image its file format must be supported by the target backend
+application. HTML and DocBook applications normally support PNG or JPG
+files.
+
+`<target>` file name paths are relative to the location of the
+referring document.
+
+[[X55]]
+.Image macro attributes
+- The optional 'alt' attribute is also the first positional attribute,
+  it specifies alternative text which is displayed if the output
+  application is unable to display the image file (see also
+  http://htmlhelp.com/feature/art3.htm[Use of ALT texts in IMGs]). For
+  example:
+
+  image:images/logo.png[Company Logo]
+
+- The optional 'title' attribute provides a title for the image. The
+  <<X49,block image macro>> renders the title alongside the image.
+  The inline image macro displays the title as a popup ``tooltip'' in
+  visual browsers (AsciiDoc HTML outputs only).
+
+- The optional `width` and `height` attributes scale the image size
+  and can be used in any combination. The units are pixels.  The
+  following example scales the previous example to a height of 32
+  pixels:
+
+  image:images/logo.png["Company Logo",height=32]
+
+- The optional `link` attribute is used to link the image to an
+  external document. The following example links a screenshot
+  thumbnail to a full size version:
+
+  image:screen-thumbnail.png[height=32,link="screen.png"]
+
+- The optional `scaledwidth` attribute is only used in DocBook block
+  images (specifically for PDF documents). The following example
+  scales the images to 75% of the available print width:
+
+  image::images/logo.png[scaledwidth="75%",alt="Company Logo"]
+
+- The image `scale` attribute sets the DocBook `imagedata` element
+  `scale` attribute.
+
+- The optional `align` attribute is used for horizontal image
+  alignment.  Allowed values are `center`, `left` and `right`. For
+  example:
+
+  image::images/tiger.png["Tiger image",align="left"]
+
+- The optional `float` attribute floats the image `left` or `right` on
+  the page (works with HTML outputs only, has no effect on DocBook
+  outputs). `float` and `align` attributes are mutually exclusive.
+  Use the `unfloat::[]` block macro to stop floating.
+
+Comment Lines
+^^^^^^^^^^^^^
+See <<X25,comment block macro>>.
+
+Block Macros
+~~~~~~~~~~~~
+A Block macro reference must be contained in a single line separated
+either side by a blank line or a block delimiter.
+
+Block macros behave just like Inline macros, with the following
+differences:
+
+- They occur in a block context.
+- The default syntax is `<name>::<target>[<attrlist>]` (two
+  colons, not one).
+- Markup template section names end in `-blockmacro` instead of
+  `-inlinemacro`.
+
+Block Identifier
+^^^^^^^^^^^^^^^^
+The Block Identifier macro sets the `id` attribute and has the same
+syntax as the <<X30,anchor inline macro>> since it performs
+essentially the same function -- block templates use the `id`
+attribute as a block element ID. For example:
+
+  [[X30]]
+
+This is equivalent to the `[id="X30"]` <<X79,AttributeList element>>).
+
+[[X49]]
+Images
+^^^^^^
+The 'image' block macro is used to display images in a block context.
+The syntax is:
+
+  image::<target>[<attributes>]
+
+The block `image` macro has the same <<X55,macro attributes>> as it's
+<<X9,inline image macro>> counterpart.
+
+Block images can be titled by preceding the 'image' macro with a
+'BlockTitle'.  DocBook toolchains normally number titled block images
+and optionally list them in an automatically generated 'List of
+Figures' backmatter section.
+
+This example:
+
+  .Main circuit board
+  image::images/layout.png[J14P main circuit board]
+
+is equivalent to:
+
+  image::images/layout.png["J14P main circuit board",
+                            title="Main circuit board"]
+
+A title prefix that can be inserted with the `caption` attribute
+(HTML backends). For example:
+
+  .Main circuit board
+  [caption="Figure 2: "]
+  image::images/layout.png[J14P main circuit board]
+
+[[X66]]
+.Embedding images in XHTML documents
+*********************************************************************
+If you define the `data-uri` attribute then images will be embedded in
+XHTML outputs using the
+http://en.wikipedia.org/wiki/Data:_URI_scheme[data URI scheme].  You
+can use the 'data-uri' attribute with the 'xhtml11' and 'html5'
+backends to produce single-file XHTML documents with embedded images
+and CSS, for example:
+
+  $ asciidoc -a data-uri mydocument.txt
+
+[NOTE]
+======
+- All current popular browsers support data URIs, although versions
+  of Internet Explorer prior to version 8 do not.
+- Some browsers limit the size of data URIs.
+======
+*********************************************************************
+
+[[X25]]
+Comment Lines
+^^^^^^^^^^^^^
+Single lines starting with two forward slashes hard up against the
+left margin are treated as comments. Comment lines do not appear in
+the output unless the 'showcomments' attribute is defined.  Comment
+lines have been implemented as both block and inline macros so a
+comment line can appear as a stand-alone block or within block elements
+that support inline macro expansion. Example comment line:
+
+  // This is a comment.
+
+If the 'showcomments' attribute is defined comment lines are written
+to the output:
+
+- In DocBook the comment lines are enclosed by the 'remark' element
+  (which may or may not be rendered by your toolchain).
+- The 'showcomments' attribute does not expose <<X26,Comment Blocks>>.
+  Comment Blocks are never passed to the output.
+
+System Macros
+~~~~~~~~~~~~~
+System macros are block macros that perform a predefined task and are
+hardwired into the asciidoc(1) program.
+
+- You can escape system macros with a leading backslash character
+  (as you can with other macros).
+- The syntax and tasks performed by system macros is built into
+  asciidoc(1) so they don't appear in configuration files.  You can
+  however customize the syntax by adding entries to a configuration
+  file `[macros]` section.
+
+[[X63]]
+Include Macros
+^^^^^^^^^^^^^^
+The `include` and `include1`  system macros to include the contents of
+a named file into the source document.
+
+The `include` macro includes a file as if it were part of the parent
+document -- tabs are expanded and system macros processed. The
+contents of `include1` files are not subject to tab expansion or
+system macro processing nor are attribute or lower priority
+substitutions performed. The `include1` macro's intended use is to
+include verbatim embedded CSS or scripts into configuration file
+headers.  Example:
+
+------------------------------------
+\include::chapter1.txt[tabsize=4]
+------------------------------------
+
+.Include macro behavior
+- If the included file name is specified with a relative path then the
+  path is relative to the location of the referring document.
+- Include macros can appear inside configuration files.
+- Files included from within 'DelimitedBlocks' are read to completion
+  to avoid false end-of-block underline termination.
+- Attribute references are expanded inside the include 'target'; if an
+  attribute is undefined then the included file is silently skipped.
+- The 'tabsize' macro attribute sets the number of space characters to
+  be used for tab expansion in the included file (not applicable to
+  `include1` macro).
+- The 'depth' macro attribute sets the maximum permitted number of
+  subsequent nested includes (not applicable to `include1` macro which
+  does not process nested includes). Setting 'depth' to '1' disables
+  nesting inside the included file. By default, nesting is limited to
+  a depth of ten.
+- If the he 'warnings' attribute is set to 'False' (or any other
+  Python literal that evaluates to boolean false) then no warning
+  message is printed if the included file does not exist. By default
+  'warnings' are enabled.
+- Internally the `include1` macro is translated to the `include1`
+  system attribute which means it must be evaluated in a region where
+  attribute substitution is enabled. To inhibit nested substitution in
+  included files it is preferable to use the `include` macro and set
+  the attribute `depth=1`.
+
+Conditional Inclusion Macros
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Lines of text in the source document can be selectively included or
+excluded from processing based on the existence (or not) of a document
+attribute.
+
+Document text between the `ifdef` and `endif` macros is included if a
+document attribute is defined:
+
+  ifdef::<attribute>[]
+  :
+  endif::<attribute>[]
+
+Document text between the `ifndef` and `endif` macros is not included
+if a document attribute is defined:
+
+  ifndef::<attribute>[]
+  :
+  endif::<attribute>[]
+
+`<attribute>` is an attribute name which is optional in the trailing
+`endif` macro.
+
+If you only want to process a single line of text then the text can be
+put inside the square brackets and the `endif` macro omitted, for
+example:
+
+  ifdef::revnumber[Version number 42]
+
+Is equivalent to:
+
+  ifdef::revnumber[]
+  Version number 42
+  endif::revnumber[]
+
+'ifdef' and 'ifndef' macros also accept multiple attribute names:
+
+- Multiple ',' separated attribute names evaluate to defined if one
+  or more of the attributes is defined, otherwise it's value is
+  undefined.
+- Multiple '+' separated attribute names evaluate to defined if all
+  of the attributes is defined, otherwise it's value is undefined.
+
+Document text between the `ifeval` and `endif` macros is included if
+the Python expression inside the square brackets is true. Example:
+
+  ifeval::[{rs458}==2]
+  :
+  endif::[]
+
+- Document attribute references are expanded before the expression is
+  evaluated.
+- If an attribute reference is undefined then the expression is
+  considered false.
+
+Take a look at the `*.conf` configuration files in the AsciiDoc
+distribution for examples of conditional inclusion macro usage.
+
+Executable system macros
+^^^^^^^^^^^^^^^^^^^^^^^^
+The 'eval', 'sys' and 'sys2' block macros exhibit the same behavior as
+their same named <<X24, system attribute references>>. The difference
+is that system macros occur in a block macro context whereas system
+attributes are confined to inline contexts where attribute
+substitution is enabled.
+
+The following example displays a long directory listing inside a
+literal block:
+
+  ------------------
+  sys::[ls -l *.txt]
+  ------------------
+
+NOTE: There are no block macro versions of the 'eval3' and 'sys3'
+system attributes.
+
+Template System Macro
+^^^^^^^^^^^^^^^^^^^^^
+The `template` block macro allows the inclusion of one configuration
+file template section within another.  The following example includes
+the `[admonitionblock]` section in the `[admonitionparagraph]`
+section:
+
+  [admonitionparagraph]
+  template::[admonitionblock]
+
+.Template macro behavior
+- The `template::[]` macro is useful for factoring configuration file
+  markup.
+- `template::[]` macros cannot be nested.
+- `template::[]` macro expansion is applied after all configuration
+  files have been read.
+
+
+[[X77]]
+Passthrough macros
+~~~~~~~~~~~~~~~~~~
+Passthrough macros are analogous to <<X76,passthrough blocks>> and are
+used to pass text directly to the output. The substitution performed
+on the text is determined by the macro definition but can be overridden
+by the `<subslist>`.  The usual syntax is
+`<name>:<subslist>[<passtext>]` (for inline macros) and
+`<name>::<subslist>[<passtext>]` (for block macros). Passthroughs, by
+definition, take precedence over all other text substitutions.
+
+pass::
+  Inline and block. Passes text unmodified (apart from explicitly
+  specified substitutions). Examples:
+
+  pass:[<q>To be or not to be</q>]
+  pass:attributes,quotes[<u>the '{author}'</u>]
+
+asciimath, latexmath::
+  Inline and block. Passes text unmodified.  Used for
+  <<X78,mathematical formulas>>.
+
+\+++::
+  Inline and block. The triple-plus passthrough is functionally
+  identical to the 'pass' macro but you don't have to escape `]`
+  characters and you can prefix with quoted attributes in the inline
+  version. Example:
+
+  Red [red]+++`sum_(i=1)\^n i=(n(n+1))/2`$+++ AsciiMathML formula
+
+$$::
+  Inline and block. The double-dollar passthrough is functionally
+  identical to the triple-plus passthrough with one exception: special
+  characters are escaped. Example:
+
+  $$`[[a,b],[c,d]]((n),(k))`$$
+
+[[X80]]`::
+  Text quoted with single backtick characters constitutes an 'inline
+  literal' passthrough. The enclosed text is rendered in a monospaced
+  font and is only subject to special character substitution.  This
+  makes sense since monospace text is usually intended to be rendered
+  literally and often contains characters that would otherwise have to
+  be escaped. If you need monospaced text containing inline
+  substitutions use a <<X81,plus character instead of a backtick>>.
+
+Macro Definitions
+~~~~~~~~~~~~~~~~~
+Each entry in the configuration `[macros]` section is a macro
+definition which can take one of the following forms:
+
+`<pattern>=<name>[<subslist]`:: Inline macro definition.
+`<pattern>=#<name>[<subslist]`:: Block macro definition.
+`<pattern>=+<name>[<subslist]`:: System macro definition.
+`<pattern>`:: Delete the existing macro with this `<pattern>`.
+
+`<pattern>` is a Python regular expression and `<name>` is the name of
+a markup template. If `<name>` is omitted then it is the value of the
+regular expression match group named 'name'.  The optional
+`[<subslist]` is a comma-separated list of substitution names enclosed
+in `[]` brackets, it sets the default substitutions for passthrough
+text, if omitted then no passthrough substitutions are performed.
+
+.Pattern named groups
+The following named groups can be used in macro `<pattern>` regular
+expressions and are available as markup template attributes:
+
+name::
+  The macro name.
+
+target::
+  The macro target.
+
+attrlist::
+  The macro attribute list.
+
+passtext::
+  Contents of this group are passed unmodified to the output subject
+  only to 'subslist' substitutions.
+
+subslist::
+  Processed as a comma-separated list of substitution names for
+  'passtext' substitution, overrides the the macro definition
+  'subslist'.
+
+.Here's what happens during macro substitution
+- Each contextually relevant macro 'pattern' from the `[macros]`
+  section is matched against the input source line.
+- If a match is found the text to be substituted is loaded from a
+  configuration markup template section named like
+  `<name>-inlinemacro` or `<name>-blockmacro` (depending on the macro
+  type).
+- Global and macro attribute list attributes are substituted in the
+  macro's markup template.
+- The substituted template replaces the macro reference in the output
+  document.
+
+
+[[X98]]
+HTML 5 audio and video block macros
+-----------------------------------
+The 'html5' backend 'audio' and 'video' block macros generate the HTML
+5 'audio' and 'video' elements respectively.  They follow the usual
+AsciiDoc block macro syntax `<name>::<target>[<attrlist>]` where:
+
+[horizontal]
+`<name>`:: 'audio' or 'video'.
+`<target>`:: The URL or file name of the video or audio file.
+`<attrlist>`:: A list of named attributes (see below).
+
+.Audio macro attributes
+[options="header",cols="1,5",frame="topbot"]
+|====================================================================
+|Name | Value
+|options
+|A comma separated list of one or more of the following items:
+'autoplay', 'loop' which correspond to the same-named HTML 5 'audio'
+element boolean attributes.  By default the player 'controls' are
+enabled, include the 'nocontrols' option value to hide them.
+|====================================================================
+
+.Video macro attributes
+[options="header",cols="1,5",frame="topbot"]
+|====================================================================
+|Name   | Value
+|height | The height of the player in pixels.
+|width  | The width of the player in pixels.
+|poster | The URL or file name of an image representing the video.
+|options
+|A comma separated list of one or more of the following items:
+'autoplay', 'loop' and 'nocontrols'. The 'autoplay' and 'loop' options
+correspond to the same-named HTML 5 'video' element boolean
+attributes.  By default the player 'controls' are enabled, include the
+'nocontrols' option value to hide them.
+|====================================================================
+
+Examples:
+
+---------------------------------------------------------------------
+audio::images/example.ogg[]
+
+video::gizmo.ogv[width=200,options="nocontrols,autoplay"]
+
+.Example video
+video::gizmo.ogv[]
+
+video::http://www.808.dk/pics/video/gizmo.ogv[]
+---------------------------------------------------------------------
+
+If your needs are more complex put raw HTML 5 in a markup block, for
+example (from http://www.808.dk/?code-html-5-video):
+
+---------------------------------------------------------------------
+++++
+<video poster="pics/video/gizmo.jpg" id="video" style="cursor: pointer;" >
+  <source src="pics/video/gizmo.mp4" />
+  <source src="pics/video/gizmo.webm" type="video/webm" />
+  <source src="pics/video/gizmo.ogv" type="video/ogg" />
+  Video not playing? <a href="pics/video/gizmo.mp4">Download file</a> instead.
+</video>
+
+<script type="text/javascript">
+  var video = document.getElementById('video');
+  video.addEventListener('click',function(){
+    video.play();
+  },false);
+</script>
+++++
+---------------------------------------------------------------------
+
+
+Tables
+------
+The AsciiDoc table syntax looks and behaves like other delimited block
+types and supports standard <<X73,block configuration entries>>.
+Formatting is easy to read and, just as importantly, easy to enter.
+
+- Cells and columns can be formatted using built-in customizable styles.
+- Horizontal and vertical cell alignment can be set on columns and
+  cell.
+- Horizontal and vertical cell spanning is supported.
+
+.Use tables sparingly
+*********************************************************************
+When technical users first start creating documents, tables (complete
+with column spanning and table nesting) are often considered very
+important. The reality is that tables are seldom used, even in
+technical documentation.
+
+Try this exercise: thumb through your library of technical books,
+you'll be surprised just how seldom tables are actually used, even
+less seldom are tables containing block elements (such as paragraphs
+or lists) or spanned cells. This is no accident, like figures, tables
+are outside the normal document flow -- tables are for consulting not
+for reading.
+
+Tables are designed for, and should normally only be used for,
+displaying column oriented tabular data.
+*********************************************************************
+
+Example tables
+~~~~~~~~~~~~~~
+
+.Simple table
+[width="15%"]
+|=======
+|1 |2 |A
+|3 |4 |B
+|5 |6 |C
+|=======
+
+.AsciiDoc source
+---------------------------------------------------------------------
+[width="15%"]
+|=======
+|1 |2 |A
+|3 |4 |B
+|5 |6 |C
+|=======
+---------------------------------------------------------------------
+
+.Columns formatted with strong, monospaced and emphasis styles
+[width="50%",cols=">s,^m,e",frame="topbot",options="header,footer"]
+|==========================
+|      2+|Columns 2 and 3
+|1       |Item 1  |Item 1
+|2       |Item 2  |Item 2
+|3       |Item 3  |Item 3
+|4       |Item 4  |Item 4
+|footer 1|footer 2|footer 3
+|==========================
+
+.AsciiDoc source
+---------------------------------------------------------------------
+.An example table
+[width="50%",cols=">s,^m,e",frame="topbot",options="header,footer"]
+|==========================
+|      2+|Columns 2 and 3
+|1       |Item 1  |Item 1
+|2       |Item 2  |Item 2
+|3       |Item 3  |Item 3
+|4       |Item 4  |Item 4
+|footer 1|footer 2|footer 3
+|==========================
+---------------------------------------------------------------------
+
+.Horizontal and vertical source data
+[width="80%",cols="3,^2,^2,10",options="header"]
+|=========================================================
+|Date |Duration |Avg HR |Notes
+
+|22-Aug-08 |10:24 | 157 |
+Worked out MSHR (max sustainable heart rate) by going hard
+for this interval.
+
+|22-Aug-08 |23:03 | 152 |
+Back-to-back with previous interval.
+
+|24-Aug-08 |40:00 | 145 |
+Moderately hard interspersed with 3x 3min intervals (2min
+hard + 1min really hard taking the HR up to 160).
+
+|=========================================================
+
+Short cells can be entered horizontally, longer cells vertically.  The
+default behavior is to strip leading and trailing blank lines within a
+cell. These characteristics aid readability and data entry.
+
+.AsciiDoc source
+---------------------------------------------------------------------
+.Windtrainer workouts
+[width="80%",cols="3,^2,^2,10",options="header"]
+|=========================================================
+|Date |Duration |Avg HR |Notes
+
+|22-Aug-08 |10:24 | 157 |
+Worked out MSHR (max sustainable heart rate) by going hard
+for this interval.
+
+|22-Aug-08 |23:03 | 152 |
+Back-to-back with previous interval.
+
+|24-Aug-08 |40:00 | 145 |
+Moderately hard interspersed with 3x 3min intervals (2min
+hard + 1min really hard taking the HR up to 160).
+
+|=========================================================
+---------------------------------------------------------------------
+
+.A table with externally sourced CSV data
+[format="csv",cols="^1,4*2",options="header"]
+|===================================================
+ID,Customer Name,Contact Name,Customer Address,Phone
+include::customers.csv[]
+|===================================================
+
+.AsciiDoc source
+---------------------------------------------------------------------
+[format="csv",cols="^1,4*2",options="header"]
+|===================================================
+ID,Customer Name,Contact Name,Customer Address,Phone
+\include::customers.csv[]
+|===================================================
+---------------------------------------------------------------------
+
+
+.Cell spans, alignments and styles
+[cols="e,m,^,>s",width="25%"]
+|============================
+|1 >s|2 |3 |4
+^|5 2.2+^.^|6 .3+<.>m|7
+^|8
+|9 2+>|10
+|============================
+
+.AsciiDoc source
+---------------------------------------------------------------------
+[cols="e,m,^,>s",width="25%"]
+|============================
+|1 >s|2 |3 |4
+^|5 2.2+^.^|6 .3+<.>m|7
+^|8
+|9 2+>|10
+|============================
+---------------------------------------------------------------------
+
+[[X68]]
+Table input data formats
+~~~~~~~~~~~~~~~~~~~~~~~~
+AsciiDoc table data can be 'psv', 'dsv' or 'csv' formatted.  The
+default table format is 'psv'.
+
+AsciiDoc 'psv' ('Prefix Separated Values') and 'dsv' ('Delimiter
+Separated Values') formats are cell oriented -- the table is treated
+as a sequence of cells -- there are no explicit row separators.
+
+- 'psv' prefixes each cell with a separator whereas 'dsv' delimits
+  cells with a separator.
+- 'psv' and 'dsv' separators are Python regular expressions.
+- The default 'psv' separator contains <<X84, cell specifier>> related
+  named regular expression groups.
+- The default 'dsv' separator is `:|\n` (a colon or a new line
+  character).
+- 'psv' and 'dsv' cell separators can be escaped by preceding them
+  with a backslash character.
+
+Here are four 'psv' cells (the second item spans two columns; the
+last contains an escaped separator):
+
+  |One 2+|Two and three |A \| separator character
+
+'csv'  is the quasi-standard row oriented 'Comma Separated Values
+(CSV)' format commonly used to import and export spreadsheet and
+database data.
+
+[[X69]]
+Table attributes
+~~~~~~~~~~~~~~~~
+Tables can be customized by the following attributes:
+
+format::
+'psv' (default), 'dsv' or 'csv' (See <<X68, Table Data Formats>>).
+
+separator::
+The cell separator. A Python regular expression ('psv' and 'dsv'
+formats) or a single character ('csv' format).
+
+frame::
+Defines the table border and can take the following values: 'topbot'
+(top and bottom), 'all' (all sides), 'none' and 'sides' (left and
+right sides). The default value is 'all'.
+
+grid::
+Defines which ruler lines are drawn between table rows and columns.
+The 'grid' attribute value can be any of the following values: 'none',
+'cols', 'rows' and 'all'. The default value is 'all'.
+
+align::
+Use the 'align' attribute to horizontally align the table on the
+page (works with HTML outputs only, has no effect on DocBook outputs).
+The following values are valid: 'left', 'right', and 'center'.
+
+float::
+Use the 'float' attribute to float the table 'left' or 'right' on the
+page (works with HTML outputs only, has no effect on DocBook outputs).
+Floating only makes sense in conjunction with a table 'width'
+attribute value of less than 100% (otherwise the table will take up
+all the available space).  'float' and 'align' attributes are mutually
+exclusive.  Use the `unfloat::[]` block macro to stop floating.
+
+halign::
+Use the 'halign' attribute to horizontally align all cells in a table.
+The following values are valid: 'left', 'right', and 'center'
+(defaults to 'left'). Overridden by <<X70,Column specifiers>>  and
+<<X84,Cell specifiers>>.
+
+valign::
+Use the 'valign' attribute to vertically align all cells in a table.
+The following values are valid: 'top', 'bottom', and 'middle'
+(defaults to 'top'). Overridden by <<X70,Column specifiers>>  and
+<<X84,Cell specifiers>>.
+
+options::
+The 'options' attribute can contain comma separated values, for
+example: 'header', 'footer'. By default header and footer rows are
+omitted.  See <<X74,attribute options>> for a complete list of
+available table options.
+
+cols::
+The 'cols' attribute is a comma separated list of <<X70,column
+specifiers>>. For example `cols="2<p,2*,4p,>"`.
+
+- If 'cols' is present it must specify all columns.
+- If the 'cols' attribute is not specified the number of columns is
+  calculated as the number of data items in the *first line* of the
+  table.
+- The degenerate form for the 'cols' attribute is an integer
+  specifying the number of columns e.g. `cols=4`.
+
+width::
+The 'width' attribute is expressed as a percentage value
+('"1%"'...'"99%"'). The width specifies the table width relative to
+the available width. HTML backends use this value to set the table
+width attribute. It's a bit more complicated with DocBook, see the
+<<X89,DocBook table widths>> sidebar.
+
+filter::
+The 'filter' attribute defines an external shell command that is
+invoked for each cell. The built-in 'asciidoc' table style is
+implemented using a filter.
+
+[[X89]]
+.DocBook table widths
+**********************************************************************
+The AsciiDoc docbook backend generates CALS tables. CALS tables do not
+support a table width attribute -- table width can only be controlled
+by specifying absolute column widths.
+
+Specifying absolute column widths is not media independent because
+different presentation media have different physical dimensions. To
+get round this limitation both
+http://www.sagehill.net/docbookxsl/Tables.html#TableWidth[DocBook XSL
+Stylesheets] and
+http://dblatex.sourceforge.net/doc/manual/ch03s05.html#sec-table-width[dblatex]
+have implemented table width processing instructions for setting the
+table width as a percentage of the available width. AsciiDoc emits
+these processing instructions if the 'width' attribute is set along
+with proportional column widths (the AsciiDoc docbook backend
+'pageunits' attribute defaults to '*').
+
+To generate DocBook tables with absolute column widths set the
+'pageunits' attribute to a CALS absolute unit such as 'pt' and set the
+'pagewidth' attribute to match the width of the presentation media.
+**********************************************************************
+
+[[X70]]
+Column Specifiers
+~~~~~~~~~~~~~~~~~
+Column specifiers define how columns are rendered and appear in the
+table <<X69,cols attribute>>.  A column specifier consists of an
+optional column multiplier followed by optional alignment, width and
+style values and is formatted like:
+
+  [<multiplier>*][<align>][<width>][<style>]
+
+- All components are optional. The multiplier must be first and the
+  style last. The order of `<align>` or `<width>` is not important.
+- Column `<width>` can be either an integer proportional value (1...)
+  or a percentage (1%...100%). The default value is 1. To ensure
+  portability across different backends, there is no provision for
+  absolute column widths (not to be confused with output column width
+  <<X72,markup attributes>> which are available in both percentage and
+  absolute units).
+- The '<align>' column alignment specifier is formatted like:
+
+  [<horizontal>][.<vertical>]
++
+Where `<horizontal>` and `<vertical>` are one of the following
+characters: `<`, `^` or `>` which represent 'left', 'center' and
+'right' horizontal alignment or 'top', 'middle' and 'bottom' vertical
+alignment respectively.
+
+- A `<multiplier>` can be used to specify repeated columns e.g.
+  `cols="4*<"` specifies four left-justified columns. The default
+  multiplier value is 1.
+- The `<style>` name specifies a <<X71,table style>> to used to markup
+  column cells (you can use the full style names if you wish but the
+  first letter is normally sufficient).
+- Column specific styles are not applied to header rows.
+
+[[X84]]
+Cell Specifiers
+~~~~~~~~~~~~~~~
+Cell specifiers allow individual cells in 'psv' formatted tables to be
+spanned, multiplied, aligned and styled.  Cell specifiers prefix 'psv'
+`|` delimiters and are formatted like:
+
+  [<span>*|+][<align>][<style>]
+
+- '<span>' specifies horizontal and vertical cell spans ('+' operator) or
+  the number of times the cell is replicated ('*' operator). '<span>'
+  is formatted like:
+
+  [<colspan>][.<rowspan>]
++
+Where `<colspan>` and `<rowspan>` are integers specifying the number of
+columns and rows to span.
+
+- `<align>` specifies horizontal and vertical cell alignment an is the
+  same as in <<X70,column specifiers>>.
+- A `<style>` value is the first letter of <<X71,table style>> name.
+
+For example, the following 'psv' formatted cell will span two columns
+and the text will be centered and emphasized:
+
+  `2+^e| Cell text`
+
+[[X71]]
+Table styles
+~~~~~~~~~~~~
+Table styles can be applied to the entire table (by setting the
+'style' attribute in the table's attribute list) or on a per column
+basis (by specifying the style in the table's <<X69,cols attribute>>).
+Table data can be formatted using the following predefined styles:
+
+default::
+The default style: AsciiDoc inline text formatting; blank lines are
+treated as paragraph breaks.
+
+emphasis::
+Like default but all text is emphasised.
+
+monospaced::
+Like default but all text is in a monospaced font.
+
+strong::
+Like default but all text is bold.
+
+header::
+Apply the same style as the table header. Normally used to create a
+vertical header in the first column.
+
+asciidoc::
+With this style table cells can contain any of the AsciiDoc elements
+that are allowed inside document sections. This style runs asciidoc(1)
+as a filter to process cell contents. See also <<X83,Docbook table
+limitations>>.
+
+literal::
+No text formatting; monospaced font; all line breaks are retained
+(the same as the AsciiDoc <<X65,LiteralBlock>> element).
+
+verse::
+All line breaks are retained (just like the AsciiDoc <<X94,verse
+paragraph style>>).
+
+[[X72]]
+Markup attributes
+~~~~~~~~~~~~~~~~~
+AsciiDoc makes a number of attributes available to table markup
+templates and tags. Column specific attributes are available when
+substituting the 'colspec' cell data tags.
+
+pageunits::
+DocBook backend only. Specifies table column absolute width units.
+Defaults to '*'.
+
+pagewidth::
+DocBook backend only. The nominal output page width in 'pageunit'
+units. Used to calculate CALS tables absolute column and table
+widths. Defaults to '425'.
+
+tableabswidth::
+Integer value calculated from 'width' and 'pagewidth' attributes.
+In 'pageunit' units.
+
+tablepcwidth::
+Table width expressed as a percentage of the available width. Integer
+value (0..100).
+
+colabswidth::
+Integer value calculated from 'cols' column width, 'width' and
+'pagewidth' attributes.  In 'pageunit' units.
+
+colpcwidth::
+Column width expressed as a percentage of the table width. Integer
+value (0..100).
+
+colcount::
+Total number of table columns.
+
+rowcount::
+Total number of table rows.
+
+halign::
+Horizontal cell content alignment: 'left', 'right' or 'center'.
+
+valign::
+Vertical cell content alignment: 'top', 'bottom' or 'middle'.
+
+colnumber, colstart::
+The number of the leftmost column occupied by the cell (1...).
+
+colend::
+The number of the rightmost column occupied by the cell (1...).
+
+colspan::
+Number of columns the cell should span.
+
+rowspan::
+Number of rows the cell should span (1...).
+
+morerows::
+Number of additional rows the cell should span (0...).
+
+Nested tables
+~~~~~~~~~~~~~
+An alternative 'psv' separator character '!' can be used (instead of
+'|') in nested tables. This allows a single level of table nesting.
+Columns containing nested tables must use the 'asciidoc' style. An
+example can be found in `./examples/website/newtables.txt`.
+
+[[X83]]
+DocBook table limitations
+~~~~~~~~~~~~~~~~~~~~~~~~~
+Fully implementing tables is not trivial, some DocBook toolchains do
+better than others.  AsciiDoc HTML table outputs are rendered
+correctly in all the popular browsers -- if your DocBook generated
+tables don't look right compare them with the output generated by the
+AsciiDoc 'xhtml11' backend or try a different DocBook toolchain.  Here
+is a list of things to be aware of:
+
+- Although nested tables are not legal in DocBook 4 the FOP and
+  dblatex toolchains will process them correctly.  If you use `a2x(1)`
+  you will need to include the `--no-xmllint` option to suppress
+  DocBook validation errors.
++
+NOTE: In theory you can nest DocBook 4 tables one level using the
+'entrytbl' element, but not all toolchains process 'entrytbl'.
+
+- DocBook only allows a subset of block elements inside table cells so
+  not all AsciiDoc elements produce valid DocBook inside table cells.
+  If you get validation errors running `a2x(1)` try the `--no-xmllint`
+  option, toolchains will often process nested block elements such as
+  sidebar blocks and floating titles correctly even though, strictly
+  speaking, they are not legal.
+
+- Text formatting in cells using the 'monospaced' table style will
+  raise validation errors because the DocBook 'literal' element was
+  not designed to support formatted text (using the 'literal' element
+  is a kludge on the part of AsciiDoc as there is no easy way to set
+  the font style in DocBook.
+
+- Cell alignments are ignored for 'verse', 'literal' or 'asciidoc'
+  table styles.
+
+
+[[X1]]
+Manpage Documents
+-----------------
+Sooner or later, if you program in a UNIX environment, you're going
+to have to write a man page.
+
+By observing a couple of additional conventions (detailed below) you
+can write AsciiDoc files that will generate HTML and PDF man pages
+plus the native manpage roff format.  The easiest way to generate roff
+manpages from AsciiDoc source is to use the a2x(1) command. The
+following example generates a roff formatted manpage file called
+`asciidoc.1` (a2x(1) uses asciidoc(1) to convert `asciidoc.1.txt` to
+DocBook which it then converts to roff using DocBook XSL Stylesheets):
+
+  a2x --doctype manpage --format manpage asciidoc.1.txt
+
+.Viewing and printing manpage files
+**********************************************************************
+Use the `man(1)` command to view the manpage file:
+
+  $ man -l asciidoc.1
+
+To print a high quality man page to a postscript printer:
+
+  $ man -l -Tps asciidoc.1 | lpr
+
+You could also create a PDF version of the man page by converting
+PostScript to PDF using `ps2pdf(1)`:
+
+  $ man -l -Tps asciidoc.1 | ps2pdf - asciidoc.1.pdf
+
+The `ps2pdf(1)` command is included in the Ghostscript distribution.
+**********************************************************************
+
+To find out more about man pages view the `man(7)` manpage
+(`man 7 man` and `man man-pages` commands).
+
+
+Document Header
+~~~~~~~~~~~~~~~
+A manpage document Header is mandatory. The title line contains the
+man page name followed immediately by the manual section number in
+brackets, for example 'ASCIIDOC(1)'. The title name should not contain
+white space and the manual section number is a single digit optionally
+followed by a single character.
+
+The NAME Section
+~~~~~~~~~~~~~~~~
+The first manpage section is mandatory, must be titled 'NAME' and must
+contain a single paragraph (usually a single line) consisting of a
+list of one or more comma separated command name(s) separated from the
+command purpose by a dash character. The dash must have at least one
+white space character on either side. For example:
+
+  printf, fprintf, sprintf - print formatted output
+
+The SYNOPSIS Section
+~~~~~~~~~~~~~~~~~~~~
+The second manpage section is mandatory and must be titled 'SYNOPSIS'.
+
+refmiscinfo attributes
+~~~~~~~~~~~~~~~~~~~~~~
+In addition to the automatically created man page <<X60,intrinsic
+attributes>> you can assign DocBook
+http://www.docbook.org/tdg5/en/html/refmiscinfo.html[refmiscinfo]
+element 'source', 'version' and 'manual' values using AsciiDoc
+`{mansource}`, `{manversion}` and `{manmanual}` attributes
+respectively. This example is from the AsciiDoc header of a man page
+source file:
+
+  :man source:   AsciiDoc
+  :man version:  {revnumber}
+  :man manual:   AsciiDoc Manual
+
+
+[[X78]]
+Mathematical Formulas
+---------------------
+The 'asciimath' and 'latexmath' <<X77,passthrough macros>> along with
+'asciimath' and 'latexmath'  <<X76,passthrough blocks>> provide a
+(backend dependent) mechanism for rendering mathematical formulas. You
+can use the following math markups:
+
+NOTE: The 'latexmath' macro used to include 'LaTeX Math' in DocBook
+outputs is not the same as the 'latexmath' macro used to include
+'LaTeX MathML' in XHTML outputs.  'LaTeX Math' applies to DocBook
+outputs that are processed by <<X31,dblatex>> and is normally used to
+generate PDF files.  'LaTeXMathML' is very much a subset of 'LaTeX
+Math' and applies to XHTML documents.
+
+LaTeX Math
+~~~~~~~~~~
+ftp://ftp.ams.org/pub/tex/doc/amsmath/short-math-guide.pdf[LaTeX
+math] can be included in documents that are processed by
+<<X31,dblatex(1)>>.  Example inline formula:
+
+  latexmath:[$C = \alpha + \beta Y^{\gamma} + \epsilon$]
+
+For more examples see the {website}[AsciiDoc website] or the
+distributed `doc/latexmath.txt` file.
+
+ASCIIMathML
+~~~~~~~~~~~
+/////////////////////////////////////////////////////////////////////
+The older ASCIIMathML 1.47 version is used instead of version 2
+because:
+
+1. Version 2 doesn't work when embedded.
+2. Version 2 is much larger.
+/////////////////////////////////////////////////////////////////////
+
+http://www1.chapman.edu/~jipsen/mathml/asciimath.html[ASCIIMathML]
+formulas can be included in XHTML documents generated using the
+'xhtml11' and 'html5' backends. To enable ASCIIMathML support you must
+define the 'asciimath' attribute, for example using the `-a asciimath`
+command-line option.  Example inline formula:
+
+  asciimath:[`x/x={(1,if x!=0),(text{undefined},if x=0):}`]
+
+For more examples see the {website}[AsciiDoc website] or the
+distributed `doc/asciimathml.txt` file.
+
+LaTeXMathML
+~~~~~~~~~~~
+/////////////////////////////////////////////////////////////////////
+There is an http://math.etsu.edu/LaTeXMathML/[extended LaTeXMathML
+version] by Jeff Knisley, in addition to a JavaScript file it requires
+the inclusion of a CSS file.
+/////////////////////////////////////////////////////////////////////
+
+'LaTeXMathML' allows LaTeX Math style formulas to be included in XHTML
+documents generated using the AsciiDoc 'xhtml11' and 'html5' backends.
+AsciiDoc uses the
+http://www.maths.nottingham.ac.uk/personal/drw/lm.html[original
+LaTeXMathML] by Douglas Woodall.  'LaTeXMathML' is derived from
+ASCIIMathML and is for users who are more familiar with or prefer
+using LaTeX math formulas (it recognizes a subset of LaTeX Math, the
+differences are documented on the 'LaTeXMathML' web page).  To enable
+LaTeXMathML support you must define the 'latexmath' attribute, for
+example using the `-a latexmath` command-line option.  Example inline
+formula:
+
+  latexmath:[$\sum_{n=1}^\infty \frac{1}{2^n}$]
+
+For more examples see the {website}[AsciiDoc website] or the
+distributed `doc/latexmathml.txt` file.
+
+MathML
+~~~~~~
+http://www.w3.org/Math/[MathML] is a low level XML markup for
+mathematics. AsciiDoc has no macros for MathML but users familiar with
+this markup could use passthrough macros and passthrough blocks to
+include MathML in output documents.
+
+
+[[X7]]
+Configuration Files
+-------------------
+AsciiDoc source file syntax and output file markup is largely
+controlled by a set of cascading, text based, configuration files.  At
+runtime The AsciiDoc default configuration files are combined with
+optional user and document specific configuration files.
+
+Configuration File Format
+~~~~~~~~~~~~~~~~~~~~~~~~~
+Configuration files contain named sections. Each section begins with a
+section name in square brackets []. The section body consists of the
+lines of text between adjacent section headings.
+
+- Section names consist of one or more alphanumeric, underscore or
+  dash characters and cannot begin or end with a dash.
+- Lines starting with a '#' character are treated as comments and
+  ignored.
+- If the section name is prefixed with a '+' character then the
+  section contents is appended to the contents of an already existing
+  same-named section.
+- Otherwise same-named sections and section entries override
+  previously loaded sections and section entries (this is sometimes
+  referred to as 'cascading').  Consequently, downstream configuration
+  files need only contain those sections and section entries that need
+  to be overridden.
+
+TIP: When creating custom configuration files you only need to include
+the sections and entries that differ from the default configuration.
+
+TIP: The best way to learn about configuration files is to read the
+default configuration files in the AsciiDoc distribution in
+conjunction with asciidoc(1) output files. You can view configuration
+file load sequence by turning on the asciidoc(1) `-v` (`--verbose`)
+command-line option.
+
+AsciiDoc reserves the following section names for specific purposes:
+
+miscellaneous::
+        Configuration options that don't belong anywhere else.
+attributes::
+        Attribute name/value entries.
+specialcharacters::
+        Special characters reserved by the backend markup.
+tags::
+        Backend markup tags.
+quotes::
+        Definitions for quoted inline character formatting.
+specialwords::
+        Lists of words and phrases singled out for special markup.
+replacements, replacements2, replacements3::
+        Find and replace substitution definitions.
+specialsections::
+        Used to single out special section names for specific markup.
+macros::
+        Macro syntax definitions.
+titles::
+        Heading, section and block title definitions.
+paradef-*::
+        Paragraph element definitions.
+blockdef-*::
+        DelimitedBlock element definitions.
+listdef-*::
+        List element definitions.
+listtags-*::
+        List element tag definitions.
+tabledef-*::
+        Table element definitions.
+tabletags-*::
+        Table element tag definitions.
+
+Each line of text in these sections is a 'section entry'. Section
+entries share the following syntax:
+
+name=value::
+        The entry value is set to value.
+name=::
+        The entry value is set to a zero length string.
+name!::
+        The entry is undefined (deleted from the configuration). This
+        syntax only applies to 'attributes' and 'miscellaneous'
+        sections.
+
+.Section entry behavior
+- All equals characters inside the `name` must be escaped with a
+  backslash character.
+- `name` and `value` are stripped of leading and trailing white space.
+- Attribute names, tag entry names and markup template section names
+  consist of one or more alphanumeric, underscore or dash characters.
+  Names should not begin or end with a dash.
+- A blank configuration file section (one without any entries) deletes
+  any preceding section with the same name (applies to non-markup
+  template sections).
+
+
+Miscellaneous section
+~~~~~~~~~~~~~~~~~~~~~
+The optional `[miscellaneous]` section specifies the following
+`name=value` options:
+
+newline::
+        Output file line termination characters. Can include any
+        valid Python string escape sequences. The default value is
+        `\r\n` (carriage return, line feed). Should not be quoted or
+        contain explicit spaces (use `\x20` instead). For example:
+
+        $ asciidoc -a 'newline=\n' -b docbook mydoc.txt
+
+outfilesuffix::
+        The default extension for the output file, for example
+        `outfilesuffix=.html`. Defaults to backend name.
+tabsize::
+        The number of spaces to expand tab characters, for example
+        `tabsize=4`. Defaults to 8. A 'tabsize' of zero suppresses tab
+        expansion (useful when piping included files through block
+        filters). Included files can override this option using the
+        'tabsize' attribute.
+pagewidth, pageunits::
+        These global table related options are documented in the
+        <<X4,Table Configuration File Definitions>> sub-section.
+
+NOTE: `[miscellaneous]` configuration file entries can be set using
+the asciidoc(1) `-a` (`--attribute`) command-line option.
+
+Titles section
+~~~~~~~~~~~~~~
+sectiontitle::
+        Two line section title pattern. The entry value is a Python
+        regular expression containing the named group 'title'.
+
+underlines::
+        A comma separated list of document and section title underline
+        character pairs starting with the section level 0 and ending
+        with section level 4 underline. The default setting is:
+
+        underlines="==","--","~~","^^","++"
+
+sect0...sect4::
+        One line section title patterns. The entry value is a Python
+        regular expression containing the named group 'title'.
+
+blocktitle::
+        <<X42,BlockTitle element>> pattern.  The entry value is a
+        Python regular expression containing the named group 'title'.
+
+subs::
+        A comma separated list of substitutions that are performed on
+        the document header and section titles. Defaults to 'normal'
+        substitution.
+
+Tags section
+~~~~~~~~~~~~
+The `[tags]` section contains backend tag definitions (one per
+line). Tags are used to translate AsciiDoc elements to backend
+markup.
+
+An AsciiDoc tag definition is formatted like
+`<tagname>=<starttag>|<endtag>`. For example:
+
+  emphasis=<em>|</em>
+
+In this example asciidoc(1) replaces the | character with the
+emphasized text from the AsciiDoc input file and writes the result to
+the output file.
+
+Use the `{brvbar}` attribute reference if you need to include a | pipe
+character inside tag text.
+
+Attributes section
+~~~~~~~~~~~~~~~~~~
+The optional `[attributes]` section contains predefined attributes.
+
+If the attribute value requires leading or trailing spaces then the
+text text should be enclosed in quotation mark (") characters.
+
+To delete a attribute insert a `name!` entry in a downstream
+configuration file or use the asciidoc(1) `--attribute name!`
+command-line option (an attribute name suffixed with a `!` character
+deletes the attribute)
+
+Special Characters section
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+The `[specialcharacters]` section specifies how to escape characters
+reserved by the backend markup. Each translation is specified on a
+single line formatted like:
+
+  <special_character>=<translated_characters>
+
+Special characters are normally confined to those that resolve
+markup ambiguity (in the case of HTML and XML markups the ampersand,
+less than and greater than characters).  The following example causes
+all occurrences of the `<` character to be replaced by `<`.
+
+  <=<
+
+Quoted Text section
+~~~~~~~~~~~~~~~~~~~
+Quoting is used primarily for text formatting.  The `[quotes]` section
+defines AsciiDoc quoting characters and their corresponding backend
+markup tags.  Each section entry value is the name of a of a `[tags]`
+section entry. The entry name is the character (or characters) that
+quote the text.  The following examples are taken from AsciiDoc
+configuration files:
+
+  [quotes]
+  _=emphasis
+
+  [tags]
+  emphasis=<em>|</em>
+
+You can specify the left and right quote strings separately by
+separating them with a | character, for example:
+
+  ``|''=quoted
+
+Omitting the tag will disable quoting, for example, if you don't want
+superscripts or subscripts put the following in a custom configuration
+file or edit the global `asciidoc.conf` configuration file:
+
+  [quotes]
+  ^=
+  ~=
+
+<<X52,Unconstrained quotes>> are differentiated from constrained
+quotes by prefixing the tag name with a hash character, for example:
+
+  __=#emphasis
+
+.Quoted text behavior
+- Quote characters must be non-alphanumeric.
+- To minimize quoting ambiguity try not to use the same quote
+  characters in different quote types.
+
+Special Words section
+~~~~~~~~~~~~~~~~~~~~~
+The `[specialwords]` section is used to single out words and phrases
+that you want to consistently format in some way throughout your
+document without having to repeatedly specify the markup. The name of
+each entry corresponds to a markup template section and the entry
+value consists of a list of words and phrases to be marked up. For
+example:
+
+  [specialwords]
+  strongwords=NOTE IMPORTANT
+
+  [strongwords]
+  <strong>{words}</strong>
+
+The examples specifies that any occurrence of `NOTE` or `IMPORTANT`
+should appear in a bold font.
+
+Words and word phrases are treated as Python regular expressions: for
+example, the word `^NOTE` would only match `NOTE` if appeared at
+the start of a line.
+
+AsciiDoc comes with three built-in Special Word types:
+'emphasizedwords', 'monospacedwords' and 'strongwords', each has a
+corresponding (backend specific) markup template section. Edit the
+configuration files to customize existing Special Words and to add new
+ones.
+
+.Special word behavior
+- Word list entries must be separated by space characters.
+- Word list entries with embedded spaces should be enclosed in quotation (")
+  characters.
+- A `[specialwords]` section entry of the form
+  +name=word1{nbsp}[word2...]+ adds words to existing `name` entries.
+- A `[specialwords]` section entry of the form `name` undefines
+  (deletes) all existing `name` words.
+- Since word list entries are processed as Python regular expressions
+  you need to be careful to escape regular expression special
+  characters.
+- By default Special Words are substituted before Inline Macros, this
+  may lead to undesirable consequences. For example the special word
+  `foobar` would be expanded inside the macro call
+  `http://www.foobar.com[]`.  A possible solution is to emphasize
+  whole words only by defining the word using regular expression
+  characters, for example `\bfoobar\b`.
+- If the first matched character of a special word is a backslash then
+  the remaining characters are output without markup i.e. the
+  backslash can be used to escape special word markup.  For example
+  the special word `\\?\b[Tt]en\b` will mark up the words `Ten` and
+  `ten` only if they are not preceded by a backslash.
+
+[[X10]]
+Replacements section
+~~~~~~~~~~~~~~~~~~~~
+`[replacements]`, `[replacements2]` and `[replacements3]`
+configuration file entries specify find and replace text and are
+formatted like:
+
+  <find_pattern>=<replacement_text>
+
+The find text can be a Python regular expression; the replace text can
+contain Python regular expression group references.
+
+Use Replacement shortcuts for often used macro references, for
+example (the second replacement allows us to backslash escape the
+macro name):
+
+  NEW!=image:./images/smallnew.png[New!]
+  \\NEW!=NEW!
+
+The only difference between the three replacement types is how they
+are applied. By default 'replacements' and 'replacement2' are applied
+in <<X102,normal>> substitution contexts whereas 'replacements3' needs
+to be configured explicitly and should only be used in backend
+configuration files.
+
+.Replacement behavior
+- The built-in replacements can be escaped with a backslash.
+- If the find or replace text has leading or trailing spaces then the
+  text should be enclosed in quotation (") characters.
+- Since the find text is processed as a regular expression you need to
+  be careful to escape regular expression special characters.
+- Replacements are performed in the same order they appear in the
+  configuration file replacements section.
+
+Markup Template Sections
+~~~~~~~~~~~~~~~~~~~~~~~~
+Markup template sections supply backend markup for translating
+AsciiDoc elements.  Since the text is normally backend dependent
+you'll find these sections in the backend specific configuration
+files. Template sections differ from other sections in that they
+contain a single block of text instead of per line 'name=value'
+entries. A markup template section body can contain:
+
+- Attribute references
+- System macro calls.
+- A document content placeholder
+
+The document content placeholder is a single | character and is
+replaced by text from the source element.  Use the `{brvbar}`
+attribute reference if you need a literal | character in the template.
+
+[[X27]]
+Configuration file names, precedence and locations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Configuration files have a `.conf` file name extension; they are
+loaded from the following locations:
+
+1. The directory containing the asciidoc executable.
+2. If there is no `asciidoc.conf` file in the directory containing the
+   asciidoc executable then load from the global configuration
+   directory (normally `/etc/asciidoc` or `/usr/local/etc/asciidoc`)
+   i.e. the global configuration files directory is skipped if
+   AsciiDoc configuration files are installed in the same directory as
+   the asciidoc executable. This allows both a system wide copy and
+   multiple local copies of AsciiDoc to coexist on the same host PC.
+3. The user's `$HOME/.asciidoc` directory (if it exists).
+4. The directory containing the AsciiDoc source file.
+5. Explicit configuration files specified using:
+   - The `conf-files` attribute (one or more file names separated by a
+     `|` character). These files are loaded in the order they are
+     specified and prior to files specified using the `--conf-file`
+     command-line option.
+   - The asciidoc(1) `--conf-file`) command-line option.  The
+     `--conf-file` option can be specified multiple times, in which
+     case configuration files will be processed in the same order they
+     appear on the command-line.
+6. <<X100,Backend plugin>> configuration files are loaded from
+   subdirectories named like `backends/<backend>` in locations 1, 2
+   and 3.
+7. <<X59,Filter>> configuration files are loaded from subdirectories
+   named like `filters/<filter>` in locations 1, 2 and 3.
+
+Configuration files from the above locations are loaded in the
+following order:
+
+- The `[attributes]` section only from:
+  * `asciidoc.conf` in location 3
+  * Files from location 5.
++
+This first pass makes locally set attributes available in the global
+`asciidoc.conf` file.
+
+- `asciidoc.conf` from locations 1, 2, 3.
+- 'attributes', 'titles' and 'specialcharacters' sections from the
+  `asciidoc.conf` in location 4.
+- The document header is parsed at this point and we can assume the
+  'backend' and 'doctype' have now been defined.
+- Backend plugin `<backend>.conf` and `<backend>-<doctype>.conf` files
+  from locations 6.  If a backend plugin is not found then try
+  locations 1, 2 and 3 for `<backend>.conf` and
+  `<backend>-<doctype>.conf` backend configuration files.
+- Filter conf files from locations 7.
+- `lang-<lang>.conf` from locations 1, 2, 3.
+- `asciidoc.conf` from location 4.
+- `<backend>.conf` and `<backend>-<doctype>.conf` from location 4.
+- Filter conf files from location 4.
+- `<docfile>.conf` and `<docfile>-<backend>.conf` from location 4.
+- Configuration files from location 5.
+
+Where:
+
+- `<backend>` and `<doctype>` are values specified by the asciidoc(1)
+  `-b` (`--backend`) and `-d` (`--doctype`) command-line options.
+- `<infile>` is the path name of the AsciiDoc input file without the
+  file name extension.
+- `<lang>` is a two letter country code set by the the AsciiDoc 'lang'
+  attribute.
+
+[NOTE]
+=====================================================================
+The backend and language global configuration files are loaded *after*
+the header has been parsed.  This means that you can set most
+attributes in the document header. Here's an example header:
+
+  Life's Mysteries
+  ================
+  :author: Hu Nose
+  :doctype: book
+  :toc:
+  :icons:
+  :data-uri:
+  :lang: en
+  :encoding: iso-8859-1
+
+Attributes set in the document header take precedence over
+configuration file attributes.
+
+=====================================================================
+
+TIP: Use the asciidoc(1) `-v` (`--verbose`) command-line option to see
+which configuration files are loaded and the order in which they are
+loaded.
+
+
+Document Attributes
+-------------------
+A document attribute is comprised of a 'name' and a textual 'value'
+and is used for textual substitution in AsciiDoc documents and
+configuration files. An attribute reference (an attribute name
+enclosed in braces) is replaced by the corresponding attribute
+value. Attribute names are case insensitive and can only contain
+alphanumeric, dash and underscore characters.
+
+There are four sources of document attributes (from highest to lowest
+precedence):
+
+- Command-line attributes.
+- AttributeEntry, AttributeList, Macro and BlockId elements.
+- Configuration file `[attributes]` sections.
+- Intrinsic attributes.
+
+Within each of these divisions the last processed entry takes
+precedence.
+
+NOTE: If an attribute is not defined then the line containing the
+attribute reference is dropped. This property is used extensively in
+AsciiDoc configuration files to facilitate conditional markup
+generation.
+
+
+[[X18]]
+Attribute Entries
+-----------------
+The `AttributeEntry` block element allows document attributes to be
+assigned within an AsciiDoc document. Attribute entries are added to
+the global document attributes dictionary. The attribute name/value
+syntax is a single line like:
+
+  :<name>: <value>
+
+For example:
+
+  :Author Initials: JB
+
+This will set an attribute reference `{authorinitials}` to the value
+'JB' in the current document.
+
+To delete (undefine) an attribute use the following syntax:
+
+  :<name>!:
+
+.AttributeEntry behavior
+- The attribute entry line begins with colon -- no white space allowed
+  in left margin.
+- AsciiDoc converts the `<name>` to a legal attribute name (lower
+  case, alphanumeric, dash and underscore characters only -- all other
+  characters deleted). This allows more human friendly text to be
+  used.
+- Leading and trailing white space is stripped from the `<value>`.
+- Lines ending in a space followed by a plus character are continued
+  to the next line, for example:
+
+  :description: AsciiDoc is a text document format for writing notes, +
+                documentation, articles, books, slideshows, web pages +
+                and man pages.
+
+- If the `<value>` is blank then the corresponding attribute value is
+  set to an empty string.
+- Attribute references contained in the entry `<value>` will be
+  expanded.
+- By default AttributeEntry values are substituted for
+  `specialcharacters` and `attributes` (see above), if you want to
+  change or disable AttributeEntry substitution use the <<X77,pass:[]
+  inline macro>> syntax.
+- Attribute entries in the document Header are available for header
+  markup template substitution.
+- Attribute elements override configuration file and intrinsic
+  attributes but do not override command-line attributes.
+
+Here are some more attribute entry examples:
+
+---------------------------------------------------------------------
+AsciiDoc User Manual
+====================
+:author:    Stuart Rackham
+:email:     srackham@gmail.com
+:revdate:   April 23, 2004
+:revnumber: 5.1.1
+---------------------------------------------------------------------
+
+Which creates these attributes:
+
+  {author}, {firstname}, {lastname}, {authorinitials}, {email},
+  {revdate}, {revnumber}
+
+The previous example is equivalent to this <<X95,document header>>:
+
+---------------------------------------------------------------------
+AsciiDoc User Manual
+====================
+Stuart Rackham <srackham@gmail.com>
+5.1.1, April 23, 2004
+---------------------------------------------------------------------
+
+Setting configuration entries
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+A variant of the Attribute Entry syntax allows configuration file
+section entries and markup template sections to be set from within an
+AsciiDoc document:
+
+  :<section_name>.[<entry_name>]: <entry_value>
+
+Where `<section_name>` is the configuration section name,
+`<entry_name>` is the name of the entry and `<entry_value>` is the
+optional entry value. This example sets the default labeled list
+style to 'horizontal':
+
+  :listdef-labeled.style: horizontal
+
+It is exactly equivalent to a configuration file containing:
+
+  [listdef-labeled]
+  style=horizontal
+
+- If the `<entry_name>` is omitted then the entire section is
+  substituted with the `<entry_value>`. This feature should only be
+  used to set markup template sections. The following example sets the
+  'xref2' inline macro markup template:
+
+  :xref2-inlinemacro.: <a href="#{1}">{2?{2}}</a>
+
+- No substitution is performed on configuration file attribute entries
+  and they cannot be undefined.
+- This feature can only be used in attribute entries -- configuration
+  attributes cannot be set using the asciidoc(1) command `--attribute`
+  option.
+
+[[X62]]
+.Attribute entries promote clarity and eliminate repetition
+*********************************************************************
+URLs and file names in AsciiDoc macros are often quite long -- they
+break paragraph flow and readability suffers.  The problem is
+compounded by redundancy if the same name is used repeatedly.
+Attribute entries can be used to make your documents easier to read
+and write, here are some examples:
+
+  :1:         http://freshmeat.net/projects/asciidoc/
+  :homepage:  http://methods.co.nz/asciidoc/[AsciiDoc home page]
+  :new:       image:./images/smallnew.png[]
+  :footnote1: footnote:[A meaningless latin term]
+
+  Using previously defined attributes: See the {1}[Freshmeat summary]
+  or the {homepage} for something new {new}. Lorem ispum {footnote1}.
+
+.Note
+- The attribute entry definition must precede it's usage.
+- You are not limited to URLs or file names, entire macro calls or
+  arbitrary lines of text can be abbreviated.
+- Shared attributes entries could be grouped into a separate file and
+  <<X63,included>> in multiple documents.
+*********************************************************************
+
+
+[[X21]]
+Attribute Lists
+---------------
+- An attribute list is a comma separated list of attribute values.
+- The entire list is enclosed in square brackets.
+- Attribute lists are used to pass parameters to macros, blocks (using
+  the <<X79,AttributeList element>>) and inline quotes.
+
+The list consists of zero or more positional attribute values followed
+by zero or more named attribute values.  Here are three examples: a
+single unquoted positional attribute; three unquoted positional
+attribute values; one positional attribute followed by two named
+attributes; the unquoted attribute value in the final example contains
+comma (`,`) and double-quote (`"`) character entities:
+
+  [Hello]
+  [quote, Bertrand Russell, The World of Mathematics (1956)]
+  ["22 times", backcolor="#0e0e0e", options="noborders,wide"]
+  [A footnote, "with an image" image:smallnew.png[]]
+
+.Attribute list behavior
+- If one or more attribute values contains a comma the all string
+  values must be quoted (enclosed in double quotation mark
+  characters).
+- If the list contains any named or quoted attributes then all string
+  attribute values must be quoted.
+- To include a double quotation mark (") character in a quoted
+  attribute value the the quotation mark must be escaped with a
+  backslash.
+- List attributes take precedence over existing attributes.
+- List attributes can only be referenced in configuration file markup
+  templates and tags, they are not available elsewhere in the
+  document.
+- Setting a named attribute to `None` undefines the attribute.
+- Positional attributes are referred to as `{1}`,`{2}`,`{3}`,...
+- Attribute `{0}` refers to the entire list (excluding the enclosing
+  square brackets).
+- Named attribute names cannot contain dash characters.
+
+[[X75]]
+Options attribute
+~~~~~~~~~~~~~~~~~
+If the attribute list contains an attribute named `options` it is
+processed as a comma separated list of option names:
+
+- Each name generates an attribute named like `<option>-option` (where
+  `<option>` is the option name) with an empty string value.  For
+  example `[options="opt1,opt2,opt3"]` is equivalent to setting the
+  following three attributes
+  `[opt1-option="",opt2-option="",opt2-option=""]`.
+- If you define a an option attribute globally (for example with an
+  <<X18,attribute entry>>) then it will apply to all elements in the
+  document.
+- AsciiDoc implements a number of predefined options which are listed
+  in the <<X74,Attribute Options appendix>>.
+
+Macro Attribute lists
+~~~~~~~~~~~~~~~~~~~~~
+Macros calls are suffixed with an attribute list. The list may be
+empty but it cannot be omitted. List entries are used to pass
+attribute values to macro markup templates.
+
+
+Attribute References
+--------------------
+An attribute reference is an attribute name (possibly followed by an
+additional parameters) enclosed in curly braces.  When an attribute
+reference is encountered it is evaluated and replaced by its
+corresponding text value.  If the attribute is undefined the line
+containing the attribute is dropped.
+
+There are three types of attribute reference: 'Simple', 'Conditional'
+and 'System'.
+
+.Attribute reference evaluation
+- You can suppress attribute reference expansion by placing a
+  backslash character immediately in front of the opening brace
+  character.
+- By default attribute references are not expanded in
+  'LiteralParagraphs', 'ListingBlocks' or 'LiteralBlocks'.
+- Attribute substitution proceeds line by line in reverse line order.
+- Attribute reference evaluation is performed in the following order:
+  'Simple' then 'Conditional' and finally 'System'.
+
+Simple Attributes References
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Simple attribute references take the form `{<name>}`. If the
+attribute name is defined its text value is substituted otherwise the
+line containing the reference is dropped from the output.
+
+Conditional Attribute References
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Additional parameters are used in conjunction with attribute names to
+calculate a substitution value. Conditional attribute references take
+the following forms:
+
+`{<names>=<value>}`::
+        `<value>` is substituted if the attribute `<names>` is
+        undefined otherwise its value is substituted. `<value>` can
+        contain simple attribute references.
+
+`{<names>?<value>}`::
+        `<value>` is substituted if the attribute `<names>` is defined
+        otherwise an empty string is substituted.  `<value>` can
+        contain simple attribute references.
+
+`{<names>!<value>}`::
+        `<value>` is substituted if the attribute `<names>` is
+        undefined otherwise an empty string is substituted.  `<value>`
+        can contain simple attribute references.
+
+`{<names>#<value>}`::
+        `<value>` is substituted if the attribute `<names>` is defined
+        otherwise the undefined attribute entry causes the containing
+        line to be dropped.  `<value>` can contain simple attribute
+        references.
+
+`{<names>%<value>}`::
+        `<value>` is substituted if the attribute `<names>` is not
+        defined otherwise the containing line is dropped.  `<value>`
+        can contain simple attribute references.
+
+`{<names>@<regexp>:<value1>[:<value2>]}`::
+        `<value1>` is substituted if the value of attribute `<names>`
+        matches the regular expression `<regexp>` otherwise `<value2>`
+        is substituted. If attribute `<names>` is not defined the
+        containing line is dropped. If `<value2>` is omitted an empty
+        string is assumed. The values and the regular expression can
+        contain simple attribute references.  To embed colons in the
+        values or the regular expression escape them with backslashes.
+
+`{<names>$<regexp>:<value1>[:<value2>]}`::
+        Same behavior as the previous ternary attribute except for
+        the following cases:
+
+        `{<names>$<regexp>:<value>}`;;
+                Substitutes `<value>` if `<names>` matches `<regexp>`
+                otherwise the result is undefined and the containing
+                line is dropped.
+
+        `{<names>$<regexp>::<value>}`;;
+                Substitutes `<value>` if `<names>` does not match
+                `<regexp>` otherwise the result is undefined and the
+                containing line is dropped.
+
+The attribute `<names>` parameter normally consists of a single
+attribute name but it can be any one of the following:
+
+- A single attribute name which evaluates to the attributes value.
+- Multiple ',' separated attribute names which evaluates to an empty
+  string if one or more of the attributes is defined, otherwise it's
+  value is undefined.
+- Multiple '+' separated attribute names which evaluates to an empty
+  string if all of the attributes are defined, otherwise it's value is
+  undefined.
+
+Conditional attributes with single attribute names are evaluated first
+so they can be used inside the multi-attribute conditional `<value>`.
+
+Conditional attribute examples
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Conditional attributes are mainly used in AsciiDoc configuration
+files -- see the distribution `.conf` files for examples.
+
+Attribute equality test::
+  If `{backend}` is 'docbook45' or 'xhtml11' the example evaluates to
+  ``DocBook 4.5 or XHTML 1.1 backend'' otherwise it evaluates to
+  ``some other backend'':
+
+  {backend@docbook45|xhtml11:DocBook 4.5 or XHTML 1.1 backend:some other backend}
+
+Attribute value map::
+  This example maps the `frame` attribute values [`topbot`, `all`,
+  `none`, `sides`] to [`hsides`, `border`, `void`, `vsides`]:
+
+  {frame@topbot:hsides}{frame@all:border}{frame@none:void}{frame@sides:vsides}
+
+
+[[X24]]
+System Attribute References
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+System attribute references generate the attribute text value by
+executing a predefined action that is parametrized by one or more
+arguments. The syntax is `{<action>:<arguments>}`.
+
+`{counter:<attrname>[:<seed>]}`::
+        Increments the document attribute (if the attribute is
+        undefined it is set to `1`). Returns the new attribute value.
+
+        - Counters generate global (document wide) attributes.
+        - The optional `<seed>` specifies the counter's initial value;
+          it can be a number or a single letter; defaults to '1'.
+        - `<seed>` can contain simple and conditional attribute
+          references.
+        - The 'counter' system attribute will not be executed if the
+          containing line is dropped by the prior evaluation of an
+          undefined attribute.
+
+`{counter2:<attrname>[:<seed>]}`::
+        Same as `counter` except the it always returns a blank string.
+
+`{eval:<expression>}`::
+        Substitutes the result of the Python `<expression>`.
+
+        - If `<expression>` evaluates to `None` or `False` the
+          reference is deemed undefined and the line containing the
+          reference is dropped from the output.
+        - If the expression evaluates to `True` the attribute
+          evaluates to an empty string.
+        - `<expression>` can contain simple and conditional attribute
+          references.
+        - The 'eval' system attribute can be nested inside other
+          system attributes.
+
+`{eval3:<command>}`::
+        Passthrough version of `{eval:<expression>}` -- the generated
+        output is written directly to the output without any further
+        substitutions.
+
+`{include:<filename>}`::
+        Substitutes contents of the file named `<filename>`.
+
+        - The included file is read at the time of attribute
+          substitution.
+        - If the file does not exist a warning is emitted and the line
+          containing the reference is dropped from the output file.
+        - Tabs are expanded based on the current 'tabsize' attribute
+          value.
+
+`{set:<attrname>[!][:<value>]}`::
+        Sets or unsets document attribute. Normally only used in
+        configuration file markup templates (use
+        <<X18,AttributeEntries>> in AsciiDoc documents).
+
+        - If the attribute name is followed by an exclamation mark
+          the attribute becomes undefined.
+        - If `<value>` is omitted the attribute is set to a blank
+          string.
+        - `<value>` can contain simple and conditional attribute
+          references.
+        - Returns a blank string unless the attribute is undefined in
+          which case the return value is undefined and the enclosing
+          line will be dropped.
+
+`{set2:<attrname>[!][:<value>]}`::
+        Same as `set` except that the attribute scope is local to the
+        template.
+
+`{sys:<command>}`::
+        Substitutes the stdout generated by the execution of the shell
+        `<command>`.
+
+`{sys2:<command>}`::
+        Substitutes the stdout and stderr generated by the execution
+        of the shell `<command>`.
+
+`{sys3:<command>}`::
+        Passthrough version of `{sys:<command>}` -- the generated
+        output is written directly to the output without any further
+        substitutions.
+
+`{template:<template>}`::
+        Substitutes the contents of the configuration file section
+        named `<template>`. Attribute references contained in the
+        template are substituted.
+
+.System reference behavior
+- System attribute arguments can contain non-system attribute
+  references.
+- Closing brace characters inside system attribute arguments must be
+  escaped with a backslash.
+
+[[X60]]
+Intrinsic Attributes
+--------------------
+Intrinsic attributes are simple attributes that are created
+automatically from: AsciiDoc document header parameters; asciidoc(1)
+command-line arguments; attributes defined in the default
+configuration files; the execution context.  Here's the list of
+predefined intrinsic attributes:
+
+  {amp}                 ampersand (&) character entity
+  {asciidoc-args}       used to pass inherited arguments to asciidoc filters
+  {asciidoc-confdir}    the asciidoc(1) global configuration directory
+  {asciidoc-dir}        the asciidoc(1) application directory
+  {asciidoc-file}       the full path name of the asciidoc(1) script
+  {asciidoc-version}    the version of asciidoc(1)
+  {author}              author's full name
+  {authored}            empty string '' if {author} or {email} defined,
+  {authorinitials}      author initials (from document header)
+  {backend-<backend>}   empty string ''
+  {<backend>-<doctype>} empty string ''
+  {backend}             document backend specified by `-b` option
+  {backend-confdir}     the directory containing the <backend>.conf file
+  {backslash}           backslash character
+  {basebackend-<base>}  empty string ''
+  {basebackend}         html or docbook
+  {blockname}           current block name (note 8).
+  {brvbar}              broken vertical bar (|) character
+  {docdate}             document last modified date
+  {docdir}              document input directory name  (note 5)
+  {docfile}             document file name  (note 5)
+  {docname}             document file name without extension (note 6)
+  {doctime}             document last modified time
+  {doctitle}            document title (from document header)
+  {doctype-<doctype>}   empty string ''
+  {doctype}             document type specified by `-d` option
+  {email}               author's email address (from document header)
+  {empty}               empty string ''
+  {encoding}            specifies input and output encoding
+  {filetype-<fileext>}  empty string ''
+  {filetype}            output file name file extension
+  {firstname}           author first name (from document header)
+  {gt}                  greater than (>) character entity
+  {id}                  running block id generated by BlockId elements
+  {indir}               input file directory name (note 2,5)
+  {infile}              input file name (note 2,5)
+  {lastname}            author last name (from document header)
+  {ldquo}               Left double quote character (note 7)
+  {level}               title level 1..4 (in section titles)
+  {listindex}           the list index (1..) of the most recent list item
+  {localdate}           the current date
+  {localtime}           the current time
+  {lsquo}               Left single quote character (note 7)
+  {lt}                  less than (<) character entity
+  {manname}             manpage name (defined in NAME section)
+  {manpurpose}          manpage (defined in NAME section)
+  {mantitle}            document title minus the manpage volume number
+  {manvolnum}           manpage volume number (1..8) (from document header)
+  {middlename}          author middle name (from document header)
+  {nbsp}                non-breaking space character entity
+  {notitle}             do not display the document title
+  {outdir}              document output directory name (note 2)
+  {outfile}             output file name (note 2)
+  {python}              the full path name of the Python interpreter executable
+  {rdquo}               Right double quote character (note 7)
+  {reftext}             running block xreflabel generated by BlockId elements
+  {revdate}             document revision date (from document header)
+  {revnumber}           document revision number (from document header)
+  {rsquo}               Right single quote character (note 7)
+  {sectnum}             formatted section number (in section titles)
+  {sp}                  space character
+  {showcomments}        send comment lines to the output
+  {title}               section title (in titled elements)
+  {two-colons}          Two colon characters
+  {two-semicolons}      Two semicolon characters
+  {user-dir}            the ~/.asciidoc directory (if it exists)
+  {verbose}             defined as '' if --verbose command option specified
+  {wj}                  Word-joiner
+  {zwsp}                Zero-width space character entity
+
+[NOTE]
+======
+1. Intrinsic attributes are global so avoid defining custom attributes
+   with the same names.
+2. `{outfile}`, `{outdir}`, `{infile}`, `{indir}` attributes are
+   effectively read-only (you can set them but it won't affect the
+   input or output file paths).
+3.  See also the <<X88,Backend Attributes>> section for attributes
+    that relate to AsciiDoc XHTML file generation.
+4. The entries that translate to blank strings are designed to be used
+   for conditional text inclusion. You can also use the `ifdef`,
+   `ifndef` and `endif` System macros for conditional inclusion.
+   footnote:[Conditional inclusion using `ifdef` and `ifndef` macros
+   differs from attribute conditional inclusion in that the former
+   occurs when the file is read while the latter occurs when the
+   contents are written.]
+5. `{docfile}` and `{docdir}` refer to root document specified on the
+   asciidoc(1) command-line; `{infile}` and `{indir}` refer to the
+   current input file which may be the root document or an included
+   file. When the input is being read from the standard input
+   (`stdin`) these attributes are undefined.
+6. If the input file is the standard input and the output file is not
+   the standard output then `{docname}` is the output file name sans
+   file extension.
+7. See
+   http://en.wikipedia.org/wiki/Non-English_usage_of_quotation_marks[non-English
+   usage of quotation marks].
+8. The `{blockname}` attribute identifies the style of the current
+   block. It applies to delimited blocks, lists and tables. Here is a
+   list of `{blockname}` values (does not include filters or custom
+   block and style names):
+
+   delimited blocks:: comment, sidebar, open, pass, literal, verse,
+   listing, quote, example, note, tip, important, caution, warning,
+   abstract, partintro
+
+   lists:: arabic, loweralpha, upperalpha, lowerroman, upperroman,
+   labeled, labeled3, labeled4, qanda, horizontal, bibliography,
+   glossary
+
+   tables:: table
+
+======
+
+
+[[X73]]
+Block Element Definitions
+-------------------------
+The syntax and behavior of Paragraph, DelimitedBlock, List and Table
+block elements is determined by block definitions contained in
+<<X7,AsciiDoc configuration file>> sections.
+
+Each definition consists of a section title followed by one or more
+section entries. Each entry defines a block parameter controlling some
+aspect of the block's behavior. Here's an example:
+
+---------------------------------------------------------------------
+[blockdef-listing]
+delimiter=^-{4,}$
+template=listingblock
+presubs=specialcharacters,callouts
+---------------------------------------------------------------------
+
+Configuration file block definition sections are processed
+incrementally after each configuration file is loaded. Block
+definition section entries are merged into the block definition, this
+allows block parameters to be overridden and extended by later
+<<X27,loading configuration files>>.
+
+AsciiDoc Paragraph, DelimitedBlock, List and Table block elements
+share a common subset of configuration file parameters:
+
+delimiter::
+  A Python regular expression that matches the first line of a block
+  element -- in the case of DelimitedBlocks and Tables it also matches
+  the last line.
+
+template::
+  The name of the configuration file markup template section that will
+  envelope the block contents. The pipe ('|') character is substituted
+  for the block contents. List elements use a set of (list specific)
+  tag parameters instead of a single template. The template name can
+  contain attribute references allowing dynamic template selection a
+  the time of template substitution.
+
+options::
+  A comma delimited list of element specific option names. In addition
+  to being used internally, options are available during markup tag
+  and template substitution as attributes with an empty string value
+  named like `<option>-option` (where `<option>` is the option name).
+  See <<X74,attribute options>> for a complete list of available
+  options.
+
+subs, presubs, postsubs::
+  * 'presubs' and 'postsubs' are lists of comma separated substitutions that are
+    performed on the block contents. 'presubs' is applied first,
+    'postsubs' (if specified) second.
+
+  * 'subs' is an alias for 'presubs'.
+
+  * If a 'filter' is allowed (Paragraphs, DelimitedBlocks and Tables)
+    and has been specified then 'presubs' and 'postsubs' substitutions
+    are performed before and after the filter is run respectively.
+
+  * Allowed values: 'specialcharacters', 'quotes', 'specialwords',
+    'replacements', 'macros', 'attributes', 'callouts'.
+
+  * [[X102]]The following composite values are also allowed:
+
+    'none';;
+        No substitutions.
+    'normal';;
+        The following substitutions in the following order:
+        'specialcharacters', 'quotes', 'attributes', 'specialwords',
+        'replacements', 'macros', 'replacements2'.
+    'verbatim';;
+        The following substitutions in the following order:
+        'specialcharacters' and 'callouts'.
+
+  * 'normal' and 'verbatim' substitutions can be redefined by with
+    `subsnormal` and `subsverbatim` entries in a configuration file
+    `[miscellaneous]` section.
+
+  * The substitutions are processed in the order in which they are
+    listed and can appear more than once.
+
+filter::
+  This optional entry specifies an executable shell command for
+  processing block content (Paragraphs, DelimitedBlocks and Tables).
+  The filter command can contain attribute references.
+
+posattrs::
+  Optional comma separated list of positional attribute names. This
+  list maps positional attributes (in the block's <<X21,attribute
+  list>>) to named block attributes. The following example, from the
+  QuoteBlock definition, maps the first and section positional
+  attributes:
+
+  posattrs=attribution,citetitle
+
+style::
+  This optional parameter specifies the default style name.
+
+
+<stylename>-style::
+  Optional style definition (see <<X23,Styles>> below).
+
+The following block parameters behave like document attributes and can
+be set in block attribute lists and style definitions: 'template',
+'options', 'subs', 'presubs', 'postsubs', 'filter'.
+
+[[X23]]
+Styles
+~~~~~~
+A style is a set of block parameter bundled as a single named
+parameter. The following example defines a style named 'verbatim':
+
+  verbatim-style=template="literalblock",subs="verbatim"
+
+If a block's <<X21,attribute list>> contains a 'style' attribute then
+the corresponding style parameters are be merged into the default
+block definition parameters.
+
+- All style parameter names must be suffixed with `-style` and the
+  style parameter value is in the form of a list of <<X21,named
+  attributes>>.
+- The 'template' style parameter is mandatory, other parameters can be
+  omitted in which case they inherit their values from the default
+  block definition parameters.
+- Multi-item style parameters ('subs','presubs','postsubs','posattrs')
+  must be specified using Python tuple syntax (rather than a simple
+  list of values as they in separate entries) e.g.
+  `postsubs=("callouts",)` not `postsubs="callouts"`.
+
+Paragraphs
+~~~~~~~~~~
+Paragraph translation is controlled by `[paradef-*]` configuration
+file section entries. Users can define new types of paragraphs and
+modify the behavior of existing types by editing AsciiDoc
+configuration files.
+
+Here is the shipped Default paragraph definition:
+
+--------------------------------------------------------------------
+[paradef-default]
+delimiter=(?P<text>\S.*)
+template=paragraph
+--------------------------------------------------------------------
+
+The normal paragraph definition has a couple of special properties:
+
+1. It must exist and be defined in a configuration file section named
+   `[paradef-default]`.
+2. Irrespective of its position in the configuration files default
+   paragraph document matches are attempted only after trying all
+   other paragraph types.
+
+Paragraph specific block parameter notes:
+
+delimiter::
+  This regular expression must contain the named group 'text' which
+  matches the text on the first line.  Paragraphs are terminated by a
+  blank line, the end of file, or the start of a DelimitedBlock.
+
+options::
+  The 'listelement' option specifies that paragraphs of this type will
+  automatically be considered part of immediately preceding list
+  items.  The 'skip' option causes the paragraph to be treated as a
+  comment (see <<X26,CommentBlocks>>).
+
+.Paragraph processing proceeds as follows:
+1. The paragraph text is aligned to the left margin.
+2. Optional 'presubs' inline substitutions are performed on the
+   paragraph text.
+3. If a filter command is specified it is executed and the paragraph
+   text piped to its standard input; the filter output replaces the
+   paragraph text.
+4. Optional 'postsubs' inline substitutions are performed on the
+   paragraph text.
+5. The paragraph text is enveloped by the paragraph's markup template
+   and written to the output file.
+
+Delimited Blocks
+~~~~~~~~~~~~~~~~
+DelimitedBlock 'options' values are:
+
+sectionbody::
+    The block contents are processed as a SectionBody.
+
+skip::
+    The block is treated as a comment (see <<X26,CommentBlocks>>).
+    Preceding <<X21,attribute lists>> and <<X42,block titles>> are not
+    consumed.
+
+'presubs', 'postsubs' and 'filter' entries are ignored when
+'sectionbody' or 'skip' options are set.
+
+DelimitedBlock processing proceeds as follows:
+
+1. Optional 'presubs' substitutions are performed on the block
+   contents.
+2. If a filter is specified it is executed and the block's contents
+   piped to its standard input. The filter output replaces the block
+   contents.
+3. Optional 'postsubs' substitutions are performed on the block
+   contents.
+4. The block contents is enveloped by the block's markup template and
+   written to the output file.
+
+TIP: Attribute expansion is performed on the block filter command
+before it is executed, this is useful for passing arguments to the
+filter.
+
+Lists
+~~~~~
+List behavior and syntax is determined by `[listdef-*]` configuration
+file sections. The user can change existing list behavior and add new
+list types by editing configuration files.
+
+List specific block definition notes:
+
+type::
+  This is either 'bulleted','numbered','labeled' or 'callout'.
+
+delimiter::
+  A Python regular expression that matches the first line of a
+  list element entry. This expression can contain the named groups
+  'text' (bulleted groups), 'index' and 'text' (numbered lists),
+  'label' and 'text' (labeled lists).
+
+tags::
+  The `<name>` of the `[listtags-<name>]` configuration file section
+  containing list markup tag definitions.  The tag entries ('list',
+  'entry', 'label', 'term', 'text') map the AsciiDoc list structure to
+  backend markup; see the 'listtags' sections in the AsciiDoc
+  distributed backend `.conf` configuration files for examples.
+
+Tables
+~~~~~~
+Table behavior and syntax is determined by `[tabledef-*]` and
+`[tabletags-*]` configuration file sections. The user can change
+existing table behavior and add new table types by editing
+configuration files.  The following `[tabledef-*]` section entries
+generate table output markup elements:
+
+colspec::
+  The table 'colspec' tag definition.
+
+headrow, footrow, bodyrow::
+  Table header, footer and body row tag definitions. 'headrow' and
+  'footrow' table definition entries default to 'bodyrow' if
+  they are undefined.
+
+headdata, footdata, bodydata::
+  Table header, footer and body data tag definitions. 'headdata' and
+  'footdata' table definition entries default to 'bodydata' if they
+  are undefined.
+
+paragraph::
+  If the 'paragraph' tag is specified then blank lines in the cell
+  data are treated as paragraph delimiters and marked up using this
+  tag.
+
+[[X4]]
+Table behavior is also influenced by the following `[miscellaneous]`
+configuration file entries:
+
+pagewidth::
+  This integer value is the printable width of the output media. See
+  <<X69,table attributes>>.
+
+pageunits::
+  The units of width in output markup width attribute values.
+
+.Table definition behavior
+- The output markup generation is specifically designed to work with
+  the HTML and CALS (DocBook) table models, but should be adaptable to
+  most XML table schema.
+- Table definitions can be ``mixed in'' from multiple cascading
+  configuration files.
+- New table definitions inherit the default table and table tags
+  definitions (`[tabledef-default]` and `[tabletags-default]`) so you
+  only need to override those conf file entries that require
+  modification.
+
+
+[[X59]]
+Filters
+-------
+AsciiDoc filters allow external commands to process AsciiDoc
+'Paragraphs', 'DelimitedBlocks' and 'Table' content. Filters are
+primarily an extension mechanism for generating specialized outputs.
+Filters are implemented using external commands which are specified in
+configuration file definitions.
+
+There's nothing special about the filters, they're just standard UNIX
+filters: they read text from the standard input, process it, and write
+to the standard output.
+
+The asciidoc(1) command `--filter` option can be used to install and
+remove filters. The same option is used to unconditionally load a
+filter.
+
+Attribute substitution is performed on the filter command prior to
+execution -- attributes can be used to pass parameters from the
+AsciiDoc source document to the filter.
+
+WARNING: Filters sometimes included executable code. Before installing
+a filter you should verify that it is from a trusted source.
+
+Filter Search Paths
+~~~~~~~~~~~~~~~~~~~
+If the filter command does not specify a directory path then
+asciidoc(1) recursively searches for the executable filter command:
+
+- First it looks in the user's `$HOME/.asciidoc/filters` directory.
+- Next the global filters directory (usually `/etc/asciidoc/filters`
+  or `/usr/local/etc/asciidoc`) directory is searched.
+- Then it looks in the asciidoc(1) `./filters` directory.
+- Finally it relies on the executing shell to search the environment
+  search path (`$PATH`).
+
+Standard practice is to install each filter in it's own sub-directory
+with the same name as the filter's style definition. For example the
+music filter's style name is 'music' so it's configuration and filter
+files are stored in the `filters/music` directory.
+
+Filter Configuration Files
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+Filters are normally accompanied by a configuration file containing a
+Paragraph or DelimitedBlock definition along with corresponding markup
+templates.
+
+While it is possible to create new 'Paragraph' or 'DelimitedBlock'
+definitions the preferred way to implement a filter is to add a
+<<X23,style>> to the existing Paragraph and ListingBlock definitions
+(all filters shipped with AsciiDoc use this technique). The filter is
+applied to the paragraph or delimited block by preceding it with an
+attribute list: the first positional attribute is the style name,
+remaining attributes are normally filter specific parameters.
+
+asciidoc(1) auto-loads all `.conf` files found in the filter search
+paths unless the container directory also contains a file named
+`__noautoload__` (see previous section). The `__noautoload__` feature
+is used for filters that will be loaded manually using the `--filter`
+option.
+
+[[X56]]
+Example Filter
+~~~~~~~~~~~~~~
+AsciiDoc comes with a toy filter for highlighting source code keywords
+and comments.  See also the `./filters/code/code-filter-readme.txt`
+file.
+
+NOTE: The purpose of this toy filter is to demonstrate how to write a
+filter -- it's much to simplistic to be passed off as a code syntax
+highlighter.  If you want a full featured multi-language highlighter
+use the {website}source-highlight-filter.html[source code highlighter
+filter].
+
+Built-in filters
+~~~~~~~~~~~~~~~~
+The AsciiDoc distribution includes 'source', 'music', 'latex' and
+'graphviz' filters, details are on the
+{website}index.html#_filters[AsciiDoc website].
+
+[cols="1e,5",frame="topbot",options="header"]
+.Built-in filters list
+|====================================================================
+|Filter name |Description
+
+|music
+|A {website}music-filter.html[music filter] is included in the
+distribution `./filters/` directory. It translates music in
+http://lilypond.org/[LilyPond] or http://abcnotation.org.uk/[ABC]
+notation to standard classical notation.
+
+|source
+|A {website}source-highlight-filter.html[source code highlight filter]
+is included in the distribution `./filters/` directory.
+
+|latex
+|The {website}latex-filter.html[AsciiDoc LaTeX filter] translates
+LaTeX source to a PNG image that is automatically inserted into the
+AsciiDoc output documents.
+
+|graphviz
+|Gouichi Iisaka has written a http://www.graphviz.org/[Graphviz]
+filter for AsciiDoc.  Graphviz generates diagrams from a textual
+specification. Gouichi Iisaka's Graphviz filter is included in the
+AsciiDoc distribution. Here are some
+{website}asciidoc-graphviz-sample.html[AsciiDoc Graphviz examples].
+
+|====================================================================
+
+[[X58]]
+Filter plugins
+~~~~~~~~~~~~~~
+Filter <<X101,plugins>> are a mechanism for distributing AsciiDoc
+filters.  A filter plugin is a Zip file containing the files that
+constitute a filter.  The asciidoc(1) `--filter` option is used to
+load and manage filer <<X101,plugins>>.
+
+- Filter plugins <<X27,take precedence>> over built-in filters with
+  the same name.
+- By default filter plugins are installed in
+  `$HOME/.asciidoc/filters/<filter>` where `<filter>` is the filter
+  name.
+
+
+[[X101]]
+Plugins
+-------
+The AsciiDoc plugin architecture is an extension mechanism that allows
+additional <<X100,backends>>, <<X58,filters>> and <<X99,themes>> to be
+added to AsciiDoc.
+
+- A plugin is a Zip file containing an AsciiDoc backend, filter or
+  theme (configuration files, stylesheets, scripts, images).
+- The asciidoc(1) `--backend`, `--filter` and `--theme` command-line
+  options are used to load and manage plugins. Each of these options
+  responds to the plugin management 'install', 'list', 'remove' and
+  'build' commands.
+- The plugin management command names are reserved and cannot be used
+  for filter, backend or theme names.
+- The plugin Zip file name always begins with the backend, filter or
+  theme name.
+
+Plugin commands and conventions are documented in the asciidoc(1) man
+page.  You can find lists of plugins on the
+{website}plugins.html[AsciiDoc website].
+
+
+[[X36]]
+Help Commands
+-------------
+The asciidoc(1) command has a `--help` option which prints help topics
+to stdout. The default topic summarizes asciidoc(1) usage:
+
+  $ asciidoc --help
+
+To print a help topic specify the topic name as a command argument.
+Help topic names can be shortened so long as they are not ambiguous.
+Examples:
+
+  $ asciidoc --help manpage
+  $ asciidoc -h m              # Short version of previous example.
+  $ asciidoc --help syntax
+  $ asciidoc -h s              # Short version of previous example.
+
+Customizing Help
+~~~~~~~~~~~~~~~~
+To change, delete or add your own help topics edit a help
+configuration file.  The help file name `help-<lang>.conf` is based on
+the setting of the `lang` attribute, it defaults to `help.conf`
+(English).  The <<X27,help file location>> will depend on whether you
+want the topics to apply to all users or just the current user.
+
+The help topic files have the same named section format as other
+<<X7,configuration files>>. The `help.conf` files are stored in the
+same locations and loaded in the same order as other configuration
+files.
+
+When the `--help` command-line option is specified AsciiDoc loads the
+appropriate help files and then prints the contents of the section
+whose name matches the help topic name.  If a topic name is not
+specified `default` is used. You don't need to specify the whole help
+topic name on the command-line, just enough letters to ensure it's not
+ambiguous. If a matching help file section is not found a list of
+available topics is printed.
+
+
+Tips and Tricks
+---------------
+
+Know Your Editor
+~~~~~~~~~~~~~~~~
+Writing AsciiDoc documents will be a whole lot more pleasant if you
+know your favorite text editor. Learn how to indent and reformat text
+blocks, paragraphs, lists and sentences. <<X20,Tips for 'vim' users>>
+follow.
+
+[[X20]]
+Vim Commands for Formatting AsciiDoc
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Text Wrap Paragraphs
+^^^^^^^^^^^^^^^^^^^^
+Use the vim `:gq` command to reformat paragraphs. Setting the
+'textwidth' sets the right text wrap margin; for example:
+
+  :set textwidth=70
+
+To reformat a paragraph:
+
+1. Position the cursor at the start of the paragraph.
+2. Type `gq}`.
+
+Execute `:help gq` command to read about the vim gq command.
+
+[TIP]
+=====================================================================
+- Assign the `gq}` command to the Q key with the `nnoremap Q gq}`
+  command or put it in your `~/.vimrc` file to so it's always
+  available (see the <<X61, Example `~/.vimrc` file>>).
+- Put `set` commands in your `~/.vimrc` file so you don't have to
+  enter them manually.
+- The Vim website (http://www.vim.org) has a wealth of resources,
+  including scripts for automated spell checking and ASCII Art
+  drawing.
+=====================================================================
+
+Format Lists
+^^^^^^^^^^^^
+The `gq` command can also be used to format bulleted, numbered and
+callout lists. First you need to set the `comments`, `formatoptions`
+and `formatlistpat` (see the <<X61, Example `~/.vimrc` file>>).
+
+Now you can format simple lists that use dash, asterisk, period and
+plus bullets along with numbered ordered lists:
+
+1. Position the cursor at the start of the list.
+2. Type `gq}`.
+
+Indent Paragraphs
+^^^^^^^^^^^^^^^^^
+Indent whole paragraphs by indenting the fist line with the desired
+indent and then executing the `gq}` command.
+
+[[X61]]
+Example `~/.vimrc` File
+^^^^^^^^^^^^^^^^^^^^^^^
+---------------------------------------------------------------------
+" Use bold bright fonts.
+set background=dark
+
+" Show tabs and trailing characters.
+set listchars=tab:,trail:
+set list
+
+" Don't highlight searched text.
+highlight clear Search
+
+" Don't move to matched text while search pattern is being entered.
+set noincsearch
+
+" Reformat paragraphs and list.
+nnoremap R gq}
+
+" Delete trailing white space and Dos-returns and to expand tabs to spaces.
+nnoremap S :set et<CR>:retab!<CR>:%s/[\r \t]\+$//<CR>
+
+autocmd BufRead,BufNewFile *.txt,README,TODO,CHANGELOG,NOTES
+        \ setlocal autoindent expandtab tabstop=8 softtabstop=2 shiftwidth=2 filetype=asciidoc
+        \ textwidth=70 wrap formatoptions=tcqn
+        \ formatlistpat=^\\s*\\d\\+\\.\\s\\+\\\\|^\\s*<\\d\\+>\\s\\+\\\\|^\\s*[a-zA-Z.]\\.\\s\\+\\\\|^\\s*[ivxIVX]\\+\\.\\s\\+
+        \ comments=s1:/*,ex:*/,://,b:#,:%,:XCOMM,fb:-,fb:*,fb:+,fb:.,fb:>
+---------------------------------------------------------------------
+
+Troubleshooting
+~~~~~~~~~~~~~~~
+AsciiDoc diagnostic features are detailed in the <<X82,Diagnostics
+appendix>>.
+
+Gotchas
+~~~~~~~
+Incorrect character encoding::
+    If you get an error message like `'UTF-8' codec can't decode ...`
+    then you source file contains invalid UTF-8 characters -- set the
+    AsciiDoc <<X54,encoding attribute>> for the correct character set
+    (typically ISO-8859-1 (Latin-1) for European languages).
+
+Invalid output::
+    AsciiDoc attempts to validate the input AsciiDoc source but makes
+    no attempt to validate the output markup, it leaves that to
+    external tools such as `xmllint(1)` (integrated into `a2x(1)`).
+    Backend validation cannot be hardcoded into AsciiDoc because
+    backends are dynamically configured. The following example
+    generates valid HTML but invalid DocBook (the DocBook `literal`
+    element cannot contain an `emphasis` element):
+
+    +monospaced text with an _emphasized_ word+
+
+Misinterpreted text formatting::
+    You can suppress markup expansion by placing a backslash character
+    immediately in front of the element. The following example
+    suppresses inline monospaced formatting:
+
+    \+1 for C++.
+
+Overlapping text formatting::
+    Overlapping text formatting will generate illegal overlapping
+    markup tags which will result in downstream XML parsing errors.
+    Here's an example:
+
+    Some *strong markup _that overlaps* emphasized markup_.
+
+Ambiguous underlines::
+    A DelimitedBlock can immediately follow a paragraph without an
+    intervening blank line, but be careful, a single line paragraph
+    underline may be misinterpreted as a section title underline
+    resulting in a ``closing block delimiter expected'' error.
+
+Ambiguous ordered list items::
+    Lines beginning with numbers at the end of sentences will be
+    interpreted as ordered list items.  The following example
+    (incorrectly) begins a new list with item number 1999:
+
+    He was last sighted in
+    1999. Since then things have moved on.
++
+The 'list item out of sequence' warning makes it unlikely that this
+problem will go unnoticed.
+
+Special characters in attribute values::
+    Special character substitution precedes attribute substitution so
+    if attribute values contain special characters you may, depending
+    on the substitution context, need to escape the special characters
+    yourself. For example:
+
+    $ asciidoc -a 'orgname=Bill & Ben Inc.' mydoc.txt
+
+Attribute lists::
+    If any named attribute entries are present then all string
+    attribute values must be quoted.  For example:
+
+    ["Desktop screenshot",width=32]
+
+[[X90]]
+Combining separate documents
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+You have a number of stand-alone AsciiDoc documents that you want to
+process as a single document. Simply processing them with a series of
+`include` macros won't work because the documents contain (level 0)
+document titles.  The solution is to create a top level wrapper
+document and use the `leveloffset` attribute to push them all down one
+level. For example:
+
+[listing]
+.....................................................................
+Combined Document Title
+=======================
+
+// Push titles down one level.
+:leveloffset: 1
+
+\include::document1.txt[]
+
+// Return to normal title levels.
+:leveloffset: 0
+
+A Top Level Section
+-------------------
+Lorum ipsum.
+
+// Push titles down one level.
+:leveloffset: 1
+
+\include::document2.txt[]
+
+\include::document3.txt[]
+.....................................................................
+
+The document titles in the included documents will now be processed as
+level 1 section titles, level 1 sections as level 2 sections and so
+on.
+
+- Put a blank line between the `include` macro lines to ensure the
+  title of the included document is not seen as part of the last
+  paragraph of the previous document.
+- You won't want non-title document header lines (for example, Author
+  and Revision lines) in the included files -- conditionally exclude
+  them if they are necessary for stand-alone processing.
+
+Processing document sections separately
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+You have divided your AsciiDoc document into separate files (one per
+top level section) which are combined and processed with the following
+top level document:
+
+---------------------------------------------------------------------
+Combined Document Title
+=======================
+Joe Bloggs
+v1.0, 12-Aug-03
+
+\include::section1.txt[]
+
+\include::section2.txt[]
+
+\include::section3.txt[]
+---------------------------------------------------------------------
+
+You also want to process the section files as separate documents.
+This is easy because asciidoc(1) will quite happily process
+`section1.txt`, `section2.txt` and `section3.txt` separately -- the
+resulting output documents contain the section but have no document
+title.
+
+Processing document snippets
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Use the `-s` (`--no-header-footer`) command-line option to suppress
+header and footer output, this is useful if the processed output is to
+be included in another file. For example:
+
+  $ asciidoc -sb docbook section1.txt
+
+asciidoc(1) can be used as a filter, so you can pipe chunks of text
+through it. For example:
+
+  $ echo 'Hello *World!*' | asciidoc -s -
+  <div class="paragraph"><p>Hello <strong>World!</strong></p></div>
+
+Badges in HTML page footers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+See the `[footer]` section in the AsciiDoc distribution `xhtml11.conf`
+configuration file.
+
+Pretty printing AsciiDoc output
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If the indentation and layout of the asciidoc(1) output is not to your
+liking you can:
+
+1. Change the indentation and layout of configuration file markup
+   template sections. The `{empty}` attribute is useful for outputting
+   trailing blank lines in markup templates.
+
+2. Use Dave Raggett's http://tidy.sourceforge.net/[HTML Tidy] program
+   to tidy asciidoc(1) output. Example:
+
+   $ asciidoc -b docbook -o - mydoc.txt | tidy -indent -xml >mydoc.xml
+
+3. Use the `xmllint(1)` format option. Example:
+
+   $ xmllint --format mydoc.xml
+
+Supporting minor DocBook DTD variations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The conditional inclusion of DocBook SGML markup at the end of the
+distribution `docbook45.conf` file illustrates how to support minor
+DTD variations. The included sections override corresponding entries
+from preceding sections.
+
+Creating stand-alone HTML documents
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If you've ever tried to send someone an HTML document that includes
+stylesheets and images you'll know that it's not as straight-forward
+as exchanging a single file.  AsciiDoc has options to create
+stand-alone documents containing embedded images, stylesheets and
+scripts.  The following AsciiDoc command creates a single file
+containing <<X66,embedded images>>, CSS stylesheets, and JavaScript
+(for table of contents and footnotes):
+
+  $ asciidoc -a data-uri -a icons -a toc -a max-width=55em article.txt
+
+You can view the HTML file here: {website}article-standalone.html[]
+
+Shipping stand-alone AsciiDoc source
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Reproducing presentation documents from someone else's source has one
+major problem: unless your configuration files are the same as the
+creator's you won't get the same output.
+
+The solution is to create a single backend specific configuration file
+using the asciidoc(1) `-c` (`--dump-conf`) command-line option. You
+then ship this file along with the AsciiDoc source document plus the
+`asciidoc.py` script. The only end user requirement is that they have
+Python installed (and that they consider you a trusted source). This
+example creates a composite HTML configuration file for `mydoc.txt`:
+
+  $ asciidoc -cb xhtml11 mydoc.txt > mydoc-xhtml11.conf
+
+Ship `mydoc.txt`, `mydoc-html.conf`, and `asciidoc.py`. With
+these three files (and a Python interpreter) the recipient can
+regenerate the HMTL output:
+
+  $ ./asciidoc.py -eb xhtml11 mydoc.txt
+
+The `-e` (`--no-conf`) option excludes the use of implicit
+configuration files, ensuring that only entries from the
+`mydoc-html.conf` configuration are used.
+
+Inserting blank space
+~~~~~~~~~~~~~~~~~~~~~
+Adjust your style sheets to add the correct separation between block
+elements. Inserting blank paragraphs containing a single non-breaking
+space character `{nbsp}` works but is an ad hoc solution compared
+to using style sheets.
+
+Closing open sections
+~~~~~~~~~~~~~~~~~~~~~
+You can close off section tags up to level `N` by calling the
+`eval::[Section.setlevel(N)]` system macro. This is useful if you
+want to include a section composed of raw markup. The following
+example includes a DocBook glossary division at the top section level
+(level 0):
+
+---------------------------------------------------------------------
+\ifdef::basebackend-docbook[]
+
+\eval::[Section.setlevel(0)]
+
++++++++++++++++++++++++++++++++
+<glossary>
+  <title>Glossary
+  
+  ...
+  
+
++++++++++++++++++++++++++++++++
+\endif::basebackend-docbook[]
+---------------------------------------------------------------------
+
+Validating output files
+~~~~~~~~~~~~~~~~~~~~~~~
+Use `xmllint(1)` to check the AsciiDoc generated markup is both well
+formed and valid. Here are some examples:
+
+  $ xmllint --nonet --noout --valid docbook-file.xml
+  $ xmllint --nonet --noout --valid xhtml11-file.html
+  $ xmllint --nonet --noout --valid --html html4-file.html
+
+The `--valid` option checks the file is valid against the document
+type's DTD, if the DTD is not installed in your system's catalog then
+it will be fetched from its Internet location. If you omit the
+`--valid` option the document will only be checked that it is well
+formed.
+
+The online http://validator.w3.org/#validate_by_uri+with_options[W3C
+Markup Validation Service] is the defacto standard when it comes to
+validating HTML (it validates all HTML standards including HTML5).
+
+
+:numbered!:
+
+[glossary]
+Glossary
+--------
+[glossary]
+[[X8]] Block element::
+    An AsciiDoc block element is a document entity composed of one or
+    more whole lines of text.
+
+[[X34]] Inline element::
+    AsciiDoc inline elements occur within block element textual
+    content, they perform formatting and substitution tasks.
+
+Formal element::
+    An AsciiDoc block element that has a BlockTitle. Formal elements
+    are normally listed in front or back matter, for example lists of
+    tables, examples and figures.
+
+Verbatim element::
+    The word verbatim indicates that white space and line breaks in
+    the source document are to be preserved in the output document.
+
+
+[appendix]
+Migration Notes
+---------------
+[[X53]]
+Version 7 to version 8
+~~~~~~~~~~~~~~~~~~~~~~
+- A new set of quotes has been introduced which may match inline text
+  in existing documents -- if they do you'll need to escape the
+  matched text with backslashes.
+- The index entry inline macro syntax has changed -- if your documents
+  include indexes you may need to edit them.
+- Replaced a2x(1) `--no-icons` and `--no-copy` options with their
+  negated equivalents: `--icons` and `--copy` respectively. The
+  default behavior has also changed -- the use of icons and copying of
+  icon and CSS files must be specified explicitly with the `--icons`
+  and `--copy` options.
+
+The rationale for the changes can be found in the AsciiDoc
+`CHANGELOG`.
+
+NOTE: If you want to disable unconstrained quotes, the new alternative
+constrained quotes syntax and the new index entry syntax then you can
+define the attribute `asciidoc7compatible` (for example by using the
+`-a asciidoc7compatible` command-line option).
+
+[[X38]]
+[appendix]
+Packager Notes
+--------------
+Read the `README` and `INSTALL` files (in the distribution root
+directory) for install prerequisites and procedures.  The distribution
+`Makefile.in` (used by `configure` to generate the `Makefile`) is the
+canonical installation procedure.
+
+
+[[X39]]
+[appendix]
+AsciiDoc Safe Mode
+-------------------
+AsciiDoc 'safe mode' skips potentially dangerous scripted sections in
+AsciiDoc source files by inhibiting the execution of arbitrary code or
+the inclusion of arbitrary files.
+
+The safe mode is disabled by default, it can be enabled with the
+asciidoc(1) `--safe` command-line option.
+
+.Safe mode constraints
+- `eval`, `sys` and `sys2` executable attributes and block macros are
+  not executed.
+- `include::[]` and `include1::[]` block macro
+  files must reside inside the parent file's directory.
+- `{include:}` executable attribute files must reside
+  inside the source document directory.
+- Passthrough Blocks are dropped.
+
+[WARNING]
+=====================================================================
+The safe mode is not designed to protect against unsafe AsciiDoc
+configuration files. Be especially careful when:
+
+1. Implementing filters.
+2. Implementing elements that don't escape special characters.
+3. Accepting configuration files from untrusted sources.
+=====================================================================
+
+
+[appendix]
+Using AsciiDoc with non-English Languages
+-----------------------------------------
+AsciiDoc can process UTF-8 character sets but there are some things
+you need to be aware of:
+
+- If you are generating output documents using a DocBook toolchain
+  then you should set the AsciiDoc `lang` attribute to the appropriate
+  language (it defaults to `en` (English)). This will ensure things
+  like table of contents, figure and table captions and admonition
+  captions are output in the specified language.  For example:
+
+  $ a2x -a lang=es doc/article.txt
+
+- If you are outputting HTML directly from asciidoc(1) you'll
+  need to set the various `*_caption` attributes to match your target
+  language (see the list of captions and titles in the `[attributes]`
+  section of the distribution `lang-*.conf` files). The easiest way is
+  to create a language `.conf` file (see the AsciiDoc's `lang-en.conf`
+  file).
++
+NOTE: You still use the 'NOTE', 'CAUTION', 'TIP', 'WARNING',
+'IMPORTANT' captions in the AsciiDoc source, they get translated in
+the HTML output file.
+
+- asciidoc(1) automatically loads configuration files named like
+  `lang-.conf` where `` is a two letter language code that
+  matches the current AsciiDoc `lang` attribute. See also
+  <>.
+
+
+[appendix]
+Vim Syntax Highlighter
+----------------------
+Syntax highlighting is incredibly useful, in addition to making
+reading AsciiDoc documents much easier syntax highlighting also helps
+you catch AsciiDoc syntax errors as you write your documents.
+
+The AsciiDoc `./vim/` distribution directory contains Vim syntax
+highlighter and filetype detection scripts for AsciiDoc.  Syntax
+highlighting makes it much easier to spot AsciiDoc syntax errors.
+
+If Vim is installed on your system the AsciiDoc installer
+(`install.sh`) will automatically install the vim scripts in the Vim
+global configuration directory (`/etc/vim`).
+
+You can also turn on syntax highlighting by adding the following line
+to the end of you AsciiDoc source files:
+
+  // vim: set syntax=asciidoc:
+
+TIP: Bold fonts are often easier to read, use the Vim `:set
+background=dark` command to set bold bright fonts.
+
+NOTE: There are a number of alternative syntax highlighters for
+various editors listed on the {website}[AsciiDoc website].
+
+Limitations
+~~~~~~~~~~~
+The current implementation does a reasonable job but on occasions gets
+things wrong:
+
+- Nested quoted text formatting is highlighted according to the outer
+  format.
+- If a closing Example Block delimiter is sometimes mistaken for a
+  title underline. A workaround is to insert a blank line before the
+  closing delimiter.
+- Lines within a paragraph starting with equals characters may be
+  highlighted as single-line titles.
+- Lines within a paragraph beginning with a period may be highlighted
+  as block titles.
+
+
+[[X74]]
+[appendix]
+Attribute Options
+-----------------
+Here is the list of predefined <>:
+
+
+[cols="2e,2,2,5",frame="topbot",options="header"]
+|====================================================================
+|Option|Backends|AsciiDoc Elements|Description
+
+|autowidth |xhtml11, html5, html4 |table|
+The column widths are determined by the browser, not the AsciiDoc
+'cols' attribute. If there is no 'width' attribute the table width is
+also left up to the browser.
+
+|unbreakable |xhtml11, html5 |block elements|
+'unbreakable' attempts to keep the block element together on a single
+printed page c.f. the 'breakable' and 'unbreakable' docbook (XSL/FO)
+options below.
+
+|breakable, unbreakable |docbook (XSL/FO) |table, example, block image|
+The 'breakable' options allows block elements to break across page
+boundaries; 'unbreakable' attempts to keep the block element together
+on a single page. If neither option is specified the default XSL
+stylesheet behavior prevails.
+
+|compact |docbook, xhtml11, html5 |bulleted list, numbered list|
+Minimizes vertical space in the list
+
+|footer |docbook, xhtml11, html5, html4 |table|
+The last row of the table is rendered as a footer.
+
+|header |docbook, xhtml11, html5, html4 |table|
+The first row of the table is rendered as a header.
+
+|pgwide |docbook (XSL/FO) |table, block image, horizontal labeled list|
+Specifies that the element should be rendered across the full text
+width of the page irrespective of the current indentation.
+
+|strong |xhtml11, html5, html4 |labeled lists|
+Emboldens label text.
+|====================================================================
+
+
+[[X82]]
+[appendix]
+Diagnostics
+-----------
+The `asciidoc(1)` `--verbose` command-line option prints additional
+information to stderr: files processed, filters processed, warnings,
+system attribute evaluation.
+
+A special attribute named 'trace' enables the output of
+element-by-element diagnostic messages detailing output markup
+generation to stderr.  The 'trace' attribute can be set on the
+command-line or from within the document using <> (the latter allows tracing to be confined to specific
+portions of the document).
+
+- Trace messages print the source file name and line number and the
+  trace name followed by related markup.
+- 'trace names' are normally the names of AsciiDoc elements (see the
+  list below).
+- The trace message is only printed if the 'trace' attribute value
+  matches the start of a 'trace name'. The 'trace' attribute value can
+  be any Python regular expression.  If a trace value is not specified
+  all trace messages will be printed (this can result in large amounts
+  of output if applied to the whole document).
+
+- In the case of inline substitutions:
+  * The text before and after the substitution is printed; the before
+    text is preceded by a line containing `<<<` and the after text by
+    a line containing `>>>`.
+  * The 'subs' trace value is an alias for all inline substitutions.
+
+.Trace names
+.....................................................................
+ block close
+ block open
+
+dropped line (a line containing an undefined attribute reference).
+floating title
+footer
+header
+list close
+list entry close
+list entry open
+list item close
+list item open
+list label close
+list label open
+list open
+macro block (a block macro)
+name (man page NAME section)
+paragraph
+preamble close
+preamble open
+push blockname
+pop blockname
+section close
+section open: level 
+subs (all inline substitutions)
+table
+.....................................................................
+
+Where:
+
+- `` is section level number '0...4'.
+- `` is a delimited block name: 'comment', 'sidebar',
+  'open', 'pass', 'listing', 'literal', 'quote', 'example'.
+- `` is an inline substitution type:
+  'specialcharacters','quotes','specialwords', 'replacements',
+  'attributes','macros','callouts', 'replacements2', 'replacements3'.
+
+Command-line examples:
+
+. Trace the entire document.
+
+  $ asciidoc -a trace mydoc.txt
+
+. Trace messages whose names start with `quotes` or `macros`:
+
+  $ asciidoc -a 'trace=quotes|macros'  mydoc.txt
+
+. Print the first line of each trace message:
+
+  $ asciidoc -a trace mydoc.txt 2>&1 | grep ^TRACE:
+
+Attribute Entry examples:
+
+. Begin printing all trace messages:
+
+  :trace:
+
+. Print only matched trace messages:
+
+  :trace: quotes|macros
+
+. Turn trace messages off:
+
+  :trace!:
+
+
+[[X88]]
+[appendix]
+Backend Attributes
+------------------
+This table contains a list of optional attributes that influence the
+generated outputs.
+
+[cols="1e,1,5a",frame="topbot",options="header"]
+|====================================================================
+|Name |Backends |Description
+
+|badges |xhtml11, html5 |
+Link badges ('XHTML 1.1' and 'CSS') in document footers. By default
+badges are omitted ('badges' is undefined).
+
+NOTE: The path names of images, icons and scripts are relative path
+names to the output document not the source document.
+
+|data-uri |xhtml11, html5 |
+Embed images using the <>.
+
+|css-signature |html5, xhtml11 |
+Set a 'CSS signature' for the document (sets the 'id' attribute of the
+HTML 'body' element). CSS signatures provide a mechanism that allows
+users to personalize the document appearance. The term 'CSS signature'
+was http://archivist.incutio.com/viewlist/css-discuss/13291[coined by
+Eric Meyer].
+
+
+|disable-javascript |xhtml11, html5 |
+If the `disable-javascript` attribute is defined the `asciidoc.js`
+JavaScript is not embedded or linked to the output document.  By
+default AsciiDoc automatically embeds or links the `asciidoc.js`
+JavaScript to the output document. The script dynamically generates
+<> and <>.
+
+|[[X97]] docinfo, docinfo1, docinfo2 |All backends |
+These three attributes control which <> will be included in the the header of the output file:
+
+docinfo:: Include `-docinfo.`
+docinfo1:: Include `docinfo.`
+docinfo2:: Include `docinfo.` and `-docinfo.`
+
+Where `` is the file name (sans extension) of the AsciiDoc
+input file and `` is `.html` for HTML outputs or `.xml` for
+DocBook outputs. If the input file is the standard input then the
+output file name is used. The following example will include the
+`mydoc-docinfo.xml` docinfo file in the DocBook `mydoc.xml` output
+file:
+
+  $ asciidoc -a docinfo -b docbook mydoc.txt
+
+This next example will include `docinfo.html` and `mydoc-docinfo.html`
+docinfo files in the HTML output file:
+
+  $ asciidoc -a docinfo2 -b html4 mydoc.txt
+
+
+|[[X54]]encoding |html4, html5, xhtml11, docbook |
+Set the input and output document character set encoding. For example
+the `--attribute encoding=ISO-8859-1` command-line option will set the
+character set encoding to `ISO-8859-1`.
+
+- The default encoding is UTF-8.
+- This attribute specifies the character set in the output document.
+- The encoding name must correspond to a Python codec name or alias.
+- The 'encoding' attribute can be set using an AttributeEntry inside
+  the document header. For example:
+
+  :encoding: ISO-8859-1
+
+|[[X45]]icons |xhtml11, html5 |
+Link admonition paragraph and admonition block icon images and badge
+images. By default 'icons' is undefined and text is used in place of
+icon images.
+
+|[[X44]]iconsdir |html4, html5, xhtml11, docbook |
+The name of the directory containing linked admonition icons,
+navigation icons and the `callouts` sub-directory (the `callouts`
+sub-directory contains <> number images). 'iconsdir'
+defaults to `./images/icons`.
+
+|imagesdir |html4, html5, xhtml11, docbook |
+If this attribute is defined it is prepended to the target image file
+name paths in inline and block image macros.
+
+|keywords, description, title |html4, html5, xhtml11 |
+The 'keywords' and 'description' attributes set the correspondingly
+named HTML meta tag contents; the 'title' attribute sets the HTML
+title tag contents.  Their principle use is for SEO (Search Engine
+Optimisation).  All three are optional, but if they are used they must
+appear in the document header (or on the command-line). If 'title' is
+not specified the AsciiDoc document title is used.
+
+|linkcss |html5, xhtml11 |
+Link CSS stylesheets and JavaScripts. By default 'linkcss' is
+undefined in which case stylesheets and scripts are automatically
+embedded in the output document.
+
+|[[X103]]max-width |html5, xhtml11 |
+Set the document maximum display width (sets the 'body' element CSS
+'max-width' property).
+
+|numbered |html4, html5, xhtml11, docbook (XSL Stylesheets) |
+Adds section numbers to section titles. The 'docbook' backend ignores
+'numbered' attribute entries after the document header.
+
+|plaintext | All backends |
+If this global attribute is defined all inline substitutions are
+suppressed and block indents are retained.  This option is useful when
+dealing with large amounts of imported plain text.
+
+|quirks |xhtml11 |
+Include the `xhtml11-quirks.conf` configuration file and
+`xhtml11-quirks.css` <> to work around IE6 browser
+incompatibilities. This feature is deprecated and its use is
+discouraged -- documents are still viewable in IE6 without it.
+
+|revremark |docbook |
+A short summary of changes in this document revision. Must be defined
+prior to the first document section. The document also needs to be
+dated to output this attribute.
+
+|scriptsdir |html5, xhtml11 |
+The name of the directory containing linked JavaScripts.
+See <>.
+
+|sgml |docbook45 |
+The `--backend=docbook45` command-line option produces DocBook 4.5
+XML.  You can produce the older DocBook SGML format using the
+`--attribute sgml` command-line option.
+
+|stylesdir |html5, xhtml11 |
+The name of the directory containing linked or embedded
+<>.
+See <>.
+
+|stylesheet |html5, xhtml11 |
+The file name of an optional additional CSS <>.
+
+|theme |html5, xhtml11 |
+Use alternative stylesheet (see <>).
+
+|[[X91]]toc |html5, xhtml11, docbook (XSL Stylesheets) |
+Adds a table of contents to the start of an article or book document.
+The `toc` attribute can be specified using the `--attribute toc`
+command-line option or a `:toc:` attribute entry in the document
+header. The 'toc' attribute is defined by default when the 'docbook'
+backend is used. To disable table of contents generation undefine the
+'toc' attribute by putting a `:toc!:` attribute entry in the document
+header or from the command-line with an `--attribute toc!` option.
+
+*xhtml11 and html5 backends*
+
+- JavaScript needs to be enabled in your browser.
+- The following example generates a numbered table of contents using a
+  JavaScript embedded in the `mydoc.html` output document:
+
+  $ asciidoc -a toc -a numbered mydoc.txt
+
+|toc2 |html5, xhtml11 |
+Adds a scrollable table of contents in the left hand margin of an
+article or book document. Use the 'max-width' attribute to change the
+content width. In all other respects behaves the same as the 'toc'
+attribute.
+
+|toc-placement |html5, xhtml11 |
+When set to 'auto' (the default value) asciidoc(1) will place the
+table of contents in the document header. When 'toc-placement' is set
+to 'manual' the TOC can be positioned anywhere in the document by
+placing the `toc::[]` block macro at the point you want the TOC to
+appear.
+
+NOTE: If you use 'toc-placement' then you also have to define the
+<> attribute.
+
+|toc-title |html5, xhtml11 |
+Sets the table of contents title (defaults to 'Table of Contents').
+
+|toclevels |html5, xhtml11 |
+Sets the number of title levels (1..4) reported in the table of
+contents (see the 'toc' attribute above). Defaults to 2 and must be
+used with the 'toc' attribute. Example usage:
+
+  $ asciidoc -a toc -a toclevels=3 doc/asciidoc.txt
+
+|====================================================================
+
+
+[appendix]
+License
+-------
+AsciiDoc is free software; you can redistribute it and/or modify it
+under the terms of the 'GNU General Public License version 2' (GPLv2)
+as published by the Free Software Foundation.
+
+AsciiDoc is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License version 2 for more details.
+
+AsciiDoc Highlighter sponsored by O'Reilly Media
+
+Copyright (C) 2002-2011 Stuart Rackham.
diff --git a/demo/kitchen-sink/docs/assembly_x86.asm b/demo/kitchen-sink/docs/assembly_x86.asm
new file mode 100644
index 00000000..01e8305c
--- /dev/null
+++ b/demo/kitchen-sink/docs/assembly_x86.asm
@@ -0,0 +1,18 @@
+section	.text
+    global main         ;must be declared for using gcc
+
+main:	                ;tell linker entry point
+
+	mov	edx, len	    ;message length
+	mov	ecx, msg	    ;message to write
+	mov	ebx, 1	        ;file descriptor (stdout)
+	mov	eax, 4	        ;system call number (sys_write)
+	int	0x80	        ;call kernel
+
+	mov	eax, 1	        ;system call number (sys_exit)
+	int	0x80	        ;call kernel
+
+section	.data
+
+msg	db	'Hello, world!',0xa	;our dear string
+len	equ	$ - msg			;length of our dear string
diff --git a/demo/kitchen-sink/docs/autohotkey.ahk b/demo/kitchen-sink/docs/autohotkey.ahk
new file mode 100644
index 00000000..73687e67
--- /dev/null
+++ b/demo/kitchen-sink/docs/autohotkey.ahk
@@ -0,0 +1,35 @@
+#NoEnv
+SetBatchLines -1
+
+CoordMode Mouse, Screen
+OnExit GuiClose
+
+zoom := 9
+
+computeSize(){
+	global as_x
+	as_x := Round(ws_x/zoom/2 - 0.5)
+	if (zoom>1) {
+		pix := Round(zoom)
+	} ele {
+		pix := 1
+	}
+    ToolTip Message %as_x% %zoom% %ws_x% %hws_x% 
+}
+
+hdc_frame := DllCall("GetDC", UInt, MagnifierID)
+
+; comment
+DrawCross(byRef x="", rX,rY,z, dc){
+        ;specify the style, thickness and color of the cross lines
+    h_pen := DllCall( "gdi32.dll\CreatePen", Int, 0, Int, 1, UInt, 0x0000FF)
+}
+
+;Ctrl ^; Shift +; Win #; Alt !
+^NumPadAdd::
+^WheelUp::   
+^;::   ;comment
+    If(zoom < ws_x and ( A_ThisHotKey = "^WheelUp" or A_ThisHotKey ="^NumPadAdd") )
+		zoom *= 1.189207115         ; sqrt(sqrt(2))
+	Gosub,setZoom
+return
diff --git a/demo/kitchen-sink/docs/batchfile.bat b/demo/kitchen-sink/docs/batchfile.bat
new file mode 100644
index 00000000..c066a9e9
--- /dev/null
+++ b/demo/kitchen-sink/docs/batchfile.bat
@@ -0,0 +1,15 @@
+:: batch file highlighting in Ace!
+@echo off
+
+CALL set var1=%cd%
+echo unhide everything in %var1%!
+
+:: FOR loop in bat is super strange!
+FOR /f "tokens=*" %%G IN ('dir /A:D /b') DO (
+echo %var1%%%G
+attrib -r -a -h -s "%var1%%%G" /D /S
+)
+
+pause
+
+REM that's all
diff --git a/demo/kitchen-sink/docs/c9search.c9search_results b/demo/kitchen-sink/docs/c9search.c9search_results
new file mode 100644
index 00000000..0ad9ccd4
--- /dev/null
+++ b/demo/kitchen-sink/docs/c9search.c9search_results
@@ -0,0 +1,25 @@
+Searching for var in/.c9/metadata/workspace/pluginsregexp, case sensitive, whole word
+
+configs/default.js:
+    1: var fs = require("fs");
+	2: var argv = require('optimist').argv;
+	3: var path = require("path");
+	5: var clientExtensions = {};
+	6: var clientDirs = fs.readdirSync(__dirname + "/../plugins-client");
+	7: for (var i = 0; i < clientDirs.length; i++) {
+	8:     var dir = clientDirs[i];
+	12:     var name = dir.split(".")[1];
+	16: var projectDir = (argv.w && path.resolve(process.cwd(), argv.w)) || process.cwd();
+	17: var fsUrl = "/workspace";
+	19: var port = argv.p || process.env.PORT || 3131;
+	20: var host = argv.l || "localhost";
+	22: var config = {
+
+configs/local.js:
+	2: var config = require("./default");
+
+configs/packed.js:
+	1: var config = require("./default");
+
+
+Found 15 matches in 3 files
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/c_cpp.cpp b/demo/kitchen-sink/docs/c_cpp.cpp
new file mode 100644
index 00000000..a2ebdaa2
--- /dev/null
+++ b/demo/kitchen-sink/docs/c_cpp.cpp
@@ -0,0 +1,44 @@
+// compound assignment operators
+
+#include 
+
+#include \
+   
+
+#include \
+   \
+   
+
+#include \
+   \
+   "iostream"
+
+#include 
+#include "boost/asio/io_service.hpp"
+
+#include \
+   \
+   "iostream" \
+   "string" \
+   
+   
+using namespace std;
+
+int main ()
+{
+    int a, b=3; /* foobar */
+    a = b;
+    a+=2; // equivalent to a=a+2
+    cout << a;
+    #if VERBOSE >= 2
+        prints("trace message");
+    #endif
+    return 0;
+}
+
+/* Print an error message and get out */
+#define ABORT                             \
+    do {                                  \
+        print( "Abort\n" );                \
+        exit(8);                          \
+} while (0)                      /* Note: No semicolon */
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/cirru.cirru b/demo/kitchen-sink/docs/cirru.cirru
new file mode 100644
index 00000000..244833df
--- /dev/null
+++ b/demo/kitchen-sink/docs/cirru.cirru
@@ -0,0 +1,42 @@
+-- https://github.com/Cirru/cirru-gopher/blob/master/code/scope.cr,
+
+set a (int 2)
+
+print (self)
+
+set c (child)
+
+under c
+  under parent
+    print a
+
+print $ get c a
+
+set c x (int 3)
+print $ get c x
+
+set just-print $ code
+  print a
+
+print just-print
+
+eval (self) just-print
+eval just-print
+
+print (string "string with space")
+print (string "escapes \n \"\\")
+
+brackets ((((()))))
+
+"eval" $ string "eval"
+
+print (add $ (int 1) (int 2))
+
+print $ unwrap $
+  map (a $ int 1) (b $ int 2)
+
+print a
+  int 1
+  , b c
+  int 2
+  , d
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/clojure.clj b/demo/kitchen-sink/docs/clojure.clj
new file mode 100644
index 00000000..42acfcc7
--- /dev/null
+++ b/demo/kitchen-sink/docs/clojure.clj
@@ -0,0 +1,19 @@
+(defn parting
+  "returns a String parting in a given language"
+  ([] (parting "World"))
+  ([name] (parting name "en"))
+  ([name language]
+    ; condp is similar to a case statement in other languages.
+    ; It is described in more detail later.
+    ; It is used here to take different actions based on whether the
+    ; parameter "language" is set to "en", "es" or something else.
+    (condp = language
+      "en" (str "Goodbye, " name)
+      "es" (str "Adios, " name)
+      (throw (IllegalArgumentException.
+        (str "unsupported language " language))))))
+
+(println (parting)) ; -> Goodbye, World
+(println (parting "Mark")) ; -> Goodbye, Mark
+(println (parting "Mark" "es")) ; -> Adios, Mark
+(println (parting "Mark", "xy")) ; -> java.lang.IllegalArgumentException: unsupported language xy
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/cobol.CBL b/demo/kitchen-sink/docs/cobol.CBL
new file mode 100644
index 00000000..30404ce4
--- /dev/null
+++ b/demo/kitchen-sink/docs/cobol.CBL
@@ -0,0 +1 @@
+TODO
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/coffee.coffee b/demo/kitchen-sink/docs/coffee.coffee
new file mode 100644
index 00000000..a7e50d08
--- /dev/null
+++ b/demo/kitchen-sink/docs/coffee.coffee
@@ -0,0 +1,22 @@
+#!/usr/bin/env coffee
+
+try
+    throw URIError decodeURI(0xC0ffee * 123456.7e-8 / .9)
+catch e
+    console.log 'qstring' + "qqstring" + '''
+        qdoc
+    ''' + """
+        qqdoc
+    """
+
+do ->
+    ###
+    herecomment
+    ###
+    re = /regex/imgy.test ///
+        heregex  # comment
+    ///imgy
+    this isnt: `just JavaScript`
+    undefined
+    
+sentence = "#{ 22 / 7 } is a decent approximation of π"
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/coldfusion.cfm b/demo/kitchen-sink/docs/coldfusion.cfm
new file mode 100644
index 00000000..750a389f
--- /dev/null
+++ b/demo/kitchen-sink/docs/coldfusion.cfm
@@ -0,0 +1,5 @@
+
+
+
+
+#welcome#
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/csharp.cs b/demo/kitchen-sink/docs/csharp.cs
new file mode 100644
index 00000000..9478be87
--- /dev/null
+++ b/demo/kitchen-sink/docs/csharp.cs
@@ -0,0 +1,4 @@
+public void HelloWorld() {
+    //Say Hello!
+    Console.WriteLine("Hello World");
+}
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/css.css b/demo/kitchen-sink/docs/css.css
new file mode 100644
index 00000000..6d2d71f5
--- /dev/null
+++ b/demo/kitchen-sink/docs/css.css
@@ -0,0 +1,18 @@
+.text-layer {
+    font: 12px Monaco, "Courier New", monospace;
+    cursor: text;
+}
+
+.blinker {
+    animation: blink 1s linear infinite alternate;
+}
+
+@keyframes blink {
+    0%, 40% {
+        opacity: 0;
+    }
+
+    40.5%, 100% {
+        opacity: 1
+    }
+}
\ No newline at end of file
diff --git a/demo/kitchen-sink/docs/curly.curly b/demo/kitchen-sink/docs/curly.curly
new file mode 100644
index 00000000..c42d6790
--- /dev/null
+++ b/demo/kitchen-sink/docs/curly.curly
@@ -0,0 +1,16 @@
+
+    
+
+    
+
+    
+    
+        

{{author_name}}

+ + diff --git a/demo/kitchen-sink/docs/d.d b/demo/kitchen-sink/docs/d.d new file mode 100644 index 00000000..57069067 --- /dev/null +++ b/demo/kitchen-sink/docs/d.d @@ -0,0 +1,14 @@ +#!/usr/bin/env rdmd +// Computes average line length for standard input. +import std.stdio; + +void main() { + ulong lines = 0; + double sumLength = 0; + foreach (line; stdin.byLine()) { + ++lines; + sumLength += line.length; + } + writeln("Average line length: ", + lines ? sumLength / lines : 0); +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/dart.dart b/demo/kitchen-sink/docs/dart.dart new file mode 100644 index 00000000..735a20b3 --- /dev/null +++ b/demo/kitchen-sink/docs/dart.dart @@ -0,0 +1,19 @@ +// Go ahead and modify this example. + +import "dart:html"; + +// Computes the nth Fibonacci number. +int fibonacci(int n) { + if (n < 2) return n; + return fibonacci(n - 1) + fibonacci(n - 2); +} + +// Displays a Fibonacci number. +void main() { + int i = 20; + String message = "fibonacci($i) = ${fibonacci(i)}"; + + // This example uses HTML to display the result and it will appear + // in a nested HTML frame (an iframe). + document.body.append(new HeadingElement.h1()..appendText(message)); +} diff --git a/demo/kitchen-sink/docs/diff.diff b/demo/kitchen-sink/docs/diff.diff new file mode 100644 index 00000000..16c89890 --- /dev/null +++ b/demo/kitchen-sink/docs/diff.diff @@ -0,0 +1,69 @@ +diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js +index 23fc3fc..ed3b273 100644 +--- a/lib/ace/edit_session.js ++++ b/lib/ace/edit_session.js +@@ -51,6 +51,7 @@ var TextMode = require("./mode/text").Mode; + var Range = require("./range").Range; + var Document = require("./document").Document; + var BackgroundTokenizer = require("./background_tokenizer").BackgroundTokenizer; ++var SearchHighlight = require("./search_highlight").SearchHighlight; + + /** + * class EditSession +@@ -307,6 +308,13 @@ var EditSession = function(text, mode) { + return token; + }; + ++ this.highlight = function(re) { ++ if (!this.$searchHighlight) { ++ var highlight = new SearchHighlight(null, "ace_selected-word", "text"); ++ this.$searchHighlight = this.addDynamicMarker(highlight); ++ } ++ this.$searchHighlight.setRegexp(re); ++ } + /** + * EditSession.setUndoManager(undoManager) + * - undoManager (UndoManager): The new undo manager +@@ -556,7 +564,8 @@ var EditSession = function(text, mode) { + type : type || "line", + renderer: typeof type == "function" ? type : null, + clazz : clazz, +- inFront: !!inFront ++ inFront: !!inFront, ++ id: id + } + + if (inFront) { +diff --git a/lib/ace/editor.js b/lib/ace/editor.js +index 834e603..b27ec73 100644 +--- a/lib/ace/editor.js ++++ b/lib/ace/editor.js +@@ -494,7 +494,7 @@ var Editor = function(renderer, session) { + * Emitted when a selection has changed. + **/ + this.onSelectionChange = function(e) { +- var session = this.getSession(); ++ var session = this.session; + + if (session.$selectionMarker) { + session.removeMarker(session.$selectionMarker); +@@ -509,12 +509,40 @@ var Editor = function(renderer, session) { + this.$updateHighlightActiveLine(); + } + +- var self = this; +- if (this.$highlightSelectedWord && !this.$wordHighlightTimer) +- this.$wordHighlightTimer = setTimeout(function() { +- self.session.$mode.highlightSelection(self); +- self.$wordHighlightTimer = null; +- }, 30, this); ++ var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp() + }; +diff --git a/lib/ace/search_highlight.js b/lib/ace/search_highlight.js +new file mode 100644 +index 0000000..b2df779 +--- /dev/null ++++ b/lib/ace/search_highlight.js +@@ -0,0 +1,3 @@ ++new ++empty file \ No newline at end of file diff --git a/demo/kitchen-sink/docs/dot.dot b/demo/kitchen-sink/docs/dot.dot new file mode 100644 index 00000000..1e13be7e --- /dev/null +++ b/demo/kitchen-sink/docs/dot.dot @@ -0,0 +1,110 @@ +// Original source: http://www.graphviz.org/content/lion_share +##"A few people in the field of genetics are using dot to draw "marriage node diagram" pedigree drawings. Here is one I have done of a test pedigree from the FTREE pedigree drawing package (Lion Share was a racehorse)." Contributed by David Duffy. + +##Command to get the layout: "dot -Tpng thisfile > thisfile.png" + +digraph Ped_Lion_Share { +# page = "8.2677165,11.692913" ; +ratio = "auto" ; +mincross = 2.0 ; +label = "Pedigree Lion_Share" ; + +"001" [shape=box , regular=1,style=filled,fillcolor=white ] ; +"002" [shape=box , regular=1,style=filled,fillcolor=white ] ; +"003" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"004" [shape=box , regular=1,style=filled,fillcolor=white ] ; +"005" [shape=box , regular=1,style=filled,fillcolor=white ] ; +"006" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"007" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"009" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"014" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"015" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"016" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"ZZ01" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"ZZ02" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"017" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"012" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"008" [shape=box , regular=1,style=filled,fillcolor=white ] ; +"011" [shape=box , regular=1,style=filled,fillcolor=white ] ; +"013" [shape=box , regular=1,style=filled,fillcolor=white ] ; +"010" [shape=box , regular=1,style=filled,fillcolor=white ] ; +"023" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"020" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"021" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"018" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"025" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"019" [shape=box , regular=1,style=filled,fillcolor=white ] ; +"022" [shape=box , regular=1,style=filled,fillcolor=white ] ; +"024" [shape=box , regular=1,style=filled,fillcolor=white ] ; +"027" [shape=circle , regular=1,style=filled,fillcolor=white ] ; +"026" [shape=box , regular=1,style=filled,fillcolor=white ] ; +"028" [shape=box , regular=1,style=filled,fillcolor=grey ] ; +"marr0001" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"001" -> "marr0001" [dir=none,weight=1] ; +"007" -> "marr0001" [dir=none,weight=1] ; +"marr0001" -> "017" [dir=none, weight=2] ; +"marr0002" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"001" -> "marr0002" [dir=none,weight=1] ; +"ZZ02" -> "marr0002" [dir=none,weight=1] ; +"marr0002" -> "012" [dir=none, weight=2] ; +"marr0003" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"002" -> "marr0003" [dir=none,weight=1] ; +"003" -> "marr0003" [dir=none,weight=1] ; +"marr0003" -> "008" [dir=none, weight=2] ; +"marr0004" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"002" -> "marr0004" [dir=none,weight=1] ; +"006" -> "marr0004" [dir=none,weight=1] ; +"marr0004" -> "011" [dir=none, weight=2] ; +"marr0005" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"002" -> "marr0005" [dir=none,weight=1] ; +"ZZ01" -> "marr0005" [dir=none,weight=1] ; +"marr0005" -> "013" [dir=none, weight=2] ; +"marr0006" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"004" -> "marr0006" [dir=none,weight=1] ; +"009" -> "marr0006" [dir=none,weight=1] ; +"marr0006" -> "010" [dir=none, weight=2] ; +"marr0007" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"005" -> "marr0007" [dir=none,weight=1] ; +"015" -> "marr0007" [dir=none,weight=1] ; +"marr0007" -> "023" [dir=none, weight=2] ; +"marr0008" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"005" -> "marr0008" [dir=none,weight=1] ; +"016" -> "marr0008" [dir=none,weight=1] ; +"marr0008" -> "020" [dir=none, weight=2] ; +"marr0009" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"005" -> "marr0009" [dir=none,weight=1] ; +"012" -> "marr0009" [dir=none,weight=1] ; +"marr0009" -> "021" [dir=none, weight=2] ; +"marr0010" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"008" -> "marr0010" [dir=none,weight=1] ; +"017" -> "marr0010" [dir=none,weight=1] ; +"marr0010" -> "018" [dir=none, weight=2] ; +"marr0011" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"011" -> "marr0011" [dir=none,weight=1] ; +"023" -> "marr0011" [dir=none,weight=1] ; +"marr0011" -> "025" [dir=none, weight=2] ; +"marr0012" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"013" -> "marr0012" [dir=none,weight=1] ; +"014" -> "marr0012" [dir=none,weight=1] ; +"marr0012" -> "019" [dir=none, weight=2] ; +"marr0013" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"010" -> "marr0013" [dir=none,weight=1] ; +"021" -> "marr0013" [dir=none,weight=1] ; +"marr0013" -> "022" [dir=none, weight=2] ; +"marr0014" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"019" -> "marr0014" [dir=none,weight=1] ; +"020" -> "marr0014" [dir=none,weight=1] ; +"marr0014" -> "024" [dir=none, weight=2] ; +"marr0015" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"022" -> "marr0015" [dir=none,weight=1] ; +"025" -> "marr0015" [dir=none,weight=1] ; +"marr0015" -> "027" [dir=none, weight=2] ; +"marr0016" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"024" -> "marr0016" [dir=none,weight=1] ; +"018" -> "marr0016" [dir=none,weight=1] ; +"marr0016" -> "026" [dir=none, weight=2] ; +"marr0017" [shape=diamond,style=filled,label="",height=.1,width=.1] ; +"026" -> "marr0017" [dir=none,weight=1] ; +"027" -> "marr0017" [dir=none,weight=1] ; +"marr0017" -> "028" [dir=none, weight=2] ; +} diff --git a/demo/kitchen-sink/docs/eiffel.e b/demo/kitchen-sink/docs/eiffel.e new file mode 100644 index 00000000..943cdb35 --- /dev/null +++ b/demo/kitchen-sink/docs/eiffel.e @@ -0,0 +1,30 @@ +note + description: "Represents a person." + +class + PERSON + +create + make, make_unknown + +feature {NONE} -- Creation + + make (a_name: like name) + -- Create a person with `a_name' as `name'. + do + name := a_name + ensure + name = a_name + end + + make_unknown + do ensure + name = Void + end + +feature -- Access + + name: detachable STRING + -- Full name or Void if unknown. + +end \ No newline at end of file diff --git a/demo/kitchen-sink/docs/ejs.ejs b/demo/kitchen-sink/docs/ejs.ejs new file mode 100644 index 00000000..aaf497a9 --- /dev/null +++ b/demo/kitchen-sink/docs/ejs.ejs @@ -0,0 +1,31 @@ + + + + Cloud9 Rocks! + + + + + + + + + <% if (!isRoot) { %> + + + + + <% } %> + <% entries.forEach(function(entry) { %> + + + + + <% }) %> +
NameSize
..
+ + <%= entry.name %> + <%= entry.size %>
+ + + \ No newline at end of file diff --git a/demo/kitchen-sink/docs/elixir.ex b/demo/kitchen-sink/docs/elixir.ex new file mode 100644 index 00000000..bb6a45f1 --- /dev/null +++ b/demo/kitchen-sink/docs/elixir.ex @@ -0,0 +1,42 @@ +defmodule HelloModule do + @moduledoc """ + This is supposed to be `markdown`. + __Yes__ this is [mark](http://down.format) + + # Truly + + ## marked + + * with lists + * more + * and more + + Even.with(code) + blocks |> with |> samples + + _Docs are first class citizens in Elixir_ (Jose Valim) + """ + + # A "Hello world" function + def some_fun do + IO.puts "Juhu Kinners!" + end + # A private function + defp priv do + is_regex ~r""" + This is a regex + spanning several + lines. + """ + x = elem({ :a, :b, :c }, 0) #=> :a + end +end + +test_fun = fn(x) -> + cond do + x > 10 -> + :greater_than_ten + true -> + :maybe_ten + end +end \ No newline at end of file diff --git a/demo/kitchen-sink/docs/elm.elm b/demo/kitchen-sink/docs/elm.elm new file mode 100644 index 00000000..eef70b2a --- /dev/null +++ b/demo/kitchen-sink/docs/elm.elm @@ -0,0 +1,12 @@ +{- Ace {- 4 -} Elm -} +main = lift clock (every second) + +clock t = collage 400 400 [ filled lightGrey (ngon 12 110) + , outlined (solid grey) (ngon 12 110) + , hand orange 100 t + , hand charcoal 100 (t/60) + , hand charcoal 60 (t/720) ] + +hand clr len time = + let angle = degrees (90 - 6 * inSeconds time) + in traced (solid clr) <| segment (0,0) (len * cos angle, len * sin angle) \ No newline at end of file diff --git a/demo/kitchen-sink/docs/erlang.erl b/demo/kitchen-sink/docs/erlang.erl new file mode 100644 index 00000000..705642b3 --- /dev/null +++ b/demo/kitchen-sink/docs/erlang.erl @@ -0,0 +1,20 @@ + %% A process whose only job is to keep a counter. + %% First version + -module(counter). + -export([start/0, codeswitch/1]). + + start() -> loop(0). + + loop(Sum) -> + receive + {increment, Count} -> + loop(Sum+Count); + {counter, Pid} -> + Pid ! {counter, Sum}, + loop(Sum); + code_switch -> + ?MODULE:codeswitch(Sum) + % Force the use of 'codeswitch/1' from the latest MODULE version + end. + + codeswitch(Sum) -> loop(Sum). \ No newline at end of file diff --git a/demo/kitchen-sink/docs/forth.frt b/demo/kitchen-sink/docs/forth.frt new file mode 100644 index 00000000..dc85cd7b --- /dev/null +++ b/demo/kitchen-sink/docs/forth.frt @@ -0,0 +1,41 @@ +: HELLO ( -- ) CR ." Hello, world!" ; + +HELLO +Hello, world! + +: [CHAR] CHAR POSTPONE LITERAL ; IMMEDIATE + +0 value ii 0 value jj +0 value KeyAddr 0 value KeyLen +create SArray 256 allot \ state array of 256 bytes +: KeyArray KeyLen mod KeyAddr ; + +: get_byte + c@ ; +: set_byte + c! ; +: as_byte 255 and ; +: reset_ij 0 TO ii 0 TO jj ; +: i_update 1 + as_byte TO ii ; +: j_update ii SArray get_byte + as_byte TO jj ; +: swap_s_ij + jj SArray get_byte + ii SArray get_byte jj SArray set_byte + ii SArray set_byte +; + +: rc4_init ( KeyAddr KeyLen -- ) + 256 min TO KeyLen TO KeyAddr + 256 0 DO i i SArray set_byte LOOP + reset_ij + BEGIN + ii KeyArray get_byte jj + j_update + swap_s_ij + ii 255 < WHILE + ii i_update + REPEAT + reset_ij +; +: rc4_byte + ii i_update jj j_update + swap_s_ij + ii SArray get_byte jj SArray get_byte + as_byte SArray get_byte xor +; \ No newline at end of file diff --git a/demo/kitchen-sink/docs/ftl.ftl b/demo/kitchen-sink/docs/ftl.ftl new file mode 100644 index 00000000..faa573f5 --- /dev/null +++ b/demo/kitchen-sink/docs/ftl.ftl @@ -0,0 +1,46 @@ +<#ftl encoding="utf-8" /> +<#setting locale="en_US" /> +<#import "library" as lib /> +<#-- + FreeMarker comment + ${abc} <#assign a=12 /> +--> + + + + + + + ${title!"FreeMarker"}<title> + </head> + + <body> + + <h1>Hello ${name!""}</h1> + + <p>Today is: ${.now?date}</p> + + <#assign x = 13> + <#if x > 12 && x lt 14>x equals 13: ${x}</#if> + + <ul> + <#list items as item> + <li>${item_index}: ${item.name!?split("\n")[0]}</li> + </#list> + </ul> + + User directive: <@lib.function attr1=true attr2='value' attr3=-42.12>Test</@lib.function> + <@anotherOne /> + + <#if variable?exists> + Deprecated + <#elseif variable??> + Better + <#else> + Default + </#if> + + <img src="images/${user.id}.png" /> + + </body> +</html> diff --git a/demo/kitchen-sink/docs/gcode.gcode b/demo/kitchen-sink/docs/gcode.gcode new file mode 100644 index 00000000..5f47bca3 --- /dev/null +++ b/demo/kitchen-sink/docs/gcode.gcode @@ -0,0 +1,31 @@ +O003 (DIAMOND SQUARE) +N2 G54 G90 G49 G80 +N3 M6 T1 (1.ENDMILL) +N4 M3 S1800 +N5 G0 X-.6 Y2.050 +N6 G43 H1 Z.1 +N7 G1 Z-.3 F50. +N8 G41 D1 Y1.45 +N9 G1 X0 F20. +N10 G2 J-1.45 +(CUTTER COMP CANCEL) +N11 G1 Z-.2 F50. +N12 Y-.990 +N13 G40 +N14 G0 X-.6 Y1.590 +N15 G0 Z.1 +N16 M5 G49 G28 G91 Z0 +N17 CALL O9456 +N18 #500=0.004 +N19 #503=[#500+#501] +N20 VC45=0.0006 +VS4=0.0007 +N21 G90 G10 L20 P3 X5.Y4. Z6.567 +N22 G0 X5000 +N23 IF [#1 LT 0.370] GOTO 49 +N24 X-0.678 Y+.990 +N25 G84.3 X-0.1 +N26 #4=#5*COS[45] +N27 #4=#5*SIN[45] +N28 VZOFZ=652.9658 +% \ No newline at end of file diff --git a/demo/kitchen-sink/docs/gherkin.feature b/demo/kitchen-sink/docs/gherkin.feature new file mode 100644 index 00000000..52cd811e --- /dev/null +++ b/demo/kitchen-sink/docs/gherkin.feature @@ -0,0 +1,28 @@ +@these @are @tags +Feature: Serve coffee + Coffee should not be served until paid for + Coffee should not be served until the button has been pressed + If there is no coffee left then money should be refunded + + Scenario Outline: Eating + Given there are <start> cucumbers + When I eat <eat> cucumbers + Then I should have <left> cucumbers + + Examples: + | start | eat | left | + | 12 | 5 | 7 | + | 20 | 5 | 15 | + + Scenario: Buy last coffee + Given there are 1 coffees left in the machine + And I have deposited 1$ + When I press the coffee button + Then I should be served a "coffee" + + # this a comment + + """ + this is a + pystring + """ \ No newline at end of file diff --git a/demo/kitchen-sink/docs/glsl.glsl b/demo/kitchen-sink/docs/glsl.glsl new file mode 100644 index 00000000..e32bf07d --- /dev/null +++ b/demo/kitchen-sink/docs/glsl.glsl @@ -0,0 +1,20 @@ +uniform float amplitude; +attribute float displacement; +varying vec3 vNormal; + +void main() { + + vNormal = normal; + + // multiply our displacement by the + // amplitude. The amp will get animated + // so we'll have animated displacement + vec3 newPosition = position + + normal * + vec3(displacement * + amplitude); + + gl_Position = projectionMatrix * + modelViewMatrix * + vec4(newPosition,1.0); +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/golang.go b/demo/kitchen-sink/docs/golang.go new file mode 100644 index 00000000..6b1298f0 --- /dev/null +++ b/demo/kitchen-sink/docs/golang.go @@ -0,0 +1,34 @@ +// Concurrent computation of pi. +// See http://goo.gl/ZuTZM. +// +// This demonstrates Go's ability to handle +// large numbers of concurrent processes. +// It is an unreasonable way to calculate pi. +package main + +import ( + "fmt" + "math" +) + +func main() { + fmt.Println(pi(5000)) +} + +// pi launches n goroutines to compute an +// approximation of pi. +func pi(n int) float64 { + ch := make(chan float64) + for k := 0; k <= n; k++ { + go term(ch, float64(k)) + } + f := 0.0 + for k := 0; k <= n; k++ { + f += <-ch + } + return f +} + +func term(ch chan float64, k float64) { + ch <- 4 * math.Pow(-1, k) / (2*k + 1) +} diff --git a/demo/kitchen-sink/docs/groovy.groovy b/demo/kitchen-sink/docs/groovy.groovy new file mode 100644 index 00000000..8097a702 --- /dev/null +++ b/demo/kitchen-sink/docs/groovy.groovy @@ -0,0 +1,41 @@ +//http://groovy.codehaus.org/Martin+Fowler%27s+closure+examples+in+Groovy + +class Employee { + def name, salary + boolean manager + String toString() { return name } +} + +def emps = [new Employee(name:'Guillaume', manager:true, salary:200), + new Employee(name:'Graeme', manager:true, salary:200), + new Employee(name:'Dierk', manager:false, salary:151), + new Employee(name:'Bernd', manager:false, salary:50)] + +def managers(emps) { + emps.findAll { e -> e.isManager() } +} + +assert emps[0..1] == managers(emps) // [Guillaume, Graeme] + +def highPaid(emps) { + threshold = 150 + emps.findAll { e -> e.salary > threshold } +} + +assert emps[0..2] == highPaid(emps) // [Guillaume, Graeme, Dierk] + +def paidMore(amount) { + { e -> e.salary > amount} +} +def highPaid = paidMore(150) + +assert highPaid(emps[0]) // true +assert emps[0..2] == emps.findAll(highPaid) + +def filename = 'test.txt' +new File(filename).withReader{ reader -> doSomethingWith(reader) } + +def readersText +def doSomethingWith(reader) { readersText = reader.text } + +assert new File(filename).text == readersText \ No newline at end of file diff --git a/demo/kitchen-sink/docs/haml.haml b/demo/kitchen-sink/docs/haml.haml new file mode 100644 index 00000000..d07ed4a2 --- /dev/null +++ b/demo/kitchen-sink/docs/haml.haml @@ -0,0 +1,36 @@ +!!!5 + +# <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]--> +# <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]--> +# <!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]--> +# <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]--> + + +/adasdasdad +%div{:id => "#{@item.type}_#{@item.number}", :class => '#{@item.type} #{@item.urgency}', :phoney => `asdasdasd`} +/ file: app/views/movies/index.html.haml +\d +%ads:{:bleh => 33} +%p==ddd== + Date/Time: + - now = DateTime.now + %strong= now + = if now DateTime.parse("December 31, 2006") + = "Happy new " + "year!" +%sfd.dfdfg +#content + .title + %h1= @title + = link_to 'Home', home_url + + #contents +%div#content + %div.articles + %div.article.title Blah + %div.article.date 2006-11-05 + %div.article.entry + Neil Patrick Harris + +%div[@user, :greeting] + %bar[290]/ + ==Hello!== diff --git a/demo/kitchen-sink/docs/handlebars.hbs b/demo/kitchen-sink/docs/handlebars.hbs new file mode 100644 index 00000000..bb096a1a --- /dev/null +++ b/demo/kitchen-sink/docs/handlebars.hbs @@ -0,0 +1,8 @@ +{{!-- Ace + :-}} --}} + +<div id="comments"> + {{#each comments}} + <h2><a href="/posts/{{../permalink}}#{{id}}">{{title}}</a></h2> + <div>{{{body}}}</div> + {{/each}} +</div> diff --git a/demo/kitchen-sink/docs/haskell.hs b/demo/kitchen-sink/docs/haskell.hs new file mode 100644 index 00000000..5c0defc2 --- /dev/null +++ b/demo/kitchen-sink/docs/haskell.hs @@ -0,0 +1,20 @@ +-- Type annotation (optional) +fib :: Int -> Integer + +-- With self-referencing data +fib n = fibs !! n + where fibs = 0 : scanl (+) 1 fibs + -- 0,1,1,2,3,5,... + +-- Same, coded directly +fib n = fibs !! n + where fibs = 0 : 1 : next fibs + next (a : t@(b:_)) = (a+b) : next t + +-- Similar idea, using zipWith +fib n = fibs !! n + where fibs = 0 : 1 : zipWith (+) fibs (tail fibs) + +-- Using a generator function +fib n = fibs (0,1) !! n + where fibs (a,b) = a : fibs (b,a+b) \ No newline at end of file diff --git a/demo/kitchen-sink/docs/htaccess b/demo/kitchen-sink/docs/htaccess new file mode 100644 index 00000000..a9f5a27c --- /dev/null +++ b/demo/kitchen-sink/docs/htaccess @@ -0,0 +1,10 @@ +Redirect /linux http://www.linux.org +Redirect 301 /kernel http://www.linux.org + +# comment +RewriteEngine on + +RewriteCond %{HTTP_USER_AGENT} ^Mozilla.* +RewriteRule ^/$ /homepage.max.html [L] + +RewriteRule ^/$ /homepage.std.html [L] diff --git a/demo/kitchen-sink/docs/html.html b/demo/kitchen-sink/docs/html.html new file mode 100644 index 00000000..81398bef --- /dev/null +++ b/demo/kitchen-sink/docs/html.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html> + <head> + + <style type="text/css"> + .text-layer { + font-family: Monaco, "Courier New", monospace; + font-size: 12px; + cursor: text; + } + </style> + + </head> + <body> + <h1 style="color:red">Juhu Kinners</h1> + </body> +</html> \ No newline at end of file diff --git a/demo/kitchen-sink/docs/html_ruby.erb b/demo/kitchen-sink/docs/html_ruby.erb new file mode 100644 index 00000000..f75835ca --- /dev/null +++ b/demo/kitchen-sink/docs/html_ruby.erb @@ -0,0 +1,26 @@ +<h1>Listing Books</h1> + +<table> + <tr> + <th>Title</th> + <th>Summary</th> + <th></th> + <th></th> + <th></th> + </tr> + +<% @books.each do |book| %> + <tr> + <%# comment %> + <td><%= book.title %></td> + <td><%= book.content %></td> + <td><%= link_to 'Show', book %></td> + <td><%= link_to 'Edit', edit_book_path(book) %></td> + <td><%= link_to 'Remove', book, :confirm => 'Are you sure?', :method => :delete %></td> + </tr> +<% end %> +</table> + +<br /> + +<%= link_to 'New book', new_book_path %> \ No newline at end of file diff --git a/demo/kitchen-sink/docs/ini.ini b/demo/kitchen-sink/docs/ini.ini new file mode 100644 index 00000000..45f83c9a --- /dev/null +++ b/demo/kitchen-sink/docs/ini.ini @@ -0,0 +1,4 @@ +[.ShellClassInfo] +IconResource=..\logo.png +[ViewState] +FolderType=Generic diff --git a/demo/kitchen-sink/docs/io.io b/demo/kitchen-sink/docs/io.io new file mode 100644 index 00000000..4b80b6c2 --- /dev/null +++ b/demo/kitchen-sink/docs/io.io @@ -0,0 +1,6 @@ +// computes factorial of a number +factorial := method(n, + if(n == 0, return 1) + res := 1 + Range 1 to(n) foreach(i, res = res * i) +) \ No newline at end of file diff --git a/demo/kitchen-sink/docs/jade.jade b/demo/kitchen-sink/docs/jade.jade new file mode 100644 index 00000000..d9fb7e30 --- /dev/null +++ b/demo/kitchen-sink/docs/jade.jade @@ -0,0 +1,45 @@ +!!!doctype +!!!5 +!!! + +include something + + include another_thing + + // let's talk about it + +// + here it is. a block comment! + and another row! +but not here. + + // + a far spaced + should be lack of block + + // also not a comment + div.attemptAtBlock + + span#myName + + #{implicit} + !{more_explicit} + + #idDiv + + .idDiv + + test(id="tag") + header(id="tag", blah="foo", meh="aads") +mixin article(obj, parents) + + mixin bleh() + + mixin clever-name + + -var x = "0"; + - y each z + + - var items = ["one", "two", "three"] + each item in items + li= item \ No newline at end of file diff --git a/demo/kitchen-sink/docs/java.java b/demo/kitchen-sink/docs/java.java new file mode 100644 index 00000000..f3b542b7 --- /dev/null +++ b/demo/kitchen-sink/docs/java.java @@ -0,0 +1,15 @@ +public class InfiniteLoop { + + /* + * This will cause the program to hang... + * + * Taken from: + * http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/ + */ + public static void main(String[] args) { + double d = Double.parseDouble("2.2250738585072012e-308"); + + // unreachable code + System.out.println("Value: " + d); + } +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/javascript.js b/demo/kitchen-sink/docs/javascript.js new file mode 100644 index 00000000..5b367b5f --- /dev/null +++ b/demo/kitchen-sink/docs/javascript.js @@ -0,0 +1,5 @@ +function foo(items, nada) { + for (var i=0; i<items.length; i++) { + alert(items[i] + "juhu\n"); + } // Real Tab. +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/json.json b/demo/kitchen-sink/docs/json.json new file mode 100644 index 00000000..6028d5ed --- /dev/null +++ b/demo/kitchen-sink/docs/json.json @@ -0,0 +1,66 @@ +{ + "query": { + "count": 10, + "created": "2011-06-21T08:10:46Z", + "lang": "en-US", + "results": { + "photo": [ + { + "farm": "6", + "id": "5855620975", + "isfamily": "0", + "isfriend": "0", + "ispublic": "1", + "owner": "32021554@N04", + "secret": "f1f5e8515d", + "server": "5110", + "title": "7087 bandit cat" + }, + { + "farm": "4", + "id": "5856170534", + "isfamily": "0", + "isfriend": "0", + "ispublic": "1", + "owner": "32021554@N04", + "secret": "ff1efb2a6f", + "server": "3217", + "title": "6975 rusty cat" + }, + { + "farm": "6", + "id": "5856172972", + "isfamily": "0", + "isfriend": "0", + "ispublic": "1", + "owner": "51249875@N03", + "secret": "6c6887347c", + "server": "5192", + "title": "watermarked-cats" + }, + { + "farm": "6", + "id": "5856168328", + "isfamily": "0", + "isfriend": "0", + "ispublic": "1", + "owner": "32021554@N04", + "secret": "0c1cfdf64c", + "server": "5078", + "title": "7020 mandy cat" + }, + { + "farm": "3", + "id": "5856171774", + "isfamily": "0", + "isfriend": "0", + "ispublic": "1", + "owner": "32021554@N04", + "secret": "7f5a3180ab", + "server": "2696", + "title": "7448 bobby cat" + } + ] + } + } +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/jsoniq.jq b/demo/kitchen-sink/docs/jsoniq.jq new file mode 100644 index 00000000..30404ce4 --- /dev/null +++ b/demo/kitchen-sink/docs/jsoniq.jq @@ -0,0 +1 @@ +TODO \ No newline at end of file diff --git a/demo/kitchen-sink/docs/jsp.jsp b/demo/kitchen-sink/docs/jsp.jsp new file mode 100644 index 00000000..43fbb835 --- /dev/null +++ b/demo/kitchen-sink/docs/jsp.jsp @@ -0,0 +1,46 @@ +<html> +<body> + <script> + var x = "abc"; + function y { + } + </script> + <style> + .class { + background: #124356; + } + </style> + + <p> + Today's date: <%= (new java.util.Date()).toLocaleString()%> + </p> + <%! int i = 0; %> + <jsp:declaration> + int j = 10; + </jsp:declaration> + + <%-- This is JSP comment --%> + <%@ directive attribute="value" %> + + <h2>Select Languages:</h2> + + <form ACTION="jspCheckBox.jsp"> + <input type="checkbox" name="id" value="Java"> Java<BR> + <input type="checkbox" name="id" value=".NET"> .NET<BR> + <input type="checkbox" name="id" value="PHP"> PHP<BR> + <input type="checkbox" name="id" value="C/C++"> C/C++<BR> + <input type="checkbox" name="id" value="PERL"> PERL <BR> + <input type="submit" value="Submit"> + </form> + + <% + String select[] = request.getParameterValues("id"); + if (select != null && select.length != 0) { + out.println("You have selected: "); + for (int i = 0; i < select.length; i++) { + out.println(select[i]); + } + } + %> +</body> +</html> \ No newline at end of file diff --git a/demo/kitchen-sink/docs/jsx.jsx b/demo/kitchen-sink/docs/jsx.jsx new file mode 100644 index 00000000..fbbeb662 --- /dev/null +++ b/demo/kitchen-sink/docs/jsx.jsx @@ -0,0 +1,9 @@ +/*EXPECTED +hello world! +*/ +class Test { + static function run() : void { + // console.log("hello world!"); + log "hello world!"; + } +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/julia.jl b/demo/kitchen-sink/docs/julia.jl new file mode 100644 index 00000000..f558ae22 --- /dev/null +++ b/demo/kitchen-sink/docs/julia.jl @@ -0,0 +1,15 @@ +for op = (:+, :*, :&, :|, :$) + @eval ($op)(a,b,c) = ($op)(($op)(a,b),c) +end + +v = α'; +function g(x,y) + return x * y + x + y +end + +cd("data") do + open("outfile", "w") do f + write(f, data) + end +end diff --git a/demo/kitchen-sink/docs/latex.tex b/demo/kitchen-sink/docs/latex.tex new file mode 100644 index 00000000..1427168a --- /dev/null +++ b/demo/kitchen-sink/docs/latex.tex @@ -0,0 +1,22 @@ +\usepackage{amsmath} +\title{\LaTeX} +\date{} +\begin{document} + \maketitle + \LaTeX{} is a document preparation system for the \TeX{} + typesetting program. It offers programmable desktop publishing + features and extensive facilities for automating most aspects of + typesetting and desktop publishing, including numbering and + cross-referencing, tables and figures, page layout, bibliographies, + and much more. \LaTeX{} was originally written in 1984 by Leslie + Lamport and has become the dominant method for using \TeX; few + people write in plain \TeX{} anymore. The current version is + \LaTeXe. + + % This is a comment; it will not be shown in the final output. + % The following shows a little of the typesetting power of LaTeX: + \begin{align} + E &= mc^2 \\ + m &= \frac{m_0}{\sqrt{1-\frac{v^2}{c^2}}} + \end{align} +\end{document} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/lean.lean b/demo/kitchen-sink/docs/lean.lean new file mode 100644 index 00000000..40e82753 --- /dev/null +++ b/demo/kitchen-sink/docs/lean.lean @@ -0,0 +1,9 @@ +import logic +section + variables (A : Type) (p q : A → Prop) + + example : (∀x : A, p x ∧ q x) → ∀y : A, p y := + assume H : ∀x : A, p x ∧ q x, + take y : A, + show p y, from and.elim_left (H y) +end diff --git a/demo/kitchen-sink/docs/less.less b/demo/kitchen-sink/docs/less.less new file mode 100644 index 00000000..b3fdaadd --- /dev/null +++ b/demo/kitchen-sink/docs/less.less @@ -0,0 +1,28 @@ +/* styles.less */ + +@base: #f938ab; + +.box-shadow(@style, @c) when (iscolor(@c)) { + box-shadow: @style @c; + -webkit-box-shadow: @style @c; + -moz-box-shadow: @style @c; +} +.box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) { + .box-shadow(@style, rgba(0, 0, 0, @alpha)); +} + +// Box styles +.box { + color: saturate(@base, 5%); + border-color: lighten(@base, 30%); + + div { .box-shadow(0 0 5px, 30%) } + + a { + color: @base; + + &:hover { + color: lighten(@base, 50%); + } + } +} diff --git a/demo/kitchen-sink/docs/liquid.liquid b/demo/kitchen-sink/docs/liquid.liquid new file mode 100644 index 00000000..29c0b016 --- /dev/null +++ b/demo/kitchen-sink/docs/liquid.liquid @@ -0,0 +1,76 @@ +The following examples can be found in full at http://liquidmarkup.org/ + +Liquid is an extraction from the e-commerce system Shopify. +Shopify powers many thousands of e-commerce stores which all call for unique designs. +For this we developed Liquid which allows our customers complete design freedom while +maintaining the integrity of our servers. + +Liquid has been in production use since June 2006 and is now used by many other +hosted web applications. + +It was developed for usage in Ruby on Rails web applications and integrates seamlessly +as a plugin but it also works excellently as a stand alone library. + +Here's what it looks like: + + <ul id="products"> + {% for product in products %} + <li> + <h2>{{ product.title }}</h2> + Only {{ product.price | format_as_money }} + + <p>{{ product.description | prettyprint | truncate: 200 }}</p> + + </li> + {% endfor %} + </ul> + + +Some more features include: + +<h2>Filters</h2> +<p> The word "tobi" in uppercase: {{ 'tobi' | upcase }} </p> +<p>The word "tobi" has {{ 'tobi' | size }} letters! </p> +<p>Change "Hello world" to "Hi world": {{ 'Hello world' | replace: 'Hello', 'Hi' }} </p> +<p>The date today is {{ 'now' | date: "%Y %b %d" }} </p> + + +<h2>If</h2> +<p> + {% if user.name == 'tobi' or user.name == 'marc' %} + hi marc or tobi + {% endif %} +</p> + + +<h2>Case</h2> +<p> + {% case template %} + {% when 'index' %} + Welcome + {% when 'product' %} + {{ product.vendor | link_to_vendor }} / {{ product.title }} + {% else %} + {{ page_title }} + {% endcase %} +</p> + + +<h2>For Loops</h2> +<p> + {% for item in array %} + {{ item }} + {% endfor %} +</p> + + +<h2>Tables</h2> +<p> + {% tablerow item in items cols: 3 %} + {% if tablerowloop.col_first %} + First column: {{ item.variable }} + {% else %} + Different column: {{ item.variable }} + {% endif %} + {% endtablerow %} +</p> diff --git a/demo/kitchen-sink/docs/lisp.lisp b/demo/kitchen-sink/docs/lisp.lisp new file mode 100644 index 00000000..e8d25558 --- /dev/null +++ b/demo/kitchen-sink/docs/lisp.lisp @@ -0,0 +1,22 @@ +(defun prompt-for-cd () + "Prompts + for CD" + (prompt-read "Title" 1.53 1 2/4 1.7 1.7e0 2.9E-4 +42 -7 #b001 #b001/100 #o777 #O777 #xabc55 #c(0 -5.6)) + (prompt-read "Artist" &rest) + (or (parse-integer (prompt-read "Rating") :junk-allowed t) 0) + (if x (format t "yes") (format t "no" nil) ;and here comment + ) 0xFFLL -23ull + ;; second line comment + '(+ 1 2) + (defvar *lines*) ; list of all lines + (position-if-not #'sys::whitespacep line :start beg)) + (quote (privet 1 2 3)) + '(hello world) + (* 5 7) + (1 2 34 5) + (:use "aaaa") + (let ((x 10) (y 20)) + (print (+ x y)) + ) LAmbDa + + "asdad\0eqweqe" \ No newline at end of file diff --git a/demo/kitchen-sink/docs/livescript.ls b/demo/kitchen-sink/docs/livescript.ls new file mode 100644 index 00000000..ce082b4c --- /dev/null +++ b/demo/kitchen-sink/docs/livescript.ls @@ -0,0 +1,245 @@ +# Defines an editing mode for [Ace](http://ace.ajax.org). +# +# Open [test/ace.html](../test/ace.html) to test. + +require, exports, module <-! define \ace/mode/ls + +identifier = /(?![\d\s])[$\w\xAA-\uFFDC](?:(?!\s)[$\w\xAA-\uFFDC]|-[A-Za-z])*/$ + +exports.Mode = class LiveScriptMode extends require(\ace/mode/text)Mode + -> + @$tokenizer = + new (require \ace/tokenizer)Tokenizer LiveScriptMode.Rules + if require \ace/mode/matching_brace_outdent + @$outdent = new that.MatchingBraceOutdent + + indenter = // (? + : [({[=:] + | [-~]> + | \b (?: e(?:lse|xport) | d(?:o|efault) | t(?:ry|hen) | finally | + import (?:\s* all)? | const | var | + let | new | catch (?:\s* #identifier)? ) + ) \s* $ // + + getNextLineIndent: (state, line, tab) -> + indent = @$getIndent line + {tokens} = @$tokenizer.getLineTokens line, state + unless tokens.length and tokens[*-1]type is \comment + indent += tab if state is \start and indenter.test line + indent + + toggleCommentLines: (state, doc, startRow, endRow) -> + comment = /^(\s*)#/; range = new (require \ace/range)Range 0 0 0 0 + for i from startRow to endRow + if out = comment.test line = doc.getLine i + then line.=replace comment, \$1 + else line.=replace /^\s*/ \$&# + range.end.row = range.start.row = i + range.end.column = line.length + 1 + doc.replace range, line + 1 - out * 2 + + checkOutdent: (state, line, input) -> @$outdent?checkOutdent line, input + + autoOutdent: (state, doc, row) -> @$outdent?autoOutdent doc, row + +### Highlight Rules + +keywordend = /(?![$\w]|-[A-Za-z]|\s*:(?![:=]))/$ +stringfill = token: \string, regex: '.+' + +LiveScriptMode.Rules = + start: + * token: \keyword + regex: //(? + :t(?:h(?:is|row|en)|ry|ypeof!?) + |c(?:on(?:tinue|st)|a(?:se|tch)|lass) + |i(?:n(?:stanceof)?|mp(?:ort(?:\s+all)?|lements)|[fs]) + |d(?:e(?:fault|lete|bugger)|o) + |f(?:or(?:\s+own)?|inally|unction) + |s(?:uper|witch) + |e(?:lse|x(?:tends|port)|val) + |a(?:nd|rguments) + |n(?:ew|ot) + |un(?:less|til) + |w(?:hile|ith) + |o[fr]|return|break|let|var|loop + )//$ + keywordend + + * token: \constant.language + regex: '(?:true|false|yes|no|on|off|null|void|undefined)' + keywordend + + * token: \invalid.illegal + regex: '(? + :p(?:ackage|r(?:ivate|otected)|ublic) + |i(?:mplements|nterface) + |enum|static|yield + )' + keywordend + + * token: \language.support.class + regex: '(? + :R(?:e(?:gExp|ferenceError)|angeError) + |S(?:tring|yntaxError) + |E(?:rror|valError) + |Array|Boolean|Date|Function|Number|Object|TypeError|URIError + )' + keywordend + + * token: \language.support.function + regex: '(? + :is(?:NaN|Finite) + |parse(?:Int|Float) + |Math|JSON + |(?:en|de)codeURI(?:Component)? + )' + keywordend + + * token: \variable.language + regex: '(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)' + keywordend + + * token: \identifier + regex: identifier + /\s*:(?![:=])/$ + + * token: \variable + regex: identifier + + * token: \keyword.operator + regex: /(?:\.{3}|\s+\?)/$ + + * token: \keyword.variable + regex: /(?:@+|::|\.\.)/$ + next : \key + + * token: \keyword.operator + regex: /\.\s*/$ + next : \key + + * token: \string + regex: /\\\S[^\s,;)}\]]*/$ + + * token: \string.doc + regex: \''' + next : \qdoc + + * token: \string.doc + regex: \""" + next : \qqdoc + + * token: \string + regex: \' + next : \qstring + + * token: \string + regex: \" + next : \qqstring + + * token: \string + regex: \` + next : \js + + * token: \string + regex: '<\\[' + next : \words + + * token: \string.regex + regex: \// + next : \heregex + + * token: \comment.doc + regex: '/\\*' + next : \comment + + * token: \comment + regex: '#.*' + + * token: \string.regex + regex: // + /(?: [^ [ / \n \\ ]* + (?: (?: \\. + | \[ [^\]\n\\]* (?:\\.[^\]\n\\]*)* \] + ) [^ [ / \n \\ ]* + )* + )/ [gimy$]{0,4} + //$ + next : \key + + * token: \constant.numeric + regex: '(?:0x[\\da-fA-F][\\da-fA-F_]* + |(?:[2-9]|[12]\\d|3[0-6])r[\\da-zA-Z][\\da-zA-Z_]* + |(?:\\d[\\d_]*(?:\\.\\d[\\d_]*)?|\\.\\d[\\d_]*) + (?:e[+-]?\\d[\\d_]*)?[\\w$]*)' + + * token: \lparen + regex: '[({[]' + + * token: \rparen + regex: '[)}\\]]' + next : \key + + * token: \keyword.operator + regex: \\\S+ + + * token: \text + regex: \\\s+ + + heregex: + * token: \string.regex + regex: '.*?//[gimy$?]{0,4}' + next : \start + * token: \string.regex + regex: '\\s*#{' + * token: \comment.regex + regex: '\\s+(?:#.*)?' + * token: \string.regex + regex: '\\S+' + + key: + * token: \keyword.operator + regex: '[.?@!]+' + * token: \identifier + regex: identifier + next : \start + * token: \text + regex: '.' + next : \start + + comment: + * token: \comment.doc + regex: '.*?\\*/' + next : \start + * token: \comment.doc + regex: '.+' + + qdoc: + token: \string + regex: ".*?'''" + next : \key + stringfill + + qqdoc: + token: \string + regex: '.*?"""' + next : \key + stringfill + + qstring: + token: \string + regex: /[^\\']*(?:\\.[^\\']*)*'/$ + next : \key + stringfill + + qqstring: + token: \string + regex: /[^\\"]*(?:\\.[^\\"]*)*"/$ + next : \key + stringfill + + js: + token: \string + regex: /[^\\`]*(?:\\.[^\\`]*)*`/$ + next : \key + stringfill + + words: + token: \string + regex: '.*?\\]>' + next : \key + stringfill diff --git a/demo/kitchen-sink/docs/logiql.logic b/demo/kitchen-sink/docs/logiql.logic new file mode 100644 index 00000000..910862d7 --- /dev/null +++ b/demo/kitchen-sink/docs/logiql.logic @@ -0,0 +1,16 @@ +// ancestors +parentof("douglas", "john"). +parentof("john", "bob"). +parentof("bob", "ebbon"). + +parentof("douglas", "jane"). +parentof("jane", "jan"). + +ancestorof(A, B) <- parentof(A, B). +ancestorof(A, C) <- ancestorof(A, B), parentof(B,C). + +grandparentof(A, B) <- parentof(A, C), parentof(C, B). + +cousins(A,B) <- grandparentof(C,A), grandparentof(C,B). + +parentof[`arg](A, B) -> int[32](A), !string(B). \ No newline at end of file diff --git a/demo/kitchen-sink/docs/lsl.lsl b/demo/kitchen-sink/docs/lsl.lsl new file mode 100644 index 00000000..baf06f08 --- /dev/null +++ b/demo/kitchen-sink/docs/lsl.lsl @@ -0,0 +1,75 @@ +/* + Testing syntax highlighting + of Ace Editor + for the Linden Scripting Language +*/ + +integer someIntNormal = 3672; +integer someIntHex = 0x00000000; +integer someIntMath = PI_BY_TWO; + +integer event = 5673; // invalid.illegal + +key someKeyTexture = TEXTURE_DEFAULT; +string someStringSpecial = EOF; + +some_user_defined_function_without_return_type(string inputAsString) +{ + llSay(PUBLIC_CHANNEL, inputAsString); +} + +string user_defined_function_returning_a_string(key inputAsKey) +{ + return (string)inputAsKey; +} + +default +{ + state_entry() + { + key someKey = NULL_KEY; + someKey = llGetOwner(); + + string someString = user_defined_function_returning_a_string(someKey); + + some_user_defined_function_without_return_type(someString); + } + + touch_start(integer num_detected) + { + list agentsInRegion = llGetAgentList(AGENT_LIST_REGION, []); + integer numOfAgents = llGetListLength(agentsInRegion); + + integer index; // defaults to 0 + for (; index <= numOfAgents - 1; index++) // for each agent in region + { + llRegionSayTo(llList2Key(agentsInRegion, index), PUBLIC_CHANNEL, "Hello, Avatar!"); + } + } + + touch_end(integer num_detected) + { + someIntNormal = 3672; + someIntHex = 0x00000000; + someIntMath = PI_BY_TWO; + + event = 5673; // invalid.illegal + + someKeyTexture = TEXTURE_DEFAULT; + someStringSpecial = EOF; + + llSetInventoryPermMask("some item", MASK_NEXT, PERM_ALL); // reserved.godmode + + llWhisper(PUBLIC_CHANNEL, "Leaving \"default\" now..."); + state other; + } +} + +state other +{ + state_entry() + { + llWhisper(PUBLIC_CHANNEL, "Entered \"state other\", returning to \"default\" again..."); + state default; + } +} diff --git a/demo/kitchen-sink/docs/lua.lua b/demo/kitchen-sink/docs/lua.lua new file mode 100644 index 00000000..6c927197 --- /dev/null +++ b/demo/kitchen-sink/docs/lua.lua @@ -0,0 +1,38 @@ +--[[-- +num_args takes in 5.1 byte code and extracts the number of arguments +from its function header. +--]]-- + +function int(t) + return t:byte(1)+t:byte(2)*0x100+t:byte(3)*0x10000+t:byte(4)*0x1000000 +end + +function num_args(func) + local dump = string.dump(func) + local offset, cursor = int(dump:sub(13)), offset + 26 + --Get the params and var flag (whether there's a ... in the param) + return dump:sub(cursor):byte(), dump:sub(cursor+1):byte() +end + +-- Usage: +num_args(function(a,b,c,d, ...) end) -- return 4, 7 + +-- Python styled string format operator +local gm = debug.getmetatable("") + +gm.__mod=function(self, other) + if type(other) ~= "table" then other = {other} end + for i,v in ipairs(other) do other[i] = tostring(v) end + return self:format(unpack(other)) +end + +print([===[ + blah blah %s, (%d %d) +]===]%{"blah", num_args(int)}) + +--[=[-- +table.maxn is deprecated, use # instead. +--]=]-- +print(table.maxn{1,2,[4]=4,[8]=8) -- outputs 8 instead of 2 + +print(5 --[[ blah ]]) \ No newline at end of file diff --git a/demo/kitchen-sink/docs/luapage.lp b/demo/kitchen-sink/docs/luapage.lp new file mode 100644 index 00000000..f70c992b --- /dev/null +++ b/demo/kitchen-sink/docs/luapage.lp @@ -0,0 +1,71 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<% --[[-- + index.lp from the Kepler Project's LuaDoc HTML doclet. + http://keplerproject.github.com/luadoc/ +--]] %> +<head> + <title>Reference + " type="text/css" /> + + + + +
+ +
+ +
+
+
+ +
+ + + +
+ + +<%if not options.nomodules and #doc.modules > 0 then%> +

Modules

+ + +<%for _, modulename in ipairs(doc.modules) do%> + + + + +<%end%> +
<%=modulename%><%=doc.modules[modulename].summary%>
+<%end%> + + + +<%if not options.nofiles and #doc.files > 0 then%> +

Files

+ + +<%for _, filepath in ipairs(doc.files) do%> + + + + +<%end%> +
<%=filepath%>
+<%end%> + +
+ +
+ +
+

Valid XHTML 1.0!

+
+ +
+ + diff --git a/demo/kitchen-sink/docs/lucene.lucene b/demo/kitchen-sink/docs/lucene.lucene new file mode 100644 index 00000000..7ac4b90b --- /dev/null +++ b/demo/kitchen-sink/docs/lucene.lucene @@ -0,0 +1 @@ +(title:"foo bar" AND body:"quick fox") OR title:fox \ No newline at end of file diff --git a/demo/kitchen-sink/docs/markdown.md b/demo/kitchen-sink/docs/markdown.md new file mode 100644 index 00000000..63e96eab --- /dev/null +++ b/demo/kitchen-sink/docs/markdown.md @@ -0,0 +1,186 @@ +Ace (Ajax.org Cloud9 Editor) +============================ + +Ace is a standalone code editor written in JavaScript. Our goal is to create a browser based editor that matches and extends the features, usability and performance of existing native editors such as TextMate, Vim or Eclipse. It can be easily embedded in any web page or JavaScript application. Ace is developed as the primary editor for [Cloud9 IDE](http://www.cloud9ide.com/) and the successor of the Mozilla Skywriter (Bespin) Project. + +Features +-------- + +* Syntax highlighting +* Automatic indent and outdent +* An optional command line +* Handles huge documents (100,000 lines and more are no problem) +* Fully customizable key bindings including VI and Emacs modes +* Themes (TextMate themes can be imported) +* Search and replace with regular expressions +* Highlight matching parentheses +* Toggle between soft tabs and real tabs +* Displays hidden characters +* Drag and drop text using the mouse +* Line wrapping +* Unstructured / user code folding +* Live syntax checker (currently JavaScript/CoffeeScript) + +Take Ace for a spin! +-------------------- + +Check out the Ace live [demo](http://ajaxorg.github.com/ace/) or get a [Cloud9 IDE account](http://run.cloud9ide.com) to experience Ace while editing one of your own GitHub projects. + +If you want, you can use Ace as a textarea replacement thanks to the [Ace Bookmarklet](http://ajaxorg.github.com/ace/build/textarea/editor.html). + +History +------- + +Previously known as “Bespin” and “Skywriter” it’s now known as Ace (Ajax.org Cloud9 Editor)! Bespin and Ace started as two independent projects, both aiming to build a no-compromise code editor component for the web. Bespin started as part of Mozilla Labs and was based on the canvas tag, while Ace is the Editor component of the Cloud9 IDE and is using the DOM for rendering. After the release of Ace at JSConf.eu 2010 in Berlin the Skywriter team decided to merge Ace with a simplified version of Skywriter's plugin system and some of Skywriter's extensibility points. All these changes have been merged back to Ace. Both Ajax.org and Mozilla are actively developing and maintaining Ace. + +Getting the code +---------------- + +Ace is a community project. We actively encourage and support contributions. The Ace source code is hosted on GitHub. It is released under the BSD License. This license is very simple, and is friendly to all kinds of projects, whether open source or not. Take charge of your editor and add your favorite language highlighting and keybindings! + +```bash + git clone git://github.com/ajaxorg/ace.git + cd ace + git submodule update --init --recursive +``` + +Embedding Ace +------------- + +Ace can be easily embedded into any existing web page. The Ace git repository ships with a pre-packaged version of Ace inside of the `build` directory. The same packaged files are also available as a separate [download](https://github.com/ajaxorg/ace/downloads). Simply copy the contents of the `src` subdirectory somewhere into your project and take a look at the included demos of how to use Ace. + +The easiest version is simply: + +```html +
some text
+ + +``` + +With "editor" being the id of the DOM element, which should be converted to an editor. Note that this element must be explicitly sized and positioned `absolute` or `relative` for Ace to work. e.g. + +```css + #editor { + position: absolute; + width: 500px; + height: 400px; + } +``` + +To change the theme simply include the Theme's JavaScript file + +```html + +``` + +and configure the editor to use the theme: + +```javascript + editor.setTheme("ace/theme/twilight"); +``` + +By default the editor only supports plain text mode; many other languages are available as separate modules. After including the mode's JavaScript file: + +```html + +``` + +Then the mode can be used like this: + +```javascript + var JavaScriptMode = require("ace/mode/javascript").Mode; + editor.getSession().setMode(new JavaScriptMode()); +``` + +Documentation +------------- + +You find a lot more sample code in the [demo app](https://github.com/ajaxorg/ace/blob/master/demo/demo.js). + +There is also some documentation on the [wiki page](https://github.com/ajaxorg/ace/wiki). + +If you still need help, feel free to drop a mail on the [ace mailing list](http://groups.google.com/group/ace-discuss). + +Running Ace +----------- + +After the checkout Ace works out of the box. No build step is required. Open 'editor.html' in any browser except Google Chrome. Google Chrome doesn't allow XMLHTTPRequests from files loaded from disc (i.e. with a file:/// URL). To open Ace in Chrome simply start the bundled mini HTTP server: + +```bash + ./static.py +``` + +Or using Node.JS + +```bash + ./static.js +``` + +The editor can then be opened at http://localhost:8888/index.html. + +Package Ace +----------- + +To package Ace we use the dryice build tool developed by the Mozilla Skywriter team. Before you can build you need to make sure that the submodules are up to date. + +```bash + git submodule update --init --recursive +``` + +Afterwards Ace can be built by calling + +```bash + ./Makefile.dryice.js normal +``` + +The packaged Ace will be put in the 'build' folder. + +To build the bookmarklet version execute + +```bash + ./Makefile.dryice.js bm +``` + +Running the Unit Tests +---------------------- + +The Ace unit tests run on node.js. Before the first run a couple of node modules have to be installed. The easiest way to do this is by using the node package manager (npm). In the Ace base directory simply call + +```bash + npm link . +``` + +To run the tests call: + +```bash + node lib/ace/test/all.js +``` + +You can also run the tests in your browser by serving: + + http://localhost:8888/lib/ace/test/tests.html + +This makes debugging failing tests way more easier. + +Contributing +------------ + +Ace wouldn't be what it is without contributions! Feel free to fork and improve/enhance Ace any way you want. If you feel that the editor or the Ace community will benefit from your changes, please open a pull request. To protect the interests of the Ace contributors and users we require contributors to sign a Contributors License Agreement (CLA) before we pull the changes into the main repository. Our CLA is the simplest of agreements, requiring that the contributions you make to an ajax.org project are only those you're allowed to make. This helps us significantly reduce future legal risk for everyone involved. It is easy, helps everyone, takes ten minutes, and only needs to be completed once. There are two versions of the agreement: + +1. [The Individual CLA](https://github.com/ajaxorg/ace/raw/master/doc/Contributor_License_Agreement-v2.pdf): use this version if you're working on an ajax.org in your spare time, or can clearly claim ownership of copyright in what you'll be submitting. +2. [The Corporate CLA](https://github.com/ajaxorg/ace/raw/master/doc/Corporate_Contributor_License_Agreement-v2.pdf): have your corporate lawyer review and submit this if your company is going to be contributing to ajax.org projects + +If you want to contribute to an ajax.org project please print the CLA and fill it out and sign it. Then either send it by snail mail or fax to us or send it back scanned (or as a photo) by email. + +Email: fabian.jakobs@web.de + +Fax: +31 (0) 206388953 + +Address: Ajax.org B.V. + Keizersgracht 241 + 1016 EA, Amsterdam + the Netherlands \ No newline at end of file diff --git a/demo/kitchen-sink/docs/mask.mask b/demo/kitchen-sink/docs/mask.mask new file mode 100644 index 00000000..85a9e6c2 --- /dev/null +++ b/demo/kitchen-sink/docs/mask.mask @@ -0,0 +1,52 @@ +/* Mask Syntax Demo */ + +div > ' Test ~[name]'; + +define :userProfile { + header { + h4 > @title; + button.close; + } +} + +:userProfile { + @title > ' Hello ~[: username.toUpperCase()]' +} + +style { + html, body { + background: url('name.png') 0 0 no-repeat; + } +} + +button { + event click (e) { + this.textContent = `name ${e.clientX} !`; + } +} + +md > """ + +- div +- span + +Hello + +[one](http://google.com) + +"""; + + +header .foo > 'Heading' + +button .baz x-signal='click: test' disabled > " + Hello, + world + \"Buddy\" +" + +var a = { + name: `name ${window.innerWidth}` +}; + +span .foo > "~[bind: a.name]" \ No newline at end of file diff --git a/demo/kitchen-sink/docs/matlab.matlab b/demo/kitchen-sink/docs/matlab.matlab new file mode 100644 index 00000000..b2ca44d5 --- /dev/null +++ b/demo/kitchen-sink/docs/matlab.matlab @@ -0,0 +1,17 @@ +%{ + %{ + Ace Matlab demo + %} +%} + +classdef hello + methods + function greet(this) + disp('Hello!') % say hi + end + end +end + +% transpose +a = [ 'x''y', "x\n\ + y", 1' ]' + 2' \ No newline at end of file diff --git a/demo/kitchen-sink/docs/mel.mel b/demo/kitchen-sink/docs/mel.mel new file mode 100644 index 00000000..63dc14d6 --- /dev/null +++ b/demo/kitchen-sink/docs/mel.mel @@ -0,0 +1,33 @@ +// animated duplicates, instances script +proc animatedDuplication (int $rangeStart, int $rangeEnd, int $numOfDuplicates, int $duplicateOrInstance) +{ + int $range_start = $rangeStart; + int $range_end = $rangeEnd; + int $num_of_duplicates = $numOfDuplicates; + int $step_size = ($range_end - $range_start) / $num_of_duplicates; + int $i = 0; + int $temp; + + currentTime $range_start; // set to range start + + string $selectedObjects[]; // to store selected objects + $selectedObjects = `ls -sl`; // store selected objects + select $selectedObjects; + + while ($i <= $num_of_duplicates) + { + $temp = $range_start + ($step_size * $i); + currentTime ($temp); + // seleced the objects to duplicate or instance + select $selectedObjects; + if($duplicateOrInstance == 0) + { + duplicate; + } + else + { + instance; + } + $i++; + } +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/mushcode.mc b/demo/kitchen-sink/docs/mushcode.mc new file mode 100644 index 00000000..6861f955 --- /dev/null +++ b/demo/kitchen-sink/docs/mushcode.mc @@ -0,0 +1,8 @@ +@create phone +&pickup phone=$pick up:@ifelse [u(is,u(mode),ICC)]={@pemit %#=You pick up the [fullname(me)].[set(me,PHONER:%#)][set(me,MODE:CIP)][set([u(INCOMING)],CONNECTED:[num(me)])][set(me,CONNECTED:[u(INCOMING)])]%r[showpicture(PICPICKUP)]%rUse '[color(green,black,psay )]' (or '[color(green,black,p )]') to talk into the phone.;@oemit %#=%N picks up the [fullname(me)].},{@pemit %#=You pick up the phone but no one is there. You hear a dialtone and then hang up. [play(u(DIALTONE))];@oemit %#=%N picks up the phone, but no one is on the other end.} +&ringfun phone=[ifelse(eq(comp([u(%0/ringtone)],off),0),[color(black,cyan,INCOMING CALL FROM %1)],[play([switch([u(%0/ringtone)],1,[u(%0/ringtone1)],2,[u(%0/ringtone2)],3,[u(%0/ringtone3)],4,[u(%0/ringtone4)],5,[u(%0/ringtone5)],6,[u(%0/ringtone6)],7,[u(%0/ringtone7)],8,[u(%0/ringtone8)],9,[u(%0/ringtone9)],custom,[u(%0/customtone)],vibrate,[u(%0/vibrate)])])] +&ringloop phone=@switch [u(ringstate)]=1,{@emit [setq(q,[u(connecting)])][set(%qq,rangs:0)][set(%qq,mode:WFC)][set(%qq,INCOMING:)];@ifelse [u(%qq/HASVMB)]={@tr me/ROUTEVMB=[u(connecting)];},{@pemit %#=[u(MSGCNC)];}},2,{@pemit %#=The call is connected.[setq(q,[u(CONNECTING)])][set(me,CONNECTED:%qq)][set(%qq,CONNECTED:[num(me)])][set(%qq,MODE:CIP)];@tr me/ciploop;@tr %qq/ciploop;},3,{@emit On [fullname(me)]'s earpiece you hear a ringing sound.[play(u(LINETONE))];@tr me/ringhere;@increment [u(connecting)]/RANGS;@wait 5={@tr me/ringloop};},4,{} +&ringstate phone=[setq(q,u(connecting))][setq(1,[gt(u(%qq/rangs),sub(u(%qq/rings),1))])][setq(2,[and(u(is,u(%qq/MODE),CIP),u(is,u(%qq/INCOMING),[num(me)]))][setq(3,[u(is,u(%qq/MODE),ICC)])][ifelse(%q1,1,ifelse(%q2,2,ifelse(%q3,3,4)))] +;comment +@@(comment) +say [time()] diff --git a/demo/kitchen-sink/docs/mysql.mysql b/demo/kitchen-sink/docs/mysql.mysql new file mode 100644 index 00000000..30404ce4 --- /dev/null +++ b/demo/kitchen-sink/docs/mysql.mysql @@ -0,0 +1 @@ +TODO \ No newline at end of file diff --git a/demo/kitchen-sink/docs/objectivec.m b/demo/kitchen-sink/docs/objectivec.m new file mode 100644 index 00000000..1728dfe5 --- /dev/null +++ b/demo/kitchen-sink/docs/objectivec.m @@ -0,0 +1,104 @@ +@protocol Printing: someParent +-(void) print; +@end + +@interface Fraction: NSObject { + int numerator; + int denominator; +} +@end + +@"blah\8" @"a\222sd\d" @"\faw\"\? \' \4 n\\" @"\56" +@"\xSF42" + +-(NSDecimalNumber*)addCount:(id)addObject{ + +return [count decimalNumberByAdding:addObject.count]; + +} + + NS_DURING NS_HANDLER NS_ENDHANDLER + +@try { + if (argc > 1) { + @throw [NSException exceptionWithName:@"Throwing a test exception" reason:@"Testing the @throw directive." userInfo:nil]; + } +} +@catch (id theException) { + NSLog(@"%@", theException); + result = 1 ; +} +@finally { + NSLog(@"This always happens."); + result += 2 ; +} + + @synchronized(lock) { + NSLog(@"Hello World"); + } + +struct { @defs( NSObject) } + +char *enc1 = @encode(int); + + IBOutlet|IBAction|BOOL|SEL|id|unichar|IMP|Class + + + @class @protocol + +@public + // instance variables +@package + // instance variables +@protected + // instance variables +@private + // instance variables + + YES NO Nil nil +NSApp() +NSRectToCGRect (Protocol ProtocolFromString:"NSTableViewDelegate")) + +[SPPoint pointFromCGPoint:self.position] + +NSRoundDownToMultipleOfPageSize + +#import + +int main( int argc, const char *argv[] ) { + printf( "hello world\n" ); + return 0; +} + +NSChangeSpelling + +@"0 != SUBQUERY(image, $x, 0 != SUBQUERY($x.bookmarkItems, $y, $y.@count == 0).@count).@count" + +@selector(lowercaseString) @selector(uppercaseString:) + +NSFetchRequest *localRequest = [[NSFetchRequest alloc] init]; +localRequest.entity = [NSEntityDescription entityForName:@"VNSource" inManagedObjectContext:context]; +localRequest.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"resolution" ascending:YES]]; +NSPredicate *predicate = [NSPredicate predicateWithFormat:@"0 != SUBQUERY(image, $x, 0 != SUBQUERY($x.bookmarkItems, $y, $y.@count == 0).@count).@count"]; +[NSPredicate predicateWithFormat:] +NSString *predicateString = [NSString stringWithFormat:@"SELF beginsWith[cd] %@", searchString]; +NSPredicate *pred = [NSPredicate predicateWithFormat:predicateString]; +NSArray *filteredKeys = [[myMutableDictionary allKeys] filteredArrayUsingPredicate:pred]; + +localRequest.predicate = [NSPredicate predicateWithFormat:@"whichChart = %@" argumentArray: listChartToDownload]; +localRequest.fetchBatchSize = 100; +arrayRequest = [context executeFetchRequest:localRequest error:&error1]; + +[localRequest release]; + +#ifndef Nil +#define Nil __DARWIN_NULL /* id of Nil class */ +#endif + +@implementation MyObject +- (unsigned int)areaOfWidth:(unsigned int)width + height:(unsigned int)height +{ + return width*height; +} +@end diff --git a/demo/kitchen-sink/docs/ocaml.ml b/demo/kitchen-sink/docs/ocaml.ml new file mode 100644 index 00000000..85e6eba7 --- /dev/null +++ b/demo/kitchen-sink/docs/ocaml.ml @@ -0,0 +1,18 @@ +(* + * Example of early return implementation taken from + * http://ocaml.janestreet.com/?q=node/91 + *) + +let with_return (type t) (f : _ -> t) = + let module M = + struct exception Return of t end + in + let return = { return = (fun x -> raise (M.Return x)); } in + try f return with M.Return x -> x + + +(* Function that uses the 'early return' functionality provided by `with_return` *) +let sum_until_first_negative list = + with_return (fun r -> + List.fold list ~init:0 ~f:(fun acc x -> + if x >= 0 then acc + x else r.return acc)) \ No newline at end of file diff --git a/demo/kitchen-sink/docs/pascal.pas b/demo/kitchen-sink/docs/pascal.pas new file mode 100644 index 00000000..7a4a7fc6 --- /dev/null +++ b/demo/kitchen-sink/docs/pascal.pas @@ -0,0 +1,48 @@ +(***************************************************************************** + * A simple bubble sort program. Reads integers, one per line, and prints * + * them out in sorted order. Blows up if there are more than 49. * + *****************************************************************************) +PROGRAM Sort(input, output); + CONST + (* Max array size. *) + MaxElts = 50; + TYPE + (* Type of the element array. *) + IntArrType = ARRAY [1..MaxElts] OF Integer; + + VAR + (* Indexes, exchange temp, array size. *) + i, j, tmp, size: integer; + + (* Array of ints *) + arr: IntArrType; + + (* Read in the integers. *) + PROCEDURE ReadArr(VAR size: Integer; VAR a: IntArrType); + BEGIN + size := 1; + WHILE NOT eof DO BEGIN + readln(a[size]); + IF NOT eof THEN + size := size + 1 + END + END; + + BEGIN + (* Read *) + ReadArr(size, arr); + + (* Sort using bubble sort. *) + FOR i := size - 1 DOWNTO 1 DO + FOR j := 1 TO i DO + IF arr[j] > arr[j + 1] THEN BEGIN + tmp := arr[j]; + arr[j] := arr[j + 1]; + arr[j + 1] := tmp; + END; + + (* Print. *) + FOR i := 1 TO size DO + writeln(arr[i]) + END. + \ No newline at end of file diff --git a/demo/kitchen-sink/docs/perl.pl b/demo/kitchen-sink/docs/perl.pl new file mode 100644 index 00000000..d6a332e2 --- /dev/null +++ b/demo/kitchen-sink/docs/perl.pl @@ -0,0 +1,37 @@ +#!/usr/bin/perl +=begin + perl example code for Ace +=cut + +use strict; +use warnings; +my $num_primes = 0; +my @primes; + +# Put 2 as the first prime so we won't have an empty array +$primes[$num_primes] = 2; +$num_primes++; + +MAIN_LOOP: +for my $number_to_check (3 .. 200) +{ + for my $p (0 .. ($num_primes-1)) + { + if ($number_to_check % $primes[$p] == 0) + { + next MAIN_LOOP; + } + } + + # If we reached this point it means $number_to_check is not + # divisable by any prime number that came before it. + $primes[$num_primes] = $number_to_check; + $num_primes++; +} + +for my $p (0 .. ($num_primes-1)) +{ + print $primes[$p], ", "; +} +print "\n"; + diff --git a/demo/kitchen-sink/docs/pgsql.pgsql b/demo/kitchen-sink/docs/pgsql.pgsql new file mode 100644 index 00000000..ef265cdc --- /dev/null +++ b/demo/kitchen-sink/docs/pgsql.pgsql @@ -0,0 +1,118 @@ + +BEGIN; + +/** +* Samples from PostgreSQL src/tutorial/basics.source +*/ +CREATE TABLE weather ( + city varchar(80), + temp_lo int, -- low temperature + temp_hi int, -- high temperature + prcp real, -- precipitation + "date" date +); + +CREATE TABLE cities ( + name varchar(80), + location point +); + + +INSERT INTO weather + VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27'); + +INSERT INTO cities + VALUES ('San Francisco', '(-194.0, 53.0)'); + +INSERT INTO weather (city, temp_lo, temp_hi, prcp, "date") + VALUES ('San Francisco', 43, 57, 0.0, '1994-11-29'); + +INSERT INTO weather (date, city, temp_hi, temp_lo) + VALUES ('1994-11-29', 'Hayward', 54, 37); + + +SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, "date" FROM weather; + +SELECT city, temp_lo, temp_hi, prcp, "date", location + FROM weather, cities + WHERE city = name; + + + +/** +* Dollar quotes starting at the end of the line are colored as SQL unless +* a special language tag is used. Dollar quote syntax coloring is implemented +* for Perl, Python, JavaScript, and Json. +*/ +create or replace function blob_content_chunked( + in p_data bytea, + in p_chunk integer) +returns setof bytea as $$ +-- Still SQL comments +declare + v_size integer = octet_length(p_data); +begin + for i in 1..v_size by p_chunk loop + return next substring(p_data from i for p_chunk); + end loop; +end; +$$ language plpgsql stable; + + +-- pl/perl +CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $perl$ + # perl comment... + my ($x,$y) = @_; + if (! defined $x) { + if (! defined $y) { return undef; } + return $y; + } + if (! defined $y) { return $x; } + if ($x > $y) { return $x; } + return $y; +$perl$ LANGUAGE plperl; + +-- pl/python +CREATE FUNCTION usesavedplan() RETURNS trigger AS $python$ + # python comment... + if SD.has_key("plan"): + plan = SD["plan"] + else: + plan = plpy.prepare("SELECT 1") + SD["plan"] = plan +$python$ LANGUAGE plpythonu; + +-- pl/v8 (javascript) +CREATE FUNCTION plv8_test(keys text[], vals text[]) RETURNS text AS $javascript$ +var o = {}; +for(var i=0; i \ No newline at end of file diff --git a/demo/kitchen-sink/docs/plaintext.txt b/demo/kitchen-sink/docs/plaintext.txt new file mode 100644 index 00000000..37bb4cca --- /dev/null +++ b/demo/kitchen-sink/docs/plaintext.txt @@ -0,0 +1,11 @@ +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + +Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + +Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + +Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + +Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. + +At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur \ No newline at end of file diff --git a/demo/kitchen-sink/docs/powershell.ps1 b/demo/kitchen-sink/docs/powershell.ps1 new file mode 100644 index 00000000..f3a70bc1 --- /dev/null +++ b/demo/kitchen-sink/docs/powershell.ps1 @@ -0,0 +1,24 @@ +# This is a simple comment +function Hello($name) { + Write-host "Hello $name" +} + +function add($left, $right=4) { + if ($right -ne 4) { + return $left + } elseif ($left -eq $null -and $right -eq 2) { + return 3 + } else { + return 2 + } +} + +$number = 1 + 2; +$number += 3 + +Write-Host Hello -name "World" + +$an_array = @(1, 2, 3) +$a_hash = @{"something" = "something else"} + +& notepad .\readme.md diff --git a/demo/kitchen-sink/docs/praat.praat b/demo/kitchen-sink/docs/praat.praat new file mode 100644 index 00000000..3700ae6f --- /dev/null +++ b/demo/kitchen-sink/docs/praat.praat @@ -0,0 +1,148 @@ +form Highlighter test + sentence My_sentence This should all be a string + text My_text This should also all be a string + word My_word Only the first word is a string, the rest is invalid + boolean Binary 1 + boolean Text no + boolean Quoted "yes" + comment This should be a string + real left_Range -123.6 + positive right_Range_max 3.3 + integer Int 4 + natural Nat 4 +endform + +# External scripts +include /path/to/file +runScript: "/path/to/file" +execute /path/to/file + +stopwatch + +# old-style procedure call +call oldStyle "quoted" 2 unquoted string +assert oldStyle.local = 1 + +# New-style procedure call with parens +@newStyle("quoted", 2, "quoted string") +if praatVersion >= 5364 + # New-style procedure call with colon + @newStyle: "quoted", 2, "quoted string" +endif + +# if-block with built-in variables +if windows + # We are on Windows +elsif unix = 1 or !macintosh + exitScript: "We are on Linux" +else macintosh == 1 + exit We are on Mac +endif + +# inline if with inline comment +var = if macintosh = 1 then 0 else 1 fi ; This is an inline comment + +# for-loop with explicit from using local variable +# and paren-style function calls and variable interpolation +n = numberOfSelected("Sound") +for i from newStyle.local to n + sound'i' = selected("Sound", i) + sound[i] = sound'i' +endfor + +for i from 1 to n + # Different styles of object selection + select sound'i' + sound = selected() + sound$ = selected$("Sound") + select Sound 'sound$' + selectObject(sound[i]) + selectObject: sound + + # Pause commands + beginPause("Viewing " + sound$) + if i > 1 + button = endPause("Stop", "Previous", + ...if i = total_sounds then "Finish" else "Next" fi, + ...3, 1) + else + button = endPause("Stop", + ...if i = total_sounds then "Finish" else "Next" fi, + ...2, 1) + endif + editor_name$ = if total_textgrids then "TextGrid " else "Sound " fi + name$ + nocheck editor 'editor_name$' + nocheck Close + nocheck endeditor + + # New-style standalone command call + Rename: "SomeName" + + # Command call with assignment + duration = Get total duration + + # Multi-line command with modifier + pitch = noprogress To Pitch (ac): 0, 75, 15, "no", + ...0.03, 0.45, 0.01, 0.35, 0.14, 600 + + # do-style command with assignment + minimum = do("Get minimum...", 0, 0, "Hertz", "Parabolic") + + # New-style multi-line command call with broken strings + table = Create Table with column names: "table", 0, + ..."file subject speaker + ...f0 f1 f2 f3 " + + ..."duration response" + + removeObject: pitch, table + + # Picture window commands + selectObject: sound + # do-style command + do("Select inner viewport...", 1, 6, 0.5, 1.5) + Black + Draw... 0 0 0 0 "no" Curve + Draw inner box + Text bottom: "yes", sound$ + Erase all + + # Demo window commands + demo Erase all + demo Select inner viewport... 0 100 0 100 + demo Axes... 0 100 0 100 + demo Paint rectangle... white 0 100 0 100 + demo Text... 50 centre 50 half Click to finish + demoWaitForInput ( ) + demo Erase all + demo Text: 50, "centre", 50, "half", "Finished" +endfor + +# An old-style sendpraat block +sendpraat Praat + ...'newline$' Create Sound as pure tone... "tone" 1 0 0.4 44100 440 0.2 0.01 0.01 + ...'newline$' Play + ...'newline$' Remove + +# A new-style sendpraat block +beginSendPraat: "Praat" + Create Sound as pure tone: "tone", 1, 0, 0.4, 44100, 440, 0.2, 0.01, 0.01 + duration = Get total duration + Remove +endSendPraat: "duration" +appendInfoLine: "The generated sound lasted for ", duration, "seconds" + +time = stopwatch +clearinfo +echo This script took +print 'time' seconds to +printline execute. + +# Old-style procedure declaration +procedure oldStyle .str1$ .num .str2$ + .local = 1 +endproc + +# New-style procedure declaration +procedure newStyle (.str1$, .num, .str2$) + .local = 1 +endproc diff --git a/demo/kitchen-sink/docs/prolog.plg b/demo/kitchen-sink/docs/prolog.plg new file mode 100644 index 00000000..2c867157 --- /dev/null +++ b/demo/kitchen-sink/docs/prolog.plg @@ -0,0 +1,18 @@ +partition([], _, [], []). +partition([X|Xs], Pivot, Smalls, Bigs) :- + ( X @< Pivot -> + Smalls = [X|Rest], + partition(Xs, Pivot, Rest, Bigs) + ; Bigs = [X|Rest], + partition(Xs, Pivot, Smalls, Rest) + ). + +quicksort([]) --> []. +quicksort([X|Xs]) --> + { partition(Xs, X, Smaller, Bigger) }, + quicksort(Smaller), [X], quicksort(Bigger). + +perfect(N) :- + between(1, inf, N), U is N // 2, + findall(D, (between(1,U,D), N mod D =:= 0), Ds), + sumlist(Ds, N). \ No newline at end of file diff --git a/demo/kitchen-sink/docs/properties.properties b/demo/kitchen-sink/docs/properties.properties new file mode 100644 index 00000000..446b340d --- /dev/null +++ b/demo/kitchen-sink/docs/properties.properties @@ -0,0 +1,15 @@ +# You are reading the ".properties" entry. +! The exclamation mark can also mark text as comments. +# The key and element characters #, !, =, and : are written with a preceding backslash to ensure that they are properly loaded. +website = http\://en.wikipedia.org/ +language = English +# The backslash below tells the application to continue reading +# the value onto the next line. +message = Welcome to \ + Wikipedia! +# Add spaces to the key +key\ with\ spaces = This is the value that could be looked up with the key "key with spaces". +# Unicode +tab : \u0009 +empty-key= +last.line=value diff --git a/demo/kitchen-sink/docs/protobuf.proto b/demo/kitchen-sink/docs/protobuf.proto new file mode 100644 index 00000000..4da95a75 --- /dev/null +++ b/demo/kitchen-sink/docs/protobuf.proto @@ -0,0 +1,16 @@ +message Point { + required int32 x = 1; + required int32 y = 2; + optional string label = 3; +} + +message Line { + required Point start = 1; + required Point end = 2; + optional string label = 3; +} + +message Polyline { + repeated Point point = 1; + optional string label = 2; +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/python.py b/demo/kitchen-sink/docs/python.py new file mode 100644 index 00000000..90afdc30 --- /dev/null +++ b/demo/kitchen-sink/docs/python.py @@ -0,0 +1,19 @@ +#!/usr/local/bin/python + +import string, sys + +# If no arguments were given, print a helpful message +if len(sys.argv)==1: + print '''Usage: +celsius temp1 temp2 ...''' + sys.exit(0) + +# Loop over the arguments +for i in sys.argv[1:]: + try: + fahrenheit=float(string.atoi(i)) + except string.atoi_error: + print repr(i), "not a numeric value" + else: + celsius=(fahrenheit-32)*5.0/9.0 + print '%i\260F = %i\260C' % (int(fahrenheit), int(celsius+.5)) \ No newline at end of file diff --git a/demo/kitchen-sink/docs/r.r b/demo/kitchen-sink/docs/r.r new file mode 100644 index 00000000..e4d4c579 --- /dev/null +++ b/demo/kitchen-sink/docs/r.r @@ -0,0 +1,20 @@ +Call: +lm(formula = y ~ x) + +Residuals: +1 2 3 4 5 6 +3.3333 -0.6667 -2.6667 -2.6667 -0.6667 3.3333 + +Coefficients: + Estimate Std. Error t value Pr(>|t|) +(Intercept) -9.3333 2.8441 -3.282 0.030453 * +x 7.0000 0.7303 9.585 0.000662 *** +--- +Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 + +Residual standard error: 3.055 on 4 degrees of freedom +Multiple R-squared: 0.9583, Adjusted R-squared: 0.9478 +F-statistic: 91.88 on 1 and 4 DF, p-value: 0.000662 + +> par(mfrow=c(2, 2)) # Request 2x2 plot layout +> plot(lm_1) # Diagnostic plot of regression model \ No newline at end of file diff --git a/demo/kitchen-sink/docs/rdoc.Rd b/demo/kitchen-sink/docs/rdoc.Rd new file mode 100644 index 00000000..16664795 --- /dev/null +++ b/demo/kitchen-sink/docs/rdoc.Rd @@ -0,0 +1,64 @@ +\name{picker} +\alias{picker} +\title{Create a picker control} +\description{ + Create a picker control to enable manipulation of plot variables based on a set of fixed choices. +} + +\usage{ +picker(..., initial = NULL, label = NULL) +} + + +\arguments{ + \item{\dots}{ + Arguments containing objects to be presented as choices for the picker (or a list containing the choices). If an element is named then the name is used to display it within the picker. If an element is not named then it is displayed within the picker using \code{\link{as.character}}. +} + \item{initial}{ + Initial value for picker. Value must be present in the list of choices specified. If not specified defaults to the first choice. +} + \item{label}{ + Display label for picker. Defaults to the variable name if not specified. +} +} + +\value{ + An object of class "manipulator.picker" which can be passed to the \code{\link{manipulate}} function. +} + +\seealso{ +\code{\link{manipulate}}, \code{\link{slider}}, \code{\link{checkbox}}, \code{\link{button}} +} + + +\examples{ +\dontrun{ + +## Filtering data with a picker +manipulate( + barplot(as.matrix(longley[,factor]), + beside = TRUE, main = factor), + factor = picker("GNP", "Unemployed", "Employed")) + +## Create a picker with labels +manipulate( + plot(pressure, type = type), + type = picker("points" = "p", "line" = "l", "step" = "s")) + +## Picker with groups +manipulate( + barplot(as.matrix(mtcars[group,"mpg"]), beside=TRUE), + group = picker("Group 1" = 1:11, + "Group 2" = 12:22, + "Group 3" = 23:32)) + +## Histogram w/ picker to select type +require(lattice) +require(stats) +manipulate( + histogram(~ height | voice.part, + data = singer, type = type), + type = picker("percent", "count", "density")) + +} +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/rhtml.Rhtml b/demo/kitchen-sink/docs/rhtml.Rhtml new file mode 100644 index 00000000..5eb6189d --- /dev/null +++ b/demo/kitchen-sink/docs/rhtml.Rhtml @@ -0,0 +1,22 @@ + + + +Title + + + + +

This is an R HTML document. When you click the Knit HTML button a web page will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

+ + + +

You can also embed plots, for example:

+ + + + + diff --git a/demo/kitchen-sink/docs/ruby.rb b/demo/kitchen-sink/docs/ruby.rb new file mode 100644 index 00000000..386fbb86 --- /dev/null +++ b/demo/kitchen-sink/docs/ruby.rb @@ -0,0 +1,35 @@ +#!/usr/bin/ruby + +# Program to find the factorial of a number +def fact(n) + if n == 0 + 1 + else + n * fact(n-1) + end +end + +puts fact(ARGV[0].to_i) + +class Range + def to_json(*a) + { + 'json_class' => self.class.name, # = 'Range' + 'data' => [ first, last, exclude_end? ] + }.to_json(*a) + end +end + +{:id => ?", :key => "value"} + + + herDocs = [<<'FOO', <(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] { + let mut accumulator = ~[]; + for vec::each(vector) |element| { + accumulator.push(function(element)); + } + return accumulator; +} diff --git a/demo/kitchen-sink/docs/sass.sass b/demo/kitchen-sink/docs/sass.sass new file mode 100644 index 00000000..6caaaff8 --- /dev/null +++ b/demo/kitchen-sink/docs/sass.sass @@ -0,0 +1,39 @@ +// sass ace mode; + +@import url(http://fonts.googleapis.com/css?family=Ace:700) + +html, body + :background-color #ace + text-align: center + height: 100% + /*;*********; + ;comment ; + ;*********; + +.toggle + $size: 14px + + :background url(http://subtlepatterns.com/patterns/dark_stripes.png) + border-radius: 8px + height: $size + + &:before + $radius: $size * 0.845 + $glow: $size * 0.125 + + box-shadow: 0 0 $glow $glow / 2 #fff + border-radius: $radius + + &:active + ~ .button + box-shadow: 0 15px 25px -4px rgba(0,0,0,0.4) + ~ .label + font-size: 40px + color: rgba(0,0,0,0.45) + + &:checked + ~ .button + box-shadow: 0 15px 25px -4px #ace + ~ .label + font-size: 40px + color: #c9c9c9 diff --git a/demo/kitchen-sink/docs/scad.scad b/demo/kitchen-sink/docs/scad.scad new file mode 100644 index 00000000..a45c1aec --- /dev/null +++ b/demo/kitchen-sink/docs/scad.scad @@ -0,0 +1,21 @@ +// ace can highlight scad! +module Element(xpos, ypos, zpos){ + translate([xpos,ypos,zpos]){ + union(){ + cube([10,10,4],true); + cylinder(10,15,5); + translate([0,0,10])sphere(5); + } + } +} + +union(){ + for(i=[0:30]){ + # Element(0,0,0); + Element(15*i,0,0); + } +} + +for (i = [3, 5, 7, 11]){ + rotate([i*10,0,0])scale([1,1,i])cube(10); +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/scala.scala b/demo/kitchen-sink/docs/scala.scala new file mode 100644 index 00000000..f8280677 --- /dev/null +++ b/demo/kitchen-sink/docs/scala.scala @@ -0,0 +1,69 @@ +// http://www.scala-lang.org/node/54 + +package examples.actors + +import scala.actors.Actor +import scala.actors.Actor._ + +abstract class PingMessage +case object Start extends PingMessage +case object SendPing extends PingMessage +case object Pong extends PingMessage + +abstract class PongMessage +case object Ping extends PongMessage +case object Stop extends PongMessage + +object pingpong extends Application { + val pong = new Pong + val ping = new Ping(100000, pong) + ping.start + pong.start + ping ! Start +} + +class Ping(count: Int, pong: Actor) extends Actor { + def act() { + println("Ping: Initializing with count "+count+": "+pong) + var pingsLeft = count + loop { + react { + case Start => + println("Ping: starting.") + pong ! Ping + pingsLeft = pingsLeft - 1 + case SendPing => + pong ! Ping + pingsLeft = pingsLeft - 1 + case Pong => + if (pingsLeft % 1000 == 0) + println("Ping: pong from: "+sender) + if (pingsLeft > 0) + self ! SendPing + else { + println("Ping: Stop.") + pong ! Stop + exit('stop) + } + } + } + } +} + +class Pong extends Actor { + def act() { + var pongCount = 0 + loop { + react { + case Ping => + if (pongCount % 1000 == 0) + println("Pong: ping "+pongCount+" from "+sender) + sender ! Pong + pongCount = pongCount + 1 + case Stop => + println("Pong: Stop.") + exit('stop) + } + } + } +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/scheme.scm b/demo/kitchen-sink/docs/scheme.scm new file mode 100644 index 00000000..8c78359c --- /dev/null +++ b/demo/kitchen-sink/docs/scheme.scm @@ -0,0 +1,21 @@ +(define (prompt-for-cd) + "Prompts + for CD" + (prompt-read "Title" 1.53 1 2/4 1.7 1.7e0 2.9E-4 +42 -7 #b001 #b001/100 #o777 #O777 #xabc55 #c(0 -5.6)) + (prompt-read "Artist") + (or (parse-integer (prompt-read "Rating") #:junk-allowed #t) 0) + (if x (format #t "yes") (format #f "no") ;and here comment + ) + ;; second line comment + '(+ 1 2) + (position-if-not char-set:whitespace line #:start beg)) + (quote (privet 1 2 3)) + '(hello world) + (* 5 7) + (1 2 34 5) + (#:use "aaaa") + (let ((x 10) (y 20)) + (display (+ x y)) + ) + + "asdad\0eqweqe" diff --git a/demo/kitchen-sink/docs/scss.scss b/demo/kitchen-sink/docs/scss.scss new file mode 100644 index 00000000..e1558168 --- /dev/null +++ b/demo/kitchen-sink/docs/scss.scss @@ -0,0 +1,20 @@ +/* style.scss */ + +#navbar { + $navbar-width: 800px; + $items: 5; + $navbar-color: #ce4dd6; + + width: $navbar-width; + border-bottom: 2px solid $navbar-color; + + li { + float: left; + width: $navbar-width/$items - 10px; + + background-color: lighten($navbar-color, 20%); + &:hover { + background-color: lighten($navbar-color, 10%); + } + } +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/sh.sh b/demo/kitchen-sink/docs/sh.sh new file mode 100755 index 00000000..4c5e6968 --- /dev/null +++ b/demo/kitchen-sink/docs/sh.sh @@ -0,0 +1,40 @@ +#!/bin/sh + +# Script to open a browser to current branch +# Repo formats: +# ssh git@github.com:richo/gh_pr.git +# http https://richoH@github.com/richo/gh_pr.git +# git git://github.com/richo/gh_pr.git + +username=`git config --get github.user` + +get_repo() { + git remote -v | grep ${@:-$username} | while read remote; do + if repo=`echo $remote | grep -E -o "git@github.com:[^ ]*"`; then + echo $repo | sed -e "s/^git@github\.com://" -e "s/\.git$//" + exit 1 + fi + if repo=`echo $remote | grep -E -o "https?://([^@]*@)?github.com/[^ ]*\.git"`; then + echo $repo | sed -e "s|^https?://||" -e "s/^.*github\.com\///" -e "s/\.git$//" + exit 1 + fi + if repo=`echo $remote | grep -E -o "git://github.com/[^ ]*\.git"`; then + echo $repo | sed -e "s|^git://github.com/||" -e "s/\.git$//" + exit 1 + fi + done + + if [ $? -eq 0 ]; then + echo "Couldn't find a valid remote" >&2 + exit 1 + fi +} + +echo ${#x[@]} + +if repo=`get_repo $@`; then + branch=`git symbolic-ref HEAD 2>/dev/null` + echo "http://github.com/$repo/pull/new/${branch##refs/heads/}" +else + exit 1 +fi diff --git a/demo/kitchen-sink/docs/sjs.sjs b/demo/kitchen-sink/docs/sjs.sjs new file mode 100644 index 00000000..18ce0e49 --- /dev/null +++ b/demo/kitchen-sink/docs/sjs.sjs @@ -0,0 +1,28 @@ +var { each, map } = require('sjs:sequence'); +var { get } = require('sjs:http'); + +function foo(items, nada) { + var component = { name: "Ace", role: "Editor" }; + console.log(" + Welcome, #{component.name} + ".trim()); + + logging.debug(`Component added: $String(component) (${component})`); + + console.log(` + Welcome, {${function() { + return { x: 1, y: "why?}"}; + }()} + `.trim()); + + waitfor { + items .. each.par { |item| + get(item); + } + } and { + var lengths = items .. map(i -> i.length); + } or { + hold(1500); + throw new Error("timed out"); + } +} // Real Tab. diff --git a/demo/kitchen-sink/docs/smarty.smarty b/demo/kitchen-sink/docs/smarty.smarty new file mode 100644 index 00000000..77206724 --- /dev/null +++ b/demo/kitchen-sink/docs/smarty.smarty @@ -0,0 +1,7 @@ +{foreach $foo as $bar} + {$bar.zag} + {$bar.zag2} + {$bar.zag3} +{foreachelse} + There were no rows found. +{/foreach} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/snippets.snippets b/demo/kitchen-sink/docs/snippets.snippets new file mode 100644 index 00000000..be99f51e --- /dev/null +++ b/demo/kitchen-sink/docs/snippets.snippets @@ -0,0 +1,26 @@ +# Function +snippet fun + function ${1?:function_name}(${2:argument}) { + ${3:// body...} + } +# Anonymous Function +regex /((=)\s*|(:)\s*|(\()|\b)/f/(\))?/ +name f + function${M1?: ${1:functionName}}($2) { + ${0:$TM_SELECTED_TEXT} + }${M2?;}${M3?,}${M4?)} +# Immediate function +trigger \(?f\( +endTrigger \)? +snippet f( + (function(${1}) { + ${0:${TM_SELECTED_TEXT:/* code */}} + }(${1})); +# if +snippet if + if (${1:true}) { + ${0} + } + + + \ No newline at end of file diff --git a/demo/kitchen-sink/docs/soy_template.soy b/demo/kitchen-sink/docs/soy_template.soy new file mode 100644 index 00000000..3a9e3436 --- /dev/null +++ b/demo/kitchen-sink/docs/soy_template.soy @@ -0,0 +1,46 @@ +/** + * Greets a person using "Hello" by default. + * @param name The name of the person. + * @param? greetingWord Optional greeting word to use instead of "Hello". + */ +{template .helloName #eee} + {if not $greetingWord} + Hello {$name}! + {else} + {$greetingWord} {$name}! + {/if} +{/template} + +/** + * Greets a person and optionally a list of other people. + * @param name The name of the person. + * @param additionalNames The additional names to greet. May be an empty list. + */ +{template .helloNames} + // Greet the person. + {call .helloName data="all" /}
+ // Greet the additional people. + {foreach $additionalName in $additionalNames} + {call .helloName} + {param name: $additionalName /} + {/call} + {if not isLast($additionalName)} +
// break after every line except the last + {/if} + {ifempty} + No additional people to greet. + {/foreach} +{/template} + + +{/foreach} +{if length($items) > 5} +{msg desc="Says hello to the user."} + + +{namespace ns autoescape="contextual"} + +/** Example. */ +{template .example} + foo is {$ij.foo} +{/template} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/space.space b/demo/kitchen-sink/docs/space.space new file mode 100644 index 00000000..7bd8ab19 --- /dev/null +++ b/demo/kitchen-sink/docs/space.space @@ -0,0 +1,56 @@ +query + count 10 + created 2011-06-21T08:10:46Z + lang en-US + results + photo + 0 + farm 6 + id 5855620975 + isfamily 0 + isfriend 0 + ispublic 1 + owner 32021554@N04 + secret f1f5e8515d + server 5110 + title 7087 bandit cat + 1 + farm 4 + id 5856170534 + isfamily 0 + isfriend 0 + ispublic 1 + owner 32021554@N04 + secret ff1efb2a6f + server 3217 + title 6975 rusty cat + 2 + farm 6 + id 5856172972 + isfamily 0 + isfriend 0 + ispublic 1 + owner 51249875@N03 + secret 6c6887347c + server 5192 + title watermarked-cats + 3 + farm 6 + id 5856168328 + isfamily 0 + isfriend 0 + ispublic 1 + owner 32021554@N04 + secret 0c1cfdf64c + server 5078 + title 7020 mandy cat + 4 + farm 3 + id 5856171774 + isfamily 0 + isfriend 0 + ispublic 1 + owner 32021554@N04 + secret 7f5a3180ab + server 2696 + title 7448 bobby cat diff --git a/demo/kitchen-sink/docs/sql.sql b/demo/kitchen-sink/docs/sql.sql new file mode 100644 index 00000000..d674f8a6 --- /dev/null +++ b/demo/kitchen-sink/docs/sql.sql @@ -0,0 +1,6 @@ +SELECT city, COUNT(id) AS users_count +FROM users +WHERE group_name = 'salesman' +AND created > '2011-05-21' +GROUP BY 1 +ORDER BY 2 DESC \ No newline at end of file diff --git a/demo/kitchen-sink/docs/sqlserver.sqlserver b/demo/kitchen-sink/docs/sqlserver.sqlserver new file mode 100644 index 00000000..7efd2b7e --- /dev/null +++ b/demo/kitchen-sink/docs/sqlserver.sqlserver @@ -0,0 +1,72 @@ +-- ============================================= +-- Author: Morgan Yarbrough +-- Create date: 4/27/2015 +-- Description: Test procedure that shows off language features. +-- Includes non-standard folding with region comments using either +-- line comments or block comments (both are demonstrated below). +-- This mode imitates SSMS and it designed to be used with SQL Server theme. +-- ============================================= +CREATE PROCEDURE dbo.TestProcedure + +--#region parameters + @vint INT = 1 + ,@vdate DATE = NULL + ,@vdatetime DATETIME = DATEADD(dd, 1, GETDATE()) + ,@vvarchar VARCHAR(MAX) = '' +--#endregion + +AS +BEGIN + + /*#region set statements */ + SET NOCOUNT ON; + SET XACT_ABORT ON; + SET QUOTED_IDENTIFIER ON; + /*#endregion*/ + + /** + * These comments will produce a fold widget + */ + + -- folding demonstration + SET @vint = CASE + WHEN @vdate IS NULL + THEN 1 + ELSE 2 + END + + -- another folding demonstration + IF @vint = 1 + BEGIN + SET @vvarchar = 'one' + SET @vint = DATEDIFF(dd, @vdate, @vdatetime) + END + + -- this mode handles strings properly + DECLARE @sql NVARCHAR(4000) = N'SELECT TOP(1) OrderID + FROM Orders + WHERE @OrderDate > GETDATE()' + + -- this mode is aware of built in stored procedures + EXECUTE sp_executesql @sql + + -- demonstrating some syntax highlighting + SELECT Orders.OrderID + ,Customers.CompanyName + ,DATEFROMPARTS(YEAR(GETDATE()), 1, 1) AS FirstDayOfYear + FROM Orders + INNER JOIN Customers + ON Orders.CustomerID = Customers.CustomerID + WHERE CompanyName NOT LIKE '%something' + OR CompanyName IS NULL + OR CompanyName IN ('bla', 'nothing') + + -- this mode includes snippets + -- place your cusor at the end of the line below and trigger auto complete (Ctrl+Space) + createpr + + -- SQL Server allows using keywords as object names (not recommended) as long as they are wrapped in brackets + DATABASE -- keyword + [DATABASE] -- not a keyword + +END diff --git a/demo/kitchen-sink/docs/stylus.styl b/demo/kitchen-sink/docs/stylus.styl new file mode 100644 index 00000000..614981a4 --- /dev/null +++ b/demo/kitchen-sink/docs/stylus.styl @@ -0,0 +1,55 @@ +// I'm a comment! + +/* + * Adds the given numbers together. + */ + + +/*! + * Adds the given numbers together. + */ + + +asdasdasdad(df, ad=23) + +add(a, b = a) + a + b +green(#0c0) + add(10, 5) + // => 15 + + add(10) + add(a, b) + + &asdasd + + (arguments) + + @sdfsdf +.signatures + background-color #e0e8e0 + border 1px solid grayLighter + box-shadow 0 0 3px grayLightest + border-radius 3px + padding 3px 5px + "adsads" + margin-left 0 + list-style none +.signature + list-style none + display: inline + margin-left 0 + > li + display inline +is not +.signature-values + list-style none + display inline + margin-left 0 + &:before + content '→' + margin 0 5px + > li + !important + + unless \ No newline at end of file diff --git a/demo/kitchen-sink/docs/svg.svg b/demo/kitchen-sink/docs/svg.svg new file mode 100644 index 00000000..4bb28e22 --- /dev/null +++ b/demo/kitchen-sink/docs/svg.svg @@ -0,0 +1,83 @@ + + + Test Tube Progress Bar + Created for the Web Directions SVG competition + + + + + + + Hickory, + + dickory, + + dock! + \ No newline at end of file diff --git a/demo/kitchen-sink/docs/tcl.tcl b/demo/kitchen-sink/docs/tcl.tcl new file mode 100644 index 00000000..5c53b971 --- /dev/null +++ b/demo/kitchen-sink/docs/tcl.tcl @@ -0,0 +1,40 @@ + +proc dijkstra {graph origin} { + # Initialize + dict for {vertex distmap} $graph { + dict set dist $vertex Inf + dict set path $vertex {} + } + dict set dist $origin 0 + dict set path $origin [list $origin] + + while {[dict size $graph]} { + # Find unhandled node with least weight + set d Inf + dict for {uu -} $graph { + if {$d > [set dd [dict get $dist $uu]]} { + set u $uu + set d $dd + } + } + + # No such node; graph must be disconnected + if {$d == Inf} break + + # Update the weights for nodes\ + lead to by the node we've picked + dict for {v dd} [dict get $graph $u] { + if {[dict exists $graph $v]} { + set alt [expr {$d + $dd}] + if {$alt < [dict get $dist $v]} { + dict set dist $v $alt + dict set path $v [list {*}[dict get $path $u] $v] + } + } + } + + # Remove chosen node from graph still to be handled + dict unset graph $u + } + return [list $dist $path] +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/tex.tex b/demo/kitchen-sink/docs/tex.tex new file mode 100644 index 00000000..9f1df621 --- /dev/null +++ b/demo/kitchen-sink/docs/tex.tex @@ -0,0 +1,20 @@ +The quadratic formula is $$-b \pm \sqrt{b^2 - 4ac} \over 2a$$ +\bye + +\makeatletter + \newcommand{\be}{% + \begingroup + % \setlength{\arraycolsep}{2pt} + \eqnarray% + \@ifstar{\nonumber}{}% + } + \newcommand{\ee}{\endeqnarray\endgroup} + \makeatother + + \begin{equation} + x=\left\{ \begin{array}{cl} + 0 & \textrm{if }A=\ldots\\ + 1 & \textrm{if }B=\ldots\\ + x & \textrm{this runs with as much text as you like, but without an raggeright text +.}\end{array}\right. + \end{equation} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/textile.textile b/demo/kitchen-sink/docs/textile.textile new file mode 100644 index 00000000..8c67ec16 --- /dev/null +++ b/demo/kitchen-sink/docs/textile.textile @@ -0,0 +1,29 @@ +h1. Textile document + +h2. Heading Two + +h3. A two-line + header + +h2. Another two-line +header + +Paragraph: +one, two, +thee lines! + +p(classone two three). This is a paragraph with classes + +p(#id). (one with an id) + +p(one two three#my_id). ..classes + id + +* Unordered list +** sublist +* back again! +** sublist again.. + +# ordered + +bg. Blockquote! + This is a two-list blockquote..! \ No newline at end of file diff --git a/demo/kitchen-sink/docs/toml.toml b/demo/kitchen-sink/docs/toml.toml new file mode 100644 index 00000000..46e5b9d1 --- /dev/null +++ b/demo/kitchen-sink/docs/toml.toml @@ -0,0 +1,29 @@ +# This is a TOML document. Boom. + +title = "TOML Example" + +[owner] +name = "Tom Preston-Werner" +organization = "GitHub" +bio = "GitHub Cofounder & CEO\nLikes tater tots and beer." +dob = 1979-05-27T07:32:00Z # First class dates? Why not? + +[database] +server = "192.168.1.1" +ports = [ 8001, 8001, 8002 ] +connection_max = 5000 +enabled = true + +[servers] + + # You can indent as you please. Tabs or spaces. TOML don't care. + [servers.alpha] + ip = "10.0.0.1" + dc = "eqdc10" + + [servers.beta] + ip = "10.0.0.2" + dc = "eqdc10" + +[clients] +data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it \ No newline at end of file diff --git a/demo/kitchen-sink/docs/twig.twig b/demo/kitchen-sink/docs/twig.twig new file mode 100644 index 00000000..02214f09 --- /dev/null +++ b/demo/kitchen-sink/docs/twig.twig @@ -0,0 +1,30 @@ + + + + My Webpage + + + + + {% if 1 not in [1, 2, 3] %} + + {# is equivalent to #} + {% if not (1 in [1, 2, 3]) %} + + {% autoescape true %} + {{ var }} + {{ var|raw }} {# var won't be escaped #} + {{ var|escape }} {# var won't be doubled-escaped #} + {% endautoescape %} + + {{ include('twig.html', sandboxed = true) }} + + {{"string #{with} \" escapes" 'another#one' }} +

My Webpage

+ {{ a_variable }} + + \ No newline at end of file diff --git a/demo/kitchen-sink/docs/typescript.ts b/demo/kitchen-sink/docs/typescript.ts new file mode 100644 index 00000000..2f880d03 --- /dev/null +++ b/demo/kitchen-sink/docs/typescript.ts @@ -0,0 +1,72 @@ +class Greeter { + greeting: string; + constructor (message: string) { + this.greeting = message; + } + greet() { + return "Hello, " + this.greeting; + } +} + +var greeter = new Greeter("world"); + +var button = document.createElement('button') +button.innerText = "Say Hello" +button.onclick = function() { + alert(greeter.greet()) +} + +document.body.appendChild(button) + +class Snake extends Animal { + move() { + alert("Slithering..."); + super(5); + } +} + +class Horse extends Animal { + move() { + alert("Galloping..."); + super.move(45); + } +} + +module Sayings { + export class Greeter { + greeting: string; + constructor (message: string) { + this.greeting = message; + } + greet() { + return "Hello, " + this.greeting; + } + } +} +module Mankala { + export class Features { + public turnContinues = false; + public seedStoredCount = 0; + public capturedCount = 0; + public spaceCaptured = NoSpace; + + public clear() { + this.turnContinues = false; + this.seedStoredCount = 0; + this.capturedCount = 0; + this.spaceCaptured = NoSpace; + } + + public toString() { + var stringBuilder = ""; + if (this.turnContinues) { + stringBuilder += " turn continues,"; + } + stringBuilder += " stores " + this.seedStoredCount; + if (this.capturedCount > 0) { + stringBuilder += " captures " + this.capturedCount + " from space " + this.spaceCaptured; + } + return stringBuilder; + } + } +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/vala.vala b/demo/kitchen-sink/docs/vala.vala new file mode 100644 index 00000000..f9600286 --- /dev/null +++ b/demo/kitchen-sink/docs/vala.vala @@ -0,0 +1,21 @@ +using Gtk; + +int main (string[] args) { + Gtk.init (ref args); + var foo = new MyFoo>(); + + var window = new Window(); + window.title = "Hello, World!"; + window.border_width = 10; + window.window_position = WindowPosition.CENTER; + window.set_default_size(350, 70); + window.destroy.connect(Gtk.main_quit); + + var label = new Label("Hello, World!"); + + window.add(label); + window.show_all(); + + Gtk.main(); + return 0; +} \ No newline at end of file diff --git a/demo/kitchen-sink/docs/vbscript.vbs b/demo/kitchen-sink/docs/vbscript.vbs new file mode 100644 index 00000000..ace5c9f9 --- /dev/null +++ b/demo/kitchen-sink/docs/vbscript.vbs @@ -0,0 +1,23 @@ +myfilename = "C:\Wikipedia - VBScript - Example - Hello World.txt" +MakeHelloWorldFile myfilename + +Sub MakeHelloWorldFile (FileName) +'Create a new file in C: drive or overwrite existing file + Set FSO = CreateObject("Scripting.FileSystemObject") + If FSO.FileExists(FileName) Then + Answer = MsgBox ("File " & FileName & " exists ... OK to overwrite?", vbOKCancel) + 'If button selected is not OK, then quit now + 'vbOK is a language constant + If Answer <> vbOK Then Exit Sub + Else + 'Confirm OK to create + Answer = MsgBox ("File " & FileName & " ... OK to create?", vbOKCancel) + If Answer <> vbOK Then Exit Sub + End If + 'Create new file (or replace an existing file) + Set FileObject = FSO.CreateTextFile (FileName) + FileObject.WriteLine "Time ... " & Now() + FileObject.WriteLine "Hello World" + FileObject.Close() + MsgBox "File " & FileName & " ... updated." +End Sub \ No newline at end of file diff --git a/demo/kitchen-sink/docs/velocity.vm b/demo/kitchen-sink/docs/velocity.vm new file mode 100644 index 00000000..9156020b --- /dev/null +++ b/demo/kitchen-sink/docs/velocity.vm @@ -0,0 +1,44 @@ +#* + This is a sample comment block that + spans multiple lines. +*# + +#macro ( outputItem $item ) +
  • ${item}
  • +#end + +## Define the items to iterate +#set ( $items = [1, 2, 3, 4] ) + +
      + ## Iterate over the items and output the evens. + #foreach ( $item in $items ) + #if ( $_MathTool.mod($item, 2) == 0 ) + #outputItem ($item) + #end + #end +
    + + + + \ No newline at end of file diff --git a/demo/kitchen-sink/docs/verilog.v b/demo/kitchen-sink/docs/verilog.v new file mode 100644 index 00000000..b1f79265 --- /dev/null +++ b/demo/kitchen-sink/docs/verilog.v @@ -0,0 +1,12 @@ +always @(negedge reset or posedge clk) begin + if (reset == 0) begin + d_out <= 16'h0000; + d_out_mem[resetcount] <= d_out; + laststoredvalue <= d_out; + end else begin + d_out <= d_out + 1'b1; + end +end + +always @(bufreadaddr) + bufreadval = d_out_mem[bufreadaddr]; \ No newline at end of file diff --git a/demo/kitchen-sink/docs/vhdl.vhd b/demo/kitchen-sink/docs/vhdl.vhd new file mode 100644 index 00000000..662375e8 --- /dev/null +++ b/demo/kitchen-sink/docs/vhdl.vhd @@ -0,0 +1,34 @@ +library IEEE +user IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity COUNT16 is + + port ( + cOut :out std_logic_vector(15 downto 0); -- counter output + clkEn :in std_logic; -- count enable + clk :in std_logic; -- clock input + rst :in std_logic -- reset input + ); + +end entity; + +architecture count_rtl of COUNT16 is + signal count :std_logic_vector (15 downto 0); + +begin + process (clk, rst) begin + + if(rst = '1') then + count <= (others=>'0'); + elsif(rising_edge(clk)) then + if(clkEn = '1') then + count <= count + 1; + end if; + end if; + + end process; + cOut <= count; + +end architecture; + \ No newline at end of file diff --git a/demo/kitchen-sink/docs/xml.xml b/demo/kitchen-sink/docs/xml.xml new file mode 100644 index 00000000..5b12c0a2 --- /dev/null +++ b/demo/kitchen-sink/docs/xml.xml @@ -0,0 +1,55 @@ + + + + true + + 26 + 25 + 21978 + + + + 24865670 + Continent + Africa + + + 24865675 + Continent + Europe + + + 24865673 + Continent + South America + + + 28289421 + Continent + Antarctic + + + 24865671 + Continent + Asia + + + 24865672 + Continent + North America + + + 55949070 + Continent + Australia + + + \ No newline at end of file diff --git a/demo/kitchen-sink/docs/xquery.xq b/demo/kitchen-sink/docs/xquery.xq new file mode 100644 index 00000000..1b0ac753 --- /dev/null +++ b/demo/kitchen-sink/docs/xquery.xq @@ -0,0 +1,6 @@ +xquery version "1.0"; + +let $message := "Hello World!" +return + {$message} + diff --git a/demo/kitchen-sink/docs/yaml.yaml b/demo/kitchen-sink/docs/yaml.yaml new file mode 100644 index 00000000..52ee320e --- /dev/null +++ b/demo/kitchen-sink/docs/yaml.yaml @@ -0,0 +1,35 @@ +# This sample document was taken from wikipedia: +# http://en.wikipedia.org/wiki/YAML#Sample_document +--- +receipt: Oz-Ware Purchase Invoice +date: 2007-08-06 +customer: + given: Dorothy + family: Gale + +items: + - part_no: 'A4786' + descrip: Water Bucket (Filled) + price: 1.47 + quantity: 4 + + - part_no: 'E1628' + descrip: High Heeled "Ruby" Slippers + size: 8 + price: 100.27 + quantity: 1 + +bill-to: &id001 + street: | + 123 Tornado Alley + Suite 16 + city: East Centerville + state: KS + +ship-to: *id001 + +specialDelivery: > + Follow the Yellow Brick + Road to the Emerald City. + Pay no attention to the + man behind the curtain. diff --git a/demo/kitchen-sink/file_drop.js b/demo/kitchen-sink/file_drop.js new file mode 100644 index 00000000..8b89d5f1 --- /dev/null +++ b/demo/kitchen-sink/file_drop.js @@ -0,0 +1,73 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var config = require("ace/config"); +var event = require("ace/lib/event"); +var modelist = require("ace/ext/modelist"); + +module.exports = function(editor) { + event.addListener(editor.container, "dragover", function(e) { + var types = e.dataTransfer.types; + if (types && Array.prototype.indexOf.call(types, 'Files') !== -1) + return event.preventDefault(e); + }); + + event.addListener(editor.container, "drop", function(e) { + var file; + try { + file = e.dataTransfer.files[0]; + if (window.FileReader) { + var reader = new FileReader(); + reader.onload = function() { + var mode = modelist.getModeForPath(file.name); + editor.session.doc.setValue(reader.result); + editor.session.setMode(mode.mode); + editor.session.modeName = mode.name; + }; + reader.readAsText(file); + } + return event.preventDefault(e); + } catch(err) { + return event.stopEvent(e); + } + }); +}; + +var Editor = require("ace/editor").Editor; +config.defineOptions(Editor.prototype, "editor", { + loadDroppedFile: { + set: function() { module.exports(this); }, + value: true + } +}); + +}); \ No newline at end of file diff --git a/demo/icons/Readme.txt b/demo/kitchen-sink/icons/Readme.txt similarity index 100% rename from demo/icons/Readme.txt rename to demo/kitchen-sink/icons/Readme.txt diff --git a/demo/icons/epl.html b/demo/kitchen-sink/icons/epl.html similarity index 100% rename from demo/icons/epl.html rename to demo/kitchen-sink/icons/epl.html diff --git a/demo/icons/error_obj.gif b/demo/kitchen-sink/icons/error_obj.gif similarity index 100% rename from demo/icons/error_obj.gif rename to demo/kitchen-sink/icons/error_obj.gif diff --git a/demo/icons/warning_obj.gif b/demo/kitchen-sink/icons/warning_obj.gif similarity index 100% rename from demo/icons/warning_obj.gif rename to demo/kitchen-sink/icons/warning_obj.gif diff --git a/demo/kitchen-sink/inline_editor.js b/demo/kitchen-sink/inline_editor.js new file mode 100644 index 00000000..6b56887d --- /dev/null +++ b/demo/kitchen-sink/inline_editor.js @@ -0,0 +1,102 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + + +define(function(require, exports, module) { +"use strict"; + +var LineWidgets = require("ace/line_widgets").LineWidgets; +var Editor = require("ace/editor").Editor; +var Renderer = require("ace/virtual_renderer").VirtualRenderer; +var dom = require("ace/lib/dom"); + + +require("ace/commands/default_commands").commands.push({ + name: "openInlineEditor", + bindKey: "F3", + exec: function(editor) { + var split = window.env.split; + var s = editor.session; + var inlineEditor = new Editor(new Renderer()); + var splitSession = split.$cloneSession(s); + + var row = editor.getCursorPosition().row; + if (editor.session.lineWidgets && editor.session.lineWidgets[row]) { + editor.session.lineWidgets[row].destroy(); + return; + } + + var rowCount = 10; + var w = { + row: row, + // rowCount: rowCount, + fixedWidth: true, + el: dom.createElement("div"), + editor: inlineEditor + }; + var el = w.el; + el.appendChild(inlineEditor.container); + + if (!editor.session.widgetManager) { + editor.session.widgetManager = new LineWidgets(editor.session); + editor.session.widgetManager.attach(editor); + } + + var h = rowCount*editor.renderer.layerConfig.lineHeight; + inlineEditor.container.style.height = h + "px"; + + el.style.position = "absolute"; + el.style.zIndex = "4"; + el.style.borderTop = "solid blue 2px"; + el.style.borderBottom = "solid blue 2px"; + + inlineEditor.setSession(splitSession); + editor.session.widgetManager.addLineWidget(w); + + var kb = { + handleKeyboard:function(_,hashId, keyString) { + if (hashId === 0 && keyString === "esc") { + w.destroy(); + return true; + } + } + }; + + w.destroy = function() { + editor.keyBinding.removeKeyboardHandler(kb); + s.widgetManager.removeLineWidget(w); + }; + + editor.keyBinding.addKeyboardHandler(kb); + inlineEditor.keyBinding.addKeyboardHandler(kb); + inlineEditor.setTheme("ace/theme/solarized_light"); + } +}); +}); diff --git a/demo/kitchen-sink/layout.js b/demo/kitchen-sink/layout.js new file mode 100644 index 00000000..1332eef3 --- /dev/null +++ b/demo/kitchen-sink/layout.js @@ -0,0 +1,132 @@ + +define(function(require, exports, module) { +"use strict"; + +var dom = require("ace/lib/dom"); +var event = require("ace/lib/event"); + +var EditSession = require("ace/edit_session").EditSession; +var UndoManager = require("ace/undomanager").UndoManager; +var Renderer = require("ace/virtual_renderer").VirtualRenderer; +var Editor = require("ace/editor").Editor; +var MultiSelect = require("ace/multi_select").MultiSelect; + +dom.importCssString("\ +splitter {\ + border: 1px solid #C6C6D2;\ + width: 0px;\ + cursor: ew-resize;\ + z-index:10}\ +splitter:hover {\ + margin-left: -2px;\ + width:3px;\ + border-color: #B5B4E0;\ +}\ +", "splitEditor"); + +exports.edit = function(el) { + if (typeof(el) == "string") + el = document.getElementById(el); + + var editor = new Editor(new Renderer(el, require("ace/theme/textmate"))); + + editor.resize(); + event.addListener(window, "resize", function() { + editor.resize(); + }); + return editor; +}; + + +var SplitRoot = function(el, theme, position, getSize) { + el.style.position = position || "relative"; + this.container = el; + this.getSize = getSize || this.getSize; + this.resize = this.$resize.bind(this); + + event.addListener(el.ownerDocument.defaultView, "resize", this.resize); + this.editor = this.createEditor(); +}; + +(function(){ + this.createEditor = function() { + var el = document.createElement("div"); + el.className = this.$editorCSS; + el.style.cssText = "position: absolute; top:0px; bottom:0px"; + this.$container.appendChild(el); + var session = new EditSession(""); + var editor = new Editor(new Renderer(el, this.$theme)); + + /*editor.on("focus", function() { + this._emit("focus", editor); + }.bind(this));*/ + + this.$editors.push(editor); + editor.setFontSize(this.$fontSize); + return editor; + }; + this.$resize = function() { + var size = this.getSize(this.container); + this.rect = { + x: size.left, + y: size.top, + w: size.width, + h: size.height + }; + this.item.resize(this.rect); + }; + this.getSize = function(el) { + return el.getBoundingClientRect(); + }; + this.destroy = function() { + var win = this.container.ownerDocument.defaultView; + event.removeListener(win, "resize", this.resize); + }; + + +}).call(SplitRoot.prototype); + + + +var Split = function(){ + +}; +(function(){ + this.execute = function(options) { + this.$u.execute(options); + }; + +}).call(Split.prototype); + + + +exports.singleLineEditor = function(el) { + var renderer = new Renderer(el); + el.style.overflow = "hidden"; + + renderer.screenToTextCoordinates = function(x, y) { + var pos = this.pixelToScreenCoordinates(x, y); + return this.session.screenToDocumentPosition( + Math.min(this.session.getScreenLength() - 1, Math.max(pos.row, 0)), + Math.max(pos.column, 0) + ); + }; + + renderer.$maxLines = 4; + + renderer.setStyle("ace_one-line"); + var editor = new Editor(renderer); + editor.session.setUndoManager(new UndoManager()); + + editor.setShowPrintMargin(false); + editor.renderer.setShowGutter(false); + editor.renderer.setHighlightGutterLine(false); + editor.$mouseHandler.$focusWaitTimout = 0; + + return editor; +}; + + + +}); + diff --git a/demo/kitchen-sink/logo.png b/demo/kitchen-sink/logo.png new file mode 100644 index 00000000..a722472f Binary files /dev/null and b/demo/kitchen-sink/logo.png differ diff --git a/demo/kitchen-sink/require.js b/demo/kitchen-sink/require.js new file mode 100644 index 00000000..203843c1 --- /dev/null +++ b/demo/kitchen-sink/require.js @@ -0,0 +1,2074 @@ +/** vim: et:ts=4:sw=4:sts=4 + * @license RequireJS 2.1.11+ Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved. + * Available via the MIT or new BSD license. + * see: http://github.com/jrburke/requirejs for details + */ +//Not using strict: uneven strict support in browsers, #392, and causes +//problems with requirejs.exec()/transpiler plugins that may not be strict. +/*jslint regexp: true, nomen: true, sloppy: true */ +/*global window, navigator, document, importScripts, setTimeout, opera */ + +var requirejs, require, define; +(function (global) { + var req, s, head, baseElement, dataMain, src, + interactiveScript, currentlyAddingScript, mainScript, subPath, + version = '2.1.11+', + commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, + cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, + jsSuffixRegExp = /\.js$/, + currDirRegExp = /^\.\//, + op = Object.prototype, + ostring = op.toString, + hasOwn = op.hasOwnProperty, + ap = Array.prototype, + apsp = ap.splice, + isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document), + isWebWorker = !isBrowser && typeof importScripts !== 'undefined', + //PS3 indicates loaded and complete, but need to wait for complete + //specifically. Sequence is 'loading', 'loaded', execution, + // then 'complete'. The UA check is unfortunate, but not sure how + //to feature test w/o causing perf issues. + readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? + /^complete$/ : /^(complete|loaded)$/, + defContextName = '_', + //Oh the tragedy, detecting opera. See the usage of isOpera for reason. + isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]', + contexts = {}, + cfg = {}, + globalDefQueue = [], + useInteractive = false; + + function isFunction(it) { + return ostring.call(it) === '[object Function]'; + } + + function isArray(it) { + return ostring.call(it) === '[object Array]'; + } + + /** + * Helper function for iterating over an array. If the func returns + * a true value, it will break out of the loop. + */ + function each(ary, func) { + if (ary) { + var i; + for (i = 0; i < ary.length; i += 1) { + if (ary[i] && func(ary[i], i, ary)) { + break; + } + } + } + } + + /** + * Helper function for iterating over an array backwards. If the func + * returns a true value, it will break out of the loop. + */ + function eachReverse(ary, func) { + if (ary) { + var i; + for (i = ary.length - 1; i > -1; i -= 1) { + if (ary[i] && func(ary[i], i, ary)) { + break; + } + } + } + } + + function hasProp(obj, prop) { + return hasOwn.call(obj, prop); + } + + function getOwn(obj, prop) { + return hasProp(obj, prop) && obj[prop]; + } + + /** + * Cycles over properties in an object and calls a function for each + * property value. If the function returns a truthy value, then the + * iteration is stopped. + */ + function eachProp(obj, func) { + var prop; + for (prop in obj) { + if (hasProp(obj, prop)) { + if (func(obj[prop], prop)) { + break; + } + } + } + } + + /** + * Simple function to mix in properties from source into target, + * but only if target does not already have a property of the same name. + */ + function mixin(target, source, force, deepStringMixin) { + if (source) { + eachProp(source, function (value, prop) { + if (force || !hasProp(target, prop)) { + if (deepStringMixin && typeof value === 'object' && value && + !isArray(value) && !isFunction(value) && + !(value instanceof RegExp)) { + + if (!target[prop]) { + target[prop] = {}; + } + mixin(target[prop], value, force, deepStringMixin); + } else { + target[prop] = value; + } + } + }); + } + return target; + } + + //Similar to Function.prototype.bind, but the 'this' object is specified + //first, since it is easier to read/figure out what 'this' will be. + function bind(obj, fn) { + return function () { + return fn.apply(obj, arguments); + }; + } + + function scripts() { + return document.getElementsByTagName('script'); + } + + function defaultOnError(err) { + throw err; + } + + //Allow getting a global that is expressed in + //dot notation, like 'a.b.c'. + function getGlobal(value) { + if (!value) { + return value; + } + var g = global; + each(value.split('.'), function (part) { + g = g[part]; + }); + return g; + } + + /** + * Constructs an error with a pointer to an URL with more information. + * @param {String} id the error ID that maps to an ID on a web page. + * @param {String} message human readable error. + * @param {Error} [err] the original error, if there is one. + * + * @returns {Error} + */ + function makeError(id, msg, err, requireModules) { + var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id); + e.requireType = id; + e.requireModules = requireModules; + if (err) { + e.originalError = err; + } + return e; + } + + if (typeof define !== 'undefined') { + //If a define is already in play via another AMD loader, + //do not overwrite. + return; + } + + if (typeof requirejs !== 'undefined') { + if (isFunction(requirejs)) { + //Do not overwrite an existing requirejs instance. + return; + } + cfg = requirejs; + requirejs = undefined; + } + + //Allow for a require config object + if (typeof require !== 'undefined' && !isFunction(require)) { + //assume it is a config object. + cfg = require; + require = undefined; + } + + function newContext(contextName) { + var inCheckLoaded, Module, context, handlers, + checkLoadedTimeoutId, + config = { + //Defaults. Do not set a default for map + //config to speed up normalize(), which + //will run faster if there is no default. + waitSeconds: 7, + baseUrl: './', + paths: {}, + bundles: {}, + pkgs: {}, + shim: {}, + config: {} + }, + registry = {}, + //registry of just enabled modules, to speed + //cycle breaking code when lots of modules + //are registered, but not activated. + enabledRegistry = {}, + undefEvents = {}, + defQueue = [], + defined = {}, + urlFetched = {}, + bundlesMap = {}, + requireCounter = 1, + unnormalizedCounter = 1; + + /** + * Trims the . and .. from an array of path segments. + * It will keep a leading path segment if a .. will become + * the first path segment, to help with module name lookups, + * which act like paths, but can be remapped. But the end result, + * all paths that use this function should look normalized. + * NOTE: this method MODIFIES the input array. + * @param {Array} ary the array of path segments. + */ + function trimDots(ary) { + var i, part, length = ary.length; + for (i = 0; i < length; i++) { + part = ary[i]; + if (part === '.') { + ary.splice(i, 1); + i -= 1; + } else if (part === '..') { + if (i === 1 && (ary[2] === '..' || ary[0] === '..')) { + //End of the line. Keep at least one non-dot + //path segment at the front so it can be mapped + //correctly to disk. Otherwise, there is likely + //no path mapping for a path starting with '..'. + //This can still fail, but catches the most reasonable + //uses of .. + break; + } else if (i > 0) { + ary.splice(i - 1, 2); + i -= 2; + } + } + } + } + + /** + * Given a relative module name, like ./something, normalize it to + * a real name that can be mapped to a path. + * @param {String} name the relative name + * @param {String} baseName a real name that the name arg is relative + * to. + * @param {Boolean} applyMap apply the map config to the value. Should + * only be done if this normalization is for a dependency ID. + * @returns {String} normalized name + */ + function normalize(name, baseName, applyMap) { + var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex, + foundMap, foundI, foundStarMap, starI, + baseParts = baseName && baseName.split('/'), + normalizedBaseParts = baseParts, + map = config.map, + starMap = map && map['*']; + + //Adjust any relative paths. + if (name && name.charAt(0) === '.') { + //If have a base name, try to normalize against it, + //otherwise, assume it is a top-level require that will + //be relative to baseUrl in the end. + if (baseName) { + //Convert baseName to array, and lop off the last part, + //so that . matches that 'directory' and not name of the baseName's + //module. For instance, baseName of 'one/two/three', maps to + //'one/two/three.js', but we want the directory, 'one/two' for + //this normalization. + normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); + name = name.split('/'); + lastIndex = name.length - 1; + + // If wanting node ID compatibility, strip .js from end + // of IDs. Have to do this here, and not in nameToUrl + // because node allows either .js or non .js to map + // to same file. + if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { + name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); + } + + name = normalizedBaseParts.concat(name); + trimDots(name); + name = name.join('/'); + } else if (name.indexOf('./') === 0) { + // No baseName, so this is ID is resolved relative + // to baseUrl, pull off the leading dot. + name = name.substring(2); + } + } + + //Apply map config if available. + if (applyMap && map && (baseParts || starMap)) { + nameParts = name.split('/'); + + outerLoop: for (i = nameParts.length; i > 0; i -= 1) { + nameSegment = nameParts.slice(0, i).join('/'); + + if (baseParts) { + //Find the longest baseName segment match in the config. + //So, do joins on the biggest to smallest lengths of baseParts. + for (j = baseParts.length; j > 0; j -= 1) { + mapValue = getOwn(map, baseParts.slice(0, j).join('/')); + + //baseName segment has config, find if it has one for + //this name. + if (mapValue) { + mapValue = getOwn(mapValue, nameSegment); + if (mapValue) { + //Match, update name to the new value. + foundMap = mapValue; + foundI = i; + break outerLoop; + } + } + } + } + + //Check for a star map match, but just hold on to it, + //if there is a shorter segment match later in a matching + //config, then favor over this star map. + if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { + foundStarMap = getOwn(starMap, nameSegment); + starI = i; + } + } + + if (!foundMap && foundStarMap) { + foundMap = foundStarMap; + foundI = starI; + } + + if (foundMap) { + nameParts.splice(0, foundI, foundMap); + name = nameParts.join('/'); + } + } + + // If the name points to a package's name, use + // the package main instead. + pkgMain = getOwn(config.pkgs, name); + + return pkgMain ? pkgMain : name; + } + + function removeScript(name) { + if (isBrowser) { + each(scripts(), function (scriptNode) { + if (scriptNode.getAttribute('data-requiremodule') === name && + scriptNode.getAttribute('data-requirecontext') === context.contextName) { + scriptNode.parentNode.removeChild(scriptNode); + return true; + } + }); + } + } + + function hasPathFallback(id) { + var pathConfig = getOwn(config.paths, id); + if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { + //Pop off the first array value, since it failed, and + //retry + pathConfig.shift(); + context.require.undef(id); + + //Custom require that does not do map translation, since + //ID is "absolute", already mapped/resolved. + context.makeRequire(null, { + skipMap: true + })([id]); + + return true; + } + } + + //Turns a plugin!resource to [plugin, resource] + //with the plugin being undefined if the name + //did not have a plugin prefix. + function splitPrefix(name) { + var prefix, + index = name ? name.indexOf('!') : -1; + if (index > -1) { + prefix = name.substring(0, index); + name = name.substring(index + 1, name.length); + } + return [prefix, name]; + } + + /** + * Creates a module mapping that includes plugin prefix, module + * name, and path. If parentModuleMap is provided it will + * also normalize the name via require.normalize() + * + * @param {String} name the module name + * @param {String} [parentModuleMap] parent module map + * for the module name, used to resolve relative names. + * @param {Boolean} isNormalized: is the ID already normalized. + * This is true if this call is done for a define() module ID. + * @param {Boolean} applyMap: apply the map config to the ID. + * Should only be true if this map is for a dependency. + * + * @returns {Object} + */ + function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { + var url, pluginModule, suffix, nameParts, + prefix = null, + parentName = parentModuleMap ? parentModuleMap.name : null, + originalName = name, + isDefine = true, + normalizedName = ''; + + //If no name, then it means it is a require call, generate an + //internal name. + if (!name) { + isDefine = false; + name = '_@r' + (requireCounter += 1); + } + + nameParts = splitPrefix(name); + prefix = nameParts[0]; + name = nameParts[1]; + + if (prefix) { + prefix = normalize(prefix, parentName, applyMap); + pluginModule = getOwn(defined, prefix); + } + + //Account for relative paths if there is a base name. + if (name) { + if (prefix) { + if (pluginModule && pluginModule.normalize) { + //Plugin is loaded, use its normalize method. + normalizedName = pluginModule.normalize(name, function (name) { + return normalize(name, parentName, applyMap); + }); + } else { + normalizedName = normalize(name, parentName, applyMap); + } + } else { + //A regular module. + normalizedName = normalize(name, parentName, applyMap); + + //Normalized name may be a plugin ID due to map config + //application in normalize. The map config values must + //already be normalized, so do not need to redo that part. + nameParts = splitPrefix(normalizedName); + prefix = nameParts[0]; + normalizedName = nameParts[1]; + isNormalized = true; + + url = context.nameToUrl(normalizedName); + } + } + + //If the id is a plugin id that cannot be determined if it needs + //normalization, stamp it with a unique ID so two matching relative + //ids that may conflict can be separate. + suffix = prefix && !pluginModule && !isNormalized ? + '_unnormalized' + (unnormalizedCounter += 1) : + ''; + + return { + prefix: prefix, + name: normalizedName, + parentMap: parentModuleMap, + unnormalized: !!suffix, + url: url, + originalName: originalName, + isDefine: isDefine, + id: (prefix ? + prefix + '!' + normalizedName : + normalizedName) + suffix + }; + } + + function getModule(depMap) { + var id = depMap.id, + mod = getOwn(registry, id); + + if (!mod) { + mod = registry[id] = new context.Module(depMap); + } + + return mod; + } + + function on(depMap, name, fn) { + var id = depMap.id, + mod = getOwn(registry, id); + + if (hasProp(defined, id) && + (!mod || mod.defineEmitComplete)) { + if (name === 'defined') { + fn(defined[id]); + } + } else { + mod = getModule(depMap); + if (mod.error && name === 'error') { + fn(mod.error); + } else { + mod.on(name, fn); + } + } + } + + function onError(err, errback) { + var ids = err.requireModules, + notified = false; + + if (errback) { + errback(err); + } else { + each(ids, function (id) { + var mod = getOwn(registry, id); + if (mod) { + //Set error on module, so it skips timeout checks. + mod.error = err; + if (mod.events.error) { + notified = true; + mod.emit('error', err); + } + } + }); + + if (!notified) { + req.onError(err); + } + } + } + + /** + * Internal method to transfer globalQueue items to this context's + * defQueue. + */ + function takeGlobalQueue() { + //Push all the globalDefQueue items into the context's defQueue + if (globalDefQueue.length) { + //Array splice in the values since the context code has a + //local var ref to defQueue, so cannot just reassign the one + //on context. + apsp.apply(defQueue, + [defQueue.length, 0].concat(globalDefQueue)); + globalDefQueue = []; + } + } + + handlers = { + 'require': function (mod) { + if (mod.require) { + return mod.require; + } else { + return (mod.require = context.makeRequire(mod.map)); + } + }, + 'exports': function (mod) { + mod.usingExports = true; + if (mod.map.isDefine) { + if (mod.exports) { + return (defined[mod.map.id] = mod.exports); + } else { + return (mod.exports = defined[mod.map.id] = {}); + } + } + }, + 'module': function (mod) { + if (mod.module) { + return mod.module; + } else { + return (mod.module = { + id: mod.map.id, + uri: mod.map.url, + config: function () { + return getOwn(config.config, mod.map.id) || {}; + }, + exports: mod.exports || (mod.exports = {}) + }); + } + } + }; + + function cleanRegistry(id) { + //Clean up machinery used for waiting modules. + delete registry[id]; + delete enabledRegistry[id]; + } + + function breakCycle(mod, traced, processed) { + var id = mod.map.id; + + if (mod.error) { + mod.emit('error', mod.error); + } else { + traced[id] = true; + each(mod.depMaps, function (depMap, i) { + var depId = depMap.id, + dep = getOwn(registry, depId); + + //Only force things that have not completed + //being defined, so still in the registry, + //and only if it has not been matched up + //in the module already. + if (dep && !mod.depMatched[i] && !processed[depId]) { + if (getOwn(traced, depId)) { + mod.defineDep(i, defined[depId]); + mod.check(); //pass false? + } else { + breakCycle(dep, traced, processed); + } + } + }); + processed[id] = true; + } + } + + function checkLoaded() { + var err, usingPathFallback, + waitInterval = config.waitSeconds * 1000, + //It is possible to disable the wait interval by using waitSeconds of 0. + expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), + noLoads = [], + reqCalls = [], + stillLoading = false, + needCycleCheck = true; + + //Do not bother if this call was a result of a cycle break. + if (inCheckLoaded) { + return; + } + + inCheckLoaded = true; + + //Figure out the state of all the modules. + eachProp(enabledRegistry, function (mod) { + var map = mod.map, + modId = map.id; + + //Skip things that are not enabled or in error state. + if (!mod.enabled) { + return; + } + + if (!map.isDefine) { + reqCalls.push(mod); + } + + if (!mod.error) { + //If the module should be executed, and it has not + //been inited and time is up, remember it. + if (!mod.inited && expired) { + if (hasPathFallback(modId)) { + usingPathFallback = true; + stillLoading = true; + } else { + noLoads.push(modId); + removeScript(modId); + } + } else if (!mod.inited && mod.fetched && map.isDefine) { + stillLoading = true; + if (!map.prefix) { + //No reason to keep looking for unfinished + //loading. If the only stillLoading is a + //plugin resource though, keep going, + //because it may be that a plugin resource + //is waiting on a non-plugin cycle. + return (needCycleCheck = false); + } + } + } + }); + + if (expired && noLoads.length) { + //If wait time expired, throw error of unloaded modules. + err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); + err.contextName = context.contextName; + return onError(err); + } + + //Not expired, check for a cycle. + if (needCycleCheck) { + each(reqCalls, function (mod) { + breakCycle(mod, {}, {}); + }); + } + + //If still waiting on loads, and the waiting load is something + //other than a plugin resource, or there are still outstanding + //scripts, then just try back later. + if ((!expired || usingPathFallback) && stillLoading) { + //Something is still waiting to load. Wait for it, but only + //if a timeout is not already in effect. + if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { + checkLoadedTimeoutId = setTimeout(function () { + checkLoadedTimeoutId = 0; + checkLoaded(); + }, 50); + } + } + + inCheckLoaded = false; + } + + Module = function (map) { + this.events = getOwn(undefEvents, map.id) || {}; + this.map = map; + this.shim = getOwn(config.shim, map.id); + this.depExports = []; + this.depMaps = []; + this.depMatched = []; + this.pluginMaps = {}; + this.depCount = 0; + + /* this.exports this.factory + this.depMaps = [], + this.enabled, this.fetched + */ + }; + + Module.prototype = { + init: function (depMaps, factory, errback, options) { + options = options || {}; + + //Do not do more inits if already done. Can happen if there + //are multiple define calls for the same module. That is not + //a normal, common case, but it is also not unexpected. + if (this.inited) { + return; + } + + this.factory = factory; + + if (errback) { + //Register for errors on this module. + this.on('error', errback); + } else if (this.events.error) { + //If no errback already, but there are error listeners + //on this module, set up an errback to pass to the deps. + errback = bind(this, function (err) { + this.emit('error', err); + }); + } + + //Do a copy of the dependency array, so that + //source inputs are not modified. For example + //"shim" deps are passed in here directly, and + //doing a direct modification of the depMaps array + //would affect that config. + this.depMaps = depMaps && depMaps.slice(0); + + this.errback = errback; + + //Indicate this module has be initialized + this.inited = true; + + this.ignore = options.ignore; + + //Could have option to init this module in enabled mode, + //or could have been previously marked as enabled. However, + //the dependencies are not known until init is called. So + //if enabled previously, now trigger dependencies as enabled. + if (options.enabled || this.enabled) { + //Enable this module and dependencies. + //Will call this.check() + this.enable(); + } else { + this.check(); + } + }, + + defineDep: function (i, depExports) { + //Because of cycles, defined callback for a given + //export can be called more than once. + if (!this.depMatched[i]) { + this.depMatched[i] = true; + this.depCount -= 1; + this.depExports[i] = depExports; + } + }, + + fetch: function () { + if (this.fetched) { + return; + } + this.fetched = true; + + context.startTime = (new Date()).getTime(); + + var map = this.map; + + //If the manager is for a plugin managed resource, + //ask the plugin to load it now. + if (this.shim) { + context.makeRequire(this.map, { + enableBuildCallback: true + })(this.shim.deps || [], bind(this, function () { + return map.prefix ? this.callPlugin() : this.load(); + })); + } else { + //Regular dependency. + return map.prefix ? this.callPlugin() : this.load(); + } + }, + + load: function () { + var url = this.map.url; + + //Regular dependency. + if (!urlFetched[url]) { + urlFetched[url] = true; + context.load(this.map.id, url); + } + }, + + /** + * Checks if the module is ready to define itself, and if so, + * define it. + */ + check: function () { + if (!this.enabled || this.enabling) { + return; + } + + var err, cjsModule, + id = this.map.id, + depExports = this.depExports, + exports = this.exports, + factory = this.factory; + + if (!this.inited) { + this.fetch(); + } else if (this.error) { + this.emit('error', this.error); + } else if (!this.defining) { + //The factory could trigger another require call + //that would result in checking this module to + //define itself again. If already in the process + //of doing that, skip this work. + this.defining = true; + + if (this.depCount < 1 && !this.defined) { + if (isFunction(factory)) { + //If there is an error listener, favor passing + //to that instead of throwing an error. However, + //only do it for define()'d modules. require + //errbacks should not be called for failures in + //their callbacks (#699). However if a global + //onError is set, use that. + if ((this.events.error && this.map.isDefine) || + req.onError !== defaultOnError) { + try { + exports = context.execCb(id, factory, depExports, exports); + } catch (e) { + err = e; + } + } else { + exports = context.execCb(id, factory, depExports, exports); + } + + // Favor return value over exports. If node/cjs in play, + // then will not have a return value anyway. Favor + // module.exports assignment over exports object. + if (this.map.isDefine && exports === undefined) { + cjsModule = this.module; + if (cjsModule) { + exports = cjsModule.exports; + } else if (this.usingExports) { + //exports already set the defined value. + exports = this.exports; + } + } + + if (err) { + err.requireMap = this.map; + err.requireModules = this.map.isDefine ? [this.map.id] : null; + err.requireType = this.map.isDefine ? 'define' : 'require'; + return onError((this.error = err)); + } + + } else { + //Just a literal value + exports = factory; + } + + this.exports = exports; + + if (this.map.isDefine && !this.ignore) { + defined[id] = exports; + + if (req.onResourceLoad) { + req.onResourceLoad(context, this.map, this.depMaps); + } + } + + //Clean up + cleanRegistry(id); + + this.defined = true; + } + + //Finished the define stage. Allow calling check again + //to allow define notifications below in the case of a + //cycle. + this.defining = false; + + if (this.defined && !this.defineEmitted) { + this.defineEmitted = true; + this.emit('defined', this.exports); + this.defineEmitComplete = true; + } + + } + }, + + callPlugin: function () { + var map = this.map, + id = map.id, + //Map already normalized the prefix. + pluginMap = makeModuleMap(map.prefix); + + //Mark this as a dependency for this plugin, so it + //can be traced for cycles. + this.depMaps.push(pluginMap); + + on(pluginMap, 'defined', bind(this, function (plugin) { + var load, normalizedMap, normalizedMod, + bundleId = getOwn(bundlesMap, this.map.id), + name = this.map.name, + parentName = this.map.parentMap ? this.map.parentMap.name : null, + localRequire = context.makeRequire(map.parentMap, { + enableBuildCallback: true + }); + + //If current map is not normalized, wait for that + //normalized name to load instead of continuing. + if (this.map.unnormalized) { + //Normalize the ID if the plugin allows it. + if (plugin.normalize) { + name = plugin.normalize(name, function (name) { + return normalize(name, parentName, true); + }) || ''; + } + + //prefix and name should already be normalized, no need + //for applying map config again either. + normalizedMap = makeModuleMap(map.prefix + '!' + name, + this.map.parentMap); + on(normalizedMap, + 'defined', bind(this, function (value) { + this.init([], function () { return value; }, null, { + enabled: true, + ignore: true + }); + })); + + normalizedMod = getOwn(registry, normalizedMap.id); + if (normalizedMod) { + //Mark this as a dependency for this plugin, so it + //can be traced for cycles. + this.depMaps.push(normalizedMap); + + if (this.events.error) { + normalizedMod.on('error', bind(this, function (err) { + this.emit('error', err); + })); + } + normalizedMod.enable(); + } + + return; + } + + //If a paths config, then just load that file instead to + //resolve the plugin, as it is built into that paths layer. + if (bundleId) { + this.map.url = context.nameToUrl(bundleId); + this.load(); + return; + } + + load = bind(this, function (value) { + this.init([], function () { return value; }, null, { + enabled: true + }); + }); + + load.error = bind(this, function (err) { + this.inited = true; + this.error = err; + err.requireModules = [id]; + + //Remove temp unnormalized modules for this module, + //since they will never be resolved otherwise now. + eachProp(registry, function (mod) { + if (mod.map.id.indexOf(id + '_unnormalized') === 0) { + cleanRegistry(mod.map.id); + } + }); + + onError(err); + }); + + //Allow plugins to load other code without having to know the + //context or how to 'complete' the load. + load.fromText = bind(this, function (text, textAlt) { + /*jslint evil: true */ + var moduleName = map.name, + moduleMap = makeModuleMap(moduleName), + hasInteractive = useInteractive; + + //As of 2.1.0, support just passing the text, to reinforce + //fromText only being called once per resource. Still + //support old style of passing moduleName but discard + //that moduleName in favor of the internal ref. + if (textAlt) { + text = textAlt; + } + + //Turn off interactive script matching for IE for any define + //calls in the text, then turn it back on at the end. + if (hasInteractive) { + useInteractive = false; + } + + //Prime the system by creating a module instance for + //it. + getModule(moduleMap); + + //Transfer any config to this other module. + if (hasProp(config.config, id)) { + config.config[moduleName] = config.config[id]; + } + + try { + req.exec(text); + } catch (e) { + return onError(makeError('fromtexteval', + 'fromText eval for ' + id + + ' failed: ' + e, + e, + [id])); + } + + if (hasInteractive) { + useInteractive = true; + } + + //Mark this as a dependency for the plugin + //resource + this.depMaps.push(moduleMap); + + //Support anonymous modules. + context.completeLoad(moduleName); + + //Bind the value of that module to the value for this + //resource ID. + localRequire([moduleName], load); + }); + + //Use parentName here since the plugin's name is not reliable, + //could be some weird string with no path that actually wants to + //reference the parentName's path. + plugin.load(map.name, localRequire, load, config); + })); + + context.enable(pluginMap, this); + this.pluginMaps[pluginMap.id] = pluginMap; + }, + + enable: function () { + enabledRegistry[this.map.id] = this; + this.enabled = true; + + //Set flag mentioning that the module is enabling, + //so that immediate calls to the defined callbacks + //for dependencies do not trigger inadvertent load + //with the depCount still being zero. + this.enabling = true; + + //Enable each dependency + each(this.depMaps, bind(this, function (depMap, i) { + var id, mod, handler; + + if (typeof depMap === 'string') { + //Dependency needs to be converted to a depMap + //and wired up to this module. + depMap = makeModuleMap(depMap, + (this.map.isDefine ? this.map : this.map.parentMap), + false, + !this.skipMap); + this.depMaps[i] = depMap; + + handler = getOwn(handlers, depMap.id); + + if (handler) { + this.depExports[i] = handler(this); + return; + } + + this.depCount += 1; + + on(depMap, 'defined', bind(this, function (depExports) { + this.defineDep(i, depExports); + this.check(); + })); + + if (this.errback) { + on(depMap, 'error', bind(this, this.errback)); + } + } + + id = depMap.id; + mod = registry[id]; + + //Skip special modules like 'require', 'exports', 'module' + //Also, don't call enable if it is already enabled, + //important in circular dependency cases. + if (!hasProp(handlers, id) && mod && !mod.enabled) { + context.enable(depMap, this); + } + })); + + //Enable each plugin that is used in + //a dependency + eachProp(this.pluginMaps, bind(this, function (pluginMap) { + var mod = getOwn(registry, pluginMap.id); + if (mod && !mod.enabled) { + context.enable(pluginMap, this); + } + })); + + this.enabling = false; + + this.check(); + }, + + on: function (name, cb) { + var cbs = this.events[name]; + if (!cbs) { + cbs = this.events[name] = []; + } + cbs.push(cb); + }, + + emit: function (name, evt) { + each(this.events[name], function (cb) { + cb(evt); + }); + if (name === 'error') { + //Now that the error handler was triggered, remove + //the listeners, since this broken Module instance + //can stay around for a while in the registry. + delete this.events[name]; + } + } + }; + + function callGetModule(args) { + //Skip modules already defined. + if (!hasProp(defined, args[0])) { + getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); + } + } + + function removeListener(node, func, name, ieName) { + //Favor detachEvent because of IE9 + //issue, see attachEvent/addEventListener comment elsewhere + //in this file. + if (node.detachEvent && !isOpera) { + //Probably IE. If not it will throw an error, which will be + //useful to know. + if (ieName) { + node.detachEvent(ieName, func); + } + } else { + node.removeEventListener(name, func, false); + } + } + + /** + * Given an event from a script node, get the requirejs info from it, + * and then removes the event listeners on the node. + * @param {Event} evt + * @returns {Object} + */ + function getScriptData(evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + var node = evt.currentTarget || evt.srcElement; + + //Remove the listeners once here. + removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); + removeListener(node, context.onScriptError, 'error'); + + return { + node: node, + id: node && node.getAttribute('data-requiremodule') + }; + } + + function intakeDefines() { + var args; + + //Any defined modules in the global queue, intake them now. + takeGlobalQueue(); + + //Make sure any remaining defQueue items get properly processed. + while (defQueue.length) { + args = defQueue.shift(); + if (args[0] === null) { + return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1])); + } else { + //args are id, deps, factory. Should be normalized by the + //define() function. + callGetModule(args); + } + } + } + + context = { + config: config, + contextName: contextName, + registry: registry, + defined: defined, + urlFetched: urlFetched, + defQueue: defQueue, + Module: Module, + makeModuleMap: makeModuleMap, + nextTick: req.nextTick, + onError: onError, + + /** + * Set a configuration for the context. + * @param {Object} cfg config object to integrate. + */ + configure: function (cfg) { + //Make sure the baseUrl ends in a slash. + if (cfg.baseUrl) { + if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { + cfg.baseUrl += '/'; + } + } + + //Save off the paths since they require special processing, + //they are additive. + var shim = config.shim, + objs = { + paths: true, + bundles: true, + config: true, + map: true + }; + + eachProp(cfg, function (value, prop) { + if (objs[prop]) { + if (!config[prop]) { + config[prop] = {}; + } + mixin(config[prop], value, true, true); + } else { + config[prop] = value; + } + }); + + //Reverse map the bundles + if (cfg.bundles) { + eachProp(cfg.bundles, function (value, prop) { + each(value, function (v) { + if (v !== prop) { + bundlesMap[v] = prop; + } + }); + }); + } + + //Merge shim + if (cfg.shim) { + eachProp(cfg.shim, function (value, id) { + //Normalize the structure + if (isArray(value)) { + value = { + deps: value + }; + } + if ((value.exports || value.init) && !value.exportsFn) { + value.exportsFn = context.makeShimExports(value); + } + shim[id] = value; + }); + config.shim = shim; + } + + //Adjust packages if necessary. + if (cfg.packages) { + each(cfg.packages, function (pkgObj) { + var location, name; + + pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj; + + name = pkgObj.name; + location = pkgObj.location; + if (location) { + config.paths[name] = pkgObj.location; + } + + //Save pointer to main module ID for pkg name. + //Remove leading dot in main, so main paths are normalized, + //and remove any trailing .js, since different package + //envs have different conventions: some use a module name, + //some use a file name. + config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main') + .replace(currDirRegExp, '') + .replace(jsSuffixRegExp, ''); + }); + } + + //If there are any "waiting to execute" modules in the registry, + //update the maps for them, since their info, like URLs to load, + //may have changed. + eachProp(registry, function (mod, id) { + //If module already has init called, since it is too + //late to modify them, and ignore unnormalized ones + //since they are transient. + if (!mod.inited && !mod.map.unnormalized) { + mod.map = makeModuleMap(id); + } + }); + + //If a deps array or a config callback is specified, then call + //require with those args. This is useful when require is defined as a + //config object before require.js is loaded. + if (cfg.deps || cfg.callback) { + context.require(cfg.deps || [], cfg.callback); + } + }, + + makeShimExports: function (value) { + function fn() { + var ret; + if (value.init) { + ret = value.init.apply(global, arguments); + } + return ret || (value.exports && getGlobal(value.exports)); + } + return fn; + }, + + makeRequire: function (relMap, options) { + options = options || {}; + + function localRequire(deps, callback, errback) { + var id, map, requireMod; + + if (options.enableBuildCallback && callback && isFunction(callback)) { + callback.__requireJsBuild = true; + } + + if (typeof deps === 'string') { + if (isFunction(callback)) { + //Invalid call + return onError(makeError('requireargs', 'Invalid require call'), errback); + } + + //If require|exports|module are requested, get the + //value for them from the special handlers. Caveat: + //this only works while module is being defined. + if (relMap && hasProp(handlers, deps)) { + return handlers[deps](registry[relMap.id]); + } + + //Synchronous access to one module. If require.get is + //available (as in the Node adapter), prefer that. + if (req.get) { + return req.get(context, deps, relMap, localRequire); + } + + //Normalize module name, if it contains . or .. + map = makeModuleMap(deps, relMap, false, true); + id = map.id; + + if (!hasProp(defined, id)) { + return onError(makeError('notloaded', 'Module name "' + + id + + '" has not been loaded yet for context: ' + + contextName + + (relMap ? '' : '. Use require([])'))); + } + return defined[id]; + } + + //Grab defines waiting in the global queue. + intakeDefines(); + + //Mark all the dependencies as needing to be loaded. + context.nextTick(function () { + //Some defines could have been added since the + //require call, collect them. + intakeDefines(); + + requireMod = getModule(makeModuleMap(null, relMap)); + + //Store if map config should be applied to this require + //call for dependencies. + requireMod.skipMap = options.skipMap; + + requireMod.init(deps, callback, errback, { + enabled: true + }); + + checkLoaded(); + }); + + return localRequire; + } + + mixin(localRequire, { + isBrowser: isBrowser, + + /** + * Converts a module name + .extension into an URL path. + * *Requires* the use of a module name. It does not support using + * plain URLs like nameToUrl. + */ + toUrl: function (moduleNamePlusExt) { + var ext, + index = moduleNamePlusExt.lastIndexOf('.'), + segment = moduleNamePlusExt.split('/')[0], + isRelative = segment === '.' || segment === '..'; + + //Have a file extension alias, and it is not the + //dots from a relative path. + if (index !== -1 && (!isRelative || index > 1)) { + ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); + moduleNamePlusExt = moduleNamePlusExt.substring(0, index); + } + + return context.nameToUrl(normalize(moduleNamePlusExt, + relMap && relMap.id, true), ext, true); + }, + + defined: function (id) { + return hasProp(defined, makeModuleMap(id, relMap, false, true).id); + }, + + specified: function (id) { + id = makeModuleMap(id, relMap, false, true).id; + return hasProp(defined, id) || hasProp(registry, id); + } + }); + + //Only allow undef on top level require calls + if (!relMap) { + localRequire.undef = function (id) { + //Bind any waiting define() calls to this context, + //fix for #408 + takeGlobalQueue(); + + var map = makeModuleMap(id, relMap, true), + mod = getOwn(registry, id); + + removeScript(id); + + delete defined[id]; + delete urlFetched[map.url]; + delete undefEvents[id]; + + //Clean queued defines too. Go backwards + //in array so that the splices do not + //mess up the iteration. + eachReverse(defQueue, function(args, i) { + if(args[0] === id) { + defQueue.splice(i, 1); + } + }); + + if (mod) { + //Hold on to listeners in case the + //module will be attempted to be reloaded + //using a different config. + if (mod.events.defined) { + undefEvents[id] = mod.events; + } + + cleanRegistry(id); + } + }; + } + + return localRequire; + }, + + /** + * Called to enable a module if it is still in the registry + * awaiting enablement. A second arg, parent, the parent module, + * is passed in for context, when this method is overridden by + * the optimizer. Not shown here to keep code compact. + */ + enable: function (depMap) { + var mod = getOwn(registry, depMap.id); + if (mod) { + getModule(depMap).enable(); + } + }, + + /** + * Internal method used by environment adapters to complete a load event. + * A load event could be a script load or just a load pass from a synchronous + * load call. + * @param {String} moduleName the name of the module to potentially complete. + */ + completeLoad: function (moduleName) { + var found, args, mod, + shim = getOwn(config.shim, moduleName) || {}, + shExports = shim.exports; + + takeGlobalQueue(); + + while (defQueue.length) { + args = defQueue.shift(); + if (args[0] === null) { + args[0] = moduleName; + //If already found an anonymous module and bound it + //to this name, then this is some other anon module + //waiting for its completeLoad to fire. + if (found) { + break; + } + found = true; + } else if (args[0] === moduleName) { + //Found matching define call for this script! + found = true; + } + + callGetModule(args); + } + + //Do this after the cycle of callGetModule in case the result + //of those calls/init calls changes the registry. + mod = getOwn(registry, moduleName); + + if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { + if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { + if (hasPathFallback(moduleName)) { + return; + } else { + return onError(makeError('nodefine', + 'No define call for ' + moduleName, + null, + [moduleName])); + } + } else { + //A script that does not call define(), so just simulate + //the call for it. + callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); + } + } + + checkLoaded(); + }, + + /** + * Converts a module name to a file path. Supports cases where + * moduleName may actually be just an URL. + * Note that it **does not** call normalize on the moduleName, + * it is assumed to have already been normalized. This is an + * internal API, not a public one. Use toUrl for the public API. + */ + nameToUrl: function (moduleName, ext, skipExt) { + var paths, syms, i, parentModule, url, + parentPath, bundleId, + pkgMain = getOwn(config.pkgs, moduleName); + + if (pkgMain) { + moduleName = pkgMain; + } + + bundleId = getOwn(bundlesMap, moduleName); + + if (bundleId) { + return context.nameToUrl(bundleId, ext, skipExt); + } + + //If a colon is in the URL, it indicates a protocol is used and it is just + //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) + //or ends with .js, then assume the user meant to use an url and not a module id. + //The slash is important for protocol-less URLs as well as full paths. + if (req.jsExtRegExp.test(moduleName)) { + //Just a plain path, not module name lookup, so just return it. + //Add extension if it is included. This is a bit wonky, only non-.js things pass + //an extension, this method probably needs to be reworked. + url = moduleName + (ext || ''); + } else { + //A module that needs to be converted to a path. + paths = config.paths; + + syms = moduleName.split('/'); + //For each module name segment, see if there is a path + //registered for it. Start with most specific name + //and work up from it. + for (i = syms.length; i > 0; i -= 1) { + parentModule = syms.slice(0, i).join('/'); + + parentPath = getOwn(paths, parentModule); + if (parentPath) { + //If an array, it means there are a few choices, + //Choose the one that is desired + if (isArray(parentPath)) { + parentPath = parentPath[0]; + } + syms.splice(0, i, parentPath); + break; + } + } + + //Join the path parts together, then figure out if baseUrl is needed. + url = syms.join('/'); + url += (ext || (/^data\:|\?/.test(url) || skipExt ? '' : '.js')); + url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; + } + + return config.urlArgs ? url + + ((url.indexOf('?') === -1 ? '?' : '&') + + config.urlArgs) : url; + }, + + //Delegates to req.load. Broken out as a separate function to + //allow overriding in the optimizer. + load: function (id, url) { + req.load(context, id, url); + }, + + /** + * Executes a module callback function. Broken out as a separate function + * solely to allow the build system to sequence the files in the built + * layer in the right sequence. + * + * @private + */ + execCb: function (name, callback, args, exports) { + return callback.apply(exports, args); + }, + + /** + * callback for script loads, used to check status of loading. + * + * @param {Event} evt the event from the browser for the script + * that was loaded. + */ + onScriptLoad: function (evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + if (evt.type === 'load' || + (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { + //Reset interactive script so a script node is not held onto for + //to long. + interactiveScript = null; + + //Pull out the name of the module and the context. + var data = getScriptData(evt); + context.completeLoad(data.id); + } + }, + + /** + * Callback for script errors. + */ + onScriptError: function (evt) { + var data = getScriptData(evt); + if (!hasPathFallback(data.id)) { + return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id])); + } + } + }; + + context.require = context.makeRequire(); + return context; + } + + /** + * Main entry point. + * + * If the only argument to require is a string, then the module that + * is represented by that string is fetched for the appropriate context. + * + * If the first argument is an array, then it will be treated as an array + * of dependency string names to fetch. An optional function callback can + * be specified to execute when all of those dependencies are available. + * + * Make a local req variable to help Caja compliance (it assumes things + * on a require that are not standardized), and to give a short + * name for minification/local scope use. + */ + req = requirejs = function (deps, callback, errback, optional) { + + //Find the right context, use default + var context, config, + contextName = defContextName; + + // Determine if have config object in the call. + if (!isArray(deps) && typeof deps !== 'string') { + // deps is a config object + config = deps; + if (isArray(callback)) { + // Adjust args if there are dependencies + deps = callback; + callback = errback; + errback = optional; + } else { + deps = []; + } + } + + if (config && config.context) { + contextName = config.context; + } + + context = getOwn(contexts, contextName); + if (!context) { + context = contexts[contextName] = req.s.newContext(contextName); + } + + if (config) { + context.configure(config); + } + + return context.require(deps, callback, errback); + }; + + /** + * Support require.config() to make it easier to cooperate with other + * AMD loaders on globally agreed names. + */ + req.config = function (config) { + return req(config); + }; + + /** + * Execute something after the current tick + * of the event loop. Override for other envs + * that have a better solution than setTimeout. + * @param {Function} fn function to execute later. + */ + req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { + setTimeout(fn, 4); + } : function (fn) { fn(); }; + + /** + * Export require as a global, but only if it does not already exist. + */ + if (!require) { + require = req; + } + + req.version = version; + + //Used to filter out dependencies that are already paths. + req.jsExtRegExp = /^\/|:|\?|\.js$/; + req.isBrowser = isBrowser; + s = req.s = { + contexts: contexts, + newContext: newContext + }; + + //Create default context. + req({}); + + //Exports some context-sensitive methods on global require. + each([ + 'toUrl', + 'undef', + 'defined', + 'specified' + ], function (prop) { + //Reference from contexts instead of early binding to default context, + //so that during builds, the latest instance of the default context + //with its config gets used. + req[prop] = function () { + var ctx = contexts[defContextName]; + return ctx.require[prop].apply(ctx, arguments); + }; + }); + + if (isBrowser) { + head = s.head = document.getElementsByTagName('head')[0]; + //If BASE tag is in play, using appendChild is a problem for IE6. + //When that browser dies, this can be removed. Details in this jQuery bug: + //http://dev.jquery.com/ticket/2709 + baseElement = document.getElementsByTagName('base')[0]; + if (baseElement) { + head = s.head = baseElement.parentNode; + } + } + + /** + * Any errors that require explicitly generates will be passed to this + * function. Intercept/override it if you want custom error handling. + * @param {Error} err the error object. + */ + req.onError = defaultOnError; + + /** + * Creates the node for the load command. Only used in browser envs. + */ + req.createNode = function (config, moduleName, url) { + var node = config.xhtml ? + document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : + document.createElement('script'); + node.type = config.scriptType || 'text/javascript'; + node.charset = 'utf-8'; + node.async = true; + return node; + }; + + /** + * Does the request to load a module for the browser case. + * Make this a separate function to allow other environments + * to override it. + * + * @param {Object} context the require context to find state. + * @param {String} moduleName the name of the module. + * @param {Object} url the URL to the module. + */ + req.load = function (context, moduleName, url) { + var config = (context && context.config) || {}, + node; + if (isBrowser) { + //In the browser so use a script tag + node = req.createNode(config, moduleName, url); + + node.setAttribute('data-requirecontext', context.contextName); + node.setAttribute('data-requiremodule', moduleName); + + //Set up load listener. Test attachEvent first because IE9 has + //a subtle issue in its addEventListener and script onload firings + //that do not match the behavior of all other browsers with + //addEventListener support, which fire the onload event for a + //script right after the script execution. See: + //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution + //UNFORTUNATELY Opera implements attachEvent but does not follow the script + //script execution mode. + if (node.attachEvent && + //Check if node.attachEvent is artificially added by custom script or + //natively supported by browser + //read https://github.com/jrburke/requirejs/issues/187 + //if we can NOT find [native code] then it must NOT natively supported. + //in IE8, node.attachEvent does not have toString() + //Note the test for "[native code" with no closing brace, see: + //https://github.com/jrburke/requirejs/issues/273 + !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && + !isOpera) { + //Probably IE. IE (at least 6-8) do not fire + //script onload right after executing the script, so + //we cannot tie the anonymous define call to a name. + //However, IE reports the script as being in 'interactive' + //readyState at the time of the define call. + useInteractive = true; + + node.attachEvent('onreadystatechange', context.onScriptLoad); + //It would be great to add an error handler here to catch + //404s in IE9+. However, onreadystatechange will fire before + //the error handler, so that does not help. If addEventListener + //is used, then IE will fire error before load, but we cannot + //use that pathway given the connect.microsoft.com issue + //mentioned above about not doing the 'script execute, + //then fire the script load event listener before execute + //next script' that other browsers do. + //Best hope: IE10 fixes the issues, + //and then destroys all installs of IE 6-9. + //node.attachEvent('onerror', context.onScriptError); + } else { + node.addEventListener('load', context.onScriptLoad, false); + node.addEventListener('error', context.onScriptError, false); + } + node.src = url; + + //For some cache cases in IE 6-8, the script executes before the end + //of the appendChild execution, so to tie an anonymous define + //call to the module name (which is stored on the node), hold on + //to a reference to this node, but clear after the DOM insertion. + currentlyAddingScript = node; + if (baseElement) { + head.insertBefore(node, baseElement); + } else { + head.appendChild(node); + } + currentlyAddingScript = null; + + return node; + } else if (isWebWorker) { + try { + //In a web worker, use importScripts. This is not a very + //efficient use of importScripts, importScripts will block until + //its script is downloaded and evaluated. However, if web workers + //are in play, the expectation that a build has been done so that + //only one script needs to be loaded anyway. This may need to be + //reevaluated if other use cases become common. + importScripts(url); + + //Account for anonymous modules + context.completeLoad(moduleName); + } catch (e) { + context.onError(makeError('importscripts', + 'importScripts failed for ' + + moduleName + ' at ' + url, + e, + [moduleName])); + } + } + }; + + function getInteractiveScript() { + if (interactiveScript && interactiveScript.readyState === 'interactive') { + return interactiveScript; + } + + eachReverse(scripts(), function (script) { + if (script.readyState === 'interactive') { + return (interactiveScript = script); + } + }); + return interactiveScript; + } + + //Look for a data-main script attribute, which could also adjust the baseUrl. + if (isBrowser && !cfg.skipDataMain) { + //Figure out baseUrl. Get it from the script tag with require.js in it. + eachReverse(scripts(), function (script) { + //Set the 'head' where we can append children by + //using the script's parent. + if (!head) { + head = script.parentNode; + } + + //Look for a data-main attribute to set main script for the page + //to load. If it is there, the path to data main becomes the + //baseUrl, if it is not already set. + dataMain = script.getAttribute('data-main'); + if (dataMain) { + //Preserve dataMain in case it is a path (i.e. contains '?') + mainScript = dataMain; + + //Set final baseUrl if there is not already an explicit one. + if (!cfg.baseUrl) { + //Pull off the directory of data-main for use as the + //baseUrl. + src = mainScript.split('/'); + mainScript = src.pop(); + subPath = src.length ? src.join('/') + '/' : './'; + + cfg.baseUrl = subPath; + } + + //Strip off any trailing .js since mainScript is now + //like a module name. + mainScript = mainScript.replace(jsSuffixRegExp, ''); + + //If mainScript is still a path, fall back to dataMain + if (req.jsExtRegExp.test(mainScript)) { + mainScript = dataMain; + } + + //Put the data-main script in the files to load. + cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript]; + + return true; + } + }); + } + + /** + * The function that handles definitions of modules. Differs from + * require() in that a string for the module should be the first argument, + * and the function to execute after dependencies are loaded should + * return a value to define the module corresponding to the first argument's + * name. + */ + define = function (name, deps, callback) { + var node, context; + + //Allow for anonymous modules + if (typeof name !== 'string') { + //Adjust args appropriately + callback = deps; + deps = name; + name = null; + } + + //This module may not have dependencies + if (!isArray(deps)) { + callback = deps; + deps = null; + } + + //If no name, and callback is a function, then figure out if it a + //CommonJS thing with dependencies. + if (!deps && isFunction(callback)) { + deps = []; + //Remove comments from the callback string, + //look for require calls, and pull them into the dependencies, + //but only if there are function args. + if (callback.length) { + callback + .toString() + .replace(commentRegExp, '') + .replace(cjsRequireRegExp, function (match, dep) { + deps.push(dep); + }); + + //May be a CommonJS thing even without require calls, but still + //could use exports, and module. Avoid doing exports and module + //work though if it just needs require. + //REQUIRES the function to expect the CommonJS variables in the + //order listed below. + deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); + } + } + + //If in IE 6-8 and hit an anonymous define() call, do the interactive + //work. + if (useInteractive) { + node = currentlyAddingScript || getInteractiveScript(); + if (node) { + if (!name) { + name = node.getAttribute('data-requiremodule'); + } + context = contexts[node.getAttribute('data-requirecontext')]; + } + } + + //Always save off evaluating the def call until the script onload handler. + //This allows multiple modules to be in a file without prematurely + //tracing dependencies, and allows for anonymous module support, + //where the module name is not known until the script onload event + //occurs. If no context, use the global queue, and get it processed + //in the onscript load callback. + (context ? context.defQueue : globalDefQueue).push([name, deps, callback]); + }; + + define.amd = { + jQuery: true + }; + + + /** + * Executes the text. Normally just uses eval, but can be modified + * to use a better, environment-specific call. Only used for transpiling + * loader plugins, not for plain JS modules. + * @param {String} text the text to execute/evaluate. + */ + req.exec = function (text) { + /*jslint evil: true */ + return eval(text); + }; + + //Set up with config info. + req(cfg); +}(this)); diff --git a/demo/kitchen-sink/styles.css b/demo/kitchen-sink/styles.css new file mode 100644 index 00000000..3f46f701 --- /dev/null +++ b/demo/kitchen-sink/styles.css @@ -0,0 +1,55 @@ +html { + height: 100%; + width: 100%; + overflow: hidden; +} + +body { + overflow: hidden; + margin: 0; + padding: 0; + height: 100%; + width: 100%; + font-family: Arial, Helvetica, sans-serif, Tahoma, Verdana, sans-serif; + font-size: 12px; + background: rgb(14, 98, 165); + color: white; +} + +#c9-logo, #ace-logo { + padding: 0; + border: none; +} + +#editor-container { + position: absolute; + top: 0px; + left: 280px; + bottom: 0px; + right: 0px; + background: white; +} + +#controls { + padding: 5px; +} + +#controls td { + text-align: right; +} + +#controls td + td { + text-align: left; +} +.ace_status-indicator { + color: gray; + position: absolute; + right: 0; + border-left: 1px solid; +} + +/* .ace_text-input { + z-index: 10!important; + opacity: 1!important; + background: rgb(84, 0, 255)!important; +}*/ diff --git a/demo/kitchen-sink/token_tooltip.js b/demo/kitchen-sink/token_tooltip.js new file mode 100644 index 00000000..9e607f69 --- /dev/null +++ b/demo/kitchen-sink/token_tooltip.js @@ -0,0 +1,156 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var dom = require("ace/lib/dom"); +var oop = require("ace/lib/oop"); +var event = require("ace/lib/event"); +var Range = require("ace/range").Range; +var Tooltip = require("ace/tooltip").Tooltip; + +function TokenTooltip (editor) { + if (editor.tokenTooltip) + return; + Tooltip.call(this, editor.container); + editor.tokenTooltip = this; + this.editor = editor; + + this.update = this.update.bind(this); + this.onMouseMove = this.onMouseMove.bind(this); + this.onMouseOut = this.onMouseOut.bind(this); + event.addListener(editor.renderer.scroller, "mousemove", this.onMouseMove); + event.addListener(editor.renderer.content, "mouseout", this.onMouseOut); +} + +oop.inherits(TokenTooltip, Tooltip); + +(function(){ + this.token = {}; + this.range = new Range(); + + this.update = function() { + this.$timer = null; + + var r = this.editor.renderer; + if (this.lastT - (r.timeStamp || 0) > 1000) { + r.rect = null; + r.timeStamp = this.lastT; + this.maxHeight = window.innerHeight; + this.maxWidth = window.innerWidth; + } + + var canvasPos = r.rect || (r.rect = r.scroller.getBoundingClientRect()); + var offset = (this.x + r.scrollLeft - canvasPos.left - r.$padding) / r.characterWidth; + var row = Math.floor((this.y + r.scrollTop - canvasPos.top) / r.lineHeight); + var col = Math.round(offset); + + var screenPos = {row: row, column: col, side: offset - col > 0 ? 1 : -1}; + var session = this.editor.session; + var docPos = session.screenToDocumentPosition(screenPos.row, screenPos.column); + var token = session.getTokenAt(docPos.row, docPos.column); + + if (!token && !session.getLine(docPos.row)) { + token = { + type: "", + value: "", + state: session.bgTokenizer.getState(0) + }; + } + if (!token) { + session.removeMarker(this.marker); + this.hide(); + return; + } + + var tokenText = token.type; + if (token.state) + tokenText += "|" + token.state; + if (token.merge) + tokenText += "\n merge"; + if (token.stateTransitions) + tokenText += "\n " + token.stateTransitions.join("\n "); + + if (this.tokenText != tokenText) { + this.setText(tokenText); + this.width = this.getWidth(); + this.height = this.getHeight(); + this.tokenText = tokenText; + } + + this.show(null, this.x, this.y); + + this.token = token; + session.removeMarker(this.marker); + this.range = new Range(docPos.row, token.start, docPos.row, token.start + token.value.length); + this.marker = session.addMarker(this.range, "ace_bracket", "text"); + }; + + this.onMouseMove = function(e) { + this.x = e.clientX; + this.y = e.clientY; + if (this.isOpen) { + this.lastT = e.timeStamp; + this.setPosition(this.x, this.y); + } + if (!this.$timer) + this.$timer = setTimeout(this.update, 100); + }; + + this.onMouseOut = function(e) { + if (e && e.currentTarget.contains(e.relatedTarget)) + return; + this.hide(); + this.editor.session.removeMarker(this.marker); + this.$timer = clearTimeout(this.$timer); + }; + + this.setPosition = function(x, y) { + if (x + 10 + this.width > this.maxWidth) + x = window.innerWidth - this.width - 10; + if (y > window.innerHeight * 0.75 || y + 20 + this.height > this.maxHeight) + y = y - this.height - 30; + + Tooltip.prototype.setPosition.call(this, x + 10, y + 20); + }; + + this.destroy = function() { + this.onMouseOut(); + event.removeListener(this.editor.renderer.scroller, "mousemove", this.onMouseMove); + event.removeListener(this.editor.renderer.content, "mouseout", this.onMouseOut); + delete this.editor.tokenTooltip; + }; + +}).call(TokenTooltip.prototype); + +exports.TokenTooltip = TokenTooltip; + +}); diff --git a/demo/kitchen-sink/util.js b/demo/kitchen-sink/util.js new file mode 100644 index 00000000..c4b74f38 --- /dev/null +++ b/demo/kitchen-sink/util.js @@ -0,0 +1,235 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var dom = require("ace/lib/dom"); +var event = require("ace/lib/event"); + +var EditSession = require("ace/edit_session").EditSession; +var UndoManager = require("ace/undomanager").UndoManager; +var Renderer = require("ace/virtual_renderer").VirtualRenderer; +var Editor = require("ace/editor").Editor; +var MultiSelect = require("ace/multi_select").MultiSelect; + +exports.createEditor = function(el) { + return new Editor(new Renderer(el)); +}; + +exports.createSplitEditor = function(el) { + if (typeof(el) == "string") + el = document.getElementById(el); + + var e0 = document.createElement("div"); + var s = document.createElement("splitter"); + var e1 = document.createElement("div"); + el.appendChild(e0); + el.appendChild(e1); + el.appendChild(s); + e0.style.position = e1.style.position = s.style.position = "absolute"; + el.style.position = "relative"; + var split = {$container: el}; + + split.editor0 = split[0] = new Editor(new Renderer(e0)); + split.editor1 = split[1] = new Editor(new Renderer(e1)); + split.splitter = s; + + s.ratio = 0.5; + + split.resize = function resize(){ + var height = el.parentNode.clientHeight - el.offsetTop; + var total = el.clientWidth; + var w1 = total * s.ratio; + var w2 = total * (1- s.ratio); + s.style.left = w1 - 1 + "px"; + s.style.height = el.style.height = height + "px"; + + var st0 = split[0].container.style; + var st1 = split[1].container.style; + st0.width = w1 + "px"; + st1.width = w2 + "px"; + st0.left = 0 + "px"; + st1.left = w1 + "px"; + + st0.top = st1.top = "0px"; + st0.height = st1.height = height + "px"; + + split[0].resize(); + split[1].resize(); + }; + + split.onMouseDown = function(e) { + var rect = el.getBoundingClientRect(); + var x = e.clientX; + var y = e.clientY; + + var button = e.button; + if (button !== 0) { + return; + } + + var onMouseMove = function(e) { + x = e.clientX; + y = e.clientY; + }; + var onResizeEnd = function(e) { + clearInterval(timerId); + }; + + var onResizeInterval = function() { + s.ratio = (x - rect.left) / rect.width; + split.resize(); + }; + + event.capture(s, onMouseMove, onResizeEnd); + var timerId = setInterval(onResizeInterval, 40); + + return e.preventDefault(); + }; + + + + event.addListener(s, "mousedown", split.onMouseDown); + event.addListener(window, "resize", split.resize); + split.resize(); + return split; +}; + +/***************************/ +exports.stripLeadingComments = function(str) { + if(str.slice(0,2)=='/*') { + var j = str.indexOf('*/')+2; + str = str.substr(j); + } + return str.trim() + "\n"; +}; + +/***************************/ +exports.saveOption = function(el, val) { + if (!el.onchange && !el.onclick) + return; + + if ("checked" in el) { + if (val !== undefined) + el.checked = val; + + localStorage && localStorage.setItem(el.id, el.checked ? 1 : 0); + } + else { + if (val !== undefined) + el.value = val; + + localStorage && localStorage.setItem(el.id, el.value); + } +}; + +exports.bindCheckbox = function(id, callback, noInit) { + if (typeof id == "string") + var el = document.getElementById(id); + else { + var el = id; + id = el.id; + } + var el = document.getElementById(id); + if (localStorage && localStorage.getItem(id)) + el.checked = localStorage.getItem(id) == "1"; + + var onCheck = function() { + callback(!!el.checked); + exports.saveOption(el); + }; + el.onclick = onCheck; + noInit || onCheck(); + return el; +}; + +exports.bindDropdown = function(id, callback, noInit) { + if (typeof id == "string") + var el = document.getElementById(id); + else { + var el = id; + id = el.id; + } + if (localStorage && localStorage.getItem(id)) + el.value = localStorage.getItem(id); + + var onChange = function() { + callback(el.value); + exports.saveOption(el); + }; + + el.onchange = onChange; + noInit || onChange(); +}; + +exports.fillDropdown = function(el, values) { + if (typeof el == "string") + el = document.getElementById(el); + + dropdown(values).forEach(function(e) { + el.appendChild(e); + }); +}; + +function elt(tag, attributes, content) { + var el = dom.createElement(tag); + if (typeof content == "string") { + el.appendChild(document.createTextNode(content)); + } else if (content) { + content.forEach(function(ch) { + el.appendChild(ch); + }); + } + + for (var i in attributes) + el.setAttribute(i, attributes[i]); + return el; +} + +function optgroup(values) { + return values.map(function(item) { + if (typeof item == "string") + item = {name: item, caption: item}; + return elt("option", {value: item.value || item.name}, item.caption || item.desc); + }); +} + +function dropdown(values) { + if (Array.isArray(values)) + return optgroup(values); + + return Object.keys(values).map(function(i) { + return elt("optgroup", {"label": i}, optgroup(values[i])); + }); +} + + +}); diff --git a/demo/logo.png b/demo/logo.png deleted file mode 100644 index 58df6062..00000000 Binary files a/demo/logo.png and /dev/null differ diff --git a/demo/modelist.html b/demo/modelist.html new file mode 100644 index 00000000..9b4b6039 --- /dev/null +++ b/demo/modelist.html @@ -0,0 +1,51 @@ + + + + + + ACE Editor Modelist Demo + + + + +
    
    +    
    +
    +
    +
    +
    +
    +
    diff --git a/demo/r.js/build.js b/demo/r.js/build.js
    new file mode 100644
    index 00000000..028d2234
    --- /dev/null
    +++ b/demo/r.js/build.js
    @@ -0,0 +1,20 @@
    +({
    +    optimize: "none",
    +    preserveLicenseComments: false,
    +    name: "node_modules/almond/almond",
    +    baseUrl: "../../",
    +    paths: {
    +        ace : "lib/ace",
    +        demo: "demo/kitchen-sink"        
    +    },
    +    packages: [
    +    ],
    +    include: [
    +        "ace/ace"
    +    ],
    +    exclude: [
    +    ],
    +    out: "./packed.js",
    +    useStrict: true,
    +    wrap: false
    +})
    \ No newline at end of file
    diff --git a/demo/r.js/editor.html b/demo/r.js/editor.html
    new file mode 100644
    index 00000000..9f7a47bf
    --- /dev/null
    +++ b/demo/r.js/editor.html
    @@ -0,0 +1,36 @@
    +
    +
    +
    +
    +    Editor
    +        
    +
    +
    +    
    + + + +
    +
    +        
    + demo showing Ace usage with r.js: + + install r.js and almond + and run `r.js -o demo/r.js/build.js` + + note that you also need ace/build/src to lazy load modes and themes + require("ace/config").set("basePath", "../../build/src"); + require("ace/config").set("packaged", true); +
    +
    + + + + + diff --git a/demo/require.js b/demo/require.js deleted file mode 100644 index 1f94622e..00000000 --- a/demo/require.js +++ /dev/null @@ -1,2496 +0,0 @@ -/** vim: et:ts=4:sw=4:sts=4 - * @license RequireJS Copyright (c) 2010, The Dojo Foundation All Rights Reserved. - * Available via the MIT or new BSD license. - * see: http://github.com/jrburke/requirejs for details - */ -//laxbreak is true to allow build pragmas to change some statements. -/*jslint plusplus: false, nomen: false, laxbreak: true, regexp: false */ -/*global window: false, document: false, navigator: false, -setTimeout: false, traceDeps: true, clearInterval: false, self: false, -setInterval: false, importScripts: false, jQuery: false */ - - -var require, define; -(function () { - //Change this version number for each release. - var version = "0.14.5+", - empty = {}, s, - i, defContextName = "_", contextLoads = [], - scripts, script, rePkg, src, m, dataMain, cfg = {}, setReadyState, - commentRegExp = /(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, - cjsRequireRegExp = /require\(["']([\w\!\-_\.\/]+)["']\)/g, - main, - isBrowser = !!(typeof window !== "undefined" && navigator && document), - isWebWorker = !isBrowser && typeof importScripts !== "undefined", - //PS3 indicates loaded and complete, but need to wait for complete - //specifically. Sequence is "loading", "loaded", execution, - // then "complete". The UA check is unfortunate, but not sure how - //to feature test w/o causing perf issues. - readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? /^complete$/ : /^(complete|loaded)$/, - ostring = Object.prototype.toString, - ap = Array.prototype, - aps = ap.slice, scrollIntervalId, req, baseElement, - defQueue = [], useInteractive = false, currentlyAddingScript; - - function isFunction(it) { - return ostring.call(it) === "[object Function]"; - } - - //Check for an existing version of require. If so, then exit out. Only allow - //one version of require to be active in a page. However, allow for a require - //config object, just exit quickly if require is an actual function. - if (typeof require !== "undefined") { - if (isFunction(require)) { - return; - } else { - //assume it is a config object. - cfg = require; - } - } - - /** - * Calls a method on a plugin. The obj object should have two property, - * name: the name of the method to call on the plugin - * args: the arguments to pass to the plugin method. - */ - function callPlugin(prefix, context, obj) { - //Call the plugin, or load it. - var plugin = s.plugins.defined[prefix], waiting; - if (plugin) { - plugin[obj.name].apply(null, obj.args); - } else { - //Put the call in the waiting call BEFORE requiring the module, - //since the require could be synchronous in some environments, - //like builds - waiting = s.plugins.waiting[prefix] || (s.plugins.waiting[prefix] = []); - waiting.push(obj); - - //Load the module - req(["require/" + prefix], context.contextName); - } - } - - /** - * Convenience method to call main for a require.def call that was put on - * hold in the defQueue. - */ - function callDefMain(args, context) { - main.apply(req, args); - //Mark the module loaded. Must do it here in addition - //to doing it in require.def in case a script does - //not call require.def - context.loaded[args[0]] = true; - } - - /** - * Used to set up package paths from a packagePaths or packages config object. - * @param {Object} packages the object to store the new package config - * @param {Array} currentPackages an array of packages to configure - * @param {String} [dir] a prefix dir to use. - */ - function configurePackageDir(packages, currentPackages, dir) { - var i, location, pkgObj; - for (i = 0; (pkgObj = currentPackages[i]); i++) { - pkgObj = typeof pkgObj === "string" ? { name: pkgObj } : pkgObj; - location = pkgObj.location; - - //Add dir to the path, but avoid paths that start with a slash - //or have a colon (indicates a protocol) - if (dir && (!location || (location.indexOf("/") !== 0 && location.indexOf(":") === -1))) { - pkgObj.location = dir + "/" + (pkgObj.location || pkgObj.name); - } - - //Normalize package paths. - pkgObj.location = pkgObj.location || pkgObj.name; - pkgObj.lib = pkgObj.lib || "lib"; - pkgObj.main = pkgObj.main || "main"; - - packages[pkgObj.name] = pkgObj; - } - } - - /** - * Determine if priority loading is done. If so clear the priorityWait - */ - function isPriorityDone(context) { - var priorityDone = true, - priorityWait = context.config.priorityWait, - priorityName, i; - if (priorityWait) { - for (i = 0; (priorityName = priorityWait[i]); i++) { - if (!context.loaded[priorityName]) { - priorityDone = false; - break; - } - } - if (priorityDone) { - delete context.config.priorityWait; - } - } - return priorityDone; - } - - /** - * Resumes tracing of dependencies and then checks if everything is loaded. - */ - function resume(context) { - var args, i, paused = s.paused; - if (context.scriptCount <= 0) { - //Synchronous envs will push the number below zero with the - //decrement above, be sure to set it back to zero for good measure. - //require() calls that also do not end up loading scripts could - //push the number negative too. - context.scriptCount = 0; - - //Make sure any remaining defQueue items get properly processed. - while (defQueue.length) { - args = defQueue.shift(); - if (args[0] === null) { - req.onError(new Error('Mismatched anonymous require.def modules')); - } else { - callDefMain(args, context); - } - } - - //Skip the resume if current context is in priority wait. - if (context.config.priorityWait && !isPriorityDone(context)) { - return; - } - - if (paused.length) { - for (i = 0; (args = paused[i]); i++) { - req.checkDeps.apply(req, args); - } - } - - req.checkLoaded(s.ctxName); - } - } - - /** - * Main entry point. - * - * If the only argument to require is a string, then the module that - * is represented by that string is fetched for the appropriate context. - * - * If the first argument is an array, then it will be treated as an array - * of dependency string names to fetch. An optional function callback can - * be specified to execute when all of those dependencies are available. - */ - require = function (deps, callback, contextName, relModuleName) { - var context, config; - if (typeof deps === "string" && !isFunction(callback)) { - //Just return the module wanted. In this scenario, the - //second arg (if passed) is just the contextName. - return require.get(deps, callback, contextName, relModuleName); - } - // Dependencies first - if (!require.isArray(deps)) { - // deps is a config object - config = deps; - if (require.isArray(callback)) { - // Adjust args if there are dependencies - deps = callback; - callback = contextName; - contextName = relModuleName; - relModuleName = arguments[4]; - } else { - deps = []; - } - } - - main(null, deps, callback, config, contextName, relModuleName); - - //If the require call does not trigger anything new to load, - //then resume the dependency processing. Context will be undefined - //on first run of require. - context = s.contexts[(contextName || (config && config.context) || s.ctxName)]; - if (context && context.scriptCount === 0) { - resume(context); - } - //Returning undefined for Spidermonky strict checking in Komodo - return undefined; - }; - - //Alias for caja compliance internally - - //specifically: "Dynamically computed names should use require.async()" - //even though this spec isn't really decided on. - //Since it is here, use this alias to make typing shorter. - req = require; - - /** - * Any errors that require explicitly generates will be passed to this - * function. Intercept/override it if you want custom error handling. - * If you do override it, this method should *always* throw an error - * to stop the execution flow correctly. Otherwise, other weird errors - * will occur. - * @param {Error} err the error object. - */ - req.onError = function (err) { - throw err; - }; - - /** - * The function that handles definitions of modules. Differs from - * require() in that a string for the module should be the first argument, - * and the function to execute after dependencies are loaded should - * return a value to define the module corresponding to the first argument's - * name. - */ - define = req.def = function (name, deps, callback, contextName) { - var i, scripts, script, node = currentlyAddingScript; - - //Allow for anonymous functions - if (typeof name !== 'string') { - //Adjust args appropriately - contextName = callback; - callback = deps; - deps = name; - name = null; - } - - //This module may not have dependencies - if (!req.isArray(deps)) { - contextName = callback; - callback = deps; - deps = []; - } - - //If no name, and callback is a function, then figure out if it a - //CommonJS thing with dependencies. - if (!name && !deps.length && req.isFunction(callback)) { - //Remove comments from the callback string, - //look for require calls, and pull them into the dependencies. - callback - .toString() - .replace(commentRegExp, "") - .replace(cjsRequireRegExp, function (match, dep) { - deps.push(dep); - }); - - //May be a CommonJS thing even without require calls, but still - //could use exports, and such, so always add those as dependencies. - //This is a bit wasteful for RequireJS modules that do not need - //an exports or module object, but erring on side of safety. - //REQUIRES the function to expect the CommonJS variables in the - //order listed below. - deps = ["require", "exports", "module"].concat(deps); - } - - //If in IE 6-8 and hit an anonymous require.def call, do the interactive/ - //currentlyAddingScript scripts stuff. - if (!name && useInteractive) { - scripts = document.getElementsByTagName('script'); - for (i = scripts.length - 1; i > -1 && (script = scripts[i]); i--) { - if (script.readyState === 'interactive') { - node = script; - break; - } - } - if (!node) { - req.onError(new Error("ERROR: No matching script interactive for " + callback)); - } - - name = node.getAttribute("data-requiremodule"); - } - - if (typeof name === 'string') { - //Do not try to auto-register a jquery later. - //Do this work here and in main, since for IE/useInteractive, this function - //is the earliest touch-point. - s.contexts[s.ctxName].jQueryDef = (name === "jquery"); - } - - //Always save off evaluating the def call until the script onload handler. - //This allows multiple modules to be in a file without prematurely - //tracing dependencies, and allows for anonymous module support, - //where the module name is not known until the script onload event - //occurs. - defQueue.push([name, deps, callback, null, contextName]); - }; - - main = function (name, deps, callback, config, contextName, relModuleName) { - //Grab the context, or create a new one for the given context name. - var context, newContext, loaded, pluginPrefix, - canSetContext, prop, newLength, outDeps, mods, paths, index, i, - deferMods, deferModArgs, lastModArg, waitingName, packages, - packagePaths; - - contextName = contextName ? contextName : (config && config.context ? config.context : s.ctxName); - context = s.contexts[contextName]; - - if (name) { - // Pull off any plugin prefix. - index = name.indexOf("!"); - if (index !== -1) { - pluginPrefix = name.substring(0, index); - name = name.substring(index + 1, name.length); - } else { - //Could be that the plugin name should be auto-applied. - //Used by i18n plugin to enable anonymous i18n modules, but - //still associating the auto-generated name with the i18n plugin. - pluginPrefix = context.defPlugin[name]; - } - - - //If module already defined for context, or already waiting to be - //evaluated, leave. - waitingName = context.waiting[name]; - if (context && (context.defined[name] || (waitingName && waitingName !== ap[name]))) { - return; - } - } - - if (contextName !== s.ctxName) { - //If nothing is waiting on being loaded in the current context, - //then switch s.ctxName to current contextName. - loaded = (s.contexts[s.ctxName] && s.contexts[s.ctxName].loaded); - canSetContext = true; - if (loaded) { - for (prop in loaded) { - if (!(prop in empty)) { - if (!loaded[prop]) { - canSetContext = false; - break; - } - } - } - } - if (canSetContext) { - s.ctxName = contextName; - } - } - - if (!context) { - newContext = { - contextName: contextName, - config: { - waitSeconds: 7, - baseUrl: s.baseUrl || "./", - paths: {}, - packages: {} - }, - waiting: [], - specified: { - "require": true, - "exports": true, - "module": true - }, - loaded: {}, - scriptCount: 0, - urlFetched: {}, - defPlugin: {}, - defined: {}, - modifiers: {} - }; - - if (s.plugins.newContext) { - s.plugins.newContext(newContext); - } - - context = s.contexts[contextName] = newContext; - } - - //If have a config object, update the context's config object with - //the config values. - if (config) { - //Make sure the baseUrl ends in a slash. - if (config.baseUrl) { - if (config.baseUrl.charAt(config.baseUrl.length - 1) !== "/") { - config.baseUrl += "/"; - } - } - - //Save off the paths and packages since they require special processing, - //they are additive. - paths = context.config.paths; - packages = context.config.packages; - - //Mix in the config values, favoring the new values over - //existing ones in context.config. - req.mixin(context.config, config, true); - - //Adjust paths if necessary. - if (config.paths) { - for (prop in config.paths) { - if (!(prop in empty)) { - paths[prop] = config.paths[prop]; - } - } - context.config.paths = paths; - } - - packagePaths = config.packagePaths; - if (packagePaths || config.packages) { - //Convert packagePaths into a packages config. - if (packagePaths) { - for (prop in packagePaths) { - if (!(prop in empty)) { - configurePackageDir(packages, packagePaths[prop], prop); - } - } - } - - //Adjust packages if necessary. - if (config.packages) { - configurePackageDir(packages, config.packages); - } - - //Done with modifications, assing packages back to context config - context.config.packages = packages; - } - - //If priority loading is in effect, trigger the loads now - if (config.priority) { - //Create a separate config property that can be - //easily tested for config priority completion. - //Do this instead of wiping out the config.priority - //in case it needs to be inspected for debug purposes later. - req(config.priority); - context.config.priorityWait = config.priority; - } - - //If a deps array or a config callback is specified, then call - //require with those args. This is useful when require is defined as a - //config object before require.js is loaded. - if (config.deps || config.callback) { - req(config.deps || [], config.callback); - } - - //Set up ready callback, if asked. Useful when require is defined as a - //config object before require.js is loaded. - if (config.ready) { - req.ready(config.ready); - } - - //If it is just a config block, nothing else, - //then return. - if (!deps) { - return; - } - } - - //Normalize dependency strings: need to determine if they have - //prefixes and to also normalize any relative paths. Replace the deps - //array of strings with an array of objects. - if (deps) { - outDeps = deps; - deps = []; - for (i = 0; i < outDeps.length; i++) { - deps[i] = req.splitPrefix(outDeps[i], (name || relModuleName), context); - } - } - - //Store the module for later evaluation - newLength = context.waiting.push({ - name: name, - deps: deps, - callback: callback - }); - - if (name) { - //Store index of insertion for quick lookup - context.waiting[name] = newLength - 1; - - //Mark the module as specified so no need to fetch it again. - //Important to set specified here for the - //pause/resume case where there are multiple modules in a file. - context.specified[name] = true; - - //Load any modifiers for the module. - mods = context.modifiers[name]; - if (mods) { - req(mods, contextName); - deferMods = mods.__deferMods; - if (deferMods) { - for (i = 0; i < deferMods.length; i++) { - deferModArgs = deferMods[i]; - - //Add the context name to the def call. - lastModArg = deferModArgs[deferModArgs.length - 1]; - if (lastModArg === undefined) { - deferModArgs[deferModArgs.length - 1] = contextName; - } else if (typeof lastModArg === "string") { - deferMods.push(contextName); - } - - require.def.apply(require, deferModArgs); - } - } - } - } - - //If the callback is not an actual function, it means it already - //has the definition of the module as a literal value. - if (name && callback && !req.isFunction(callback)) { - context.defined[name] = callback; - } - - //If a pluginPrefix is available, call the plugin, or load it. - if (pluginPrefix) { - callPlugin(pluginPrefix, context, { - name: "require", - args: [name, deps, callback, context] - }); - } - - //Hold on to the module until a script load or other adapter has finished - //evaluating the whole file. This helps when a file has more than one - //module in it -- dependencies are not traced and fetched until the whole - //file is processed. - s.paused.push([pluginPrefix, name, deps, context]); - - //Set loaded here for modules that are also loaded - //as part of a layer, where onScriptLoad is not fired - //for those cases. Do this after the inline define and - //dependency tracing is done. - //Also check if auto-registry of jQuery needs to be skipped. - if (name) { - context.loaded[name] = true; - context.jQueryDef = (name === "jquery"); - } - }; - - /** - * Simple function to mix in properties from source into target, - * but only if target does not already have a property of the same name. - */ - req.mixin = function (target, source, force) { - for (var prop in source) { - if (!(prop in empty) && (!(prop in target) || force)) { - target[prop] = source[prop]; - } - } - return req; - }; - - req.version = version; - - //Set up page state. - s = req.s = { - ctxName: defContextName, - contexts: {}, - paused: [], - plugins: { - defined: {}, - callbacks: {}, - waiting: {} - }, - //Stores a list of URLs that should not get async script tag treatment. - skipAsync: {}, - isBrowser: isBrowser, - isPageLoaded: !isBrowser, - readyCalls: [], - doc: isBrowser ? document : null - }; - - req.isBrowser = s.isBrowser; - if (isBrowser) { - s.head = document.getElementsByTagName("head")[0]; - //If BASE tag is in play, using appendChild is a problem for IE6. - //When that browser dies, this can be removed. Details in this jQuery bug: - //http://dev.jquery.com/ticket/2709 - baseElement = document.getElementsByTagName("base")[0]; - if (baseElement) { - s.head = baseElement.parentNode; - } - } - - /** - * Sets up a plugin callback name. Want to make it easy to test if a plugin - * needs to be called for a certain lifecycle event by testing for - * if (s.plugins.onLifeCyleEvent) so only define the lifecycle event - * if there is a real plugin that registers for it. - */ - function makePluginCallback(name, returnOnTrue) { - var cbs = s.plugins.callbacks[name] = []; - s.plugins[name] = function () { - for (var i = 0, cb; (cb = cbs[i]); i++) { - if (cb.apply(null, arguments) === true && returnOnTrue) { - return true; - } - } - return false; - }; - } - - /** - * Registers a new plugin for require. - */ - req.plugin = function (obj) { - var i, prop, call, prefix = obj.prefix, cbs = s.plugins.callbacks, - waiting = s.plugins.waiting[prefix], generics, - defined = s.plugins.defined, contexts = s.contexts, context; - - //Do not allow redefinition of a plugin, there may be internal - //state in the plugin that could be lost. - if (defined[prefix]) { - return req; - } - - //Save the plugin. - defined[prefix] = obj; - - //Set up plugin callbacks for methods that need to be generic to - //require, for lifecycle cases where it does not care about a particular - //plugin, but just that some plugin work needs to be done. - generics = ["newContext", "isWaiting", "orderDeps"]; - for (i = 0; (prop = generics[i]); i++) { - if (!s.plugins[prop]) { - makePluginCallback(prop, prop === "isWaiting"); - } - cbs[prop].push(obj[prop]); - } - - //Call newContext for any contexts that were already created. - if (obj.newContext) { - for (prop in contexts) { - if (!(prop in empty)) { - context = contexts[prop]; - obj.newContext(context); - } - } - } - - //If there are waiting requests for a plugin, execute them now. - if (waiting) { - for (i = 0; (call = waiting[i]); i++) { - if (obj[call.name]) { - obj[call.name].apply(null, call.args); - } - } - delete s.plugins.waiting[prefix]; - } - - return req; - }; - - /** - * As of jQuery 1.4.3, it supports a readyWait property that will hold off - * calling jQuery ready callbacks until all scripts are loaded. Be sure - * to track it if readyWait is available. Also, since jQuery 1.4.3 does - * not register as a module, need to do some global inference checking. - * Even if it does register as a module, not guaranteed to be the precise - * name of the global. If a jQuery is tracked for this context, then go - * ahead and register it as a module too, if not already in process. - */ - function jQueryCheck(context, jqCandidate) { - if (!context.jQuery) { - var $ = jqCandidate || (typeof jQuery !== "undefined" ? jQuery : null); - if ($ && "readyWait" in $) { - context.jQuery = $; - - //Manually create a "jquery" module entry if not one already - //or in process. - if (!context.defined.jquery && !context.jQueryDef) { - context.defined.jquery = $; - } - - //Make sure - if (context.scriptCount) { - $.readyWait += 1; - context.jQueryIncremented = true; - } - } - } - } - - /** - * Internal method used by environment adapters to complete a load event. - * A load event could be a script load or just a load pass from a synchronous - * load call. - * @param {String} moduleName the name of the module to potentially complete. - * @param {Object} context the context object - */ - req.completeLoad = function (moduleName, context) { - //If there is a waiting require.def call - var args; - while (defQueue.length) { - args = defQueue.shift(); - if (args[0] === null) { - args[0] = moduleName; - break; - } else if (args[0] === moduleName) { - //Found matching require.def call for this script! - break; - } else { - //Some other named require.def call, most likely the result - //of a build layer that included many require.def calls. - callDefMain(args, context); - } - } - if (args) { - callDefMain(args, context); - } - - //Mark the script as loaded. Note that this can be different from a - //moduleName that maps to a require.def call. This line is important - //for traditional browser scripts. - context.loaded[moduleName] = true; - - //If a global jQuery is defined, check for it. Need to do it here - //instead of main() since stock jQuery does not register as - //a module via define. - jQueryCheck(context); - - context.scriptCount -= 1; - resume(context); - }; - - /** - * Legacy function, remove at some point - */ - req.pause = req.resume = function () {}; - - /** - * Trace down the dependencies to see if they are loaded. If not, trigger - * the load. - * @param {String} pluginPrefix the plugin prefix, if any associated with the name. - * - * @param {String} name: the name of the module that has the dependencies. - * - * @param {Array} deps array of dependencies. - * - * @param {Object} context: the loading context. - * - * @private - */ - req.checkDeps = function (pluginPrefix, name, deps, context) { - //Figure out if all the modules are loaded. If the module is not - //being loaded or already loaded, add it to the "to load" list, - //and request it to be loaded. - var i, dep; - - if (pluginPrefix) { - callPlugin(pluginPrefix, context, { - name: "checkDeps", - args: [name, deps, context] - }); - } else { - for (i = 0; (dep = deps[i]); i++) { - if (!context.specified[dep.fullName]) { - context.specified[dep.fullName] = true; - - //Reset the start time to use for timeouts - context.startTime = (new Date()).getTime(); - - //If a plugin, call its load method. - if (dep.prefix) { - callPlugin(dep.prefix, context, { - name: "load", - args: [dep.name, context.contextName] - }); - } else { - req.load(dep.name, context.contextName); - } - } - } - } - }; - - /** - * Register a module that modifies another module. The modifier will - * only be called once the target module has been loaded. - * - * First syntax: - * - * require.modify({ - * "some/target1": "my/modifier1", - * "some/target2": "my/modifier2", - * }); - * - * With this syntax, the my/modifier1 will only be loaded when - * "some/target1" is loaded. - * - * Second syntax, defining a modifier. - * - * require.modify("some/target1", "my/modifier", - * ["some/target1", "some/other"], - * function (target, other) { - * //Modify properties of target here. - * Only properties of target can be modified, but - * target cannot be replaced. - * } - * ); - */ - req.modify = function (target, name, deps, callback, contextName) { - var prop, modifier, list, - cName = (typeof target === "string" ? contextName : name) || s.ctxName, - context = s.contexts[cName], - mods = context.modifiers; - - if (typeof target === "string") { - //A modifier module. - //First store that it is a modifier. - list = mods[target] || (mods[target] = []); - if (!list[name]) { - list.push(name); - list[name] = true; - } - - //Trigger the normal module definition logic if the target - //is already in the system. - if (context.specified[target]) { - req.def(name, deps, callback, contextName); - } else { - //Hold on to the execution/dependency checks for the modifier - //until the target is fetched. - (list.__deferMods || (list.__deferMods = [])).push([name, deps, callback, contextName]); - } - } else { - //A list of modifiers. Save them for future reference. - for (prop in target) { - if (!(prop in empty)) { - //Store the modifier for future use. - modifier = target[prop]; - list = mods[prop] || (context.modifiers[prop] = []); - if (!list[modifier]) { - list.push(modifier); - list[modifier] = true; - - if (context.specified[prop]) { - //Load the modifier right away. - req([modifier], cName); - } - } - } - } - } - }; - - req.isArray = function (it) { - return ostring.call(it) === "[object Array]"; - }; - - req.isFunction = isFunction; - - /** - * Gets one module's exported value. This method is used by require(). - * It is broken out as a separate function to allow a host environment - * shim to overwrite this function with something appropriate for that - * environment. - * - * @param {String} moduleName the name of the module. - * @param {String} [contextName] the name of the context to use. Uses - * default context if no contextName is provided. You should never - * pass the contextName explicitly -- it is handled by the require() code. - * @param {String} [relModuleName] a module name to use for relative - * module name lookups. You should never pass this argument explicitly -- - * it is handled by the require() code. - * - * @returns {Object} the exported module value. - */ - req.get = function (moduleName, contextName, relModuleName) { - if (moduleName === "require" || moduleName === "exports" || moduleName === "module") { - req.onError(new Error("Explicit require of " + moduleName + " is not allowed.")); - } - contextName = contextName || s.ctxName; - - var ret, context = s.contexts[contextName], nameProps; - - //Normalize module name, if it contains . or .. - nameProps = req.splitPrefix(moduleName, relModuleName, context); - - ret = context.defined[nameProps.name]; - if (ret === undefined) { - req.onError(new Error("require: module name '" + - moduleName + - "' has not been loaded yet for context: " + - contextName)); - } - return ret; - }; - - /** - * Makes the request to load a module. May be an async load depending on - * the environment and the circumstance of the load call. Override this - * method in a host environment shim to do something specific for that - * environment. - * - * @param {String} moduleName the name of the module. - * @param {String} contextName the name of the context to use. - */ - req.load = function (moduleName, contextName) { - var context = s.contexts[contextName], - urlFetched = context.urlFetched, - loaded = context.loaded, url; - s.isDone = false; - - //Only set loaded to false for tracking if it has not already been set. - if (!loaded[moduleName]) { - loaded[moduleName] = false; - } - - if (contextName !== s.ctxName) { - //Not in the right context now, hold on to it until - //the current context finishes all its loading. - contextLoads.push(arguments); - } else { - //First derive the path name for the module. - url = req.nameToUrl(moduleName, null, contextName); - if (!urlFetched[url]) { - context.scriptCount += 1; - req.attach(url, contextName, moduleName); - urlFetched[url] = true; - - //If tracking a jQuery, then make sure its readyWait - //is incremented to prevent its ready callbacks from - //triggering too soon. - if (context.jQuery && !context.jQueryIncremented) { - context.jQuery.readyWait += 1; - context.jQueryIncremented = true; - } - } - } - }; - - req.jsExtRegExp = /^\/|:|\?|\.js$/; - - /** - * Given a relative module name, like ./something, normalize it to - * a real name that can be mapped to a path. - * @param {String} name the relative name - * @param {String} baseName a real name that the name arg is relative - * to. - * @param {Object} context - * @returns {String} normalized name - */ - req.normalizeName = function (name, baseName, context) { - //Adjust any relative paths. - var part; - if (name.charAt(0) === ".") { - //If have a base name, try to normalize against it, - //otherwise, assume it is a top-level require that will - //be relative to baseUrl in the end. - if (baseName) { - if (context.config.packages[baseName]) { - //If the baseName is a package name, then just treat it as one - //name to concat the name with. - baseName = [baseName]; - } else { - //Convert baseName to array, and lop off the last part, - //so that . matches that "directory" and not name of the baseName's - //module. For instance, baseName of "one/two/three", maps to - //"one/two/three.js", but we want the directory, "one/two" for - //this normalization. - baseName = baseName.split("/"); - baseName = baseName.slice(0, baseName.length - 1); - } - - name = baseName.concat(name.split("/")); - for (i = 0; (part = name[i]); i++) { - if (part === ".") { - name.splice(i, 1); - i -= 1; - } else if (part === "..") { - if (i === 1) { - //End of the line. Keep at least one non-dot - //path segment at the front so it can be mapped - //correctly to disk. Otherwise, there is likely - //no path mapping for '..'. - break; - } else if (i > 1) { - name.splice(i - 1, 2); - i -= 2; - } - } - } - name = name.join("/"); - } - } - return name; - }; - - /** - * Splits a name into a possible plugin prefix and - * the module name. If baseName is provided it will - * also normalize the name via require.normalizeName() - * - * @param {String} name the module name - * @param {String} [baseName] base name that name is - * relative to. - * @param {Object} context - * - * @returns {Object} with properties, 'prefix' (which - * may be null), 'name' and 'fullName', which is a combination - * of the prefix (if it exists) and the name. - */ - req.splitPrefix = function (name, baseName, context) { - var index = name.indexOf("!"), prefix = null; - if (index !== -1) { - prefix = name.substring(0, index); - name = name.substring(index + 1, name.length); - } - - //Account for relative paths if there is a base name. - name = req.normalizeName(name, baseName, context); - - return { - prefix: prefix, - name: name, - fullName: prefix ? prefix + "!" + name : name - }; - }; - - /** - * Converts a module name to a file path. - */ - req.nameToUrl = function (moduleName, ext, contextName, relModuleName) { - var paths, packages, pkg, pkgPath, syms, i, parentModule, url, - context = s.contexts[contextName], - config = context.config; - - //Normalize module name if have a base relative module name to work from. - moduleName = req.normalizeName(moduleName, relModuleName, context); - - //If a colon is in the URL, it indicates a protocol is used and it is just - //an URL to a file, or if it starts with a slash or ends with .js, it is just a plain file. - //The slash is important for protocol-less URLs as well as full paths. - if (req.jsExtRegExp.test(moduleName)) { - //Just a plain path, not module name lookup, so just return it. - //Add extension if it is included. This is a bit wonky, only non-.js things pass - //an extension, this method probably needs to be reworked. - url = moduleName + (ext ? ext : ""); - } else { - //A module that needs to be converted to a path. - paths = config.paths; - packages = config.packages; - - syms = moduleName.split("/"); - //For each module name segment, see if there is a path - //registered for it. Start with most specific name - //and work up from it. - for (i = syms.length; i > 0; i--) { - parentModule = syms.slice(0, i).join("/"); - if (paths[parentModule]) { - syms.splice(0, i, paths[parentModule]); - break; - } else if ((pkg = packages[parentModule])) { - //pkg can have just a string value to the path - //or can be an object with props: - //main, lib, name, location. - pkgPath = pkg.location + '/' + pkg.lib; - //If module name is just the package name, then looking - //for the main module. - if (moduleName === pkg.name) { - pkgPath += '/' + pkg.main; - } - syms.splice(0, i, pkgPath); - break; - } - } - - //Join the path parts together, then figure out if baseUrl is needed. - url = syms.join("/") + (ext || ".js"); - url = (url.charAt(0) === '/' || url.match(/^\w+:/) ? "" : config.baseUrl) + url; - } - return config.urlArgs ? url + - ((url.indexOf('?') === -1 ? '?' : '&') + - config.urlArgs) : url; - }; - - //In async environments, checkLoaded can get called a few times in the same - //call stack. Allow only one to do the finishing work. Set to false - //for sync environments. - req.blockCheckLoaded = true; - - /** - * Checks if all modules for a context are loaded, and if so, evaluates the - * new ones in right dependency order. - * - * @private - */ - req.checkLoaded = function (contextName) { - var context = s.contexts[contextName || s.ctxName], - waitInterval = context.config.waitSeconds * 1000, - //It is possible to disable the wait interval by using waitSeconds of 0. - expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), - loaded, defined = context.defined, - modifiers = context.modifiers, waiting, noLoads = "", - hasLoadedProp = false, stillLoading = false, prop, - - pIsWaiting = s.plugins.isWaiting, pOrderDeps = s.plugins.orderDeps, - - i, module, allDone, loads, loadArgs, err; - - //If already doing a checkLoaded call, - //then do not bother checking loaded state. - if (context.isCheckLoaded) { - return; - } - - //Determine if priority loading is done. If so clear the priority. If - //not, then do not check - if (context.config.priorityWait) { - if (isPriorityDone(context)) { - //Call resume, since it could have - //some waiting dependencies to trace. - resume(context); - } else { - return; - } - } - - //Signal that checkLoaded is being require, so other calls that could be triggered - //by calling a waiting callback that then calls require and then this function - //should not proceed. At the end of this function, if there are still things - //waiting, then checkLoaded will be called again. - context.isCheckLoaded = req.blockCheckLoaded; - - //Grab waiting and loaded lists here, since it could have changed since - //this function was first called. - waiting = context.waiting; - loaded = context.loaded; - - //See if anything is still in flight. - for (prop in loaded) { - if (!(prop in empty)) { - hasLoadedProp = true; - if (!loaded[prop]) { - if (expired) { - noLoads += prop + " "; - } else { - stillLoading = true; - break; - } - } - } - } - - //Check for exit conditions. - if (!hasLoadedProp && !waiting.length - && (!pIsWaiting || !pIsWaiting(context)) - ) { - //If the loaded object had no items, then the rest of - //the work below does not need to be done. - context.isCheckLoaded = false; - return; - } - if (expired && noLoads) { - //If wait time expired, throw error of unloaded modules. - err = new Error("require.js load timeout for modules: " + noLoads); - err.requireType = "timeout"; - err.requireModules = noLoads; - req.onError(err); - } - if (stillLoading) { - //Something is still waiting to load. Wait for it. - context.isCheckLoaded = false; - if (isBrowser || isWebWorker) { - setTimeout(function () { - req.checkLoaded(contextName); - }, 50); - } - return; - } - - //Order the dependencies. Also clean up state because the evaluation - //of modules might create new loading tasks, so need to reset. - //Be sure to call plugins too. - context.waiting = []; - context.loaded = {}; - - //Call plugins to order their dependencies, do their - //module definitions. - if (pOrderDeps) { - pOrderDeps(context); - } - - //Before defining the modules, give priority treatment to any modifiers - //for modules that are already defined. - for (prop in modifiers) { - if (!(prop in empty)) { - if (defined[prop]) { - req.execModifiers(prop, {}, waiting, context); - } - } - } - - //Define the modules, doing a depth first search. - for (i = 0; (module = waiting[i]); i++) { - req.exec(module, {}, waiting, context); - } - - //Indicate checkLoaded is now done. - context.isCheckLoaded = false; - - if (context.waiting.length - || (pIsWaiting && pIsWaiting(context)) - ) { - //More things in this context are waiting to load. They were probably - //added while doing the work above in checkLoaded, calling module - //callbacks that triggered other require calls. - req.checkLoaded(contextName); - } else if (contextLoads.length) { - //Check for other contexts that need to load things. - //First, make sure current context has no more things to - //load. After defining the modules above, new require calls - //could have been made. - loaded = context.loaded; - allDone = true; - for (prop in loaded) { - if (!(prop in empty)) { - if (!loaded[prop]) { - allDone = false; - break; - } - } - } - - if (allDone) { - s.ctxName = contextLoads[0][1]; - loads = contextLoads; - //Reset contextLoads in case some of the waiting loads - //are for yet another context. - contextLoads = []; - for (i = 0; (loadArgs = loads[i]); i++) { - req.load.apply(req, loadArgs); - } - } - } else { - //Make sure we reset to default context. - s.ctxName = defContextName; - s.isDone = true; - if (req.callReady) { - req.callReady(); - } - } - }; - - /** - * Helper function that creates a setExports function for a "module" - * CommonJS dependency. Do this here to avoid creating a closure that - * is part of a loop in require.exec. - */ - function makeSetExports(moduleObj) { - return function (exports) { - moduleObj.exports = exports; - }; - } - - function makeContextModuleFunc(name, contextName, moduleName) { - return function () { - //A version of a require function that forces a contextName value - //and also passes a moduleName value for items that may need to - //look up paths relative to the moduleName - var args = [].concat(aps.call(arguments, 0)); - args.push(contextName, moduleName); - return (name ? require[name] : require).apply(null, args); - }; - } - - /** - * Helper function that creates a require function object to give to - * modules that ask for it as a dependency. It needs to be specific - * per module because of the implication of path mappings that may - * need to be relative to the module name. - */ - function makeRequire(context, moduleName) { - var contextName = context.contextName, - modRequire = makeContextModuleFunc(null, contextName, moduleName); - - req.mixin(modRequire, { - modify: makeContextModuleFunc("modify", contextName, moduleName), - def: makeContextModuleFunc("def", contextName, moduleName), - get: makeContextModuleFunc("get", contextName, moduleName), - nameToUrl: makeContextModuleFunc("nameToUrl", contextName, moduleName), - ready: req.ready, - context: context, - config: context.config, - isBrowser: s.isBrowser - }); - return modRequire; - } - - /** - * Executes the modules in the correct order. - * - * @private - */ - req.exec = function (module, traced, waiting, context) { - //Some modules are just plain script files, abddo not have a formal - //module definition, - if (!module) { - //Returning undefined for Spidermonky strict checking in Komodo - return undefined; - } - - var name = module.name, cb = module.callback, deps = module.deps, j, dep, - defined = context.defined, ret, args = [], depModule, cjsModule, - usingExports = false, depName; - - //If already traced or defined, do not bother a second time. - if (name) { - if (traced[name] || name in defined) { - return defined[name]; - } - - //Mark this module as being traced, so that it is not retraced (as in a circular - //dependency) - traced[name] = true; - } - - if (deps) { - for (j = 0; (dep = deps[j]); j++) { - depName = dep.name; - if (depName === "require") { - depModule = makeRequire(context, name); - } else if (depName === "exports") { - //CommonJS module spec 1.1 - depModule = defined[name] = {}; - usingExports = true; - } else if (depName === "module") { - //CommonJS module spec 1.1 - cjsModule = depModule = { - id: name, - uri: name ? req.nameToUrl(name, null, context.contextName) : undefined - }; - cjsModule.setExports = makeSetExports(cjsModule); - } else { - //Get dependent module. It could not exist, for a circular - //dependency or if the loaded dependency does not actually call - //require. Favor not throwing an error here if undefined because - //we want to allow code that does not use require as a module - //definition framework to still work -- allow a web site to - //gradually update to contained modules. That is more - //important than forcing a throw for the circular dependency case. - depModule = depName in defined ? defined[depName] : (traced[depName] ? undefined : req.exec(waiting[waiting[depName]], traced, waiting, context)); - } - - args.push(depModule); - } - } - - //Call the callback to define the module, if necessary. - cb = module.callback; - if (cb && req.isFunction(cb)) { - ret = req.execCb(name, cb, args); - if (name) { - //If using exports and the function did not return a value, - //and the "module" object for this definition function did not - //define an exported value, then use the exports object. - if (usingExports && ret === undefined && (!cjsModule || !("exports" in cjsModule))) { - ret = defined[name]; - } else { - if (cjsModule && "exports" in cjsModule) { - ret = defined[name] = cjsModule.exports; - } else { - if (name in defined && !usingExports) { - req.onError(new Error(name + " has already been defined")); - } - defined[name] = ret; - } - } - } - } - - //Execute modifiers, if they exist. - req.execModifiers(name, traced, waiting, context); - - return ret; - }; - - /** - * Executes a module callack function. Broken out as a separate function - * solely to allow the build system to sequence the files in the built - * layer in the right sequence. - * @param {String} name the module name. - * @param {Function} cb the module callback/definition function. - * @param {Array} args The arguments (dependent modules) to pass to callback. - * - * @private - */ - req.execCb = function (name, cb, args) { - return cb.apply(null, args); - }; - - /** - * Executes modifiers for the given module name. - * @param {String} target - * @param {Object} traced - * @param {Object} context - * - * @private - */ - req.execModifiers = function (target, traced, waiting, context) { - var modifiers = context.modifiers, mods = modifiers[target], mod, i; - if (mods) { - for (i = 0; i < mods.length; i++) { - mod = mods[i]; - //Not all modifiers define a module, they might collect other modules. - //If it is just a collection it will not be in waiting. - if (mod in waiting) { - req.exec(waiting[waiting[mod]], traced, waiting, context); - } - } - delete modifiers[target]; - } - }; - - /** - * callback for script loads, used to check status of loading. - * - * @param {Event} evt the event from the browser for the script - * that was loaded. - * - * @private - */ - req.onScriptLoad = function (evt) { - //Using currentTarget instead of target for Firefox 2.0's sake. Not - //all old browsers will be supported, but this one was easy enough - //to support and still makes sense. - var node = evt.currentTarget || evt.srcElement, contextName, moduleName, - context; - if (evt.type === "load" || readyRegExp.test(node.readyState)) { - //Pull out the name of the module and the context. - contextName = node.getAttribute("data-requirecontext"); - moduleName = node.getAttribute("data-requiremodule"); - context = s.contexts[contextName]; - - req.completeLoad(moduleName, context); - - //Clean up script binding. - if (node.removeEventListener) { - node.removeEventListener("load", req.onScriptLoad, false); - } else { - //Probably IE. If not it will throw an error, which will be - //useful to know. - node.detachEvent("onreadystatechange", req.onScriptLoad); - } - } - }; - - /** - * Attaches the script represented by the URL to the current - * environment. Right now only supports browser loading, - * but can be redefined in other environments to do the right thing. - * @param {String} url the url of the script to attach. - * @param {String} contextName the name of the context that wants the script. - * @param {moduleName} the name of the module that is associated with the script. - * @param {Function} [callback] optional callback, defaults to require.onScriptLoad - * @param {String} [type] optional type, defaults to text/javascript - */ - req.attach = function (url, contextName, moduleName, callback, type) { - var node, loaded, context; - if (isBrowser) { - //In the browser so use a script tag - callback = callback || req.onScriptLoad; - node = document.createElement("script"); - node.type = type || "text/javascript"; - node.charset = "utf-8"; - //Use async so Gecko does not block on executing the script if something - //like a long-polling comet tag is being run first. Gecko likes - //to evaluate scripts in DOM order, even for dynamic scripts. - //It will fetch them async, but only evaluate the contents in DOM - //order, so a long-polling script tag can delay execution of scripts - //after it. But telling Gecko we expect async gets us the behavior - //we want -- execute it whenever it is finished downloading. Only - //Helps Firefox 3.6+ - //Allow some URLs to not be fetched async. Mostly helps the order! - //plugin - if (!s.skipAsync[url]) { - node.async = true; - } - node.setAttribute("data-requirecontext", contextName); - node.setAttribute("data-requiremodule", moduleName); - - //Set up load listener. - if (node.addEventListener) { - node.addEventListener("load", callback, false); - } else { - //Probably IE. If not it will throw an error, which will be - //useful to know. IE (at least 6-8) do not fire - //script onload right after executing the script, so - //we cannot tie the anonymous require.def call to a name. - //However, IE reports the script as being in "interactive" - //readyState at the time of the require.def call. - useInteractive = true; - node.attachEvent("onreadystatechange", callback); - } - node.src = url; - - //For some cache cases in IE 6-8, the script executes before the end - //of the appendChild execution, so to tie an anonymous require.def - //call to the module name (which is stored on the node), hold on - //to a reference to this node, but clear after the DOM insertion. - currentlyAddingScript = node; - if (baseElement) { - s.head.insertBefore(node, baseElement); - } else { - s.head.appendChild(node); - } - currentlyAddingScript = null; - return node; - } else if (isWebWorker) { - //In a web worker, use importScripts. This is not a very - //efficient use of importScripts, importScripts will block until - //its script is downloaded and evaluated. However, if web workers - //are in play, the expectation that a build has been done so that - //only one script needs to be loaded anyway. This may need to be - //reevaluated if other use cases become common. - context = s.contexts[contextName]; - loaded = context.loaded; - loaded[moduleName] = false; - importScripts(url); - - //Account for anonymous modules - req.completeLoad(moduleName, context); - } - return null; - }; - - //Determine what baseUrl should be if not already defined via a require config object - s.baseUrl = cfg.baseUrl; - if (isBrowser && (!s.baseUrl || !s.head)) { - //Figure out baseUrl. Get it from the script tag with require.js in it. - scripts = document.getElementsByTagName("script"); - if (cfg.baseUrlMatch) { - rePkg = cfg.baseUrlMatch; - } else { - - - - rePkg = /(allplugins-)?require\.js(\W|$)/i; - - } - - for (i = scripts.length - 1; i > -1 && (script = scripts[i]); i--) { - //Set the "head" where we can append children by - //using the script's parent. - if (!s.head) { - s.head = script.parentNode; - } - - //Look for a data-main attribute to set main script for the page - //to load. - if (!cfg.deps) { - dataMain = script.getAttribute('data-main'); - if (dataMain) { - cfg.deps = [dataMain]; - } - } - - //Using .src instead of getAttribute to get an absolute URL. - //While using a relative URL will be fine for script tags, other - //URLs used for text! resources that use XHR calls might benefit - //from an absolute URL. - src = script.src; - if (src && !s.baseUrl) { - m = src.match(rePkg); - if (m) { - s.baseUrl = src.substring(0, m.index); - break; - } - } - } - } - - //****** START page load functionality **************** - /** - * Sets the page as loaded and triggers check for all modules loaded. - */ - req.pageLoaded = function () { - if (!s.isPageLoaded) { - s.isPageLoaded = true; - if (scrollIntervalId) { - clearInterval(scrollIntervalId); - } - - //Part of a fix for FF < 3.6 where readyState was not set to - //complete so libraries like jQuery that check for readyState - //after page load where not getting initialized correctly. - //Original approach suggested by Andrea Giammarchi: - //http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html - //see other setReadyState reference for the rest of the fix. - if (setReadyState) { - document.readyState = "complete"; - } - - req.callReady(); - } - }; - - /** - * Internal function that calls back any ready functions. If you are - * integrating RequireJS with another library without require.ready support, - * you can define this method to call your page ready code instead. - */ - req.callReady = function () { - var callbacks = s.readyCalls, i, callback, contexts, context, prop; - - if (s.isPageLoaded && s.isDone) { - if (callbacks.length) { - s.readyCalls = []; - for (i = 0; (callback = callbacks[i]); i++) { - callback(); - } - } - - //If jQuery with readyWait is being tracked, updated its - //readyWait count. - contexts = s.contexts; - for (prop in contexts) { - if (!(prop in empty)) { - context = contexts[prop]; - if (context.jQueryIncremented) { - context.jQuery.readyWait -= 1; - context.jQueryIncremented = false; - } - } - } - } - }; - - /** - * Registers functions to call when the page is loaded - */ - req.ready = function (callback) { - if (s.isPageLoaded && s.isDone) { - callback(); - } else { - s.readyCalls.push(callback); - } - return req; - }; - - if (isBrowser) { - if (document.addEventListener) { - //Standards. Hooray! Assumption here that if standards based, - //it knows about DOMContentLoaded. - document.addEventListener("DOMContentLoaded", req.pageLoaded, false); - window.addEventListener("load", req.pageLoaded, false); - //Part of FF < 3.6 readystate fix (see setReadyState refs for more info) - if (!document.readyState) { - setReadyState = true; - document.readyState = "loading"; - } - } else if (window.attachEvent) { - window.attachEvent("onload", req.pageLoaded); - - //DOMContentLoaded approximation, as found by Diego Perini: - //http://javascript.nwbox.com/IEContentLoaded/ - if (self === self.top) { - scrollIntervalId = setInterval(function () { - try { - //From this ticket: - //http://bugs.dojotoolkit.org/ticket/11106, - //In IE HTML Application (HTA), such as in a selenium test, - //javascript in the iframe can't see anything outside - //of it, so self===self.top is true, but the iframe is - //not the top window and doScroll will be available - //before document.body is set. Test document.body - //before trying the doScroll trick. - if (document.body) { - document.documentElement.doScroll("left"); - req.pageLoaded(); - } - } catch (e) {} - }, 30); - } - } - - //Check if document already complete, and if so, just trigger page load - //listeners. NOTE: does not work with Firefox before 3.6. To support - //those browsers, manually call require.pageLoaded(). - if (document.readyState === "complete") { - req.pageLoaded(); - } - } - //****** END page load functionality **************** - - //Set up default context. If require was a configuration object, use that as base config. - req(cfg); - - //If modules are built into require.js, then need to make sure dependencies are - //traced. Use a setTimeout in the browser world, to allow all the modules to register - //themselves. In a non-browser env, assume that modules are not built into require.js, - //which seems odd to do on the server. - if (typeof setTimeout !== "undefined") { - setTimeout(function () { - var ctx = s.contexts[(cfg.context || defContextName)]; - //Allow for jQuery to be loaded/already in the page, and if jQuery 1.4.3, - //make sure to hold onto it for readyWait triggering. - jQueryCheck(ctx); - resume(ctx); - }, 0); - } -}()); - -/** - * @license RequireJS i18n Copyright (c) 2010, The Dojo Foundation All Rights Reserved. - * Available via the MIT or new BSD license. - * see: http://github.com/jrburke/requirejs for details - */ -/*jslint regexp: false, nomen: false, plusplus: false */ -/*global require: false, navigator: false */ - - -/** - * This plugin handles i18n! prefixed modules. It does the following: - * - * 1) A regular module can have a dependency on an i18n bundle, but the regular - * module does not want to specify what locale to load. So it just specifies - * the top-level bundle, like "i18n!nls/colors". - * - * This plugin will load the i18n bundle at nls/colors, see that it is a root/master - * bundle since it does not have a locale in its name. It will then try to find - * the best match locale available in that master bundle, then request all the - * locale pieces for that best match locale. For instance, if the locale is "en-us", - * then the plugin will ask for the "en-us", "en" and "root" bundles to be loaded - * (but only if they are specified on the master bundle). - * - * Once all the bundles for the locale pieces load, then it mixes in all those - * locale pieces into each other, then finally sets the context.defined value - * for the nls/colors bundle to be that mixed in locale. - * - * 2) A regular module specifies a specific locale to load. For instance, - * i18n!nls/fr-fr/colors. In this case, the plugin needs to load the master bundle - * first, at nls/colors, then figure out what the best match locale is for fr-fr, - * since maybe only fr or just root is defined for that locale. Once that best - * fit is found, all of its locale pieces need to have their bundles loaded. - * - * Once all the bundles for the locale pieces load, then it mixes in all those - * locale pieces into each other, then finally sets the context.defined value - * for the nls/fr-fr/colors bundle to be that mixed in locale. - */ -(function () { - //regexp for reconstructing the master bundle name from parts of the regexp match - //nlsRegExp.exec("foo/bar/baz/nls/en-ca/foo") gives: - //["foo/bar/baz/nls/en-ca/foo", "foo/bar/baz/nls/", "/", "/", "en-ca", "foo"] - //nlsRegExp.exec("foo/bar/baz/nls/foo") gives: - //["foo/bar/baz/nls/foo", "foo/bar/baz/nls/", "/", "/", "foo", ""] - //so, if match[5] is blank, it means this is the top bundle definition. - var nlsRegExp = /(^.*(^|\/)nls(\/|$))([^\/]*)\/?([^\/]*)/, - empty = {}; - - function getWaiting(name, context) { - var nlswAry = context.nlsWaiting; - return nlswAry[name] || - //Push a new waiting object on the nlsWaiting array, but also put - //a shortcut lookup by name to the object on the array. - (nlswAry[name] = nlswAry[(nlswAry.push({ _name: name}) - 1)]); - } - - /** - * Makes sure all the locale pieces are loaded, and finds the best match - * for the requested locale. - */ - function resolveLocale(masterName, bundle, locale, context) { - //Break apart the locale to get the parts. - var i, parts, toLoad, nlsw, loc, val, bestLoc = "root"; - - parts = locale.split("-"); - - //Now see what bundles exist for each country/locale. - //Want to walk up the chain, so if locale is en-us-foo, - //look for en-us-foo, en-us, en, then root. - toLoad = []; - - nlsw = getWaiting(masterName, context); - - for (i = parts.length; i > -1; i--) { - loc = i ? parts.slice(0, i).join("-") : "root"; - val = bundle[loc]; - if (val) { - //Store which bundle to use for the default bundle definition. - if (locale === context.config.locale && !nlsw._match) { - nlsw._match = loc; - } - - //Store the best match for the target locale - if (bestLoc === "root") { - bestLoc = loc; - } - - //Track that the locale needs to be resolved with its parts. - //Mark what locale should be used when resolving. - nlsw[loc] = loc; - - //If locale value is true, it means it is a resource that - //needs to be loaded. Track it to load if it has not already - //been asked for. - if (val === true) { - //split off the bundl name from master name and insert the - //locale before the bundle name. So, if masterName is - //some/path/nls/colors, then the locale fr-fr's bundle name should - //be some/path/nls/fr-fr/colors - val = masterName.split("/"); - val.splice(-1, 0, loc); - val = val.join("/"); - - if (!context.specified[val] && !(val in context.loaded) && !context.defined[val]) { - context.defPlugin[val] = 'i18n'; - toLoad.push(val); - } - } - } - } - - //If locale was not an exact match, store the closest match for it. - if (bestLoc !== locale) { - if (context.defined[bestLoc]) { - //Already got it. Easy peasy lemon squeezy. - context.defined[locale] = context.defined[bestLoc]; - } else { - //Need to wait for things to load then define it. - nlsw[locale] = bestLoc; - } - } - - //Load any bundles that are still needed. - if (toLoad.length) { - require(toLoad, context.contextName); - } - } - - require.plugin({ - prefix: "i18n", - - /** - * This callback is prefix-specific, only gets called for this prefix - */ - require: function (name, deps, callback, context) { - var i, match, nlsw, bundle, master, toLoad, obj = context.defined[name]; - - //All i18n modules must match the nls module name structure. - match = nlsRegExp.exec(name); - //If match[5] is blank, it means this is the top bundle definition, - //so it does not have to be handled. Only deal with ones that have a locale - //(a match[4] value but no match[5]) - if (match[5]) { - master = match[1] + match[5]; - - //Track what locale bundle need to be generated once all the modules load. - nlsw = getWaiting(master, context); - nlsw[match[4]] = match[4]; - - bundle = context.nls[master]; - if (!bundle) { - //No master bundle yet, ask for it. - context.defPlugin[master] = 'i18n'; - require([master], context.contextName); - bundle = context.nls[master] = {}; - } - //For nls modules, the callback is just a regular object, - //so save it off in the bundle now. - bundle[match[4]] = callback; - } else { - //Integrate bundle into the nls area. - bundle = context.nls[name]; - if (bundle) { - //A specific locale already started the bundle object. - //Do a mixin (which will not overwrite the locale property - //on the bundle that has the previously loaded locale's info) - require.mixin(bundle, obj); - } else { - bundle = context.nls[name] = obj; - } - context.nlsRootLoaded[name] = true; - - //Make sure there are no locales waiting to be resolved. - toLoad = context.nlsToLoad[name]; - if (toLoad) { - delete context.nlsToLoad[name]; - for (i = 0; i < toLoad.length; i++) { - resolveLocale(name, bundle, toLoad[i], context); - } - } - - resolveLocale(name, bundle, context.config.locale, context); - } - }, - - /** - * Called when a new context is defined. Use this to store - * context-specific info on it. - */ - newContext: function (context) { - require.mixin(context, { - nlsWaiting: [], - nls: {}, - nlsRootLoaded: {}, - nlsToLoad: {} - }); - if (!context.config.locale) { - context.config.locale = typeof navigator === "undefined" ? "root" : - (navigator.language || navigator.userLanguage || "root").toLowerCase(); - } - }, - - /** - * Called when a dependency needs to be loaded. - */ - load: function (name, contextName) { - //Make sure the root bundle is loaded, to check if we can support - //loading the requested locale, or if a different one needs - //to be chosen. - var masterName, context = require.s.contexts[contextName], bundle, - match = nlsRegExp.exec(name), locale = match[4]; - - //If match[5] is blank, it means this is the top bundle definition, - //so it does not have to be handled. Only deal with ones that have a locale - //(a match[4] value but no match[5]) - if (match[5]) { - //locale-specific bundle - masterName = match[1] + match[5]; - bundle = context.nls[masterName]; - if (context.nlsRootLoaded[masterName] && bundle) { - resolveLocale(masterName, bundle, locale, context); - } else { - //Store this locale to figure out after masterName is loaded and load masterName. - (context.nlsToLoad[masterName] || (context.nlsToLoad[masterName] = [])).push(locale); - context.defPlugin[masterName] = 'i18n'; - require([masterName], contextName); - } - } else { - //Top-level bundle. Just call regular load, if not already loaded - if (!context.nlsRootLoaded[name]) { - context.defPlugin[name] = 'i18n'; - require.load(name, contextName); - } - } - }, - - /** - * Called when the dependencies of a module are checked. - */ - checkDeps: function (name, deps, context) { - //i18n bundles are always defined as objects for their "dependencies", - //and that object is already processed in the require method, no need to - //do work in here. - }, - - /** - * Called to determine if a module is waiting to load. - */ - isWaiting: function (context) { - return !!context.nlsWaiting.length; - }, - - /** - * Called when all modules have been loaded. - */ - orderDeps: function (context) { - //Clear up state since further processing could - //add more things to fetch. - var i, j, master, msWaiting, bundle, parts, moduleSuffix, mixed, - modulePrefix, loc, defLoc, locPart, nlsWaiting = context.nlsWaiting, - bestFit; - context.nlsWaiting = []; - context.nlsToLoad = {}; - - //First, properly mix in any nls bundles waiting to happen. - for (i = 0; (msWaiting = nlsWaiting[i]); i++) { - //Each property is a master bundle name. - master = msWaiting._name; - bundle = context.nls[master]; - defLoc = null; - - //Create the module name parts from the master name. So, if master - //is foo/nls/bar, then the parts should be prefix: "foo/nls", - // suffix: "bar", and the final locale's module name will be foo/nls/locale/bar - parts = master.split("/"); - modulePrefix = parts.slice(0, parts.length - 1).join("/"); - moduleSuffix = parts[parts.length - 1]; - //Cycle through the locale props on the waiting object and combine - //the locales together. - for (loc in msWaiting) { - if (loc !== "_name" && !(loc in empty)) { - if (loc === "_match") { - //Found default locale to use for the top-level bundle name. - defLoc = msWaiting[loc]; - - } else if (msWaiting[loc] !== loc) { - //A "best fit" locale, store it off to the end and handle - //it at the end by just assigning the best fit value, since - //after this for loop, the best fit locale will be defined. - (bestFit || (bestFit = {}))[loc] = msWaiting[loc]; - } else { - //Mix in the properties of this locale together. - //Split the locale into pieces. - mixed = {}; - parts = loc.split("-"); - for (j = parts.length; j > 0; j--) { - locPart = parts.slice(0, j).join("-"); - if (locPart !== "root" && bundle[locPart]) { - require.mixin(mixed, bundle[locPart]); - } - } - if (bundle.root) { - require.mixin(mixed, bundle.root); - } - - context.defined[modulePrefix + "/" + loc + "/" + moduleSuffix] = mixed; - } - } - } - - //Finally define the default locale. Wait to the end of the property - //loop above so that the default locale bundle has been properly mixed - //together. - context.defined[master] = context.defined[modulePrefix + "/" + defLoc + "/" + moduleSuffix]; - - //Handle any best fit locale definitions. - if (bestFit) { - for (loc in bestFit) { - if (!(loc in empty)) { - context.defined[modulePrefix + "/" + loc + "/" + moduleSuffix] = context.defined[modulePrefix + "/" + bestFit[loc] + "/" + moduleSuffix]; - } - } - } - } - } - }); -}()); -/** - * @license RequireJS text Copyright (c) 2010, The Dojo Foundation All Rights Reserved. - * Available via the MIT or new BSD license. - * see: http://github.com/jrburke/requirejs for details - */ -/*jslint regexp: false, nomen: false, plusplus: false */ -/*global require: false, XMLHttpRequest: false, ActiveXObject: false */ - - -(function () { - var progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], - xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, - bodyRegExp = /]*>\s*([\s\S]+)\s*<\/body>/im; - - if (!require.textStrip) { - require.textStrip = function (text) { - //Strips declarations so that external SVG and XML - //documents can be added to a document without worry. Also, if the string - //is an HTML document, only the part inside the body tag is returned. - if (text) { - text = text.replace(xmlRegExp, ""); - var matches = text.match(bodyRegExp); - if (matches) { - text = matches[1]; - } - } else { - text = ""; - } - return text; - }; - } - - //Upgrade require to add some methods for XHR handling. But it could be that - //this require is used in a non-browser env, so detect for existing method - //before attaching one. - if (!require.getXhr) { - require.getXhr = function () { - //Would love to dump the ActiveX crap in here. Need IE 6 to die first. - var xhr, i, progId; - if (typeof XMLHttpRequest !== "undefined") { - return new XMLHttpRequest(); - } else { - for (i = 0; i < 3; i++) { - progId = progIds[i]; - try { - xhr = new ActiveXObject(progId); - } catch (e) {} - - if (xhr) { - progIds = [progId]; // so faster next time - break; - } - } - } - - if (!xhr) { - throw new Error("require.getXhr(): XMLHttpRequest not available"); - } - - return xhr; - }; - } - - if (!require.fetchText) { - require.fetchText = function (url, callback) { - var xhr = require.getXhr(); - xhr.open('GET', url, true); - xhr.onreadystatechange = function (evt) { - //Do not explicitly handle errors, those should be - //visible via console output in the browser. - if (xhr.readyState === 4) { - callback(xhr.responseText); - } - }; - xhr.send(null); - }; - } - - require.plugin({ - prefix: "text", - - /** - * This callback is prefix-specific, only gets called for this prefix - */ - require: function (name, deps, callback, context) { - //No-op, require never gets these text items, they are always - //a dependency, see load for the action. - }, - - /** - * Called when a new context is defined. Use this to store - * context-specific info on it. - */ - newContext: function (context) { - require.mixin(context, { - text: {}, - textWaiting: [] - }); - }, - - /** - * Called when a dependency needs to be loaded. - */ - load: function (name, contextName) { - //Name has format: some.module!filext!strip!text - //The strip and text parts are optional. - //if strip is present, then that means only get the string contents - //inside a body tag in an HTML string. For XML/SVG content it means - //removing the declarations so the content can be inserted - //into the current doc without problems. - //If text is present, it is the actual text of the file. - var strip = false, text = null, key, url, index = name.indexOf("."), - modName = name.substring(0, index), fullKey, - ext = name.substring(index + 1, name.length), - context = require.s.contexts[contextName], - tWaitAry = context.textWaiting; - - index = ext.indexOf("!"); - if (index !== -1) { - //Pull off the strip arg. - strip = ext.substring(index + 1, ext.length); - ext = ext.substring(0, index); - index = strip.indexOf("!"); - if (index !== -1 && strip.substring(0, index) === "strip") { - //Pull off the text. - text = strip.substring(index + 1, strip.length); - strip = "strip"; - } else if (strip !== "strip") { - //strip is actually the inlined text. - text = strip; - strip = null; - } - } - key = modName + "!" + ext; - fullKey = strip ? key + "!" + strip : key; - - //Store off text if it is available for the given key and be done. - if (text !== null && !context.text[key]) { - context.defined[name] = context.text[key] = text; - return; - } - - //If text is not available, load it. - if (!context.text[key] && !context.textWaiting[key] && !context.textWaiting[fullKey]) { - //Keep track that the fullKey needs to be resolved, during the - //orderDeps stage. - if (!tWaitAry[fullKey]) { - tWaitAry[fullKey] = tWaitAry[(tWaitAry.push({ - name: name, - key: key, - fullKey: fullKey, - strip: !!strip - }) - 1)]; - } - - //Load the text. - url = require.nameToUrl(modName, "." + ext, contextName); - context.loaded[name] = false; - require.fetchText(url, function (text) { - context.text[key] = text; - context.loaded[name] = true; - }); - } - }, - - /** - * Called when the dependencies of a module are checked. - */ - checkDeps: function (name, deps, context) { - //No-op, checkDeps never gets these text items, they are always - //a dependency, see load for the action. - }, - - /** - * Called to determine if a module is waiting to load. - */ - isWaiting: function (context) { - return !!context.textWaiting.length; - }, - - /** - * Called when all modules have been loaded. - */ - orderDeps: function (context) { - //Clear up state since further processing could - //add more things to fetch. - var i, dep, text, tWaitAry = context.textWaiting; - context.textWaiting = []; - for (i = 0; (dep = tWaitAry[i]); i++) { - text = context.text[dep.key]; - context.defined[dep.name] = dep.strip ? require.textStrip(text) : text; - } - } - }); -}()); -/** - * @license RequireJS jsonp Copyright (c) 2010, The Dojo Foundation All Rights Reserved. - * Available via the MIT or new BSD license. - * see: http://github.com/jrburke/requirejs for details - */ -/*jslint nomen: false, plusplus: false */ -/*global require: false, setTimeout: false */ - - -(function () { - var countId = 0; - - //A place to hold callback functions - require._jsonp = {}; - - require.plugin({ - prefix: "jsonp", - - /** - * This callback is prefix-specific, only gets called for this prefix - */ - require: function (name, deps, callback, context) { - //No-op, require never gets these jsonp items, they are always - //a dependency, see load for the action. - }, - - /** - * Called when a new context is defined. Use this to store - * context-specific info on it. - */ - newContext: function (context) { - require.mixin(context, { - jsonpWaiting: [] - }); - }, - - /** - * Called when a dependency needs to be loaded. - */ - load: function (name, contextName) { - //Name has format: some/url?param1=value1&callback=? - //where the last question mark indicates where the jsonp callback - //function name needs to go. - var index = name.indexOf("?"), - url = name.substring(0, index), - params = name.substring(index + 1, name.length), - context = require.s.contexts[contextName], - data = { - name: name - }, - funcName = "f" + (countId++), - head = require.s.head, - node = head.ownerDocument.createElement("script"); - - //Create JSONP callback function - require._jsonp[funcName] = function (value) { - data.value = value; - context.loaded[name] = true; - //Use a setTimeout for cleanup because some older IE versions vomit - //if removing a script node while it is being evaluated. - setTimeout(function () { - head.removeChild(node); - delete require._jsonp[funcName]; - }, 15); - }; - - //Hold on to the data for later dependency resolution in orderDeps. - context.jsonpWaiting.push(data); - - //Build up the full JSONP URL - url = require.nameToUrl(url, "?", contextName); - //nameToUrl call may or may not have placed an ending ? on the URL, - //be sure there is one and add the rest of the params. - url += (url.indexOf("?") === -1 ? "?" : "") + params.replace("?", "require._jsonp." + funcName); - - context.loaded[name] = false; - node.type = "text/javascript"; - node.charset = "utf-8"; - node.src = url; - - //Use async so Gecko does not block on executing the script if something - //like a long-polling comet tag is being run first. Gecko likes - //to evaluate scripts in DOM order, even for dynamic scripts. - //It will fetch them async, but only evaluate the contents in DOM - //order, so a long-polling script tag can delay execution of scripts - //after it. But telling Gecko we expect async gets us the behavior - //we want -- execute it whenever it is finished downloading. Only - //Helps Firefox 3.6+ - node.async = true; - - head.appendChild(node); - }, - - /** - * Called when the dependencies of a module are checked. - */ - checkDeps: function (name, deps, context) { - //No-op, checkDeps never gets these jsonp items, they are always - //a dependency, see load for the action. - }, - - /** - * Called to determine if a module is waiting to load. - */ - isWaiting: function (context) { - return !!context.jsonpWaiting.length; - }, - - /** - * Called when all modules have been loaded. - */ - orderDeps: function (context) { - //Clear up state since further processing could - //add more things to fetch. - var i, dep, waitAry = context.jsonpWaiting; - context.jsonpWaiting = []; - for (i = 0; (dep = waitAry[i]); i++) { - context.defined[dep.name] = dep.value; - } - } - }); -}()); -/** - * @license RequireJS order Copyright (c) 2010, The Dojo Foundation All Rights Reserved. - * Available via the MIT or new BSD license. - * see: http://github.com/jrburke/requirejs for details - */ -/*jslint nomen: false, plusplus: false */ -/*global require: false, window: false, document: false, setTimeout: false */ - - -(function () { - //Sadly necessary browser inference due to differences in the way - //that browsers load and execute dynamically inserted javascript - //and whether the script/cache method works. - //Currently, Gecko and Opera do not load/fire onload for scripts with - //type="script/cache" but they execute injected scripts in order - //unless the 'async' flag is present. - var supportsInOrderExecution = ((window.opera && Object.prototype.toString.call(window.opera) === "[object Opera]") || - //If Firefox 2 does not have to be supported, then - //a better check may be: - //('mozIsLocallyAvailable' in window.navigator) - ("MozAppearance" in document.documentElement.style)), - readyRegExp = /^(complete|loaded)$/; - - //Callback used by the type="script/cache" callback that indicates a script - //has finished downloading. - function scriptCacheCallback(evt) { - var node = evt.currentTarget || evt.srcElement, i, - context, contextName, moduleName, waiting, cached; - - if (evt.type === "load" || readyRegExp.test(node.readyState)) { - //Pull out the name of the module and the context. - contextName = node.getAttribute("data-requirecontext"); - moduleName = node.getAttribute("data-requiremodule"); - context = require.s.contexts[contextName]; - waiting = context.orderWaiting; - cached = context.orderCached; - - //Mark this cache request as loaded - cached[moduleName] = true; - - //Find out how many ordered modules have loaded - for (i = 0; cached[waiting[i]]; i++) {} - if (i > 0) { - require(waiting.splice(0, i), contextName); - } - - //If no other order cache items are in the queue, do some cleanup. - if (!waiting.length) { - context.orderCached = {}; - } - - //Remove this script tag from the DOM - //Use a setTimeout for cleanup because some older IE versions vomit - //if removing a script node while it is being evaluated. - setTimeout(function () { - node.parentNode.removeChild(node); - }, 15); - } - } - - require.plugin({ - prefix: "order", - - /** - * This callback is prefix-specific, only gets called for this prefix - */ - require: function (name, deps, callback, context) { - //No-op, require never gets these order items, they are always - //a dependency, see load for the action. - }, - - /** - * Called when a new context is defined. Use this to store - * context-specific info on it. - */ - newContext: function (context) { - require.mixin(context, { - orderWaiting: [], - orderCached: {} - }); - }, - - /** - * Called when a dependency needs to be loaded. - */ - load: function (name, contextName) { - var context = require.s.contexts[contextName], - url = require.nameToUrl(name, null, contextName); - - //Make sure the async attribute is not set for any pathway involving - //this script. - require.s.skipAsync[url] = true; - if (supportsInOrderExecution) { - //Just a normal script tag append, but without async attribute - //on the script. - require([name], contextName); - } else { - //Credit to LABjs author Kyle Simpson for finding that scripts - //with type="script/cache" allow scripts to be downloaded into - //browser cache but not executed. Use that - //so that subsequent addition of a real type="text/javascript" - //tag will cause the scripts to be executed immediately in the - //correct order. - context.orderWaiting.push(name); - context.loaded[name] = false; - require.attach(url, contextName, name, scriptCacheCallback, "script/cache"); - } - }, - - /** - * Called when the dependencies of a module are checked. - */ - checkDeps: function (name, deps, context) { - //No-op, checkDeps never gets these order items, they are always - //a dependency, see load for the action. - }, - - /** - * Called to determine if a module is waiting to load. - */ - isWaiting: function (context) { - return !!context.orderWaiting.length; - }, - - /** - * Called when all modules have been loaded. Not needed for this plugin. - * State is reset as part of scriptCacheCallback. - */ - orderDeps: function (context) { - } - }); -}()); - -//Target build file for a require.js that has all of require's functionality, -//and includes specific plugins: i18n and text. diff --git a/build/editor.html b/demo/requirejs+build.html similarity index 50% rename from build/editor.html rename to demo/requirejs+build.html index 8f8a7895..72d50dbc 100644 --- a/build/editor.html +++ b/demo/requirejs+build.html @@ -8,8 +8,8 @@ body { overflow: hidden; } - - #editor { + + #editor { margin: 0; position: absolute; top: 0; @@ -27,18 +27,22 @@ alert("Ace Rocks " + items[i]); } } - - - - + + diff --git a/demo/scrollable-page.html b/demo/scrollable-page.html new file mode 100644 index 00000000..ef725c4a --- /dev/null +++ b/demo/scrollable-page.html @@ -0,0 +1,155 @@ + + + + + + Editor + + + +
    + + scroll down ⇓ + +
    +
    function foo(items) {
    +    var i;
    +    for (i = 0; i < items.length; i++) {
    +        alert("Ace Rocks " + items[i]);
    +    }
    +
    +}
    +
    +
    + press F11 to switch to fullscreen mode +
    + + + + + +
    + + + + + + diff --git a/demo/settings_menu.html b/demo/settings_menu.html new file mode 100644 index 00000000..9fb82a43 --- /dev/null +++ b/demo/settings_menu.html @@ -0,0 +1,49 @@ + + + + + + Editor + + + + +
    
    +    
    +
    +
    +
    +
    +
    +
    diff --git a/demo/show_own_source.js b/demo/show_own_source.js
    new file mode 100644
    index 00000000..a9e0ec69
    --- /dev/null
    +++ b/demo/show_own_source.js
    @@ -0,0 +1,16 @@
    +if (typeof ace == "undefined" && typeof require == "undefined") {
    +    document.body.innerHTML = "

    couldn't find ace.js file,
    " + + "to build it run node Makefile.dryice.js full" +} else if (typeof ace == "undefined" && typeof require != "undefined") { + require(["ace/ace"], setValue) +} else { + require = ace.require; + setValue() +} + +function setValue() { + require("ace/lib/net").get(document.baseURI, function(t){ + var el = document.getElementById("editor"); + el.env.editor.setValue(t, 1); + }) +} \ No newline at end of file diff --git a/demo/static-highlighter.html b/demo/static-highlighter.html new file mode 100644 index 00000000..8e43789d --- /dev/null +++ b/demo/static-highlighter.html @@ -0,0 +1,83 @@ + + + + + Static Code highlighter using Ace + + + + + +

    Client Side Syntax Highlighting

    + +

    Syntax highlighting using Ace language modes and themes.

    + +
    +.code { + width: 50%; + white-space: pre-wrap; + border: solid lightgrey 1px +} + +
    + +
    +function wobble (flam) {
    +    return flam.wobbled = true;
    +}
    +
    +
    + + +
    +--[[-- +num_args takes in 5.1 byte code and extracts the number of arguments from its function header. +--]]-- + +function int(t) + return t:byte(1) + t:byte(2) * 0x100 + t:byte(3) * 0x10000 + t:byte(4) * 0x1000000 +end + +function num_args(func) + local dump = string.dump(func) + local offset, cursor = int(dump:sub(13)), offset + 26 + --Get the params and var flag (whether there's a ... in the param) + return dump:sub(cursor):byte(), dump:sub(cursor+1):byte() +end + +
    + + + + + + + diff --git a/demo/static-highlighter/client.html b/demo/static-highlighter/client.html new file mode 100644 index 00000000..93d20909 --- /dev/null +++ b/demo/static-highlighter/client.html @@ -0,0 +1,47 @@ + + + + + + Static Code highlighter using Ace + + + + +

    Client Side Syntax Highlighting

    + +

    Syntax highlighting using Ace language modes and themes.

    + +
    + + + + + + diff --git a/demo/static-highlighter/server.js b/demo/static-highlighter/server.js new file mode 100644 index 00000000..ea8361d4 --- /dev/null +++ b/demo/static-highlighter/server.js @@ -0,0 +1,42 @@ +/** + * Simple node.js server, which generates the synax highlighted version of itself + * using the Ace modes and themes on the server and serving a static web page. + */ + +// include ace search path and modules +require("amd-loader"); + +var http = require("http"); +var fs = require("fs"); +var resolve = require("path").resolve; + +// load the highlighter and the desired mode and theme +var highlighter = require("../../lib/ace/ext/static_highlight"); +var JavaScriptMode = require("../../lib/ace/mode/javascript").Mode; +var theme = require("../../lib/ace/theme/twilight"); + +var port = process.env.PORT || 2222; + +http.createServer(function(req, res) { + var url = req.url; + var path = /[^#?\x00]*/.exec(url)[0]; + var root = resolve(__dirname + "/../../").replace(/\\/g, "/"); + path = resolve(root + "/" + path).replace(/\\/g, "/"); + if (path.indexOf(root + "/") != 0) + path = __filename; + res.writeHead(200, {"Content-Type": "text/html; charset=utf-8"}); + fs.readFile(path, "utf8", function(err, data) { + if (err) data = err.message; + var highlighted = highlighter.render(data, new JavaScriptMode(), theme); + res.end( + '\n' + + '\n' + + highlighted.html + + '' + ); + }); +}).listen(port); + +console.log("Listening on port " + port); \ No newline at end of file diff --git a/demo/statusbar.html b/demo/statusbar.html new file mode 100644 index 00000000..d38bfcb9 --- /dev/null +++ b/demo/statusbar.html @@ -0,0 +1,61 @@ + + + + + + ACE Editor StatusBar Demo + + + + +
    
    +
    ace rocks!
    + + + + + + + diff --git a/demo/styles.css b/demo/styles.css deleted file mode 100644 index 3f244f7c..00000000 --- a/demo/styles.css +++ /dev/null @@ -1,47 +0,0 @@ -html { - height: 100%; - overflow: hidden; -} - -body { - overflow: hidden; - margin: 0; - padding: 0; - height: 100%; - width: 100%; - font-family: Arial, Helvetica, sans-serif, Tahoma, Verdana, sans-serif; - font-size: 12px; - background: rgb(14, 98, 165); - color: white; -} - -#editor { - position: absolute; - top: 60px; - left: 0px; - background: white; -} - -#controls { - width: 100%; -} - -#cockpitInput { - position: absolute; - width: 100%; - bottom: 0; - - border: none; outline: none; - font-family: consolas, courier, monospace; - font-size: 120%; -} - -#cockpitOutput { - padding: 10px; - margin: 0 15px; - border: 1px solid #AAA; - -moz-border-radius-topleft: 10px; - -moz-border-radius-topright: 10px; - border-top-left-radius: 4px; border-top-right-radius: 4px; - background: #DDD; color: #000; -} \ No newline at end of file diff --git a/doc/Editor.mm b/doc/Editor.mm deleted file mode 100644 index ebcd7a5f..00000000 --- a/doc/Editor.mm +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 00000000..455a1c05 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,17 @@ +# 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 on the build system, please see that repo. + +# Building + +In the root directory, just run: + + make doc + +In this directory, just run: + + npm install + node build.js + diff --git a/doc/additionalObjs.json b/doc/additionalObjs.json new file mode 100644 index 00000000..dd734f78 --- /dev/null +++ b/doc/additionalObjs.json @@ -0,0 +1,27 @@ +{ + "Array" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array", + "Boolean" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Boolean", + "Date" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date", + "Error" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error", + "EvalError" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/EvalError", + "RangeError" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RangeError", + "ReferenceError" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/ReferenceError", + "SyntaxError" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/SyntaxError", + "TypeError" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/TypeError", + "URIError" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/URIError", + "Function" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function", + "Infinity" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Infinity", + "JSON" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON", + "Math" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math", + "NaN" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/NaN", + "Number" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number", + "Object" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object", + "RegExp" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp", + "String" : "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String", + + "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..2b1b469c --- /dev/null +++ b/doc/build.js @@ -0,0 +1,67 @@ +var fs = require("fs"); +var path = require("path"); +var panino = require("panino"); +var srcPath = __dirname + "/../lib/ace"; +var buildType = process.argv.splice(2)[0]; + +var options = { + title : "Ace API", + parseType : "jsd", + linkFormat : function(linkHtml) { + var href = linkHtml.href; + var o = href.match(/(.+)\.html(#.+)/); + var c = href.match(/#(.+)/); + + if ( o !== null ) { + href = href.replace(href, '#nav=api&api=' + o[1]);// + '§ion=' + o[2]); + } + + linkHtml.href = href; + + return linkHtml; + }, + output : "../api/", + outputAssets : "../api/resources", + skin : "./template/jade/layout.jade", + assets : "./template/resources", + additionalObjs : "./additionalObjs.json", + exclude : ["**/*_test.js", "**/mode/**", "default_commands.js", "multi_select_commands.js", "**/test/**", "**/theme/**", "**/worker/**"], + index : "./index.md" +}; + +files = [srcPath]; + +panino.parse(files, options, function (err, ast) { + if (err) { + console.error(err); + process.exit(1); + } + + panino.render(buildType || 'html', ast, options, function (err) { + if (err) { + console.error(err); + process.exit(1); + } + + /*fs.readdir(options.output, function (err, files) { + files.forEach(function(file) { + if (file.match(/\.html$/)) { + var outFile = options.output + "/" + file; + fs.readFile(outFile, "utf8", function(err, data) { + var otherPageRegExp = new RegExp('=2.2.0", + "asset-smasher": "0.2.0" + } +} \ No newline at end of file diff --git a/doc/site/images/ac-logo.png b/doc/site/images/ac-logo.png new file mode 100644 index 00000000..6ca069a3 Binary files /dev/null and b/doc/site/images/ac-logo.png differ diff --git a/doc/site/images/ace-logo.png b/doc/site/images/ace-logo.png new file mode 100644 index 00000000..886a8df31 Binary files /dev/null and b/doc/site/images/ace-logo.png differ diff --git a/doc/site/images/ace-tab.png b/doc/site/images/ace-tab.png new file mode 100644 index 00000000..50298c10 Binary files /dev/null and b/doc/site/images/ace-tab.png differ diff --git a/doc/site/images/ace.png b/doc/site/images/ace.png new file mode 100644 index 00000000..9b7c40c8 Binary files /dev/null and b/doc/site/images/ace.png differ diff --git a/doc/site/images/background.png b/doc/site/images/background.png new file mode 100644 index 00000000..c6ee9313 Binary files /dev/null and b/doc/site/images/background.png differ diff --git a/doc/site/images/body_background.png b/doc/site/images/body_background.png new file mode 100644 index 00000000..2101cdfa Binary files /dev/null and b/doc/site/images/body_background.png differ diff --git a/doc/site/images/bottombar.png b/doc/site/images/bottombar.png new file mode 100644 index 00000000..2e76bf84 Binary files /dev/null and b/doc/site/images/bottombar.png differ diff --git a/doc/site/images/cloud9-logo.png b/doc/site/images/cloud9-logo.png new file mode 100644 index 00000000..5466cf7e Binary files /dev/null and b/doc/site/images/cloud9-logo.png differ diff --git a/doc/site/images/codecademy-logo.png b/doc/site/images/codecademy-logo.png new file mode 100644 index 00000000..e27947ae Binary files /dev/null and b/doc/site/images/codecademy-logo.png differ diff --git a/doc/site/images/codiad.png b/doc/site/images/codiad.png new file mode 100644 index 00000000..c77a446c Binary files /dev/null and b/doc/site/images/codiad.png differ diff --git a/doc/site/images/crunchapp-logo.png b/doc/site/images/crunchapp-logo.png new file mode 100644 index 00000000..1ed8d2f7 Binary files /dev/null and b/doc/site/images/crunchapp-logo.png differ diff --git a/doc/site/images/empty-logo.png b/doc/site/images/empty-logo.png new file mode 100644 index 00000000..c0bbbbe3 Binary files /dev/null and b/doc/site/images/empty-logo.png differ diff --git a/doc/site/images/favicon.ico b/doc/site/images/favicon.ico new file mode 100644 index 00000000..e97c70f6 Binary files /dev/null and b/doc/site/images/favicon.ico differ diff --git a/doc/site/images/firefox-logo.png b/doc/site/images/firefox-logo.png new file mode 100644 index 00000000..711fad62 Binary files /dev/null and b/doc/site/images/firefox-logo.png differ diff --git a/doc/site/images/fork_on_github.png b/doc/site/images/fork_on_github.png new file mode 100644 index 00000000..e8ddb66e Binary files /dev/null and b/doc/site/images/fork_on_github.png differ diff --git a/doc/site/images/github-logo.png b/doc/site/images/github-logo.png new file mode 100644 index 00000000..9456846a Binary files /dev/null and b/doc/site/images/github-logo.png differ diff --git a/doc/site/images/habitat-logo.svg b/doc/site/images/habitat-logo.svg new file mode 100644 index 00000000..986c3687 --- /dev/null +++ b/doc/site/images/habitat-logo.svg @@ -0,0 +1 @@ +Slice 1 \ No newline at end of file diff --git a/doc/site/images/header-bg.png b/doc/site/images/header-bg.png new file mode 100644 index 00000000..aaab9e3e Binary files /dev/null and b/doc/site/images/header-bg.png differ diff --git a/doc/site/images/ideone-logo.png b/doc/site/images/ideone-logo.png new file mode 100644 index 00000000..cbee7fad Binary files /dev/null and b/doc/site/images/ideone-logo.png differ diff --git a/doc/site/images/khan-logo.png b/doc/site/images/khan-logo.png new file mode 100644 index 00000000..3c389f8e Binary files /dev/null and b/doc/site/images/khan-logo.png differ diff --git a/doc/site/images/logo.png b/doc/site/images/logo.png new file mode 100644 index 00000000..6af129d9 Binary files /dev/null and b/doc/site/images/logo.png differ 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/images/modx-logo-4.png b/doc/site/images/modx-logo-4.png new file mode 100644 index 00000000..a640ef23 Binary files /dev/null and b/doc/site/images/modx-logo-4.png differ diff --git a/doc/site/images/pixie-logo.png b/doc/site/images/pixie-logo.png new file mode 100644 index 00000000..99968c46 Binary files /dev/null and b/doc/site/images/pixie-logo.png differ diff --git a/doc/site/images/plunker.png b/doc/site/images/plunker.png new file mode 100644 index 00000000..e8388db6 Binary files /dev/null and b/doc/site/images/plunker.png differ diff --git a/doc/site/images/processwire-logo.svg b/doc/site/images/processwire-logo.svg new file mode 100644 index 00000000..8f64d71c --- /dev/null +++ b/doc/site/images/processwire-logo.svg @@ -0,0 +1,44 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/doc/site/images/repl.it-logo.png b/doc/site/images/repl.it-logo.png new file mode 100644 index 00000000..bf383a62 Binary files /dev/null and b/doc/site/images/repl.it-logo.png differ diff --git a/doc/site/images/rstudio_logo_64.png b/doc/site/images/rstudio_logo_64.png new file mode 100644 index 00000000..3d402a21 Binary files /dev/null and b/doc/site/images/rstudio_logo_64.png differ diff --git a/doc/site/images/sassmeister-logo.png b/doc/site/images/sassmeister-logo.png new file mode 100644 index 00000000..7ecc8939 Binary files /dev/null and b/doc/site/images/sassmeister-logo.png differ diff --git a/doc/site/images/shiftedit-logo.png b/doc/site/images/shiftedit-logo.png new file mode 100644 index 00000000..b505f9df Binary files /dev/null and b/doc/site/images/shiftedit-logo.png differ diff --git a/doc/site/images/spandexio-logo.png b/doc/site/images/spandexio-logo.png new file mode 100644 index 00000000..e2fdb79d Binary files /dev/null and b/doc/site/images/spandexio-logo.png differ diff --git a/doc/site/images/stypi-logo.png b/doc/site/images/stypi-logo.png new file mode 100644 index 00000000..ef1af148 Binary files /dev/null and b/doc/site/images/stypi-logo.png differ diff --git a/doc/site/images/sx-logo.png b/doc/site/images/sx-logo.png new file mode 100644 index 00000000..0604d279 Binary files /dev/null and b/doc/site/images/sx-logo.png differ diff --git a/doc/site/images/textimage.png b/doc/site/images/textimage.png new file mode 100644 index 00000000..6f7d3130 Binary files /dev/null and b/doc/site/images/textimage.png differ diff --git a/doc/site/images/weecod-logo.png b/doc/site/images/weecod-logo.png new file mode 100644 index 00000000..c4970727 Binary files /dev/null and b/doc/site/images/weecod-logo.png differ diff --git a/doc/site/images/wolf_3d_logo_trans.png b/doc/site/images/wolf_3d_logo_trans.png new file mode 100644 index 00000000..fe61b9b4 Binary files /dev/null and b/doc/site/images/wolf_3d_logo_trans.png differ diff --git a/doc/site/images/zorba-logo.png b/doc/site/images/zorba-logo.png new file mode 100644 index 00000000..ad2c22f6 Binary files /dev/null and b/doc/site/images/zorba-logo.png differ diff --git a/doc/site/iphone.css b/doc/site/iphone.css new file mode 100644 index 00000000..dd90db03 --- /dev/null +++ b/doc/site/iphone.css @@ -0,0 +1,25 @@ +#wrapper { + position:relative; + overflow:hidden; +} + +#wrapper .content .column1 { + margin:0 16px 0 15px; +} + +#header .content .signature { + font-size:18px; + bottom:0; +} + +UL.menu-list LI { + font-size:22px; +} + +UL.menu-footer LI { + font-size:22px; +} + +PRE{ + font-size:22px; +} \ No newline at end of file diff --git a/doc/site/js/ga.js b/doc/site/js/ga.js new file mode 100644 index 00000000..e381972d --- /dev/null +++ b/doc/site/js/ga.js @@ -0,0 +1,9 @@ + var _gaq = _gaq || []; + _gaq.push(['_setAccount', 'UA-31998201-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/site/js/main.js b/doc/site/js/main.js new file mode 100644 index 00000000..39dc202d --- /dev/null +++ b/doc/site/js/main.js @@ -0,0 +1,187 @@ +var editor; +var embedded_editor; +$(function() { + if (typeof ace !== "undefined") { + ace.config.set("workerPath", "build/src-min"); + editor = ace.edit("ace_editor_demo"); + editor.container.style.opacity = ""; + embedded_editor = ace.edit("embedded_ace_code"); + embedded_editor.container.style.opacity = ""; + embedded_editor.session.setMode("ace/mode/html"); + embedded_editor.setAutoScrollEditorIntoView(true); + embedded_editor.setOption("maxLines", 40); + + editor.setOptions({ + maxLines: 30, + mode: "ace/mode/javascript", + autoScrollEditorIntoView: true + }); + + ace.config.loadModule("ace/ext/emmet", function() { + ace.require("ace/lib/net").loadScript("http://cloud9ide.github.io/emmet-core/emmet.js", function() { + embedded_editor.setOption("enableEmmet", true); + editor.setOption("enableEmmet", true); + }); + }); + + ace.config.loadModule("ace/ext/language_tools", function() { + embedded_editor.setOptions({ + enableSnippets: true, + enableBasicAutocompletion: true + }); + editor.setOptions({ + enableSnippets: true, + enableBasicAutocompletion: true + }); + }); + } else { + document.body.insertAdjacentHTML("afterbegin", '
    \ +
    \ + \ + Oh No! Couldn\'t load build/src/ace.js.
    \ + You can build it by running node Makefile.dryice.js
    \ + Or download older version by running git submodule update --init --recursive
    \ +
    \ +
    '); + } + $("ul.menu-list").mousedown(function(e) { + if (e.button === 1) { + e.preventDefault(); + } + }); + + $("ul.menu-list li").click(function(e) { + if (e.target.tagName !== "A") { + var href = $(this).find("a").attr("href"); + if (e.button == 1) + window.open(href, "_blank"); + else + window.location = href; + } + }); + + // used when page is access directly + function magicClickInterceptor(e) { + e.preventDefault(); + + var state = {}; + state.api = $(this).attr("href").substring(6, $(this).attr("href").length - 5); + $.bbq.pushState(state); + + var _self = $(this); + $("#apiHolder").load($(this).attr("href") + " #documentation", function(){ + $("#apiHolder").removeClass("apiIntro").removeClass("span9"); + $("#documentation").removeClass("span9").addClass("span7"); + ux(); + setupClicker(); + + // handles dropping in from new link + var section = $.bbq.getState("section"); + if (section) { + $("li#dropdown_" + section.replace(/\./g, '\\.') + " a").triggerHandler('click'); + } + + //setupDisqus(_self.attr("href")); + }); + } + + $('.menu-item a').click(magicClickInterceptor); + $('a.argument').click(magicClickInterceptor); + + $('a.external').click(function(e) { + e.preventDefault(); + }); + + var tabs = $("#tabnav"), + tab_a_selector = "a"; + + var firstLoad = true; + + tabs.find(tab_a_selector).click(function(e) { + e.preventDefault(); + if ($(this).attr("href") === "/") { + window.location = "http://ace.ajax.org"; + return; + } + if ($(this).attr("href").indexOf("#api") === 0) { + $("#top_container").addClass("collapse"); + scrollIntoPosition(null, 0); + } + else if ($(this).is(":visible")) { + if (firstLoad) { + firstLoad = false; + setTimeout(function() { + $("#top_container").removeClass("collapse"); + scrollIntoPosition(e.target); + }, 700); + } + else { + $("#top_container").removeClass("collapse"); + scrollIntoPosition(e.target); + } + } + + function scrollIntoPosition(el, overridePosition) { + if (typeof overridePosition !== "undefined") { + $("body").stop().animate({ + scrollTop: overridePosition + }, 400); + } + else if ($("body").scrollTop() > 345) { + $("body").stop().animate({ + scrollTop: ($(el).offset().top - 10) + }, 400); + } + } + + $(this).tab("show"); + + var state = {}; + state.nav = $(this).attr("href").substr(1); + $.bbq.pushState(state); + }); + + $('#tabnav a[data-toggle="tab"]').on('shown', function (e) { + $(".tab-content .tab-pane.active .ace_editor").each(function(i, el){ + el.env.onResize(); + }); + }); + + $(window).on("hashchange", function(e) { + _gaq.push(['_trackPageview',location.pathname + location.search + location.hash]); + tabs.each(function() { + var idx = $.bbq.getState("nav") || "about"; + var section = e.fragment.split("&")[1] || ""; + $(this).find(tab_a_selector + "[href='#" + idx + "']").triggerHandler('click'); + + // handles dropping in from new link + var api = $.bbq.getState("api"); + if (api) { + $(tab_a_selector + "[href='./api/" + api + ".html']").triggerHandler('click'); + } + }); + }).trigger("hashchange"); + + highlight(); +}); + + + +function highlight() { + var highlighter = ace.require("ace/ext/static_highlight") + var dom = ace.require("ace/lib/dom") + function qsa(sel) { + var els = document.querySelectorAll(sel); + var result = []; + for (var i = 0, l = els.length; i < l; i++) + result[i] = els[i]; + return result; + } + + qsa("code[class]").forEach(function(el) { + var m = el.className.match(/language-(\w+)|(javascript)/); + if (!m) return + var mode = "ace/mode/" + (m[1] || m[2]); + highlighter.highlight(el, {mode: mode, theme: "ace/theme/xcode"}) + }); +} \ No newline at end of file diff --git a/doc/site/style.css b/doc/site/style.css new file mode 100644 index 00000000..1167340a --- /dev/null +++ b/doc/site/style.css @@ -0,0 +1,509 @@ +body { + margin:0; + padding:0; + background-color:#e6f5fc; + font-family: Helvetica, Arial; +} + + + +#ace_editor_demo, #embedded_ace_code { + height: 275px; + border: 1px solid #DDD; + border-radius: 4px; + border-bottom-right-radius: 0px; + margin-top: 5px; +} + +#embedded_ace_code { + height: 525px; +} + +h1, h2, h3, h4, h5, h6 { + font-family: Helvetica; + font-weight: 100; + margin:0; + padding:0; +} + +h2, h3, h4, h5, h6 { + padding-top: 30px; + border-bottom: 1px solid #bedaea; +} + +H2 { + font-size:28px; + color:#263842; + padding-bottom:6px; +} + +H3 { + font-size:22px; + color:#253741; + margin-bottom:8px; +} + +H4 { + font-size:21px; + color:#222222; + margin-bottom:8px; +} + +P { + padding:13px 0; + margin:0; + line-height:21px; + font-size: 15px; +} + +UL{ + font-size: 15px; +} + +#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 { + font-family:Trebuchet MS; + font-size:11px; + color:#ebe4d6; + position:absolute; + bottom:5px; + right:42px; + letter-spacing : 1px; +} + +.content { + width:970px; + position:relative; + margin:0 auto; +} + +#header .content { + height: 100%; + z-index: 90000; +} + +#header .content .logo { + 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: 22px; + left: 329px; +} + +#wrapper { + background:url(images/body_background.png) repeat-x 0 -15px; + min-height:250px; +} + +#wrapper .content { + font-family:Arial; + font-size:14px; + color:#222222; + width: 960px; +} + +#wrapper .content .column1 { + position:relative; + overflow:hidden; + float:left; + width:315px; + margin-right:31px; +} + +#wrapper .content .column2 { + position:relative; + overflow:hidden; + float:left; + /*width:600px;*/ +} + +#top_container h1 { + font-size: 68px; + line-height: 60px; + width: 515px; + float: left; + font-weight: 100; + font-family: Helvetica; + padding: 65px 0 0 14px; + color: #333; +} + +#top_container { + background: url(images/header-bg.png) 0 0; + overflow: hidden; + padding: 11px 36px 19px 40px; + height: 267px; + -webkit-transition: height 0.4s ease-out, opacity 0.4s ease-out, padding 0.4s ease-out, margin 0.4s ease-out; + -moz-transition: height 0.4s ease-out, opacity 0.4s ease-out, padding 0.4s ease-out, margin 0.4s ease-out; + opacity: 1; + margin-top: 25px; +} + +#top_container.collapse { + padding: 0px; + height: 0px; + opacity: 0; + margin: 0; +} + +#page_logo { + padding: 35px 0 15px 0; + width: 350px; + float: right; + text-align: center; + height: 220px; +} + +.fork_on_github { + width:310px; + height:80px; + background:url(images/fork_on_github.png) no-repeat 0 0; + position:relative; + overflow:hidden; + margin-top:49px; + cursor:pointer; +} + +.fork_on_github:hover { + background-position:0 -80px; +} + +.divider { + height: 1px; + background-color:#bedaea; + margin-bottom:3px; +} + +.menu, .site-menu { + padding: 25px 0 0 35px; +} + +UL.content-list { + padding: 15px 0 15px 20px; + margin:0; +} + +UL.content-list li { + padding-left: 10px; + padding-bottom: 3px; +} + +ul.menu-list { + padding: 15px 0; + margin: 0 0 20px 0; + list-style-type: none; + line-height: 16px; + overflow: auto; +} + +ul.menu-list li { + color: #2557B4; + font-family: Helvetica, Trebuchet MS; + font-size: 12px; + padding: 5px; + cursor: pointer; + display: block; + float: left; + margin-right: 15px; + margin-bottom: 20px; + width: 100px; + height: 90px; + border-radius: 5px; + position: relative; + background: rgba(255, 255, 255, 0.7); + margin-left: 22px; + margin-top: 20px; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 0 4px rgba(0, 0, 0, 0.1); + -webkit-transition: box-shadow 0.4s; + -moz-transition: box-shadow 0.4s; + border: 1px solid #999; + background-image: -webkit-repeating-linear-gradient(left, hsla(0,0%,100%,0) 0%, hsla(0,0%,100%,0) 6%, hsla(0,0%,100%, .1) 7.5%), + -webkit-repeating-linear-gradient(left, hsla(0,0%, 0%,0) 0%, hsla(0,0%, 0%,0) 4%, hsla(0,0%, 0%,.03) 4.5%), + -webkit-repeating-linear-gradient(left, hsla(0,0%,100%,0) 0%, hsla(0,0%,100%,0) 1.2%, hsla(0,0%,100%,.15) 2.2%), + + -webkit-linear-gradient(-90deg, hsl(0,0%,78%) 0%, + hsl(0,0%,90%) 47%, + hsl(0,0%,78%) 53%, + hsl(0,0%,70%)100%); + background-image: -moz-repeating-linear-gradient(left, hsla(0,0%,100%,0) 0%, hsla(0,0%,100%,0) 6%, hsla(0,0%,100%, .1) 7.5%), + -moz-repeating-linear-gradient(left, hsla(0,0%, 0%,0) 0%, hsla(0,0%, 0%,0) 4%, hsla(0,0%, 0%,.03) 4.5%), + -moz-repeating-linear-gradient(left, hsla(0,0%,100%,0) 0%, hsla(0,0%,100%,0) 1.2%, hsla(0,0%,100%,.15) 2.2%), + + -moz-linear-gradient(-90deg, hsl(0,0%,78%) 0%, + hsl(0,0%,90%) 47%, + hsl(0,0%,78%) 53%, + hsl(0,0%,70%)100%); +} + +ul.menu-list li:hover { + box-shadow: 0 0 4px rgba(0, 0, 0, 0.5); + -moz-box-shadow: 0 0 4px rgba(0, 0, 0, 0.5); +} + +ul.menu-list li a { + position: absolute; + bottom: 0px; + left: 0px; + color: white; + text-align: center; + font-weight: bold; + text-shadow: 0px 0px 4px rgba(0, 0, 0, 0.8); + width: 100%; + display: block; + background: rgba(0, 0, 0, 0.6); + line-height: 12px; + padding: 4px 0; +} + +UL.menu-list LI a:hover { + text-decoration: none; +} + +li#add_your_site p { + font-size: 32px; + border: 3px solid #34A034; + color: #34A034; + border-radius: 34px; + padding: 3px 4px 4px 5px; + width: 20px; + height: 22px; + line-height: 18px; + position: relative; + left: 33px; + top: 22px; + background: #fff; +} + +ul.menu-list li#add_your_site a { + color: #A3EEA3; +} + +/* This is the animation code. */ +@-webkit-keyframes example { + 0% { -webkit-transform: rotate(0deg); } + 25% { -webkit-transform: rotate(3deg); } + 50% { -webkit-transform: rotate(0deg); } + 75% { -webkit-transform: rotate(-3deg); } +} + +/* This is the element that we apply the animation to. */ +li#add_your_site { + -webkit-animation-name: example; + -webkit-animation-duration: 0.4s; + -webkit-animation-timing-function: ease; /* ease is the default */ + -webkit-animation-delay: 0s; /* 0 is the default */ + -webkit-animation-iteration-count: infinite; /* 1 is the default */ + -webkit-animation-direction: alternate; /* normal is the default */ +} + +A { + color:#2557b4; + text-decoration:none; +} + +A:hover { + text-decoration:underline; +} + +#footer { + height:40px; + position:relative; + overflow:hidden; + background:url(images/bottombar.png) repeat-x 0 0; + position:relative; + margin-top:40px; +} + +UL.menu-footer { + padding:0; + margin:8px 11px 0 0; + list-style-type:none; + float:right; +} + +UL.menu-footer LI { + color:white; + font-family:Arial; + font-size:12px; + display:inline-block; + margin:0 1px; +} + +UL.menu-footer LI A { + color:#8dd0ff; + text-decoration:none; +} + +UL.menu-footer LI A:hover { + text-decoration:underline; +} + +.nav-pills.nav { + margin: 10px 0 25px 0; + padding: 0; + border-radius: 5px; + border: 1px solid #d7d7d7; + background: #eeeeee; + background: -moz-linear-gradient(top, #eeeeee 0%, #cccccc 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#eeeeee), color-stop(100%,#cccccc)); + background: -webkit-linear-gradient(top, #eeeeee 0%,#cccccc 100%); + background: -o-linear-gradient(top, #eeeeee 0%,#cccccc 100%); + background: -ms-linear-gradient(top, #eeeeee 0%,#cccccc 100%); + background: linear-gradient(to bottom, #eeeeee 0%,#cccccc 100%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 ); + overflow: hidden; +} + +.nav-pills > .active > a, .nav-pills > .active > a:hover { + color: white; + background-color: #555; + box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.8); + text-shadow: 0px 0px 3px #000; +} + +.nav-tabs > li > a, .nav-pills > li > a { + padding-right: 17px; + padding-left: 17px; + border-right: 1px solid #bbb; + border-radius: 0; + margin: 0; + line-height: 25px; + font-size: 14px; + color: #333; + text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.3); + box-shadow: 0 0 1px rgba(255, 255, 255, 1); + -moz-box-shadow: 0 0 1px rgba(255, 255, 255, 1); + -webkit-transition: background 0.2s; + -moz-transition: background 0.2s; +} + +.nav.nav-pills li:first-child > a { + padding-left: 28px; + padding-right: 28px; +} + +.nav.nav-pills li:first-child > a > img { + width: 34px; +} + +.nav.nav-pills li:last-child > a { + border-right: none; + box-shadow: none; + -moz-box-shadow: none; +} + +.tab-content { + margin-bottom: 50px; +} + +.tab-content > .active, .pill-content > .active { + padding: 25px 30px; +} + +#top_container, .tab-content > .active, .pill-content > .active { + border: 1px solid #DDD; + border-radius: 5px; + -moz-border-radius: 5px; +} + +.tab-content > .active, .pill-content > .active { + background: rgba(255, 255, 255, 0.7); +} + +pre .xml .javascript, pre .xml .css { + opacity: 1; +} + +#embed_link { + text-align: right; + padding-top: 0; +} +#embed_link a { + color: #059C05; + font-weight: 100; + font-family: helvetica; + font-size: 13px; + display: inline-block; + padding: 2px 10px; + background: #f4f4f4; + border: 1px solid #ddd; + border-top: none; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + text-shadow: 0px 1px 0px rgba(255, 255, 255, 1); + text-decoration: none; +} + +p.highlight_note { + padding: 8px 35px 8px 14px; + margin-top: 10px; + color: #A0762E; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #FCF8E3; + border: 1px solid #CA9C44; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +p.highlight_note a { + color: #537CC7; +} + +.prod_no_image { + position: relative; left: -10px; top: -12px; +} + + +#api { + padding: 0; +} + +/*https://github.com/twitter/bootstrap/issues/5262*/ +img { + max-width: none; +} + +.text-logo{ + color: black; + font-size: 24px; + font-weight: lighter; + margin-top: 23px; + text-align: center; + text-shadow: 1px 17px 2px gray, 1px 1px 2px gray; +} + +.menu-list>li>img { + position: relative; +} + +.rotating-logo { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + -webkit-transition: all 0.5s ease-out; + transition: all 0.5s ease-out; +} +.rotating-logo:hover { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + -webkit-transition: all 0.5s ease-in-out; + transition: all 0.5s ease-in-out; +} \ No newline at end of file diff --git a/doc/template/jade/common_layout.jade b/doc/template/jade/common_layout.jade new file mode 100644 index 00000000..bb665600 --- /dev/null +++ b/doc/template/jade/common_layout.jade @@ -0,0 +1,55 @@ +-var dirPrefix = "./"; +-var sitePrefix = "../doc/site/"; +-var landingPage = 'false' +-var versions = [] + +mixin doctype + !!! 5 + + + + + + +mixin head + meta(http-equiv='Content-Type', content='text/html; charset=UTF-8') + + -if (isIndex) + title #{title} + -else + title #{classId} - #{title} + + meta(name="generator", content="panino-doc-build") + meta(name="description", content="Ace API documentation for the online code editor") + meta(name="author", content="Garen J. Torikian") + + script(src='#{sitePrefix}/js/main.js') + link(rel='stylesheet', media='all and (max-device-width: 480px)', href='doc/site/iphone.css') + link(rel='stylesheet', media='all and (min-device-width: 481px) and (max-device-width: 1024px)', href='doc/site/iphone.css') + link(href='#{dirPrefix}resources/ace/skeleton/images/favicon.ico', rel='icon', type='image/x-icon') + + link(href='#{sitePrefix}/style.css', rel='stylesheet', type='text/css') + link(rel="stylesheet", href="#{dirPrefix}resources/csses/ace_api.css") + link(rel="stylesheet", href="#{dirPrefix}resources/csses/font-awesome.css") + + link(href="#{dirPrefix}resources/images/favicon.ico", rel="icon", type="image/x-icon") + + script(src='#{dirPrefix}resources/javascripts/bbq.js') + script(src="#{dirPrefix}resources/javascripts/jquery.collapse.js") + script(src="#{dirPrefix}resources/javascripts/jquery.cookie.js") + script(src="#{dirPrefix}resources/javascripts/bootstrap.js") + + +mixin endingScripts + script(defer, src="#{dirPrefix}resources/javascripts/ux.js") + script(src="#{dirPrefix}resources/javascripts/clicker.js") + script(src="#{dirPrefix}resources/javascripts/jquery-scrollspy.js") + script(defer, src="#{dirPrefix}resources/javascripts/disqus-ext.js") + script(defer, src="#{dirPrefix}resources/javascripts/ga.js") + +mixin identifyBuild(tree, type) + landingPage = 'true' + -dirPrefix = './' + +mixin markdown(text, inline) + != markdown(text, inline) \ No newline at end of file diff --git a/doc/template/jade/layout.jade b/doc/template/jade/layout.jade new file mode 100644 index 00000000..c2911c69 --- /dev/null +++ b/doc/template/jade/layout.jade @@ -0,0 +1,12 @@ +include common_layout +include lib + +#documentation.span9 + -if (isIndex) + != indexContent + -else + mixin api() + + mixin endingScripts + + div(id="disqus_thread") \ No newline at end of file diff --git a/doc/template/jade/lib.jade b/doc/template/jade/lib.jade new file mode 100644 index 00000000..62ee92d2 --- /dev/null +++ b/doc/template/jade/lib.jade @@ -0,0 +1,217 @@ +- var methodSection, constructorSection, propertySection, eventSection; + +-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] + + if (obj.private !== true && obj.name.charAt(0) !== "$") + title = obj.path + (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.stability + mixin markdown(">" + obj.stability) + + if obj.description + .section.description + .memberContent + mixin markdown(obj.description) + + else + .section.method + .memberContent + if obj.signatures + div.title + i(id='#{obj.path}', class='methodToggle methodClicker inactive icon-caret-right') + 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.undocumented + li + span.label.undocumented Undocumented + if obj.experimental + li + span.label.experimental Experimental + 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, ["relatedToLink"]) + + div.sideToggler + + div(id='ellipsis_#{obj.path}', class='ellipsis_description') + mixin markdown(obj.short_description) + + + div.description + + mixin markdown(obj.description) + + 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 && obj.arguments.length + h4 Arguments + != argumentTable(obj.arguments, ["argument-list", "table", "table-striped", "table-bordered"]) + + if obj.returns && obj.returns.length + h4 Returns + != returnTable(obj.returns, ["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 === '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 + -if (obj.subclasses.length == 0) + mixin render_starting_tabs(obj, pos) + -else + mixin render_starting_tabs(obj, pos) + for child in obj.children.filter(function(x){return x.type === 'namespace' || x.type === 'class' || x.type === 'mixin'}) + -pos++ + mixin render_starting_tabs(child, pos) + + +mixin render_starting_tabs(obj, pos) + .classContent + .membersBackground + + div(class=' members pos#{pos}') + div(class=' membersContent pos#{pos}') + h1.memberHeader + -var heading = obj.path + span.name #{heading} + + -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 + if (m.private !== true && m.name.charAt(0) !== "$") + li(id='dropdown_#{m.path}', data-id='#{m.path}', class='memberLink') + mixin link(m, [], true) + -methodSection = constructorSection = propertySection = eventSection = false; + 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) \ No newline at end of file diff --git a/doc/template/resources/csses/ace_api.css b/doc/template/resources/csses/ace_api.css new file mode 100644 index 00000000..7a90b4c3 --- /dev/null +++ b/doc/template/resources/csses/ace_api.css @@ -0,0 +1,912 @@ +/* + Generic "affects everything" stuff +*/ + +#wrapper .content .column2 { + float: none; +} + +#documentation ul { + font-size: 13px; +} + +#documentation li { + color: black; +} + +pre { + background-color: #FFFFFF; +} + +code { + font-size: 12px; + line-height: 16px; + font-family: 'Ubuntu Mono',Monaco,Consolas,monospace !important; + background-color: #F9F9F9; + border-radius: 3px 3px 3px 3px; + display: inline-block; + padding: 0 4px; + margin: 2px 1px; + color: inherit; +} + +#documentation 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; +} + +#documentation pre code { + background-color: transparent; + border-radius: none; + box-shadow: none; +} + +#documentation a code { + color: #00438a; +} + +#documentation h2 { + font-size: 26px; +} +#documentation p { + font-size: 13px; +} +#documentation li p:last-child { + margin-bottom : 5px; +} + +#documentation 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 .nav > li > a { + padding: 10px 15px 11px; +} + +.navbar { + text-align:center; +} + +#topSection { + width: 1000px; +} +.small_win #topSection { + width: 100%; +} +.small_win #topSection .dropdown { + margin-right: 40%; +} +.navbar .brand { + margin-left: 0px; +} +.brand { + background: transparent url(../images/ace_logo_menu.png) no-repeat 33px 5px; + width: 80px; + 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; +} + +.headerTitle { + position: relative; + top: 100px; + left: 250px; +} + +/* + Menu venue +*/ + + +h3.api_title { + padding-top: 10px; +} + +ul.menu { + margin-left: 2px; +} + +.menu li { + list-style-image: url(../images/menu_disc.png); + margin-bottom: 4px; + font-weight: 700; + padding-left: 10px; + margin-left: 0; +} + +.menu li .menu-item a.menuLink, .menu li .menu-item span.menuLink { + color: #3E7096; + font-weight: 100; +} +.menuTwo { + margin-bottom: 5px; + margin-top: 2px; +} +.menuTwo li .menu-item a.menuLink { + color: #3E7096; + font-weight: 100; +} + +/* 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 +*/ + +.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;*/ + 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; + padding-right: 10px; + margin-right: -5px; + /*width: 700px;*/ +} +.srolledHeader .membersContent { + line-height: 3; +} +.srolled .membersContent { + /*top : 0;*/ + width: 625px; + padding-left: 327px; + margin : 0 auto 0 auto; +} + +.srolled ul.nav { + padding-right: 10px; +} + +.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; + +} + +ul.tabs li:first-child ul{ + left: -63px; +} + +.tabs a.menu:after, .tabs .dropdown-toggle:after { + margin-top: 22px; +} + +.nav .dropdown-toggle .caret { + margin-top: 12px; + border-top-color: #6D8CA0; + border-bottom-color: #6D8CA0; +} + +li.dropdown { + color: #2D2D2D; + font-weight: bold; +} + +.editInC9 { + font-size: 11px; + color: #657383; +} + +.editInC9 a { + color: #657383; + font-weight: normal; + position : relative; + top : -2px; +} + +.tabs { + padding-top: 14px; + /*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; +} + +.memberLink a { + margin-left: 0 !important; +} +.menu-dropdown { + 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; +} + +.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; + left: 10px; + width: 160px; +} +.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") +*/ + +#nonFooter { + padding-top: 40px; +} +#wrapper { + height: 100%; +} + +.content { + height: 100%; +} + +header.filler { + position: relative; + height: 40px; + width: 100%; +} + +/* +.container-fluid .row-fluid { + width: 1000px; + margin-left: auto; + margin-right: auto; +}*/ + +.divider { + height: 3px; + background-color: #BEDAEA; + margin-bottom: 3px; +} + +#sidebar h3 a, +#sidebar h3 a:hover { + color: #404040; +} + +#sidebarContainer { + padding-top: 20px; +} + +#mainContent { + margin-left: 30px; +} + +#documentation { + padding-top: 35px; + padding-bottom: 10px; +} + +#documentation article.article { + border-top: 1px solid #e9e9e9; + padding: 16px 10px 2px; + -webkit-transition: padding 0.2s; + -moz-transition: padding 0.2s; + -o-transition: padding 0.2s; +} + +#documentation h3.sectionHeader + article.article { + border-top: none; +} + +div#documentation article:last-child { + border-bottom: 1px solid #e9e9e9; + padding-bottom: 40px; +} +#documentation article.article.methodToggleOpen { + background: rgba(255, 255, 255, 0.5); + 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; +} + +#documentation .signature-call a { + color: #8e487e; +} + +.sigClassName { + display: none; +} + +.eventObjName { + font-style: italic; +} +.eventListenerStart, .eventListenerClose, .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; +} + +.undocumented { + background-color: #B94A48; + color: #ffffff; +} + +#documentation .alias a, #documentation .related-to a { + color: #ffffff; + /* text-decoration: underline; */ +} +#documentation .alias a:hover, #documentation .related-to a:hover { + text-decoration: none; +} +.#documentation alias:hover, #documentation .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 { + padding-top: 10px; + font-size: 18px; + 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; +} + +.argument-list { + margin-bottom : 13px; +} +.argName { + font-style: italic; +} + + +/* + Everyday I'm togglin' +*/ + +#documentation i.methodToggle { + cursor: pointer; + color: #9f9f9f; + padding-top: 2px; + float: left; +} +#documentation i.methodToggle.methodToggleHover { + text-shadow: 0 0 10px #4699d5; + color: #4699d5; +} +#documentation i.methodToggle.active { + text-shadow: 0 0 10px #4699d5; + color: #4699d5; + /* Safari */ + -webkit-transform: rotate(45deg); + + /* Firefox */ + -moz-transform: rotate(45deg); + + /* IE */ + -ms-transform: rotate(45deg); + + /* Opera */ + -o-transform: rotate(45deg); + padding-top: 9px; +} + +#documentation h3.sectionHeader { + 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 { + width:100%; + background: #101010 url(../images/dashed_back.png) repeat 0 0; + font-size: 12px; + color: white; + height: 40px; +} +#footer .footerInner { + padding-left: 300px; + margin-left: auto; + margin-right: auto; + min-height: 40px; +} +#footer .footer-text { + display: block; + font-size: 12px; + float: right; +} +#footer div.footerInner div.footer-text p { + font-size: 12px; + font-family: Arial; + line-height: 18px; + margin: 10px 15px 0px 1px; +} + +#footer a, #footer a:hover { + color: #8DD0FF; +} + +.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; +} diff --git a/doc/template/resources/font/fontawesome-webfont.eot b/doc/template/resources/font/fontawesome-webfont.eot new file mode 100644 index 00000000..89070c1e Binary files /dev/null and b/doc/template/resources/font/fontawesome-webfont.eot differ diff --git a/doc/template/resources/font/fontawesome-webfont.svg b/doc/template/resources/font/fontawesome-webfont.svg new file mode 100644 index 00000000..1245f92c --- /dev/null +++ b/doc/template/resources/font/fontawesome-webfont.svg @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/template/resources/font/fontawesome-webfont.ttf b/doc/template/resources/font/fontawesome-webfont.ttf new file mode 100644 index 00000000..c17e9f8d Binary files /dev/null and b/doc/template/resources/font/fontawesome-webfont.ttf differ diff --git a/doc/template/resources/font/fontawesome-webfont.woff b/doc/template/resources/font/fontawesome-webfont.woff new file mode 100644 index 00000000..09f2469a Binary files /dev/null and b/doc/template/resources/font/fontawesome-webfont.woff differ diff --git a/doc/template/resources/images/Ace_ERD.png b/doc/template/resources/images/Ace_ERD.png new file mode 100644 index 00000000..78fb8dab Binary files /dev/null and b/doc/template/resources/images/Ace_ERD.png differ diff --git a/doc/template/resources/images/ace_logo.png b/doc/template/resources/images/ace_logo.png new file mode 100644 index 00000000..4dab4f66 Binary files /dev/null and b/doc/template/resources/images/ace_logo.png differ diff --git a/doc/template/resources/images/ace_logo_menu.png b/doc/template/resources/images/ace_logo_menu.png new file mode 100644 index 00000000..b011fadd Binary files /dev/null and b/doc/template/resources/images/ace_logo_menu.png differ diff --git a/doc/template/resources/images/c9-log-footer.png b/doc/template/resources/images/c9-log-footer.png new file mode 100644 index 00000000..f3bcb4d7 Binary files /dev/null and b/doc/template/resources/images/c9-log-footer.png differ diff --git a/doc/template/resources/images/c9-sponsor.png b/doc/template/resources/images/c9-sponsor.png new file mode 100644 index 00000000..599d3b49 Binary files /dev/null and b/doc/template/resources/images/c9-sponsor.png differ diff --git a/doc/template/resources/images/cloud9-logo.png b/doc/template/resources/images/cloud9-logo.png new file mode 100644 index 00000000..912524a9 Binary files /dev/null and b/doc/template/resources/images/cloud9-logo.png differ diff --git a/doc/template/resources/images/content-top.png b/doc/template/resources/images/content-top.png new file mode 100644 index 00000000..ec4ccad0 Binary files /dev/null and b/doc/template/resources/images/content-top.png differ diff --git a/doc/template/resources/images/content_bg.png b/doc/template/resources/images/content_bg.png new file mode 100644 index 00000000..928f81e4 Binary files /dev/null and b/doc/template/resources/images/content_bg.png differ diff --git a/doc/template/resources/images/content_top_bg.png b/doc/template/resources/images/content_top_bg.png new file mode 100644 index 00000000..42039338 Binary files /dev/null and b/doc/template/resources/images/content_top_bg.png differ diff --git a/doc/template/resources/images/dashed_back.png b/doc/template/resources/images/dashed_back.png new file mode 100644 index 00000000..c6ee9313 Binary files /dev/null and b/doc/template/resources/images/dashed_back.png differ diff --git a/doc/template/resources/images/footer-bg.png b/doc/template/resources/images/footer-bg.png new file mode 100644 index 00000000..0d572c28 Binary files /dev/null and b/doc/template/resources/images/footer-bg.png differ diff --git a/doc/template/resources/images/main_bg.png b/doc/template/resources/images/main_bg.png new file mode 100644 index 00000000..f26aefc2 Binary files /dev/null and b/doc/template/resources/images/main_bg.png differ diff --git a/doc/template/resources/images/member-sprites.png b/doc/template/resources/images/member-sprites.png new file mode 100644 index 00000000..96b0520f Binary files /dev/null and b/doc/template/resources/images/member-sprites.png differ diff --git a/doc/template/resources/images/menu_disc.png b/doc/template/resources/images/menu_disc.png new file mode 100644 index 00000000..1d3925b3 Binary files /dev/null and b/doc/template/resources/images/menu_disc.png differ diff --git a/doc/template/resources/images/method_bg.png b/doc/template/resources/images/method_bg.png new file mode 100644 index 00000000..b0189557 Binary files /dev/null and b/doc/template/resources/images/method_bg.png differ diff --git a/doc/template/resources/images/scrolled-heading-shadow.png b/doc/template/resources/images/scrolled-heading-shadow.png new file mode 100644 index 00000000..aed814ee Binary files /dev/null and b/doc/template/resources/images/scrolled-heading-shadow.png differ diff --git a/doc/template/resources/images/sidebar-top-bg.png b/doc/template/resources/images/sidebar-top-bg.png new file mode 100644 index 00000000..c0a800e1 Binary files /dev/null and b/doc/template/resources/images/sidebar-top-bg.png differ diff --git a/doc/template/resources/images/sidebar_border.png b/doc/template/resources/images/sidebar_border.png new file mode 100644 index 00000000..ea6cd700 Binary files /dev/null and b/doc/template/resources/images/sidebar_border.png differ diff --git a/doc/template/resources/images/swirl_divider.png b/doc/template/resources/images/swirl_divider.png new file mode 100644 index 00000000..f3e9f6c6 Binary files /dev/null and b/doc/template/resources/images/swirl_divider.png differ diff --git a/doc/template/resources/javascripts/bbq.js b/doc/template/resources/javascripts/bbq.js new file mode 100644 index 00000000..bcbf2483 --- /dev/null +++ b/doc/template/resources/javascripts/bbq.js @@ -0,0 +1,18 @@ +/* + * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010 + * http://benalman.com/projects/jquery-bbq-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ +(function($,p){var i,m=Array.prototype.slice,r=decodeURIComponent,a=$.param,c,l,v,b=$.bbq=$.bbq||{},q,u,j,e=$.event.special,d="hashchange",A="querystring",D="fragment",y="elemUrlAttr",g="location",k="href",t="src",x=/^.*\?|#.*$/g,w=/^.*\#/,h,C={};function E(F){return typeof F==="string"}function B(G){var F=m.call(arguments,1);return function(){return G.apply(this,F.concat(m.call(arguments)))}}function n(F){return F.replace(/^[^#]*#?(.*)$/,"$1")}function o(F){return F.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function f(H,M,F,I,G){var O,L,K,N,J;if(I!==i){K=F.match(H?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/);J=K[3]||"";if(G===2&&E(I)){L=I.replace(H?w:x,"")}else{N=l(K[2]);I=E(I)?l[H?D:A](I):I;L=G===2?I:G===1?$.extend({},I,N):$.extend({},N,I);L=a(L);if(H){L=L.replace(h,r)}}O=K[1]+(H?"#":L||!K[1]?"?":"")+L+J}else{O=M(F!==i?F:p[g][k])}return O}a[A]=B(f,0,o);a[D]=c=B(f,1,n);c.noEscape=function(G){G=G||"";var F=$.map(G.split(""),encodeURIComponent);h=new RegExp(F.join("|"),"g")};c.noEscape(",/");$.deparam=l=function(I,F){var H={},G={"true":!0,"false":!1,"null":null};$.each(I.replace(/\+/g," ").split("&"),function(L,Q){var K=Q.split("="),P=r(K[0]),J,O=H,M=0,R=P.split("]["),N=R.length-1;if(/\[/.test(R[0])&&/\]$/.test(R[N])){R[N]=R[N].replace(/\]$/,"");R=R.shift().split("[").concat(R);N=R.length-1}else{N=0}if(K.length===2){J=r(K[1]);if(F){J=J&&!isNaN(J)?+J:J==="undefined"?i:G[J]!==i?G[J]:J}if(N){for(;M<=N;M++){P=R[M]===""?O.length:R[M];O=O[P]=M').hide().insertAfter("body")[0].contentWindow;q=function(){return a(n.document[c][l])};o=function(u,s){if(u!==s){var t=n.document;t.open().close();t[c].hash="#"+u}};o(a())}}m.start=function(){if(r){return}var t=a();o||p();(function s(){var v=a(),u=q(t);if(v!==t){o(t=v,u);$(i).trigger(d)}else{if(u!==t){i[c][l]=i[c][l].replace(/#.*/,"")+"#"+u}}r=setTimeout(s,$[d+"Delay"])})()};m.stop=function(){if(!n){r&&clearTimeout(r);r=0}};return m})()})(jQuery,this); \ No newline at end of file diff --git a/doc/template/resources/javascripts/bootstrap.js b/doc/template/resources/javascripts/bootstrap.js new file mode 100644 index 00000000..79241e74 --- /dev/null +++ b/doc/template/resources/javascripts/bootstrap.js @@ -0,0 +1,389 @@ +/* ============================================================ + * bootstrap-dropdown.js v2.1.1 + * 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"; // jshint ;_; + + + /* 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) + , $parent + , isActive + + if ($this.is('.disabled, :disabled')) return + + $parent = getParent($this) + + isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + $parent.toggleClass('open') + $this.focus() + } + + return false + } + + , keydown: function (e) { + var $this + , $items + , $active + , $parent + , isActive + , index + + if (!/(38|40|27)/.test(e.keyCode)) return + + $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + $parent = getParent($this) + + isActive = $parent.hasClass('open') + + if (!isActive || (isActive && e.keyCode == 27)) return $this.click() + + $items = $('[role=menu] li:not(.divider) a', $parent) + + if (!$items.length) return + + index = $items.index($items.filter(':focus')) + + if (e.keyCode == 38 && index > 0) index-- // up + if (e.keyCode == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items + .eq(index) + .focus() + } + + } + + function clearMenus() { + getParent($(toggle)) + .removeClass('open') + } + + function getParent($this) { + var selector = $this.attr('data-target') + , $parent + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = $(selector) + $parent.length || ($parent = $this.parent()) + + return $parent + } + + + /* 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 touchstart.dropdown.data-api', clearMenus) + $('body') + .on('click.dropdown touchstart.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.dropdown.data-api touchstart.dropdown.data-api' , toggle, Dropdown.prototype.toggle) + .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown) + }) + +}(window.jQuery); +/* ======================================================== + * bootstrap-tab.js v2.1.1 + * http://twitter.github.com/bootstrap/javascript.html#tabs + * ======================================================== + * 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"; // jshint ;_; + + + /* TAB CLASS DEFINITION + * ==================== */ + + var Tab = function (element) { + this.element = $(element) + } + + Tab.prototype = { + + constructor: Tab + + , show: function () { + var $this = this.element + , $ul = $this.closest('ul:not(.dropdown-menu)') + , selector = $this.attr('data-target') + , previous + , $target + , e + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + if ( $this.parent('li').hasClass('active') ) return + + previous = $ul.find('.active a').last()[0] + + e = $.Event('show', { + relatedTarget: previous + }) + + $this.trigger(e) + + if (e.isDefaultPrevented()) return + + $target = $(selector) + + this.activate($this.parent('li'), $ul) + this.activate($target, $target.parent(), function () { + $this.trigger({ + type: 'shown' + , relatedTarget: previous + }) + }) + } + + , activate: function ( element, container, callback) { + var $active = container.find('> .active') + , transition = callback + && $.support.transition + && $active.hasClass('fade') + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + + element.addClass('active') + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') + } else { + element.removeClass('fade') + } + + if ( element.parent('.dropdown-menu') ) { + element.closest('li.dropdown').addClass('active') + } + + callback && callback() + } + + transition ? + $active.one($.support.transition.end, next) : + next() + + $active.removeClass('in') + } + } + + + /* TAB PLUGIN DEFINITION + * ===================== */ + + $.fn.tab = function ( option ) { + return this.each(function () { + var $this = $(this) + , data = $this.data('tab') + if (!data) $this.data('tab', (data = new Tab(this))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.tab.Constructor = Tab + + + /* TAB DATA-API + * ============ */ + + $(function () { + $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { + e.preventDefault() + $(this).tab('show') + }) + }) + +}(window.jQuery); +/* ========================================================== + * bootstrap-affix.js v2.1.1 + * http://twitter.github.com/bootstrap/javascript.html#affix + * ========================================================== + * 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"; // jshint ;_; + + + /* AFFIX CLASS DEFINITION + * ====================== */ + + var Affix = function (element, options) { + this.options = $.extend({}, $.fn.affix.defaults, options) + this.$window = $(window).on('scroll.affix.data-api', $.proxy(this.checkPosition, this)) + this.$element = $(element) + this.checkPosition() + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var scrollHeight = $(document).height() + , scrollTop = this.$window.scrollTop() + , position = this.$element.offset() + , offset = this.options.offset + , offsetBottom = offset.bottom + , offsetTop = offset.top + , reset = 'affix affix-top affix-bottom' + , affix + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top() + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom() + + affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? + false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? + 'bottom' : offsetTop != null && scrollTop <= offsetTop ? + 'top' : false + + if (this.affixed === affix) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? position.top - scrollTop : null + + this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : '')) + } + + + /* AFFIX PLUGIN DEFINITION + * ======================= */ + + $.fn.affix = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('affix') + , options = typeof option == 'object' && option + if (!data) $this.data('affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.affix.Constructor = Affix + + $.fn.affix.defaults = { + offset: 0 + } + + + /* AFFIX DATA-API + * ============== */ + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + , data = $spy.data() + + data.offset = data.offset || {} + + data.offsetBottom && (data.offset.bottom = data.offsetBottom) + data.offsetTop && (data.offset.top = data.offsetTop) + + $spy.affix(data) + }) + }) + + +}(window.jQuery); \ No newline at end of file diff --git a/doc/template/resources/javascripts/clicker.js b/doc/template/resources/javascripts/clicker.js new file mode 100644 index 00000000..90e7e12c --- /dev/null +++ b/doc/template/resources/javascripts/clicker.js @@ -0,0 +1,69 @@ +function setupClicker() { + // when hovering over arrow, add highlight (only if inactive) + $("i.methodToggle").hover(function () { + if (!$("i.methodToggle").hasClass('active')) + $(this).addClass("methodToggleHover"); + }, + function () { + $(this).removeClass("methodToggleHover"); + } + ); + + function handleClick(e, linkHref) { + //if (linkHref.indexOf("nav=api&api=") >= 0) + // return; + if (linkHref == "api") + return; + + e.preventDefault(); + + var dstElem; + if (linkHref) { + dstElem = $("article[id='" + linkHref + "']"); + } + + var $article = (dstElem || $(this)).closest('.article'), + $arrow = $('i.methodClicker', $article); + + if (!$article.hasClass('methodToggleOpen') || this.force) { + $article.addClass('methodToggleOpen'); + $arrow.removeClass('inactive').addClass('active'); + + if (!$arrow[0]) + return; + + var data = $arrow[0].id.replace(/^js_/, ""); + //var state = {}; + //state.section = data; + //$.bbq.pushState(state); + + scrollTo(null, data); + } + else { + $article.removeClass('methodToggleOpen'); + $arrow.removeClass('active').addClass('inactive'); + } + } + + function transformHash(e) { + // some bs to figure out link hash + var hashId = (e.srcElement ? e.srcElement.href : (e.hash || e.target.href)) || e.currentTarget.hash; + + handleClick(e, hashId.substring(hashId.indexOf("#") + 1)); + } + + // for the arrow + $("i.methodToggle").click(handleClick); + + // for the signature + $('.member-name').click(handleClick); + + // for the top dropdown + $('li.memberLink a').click(transformHash); + + //$('a[href^="#"]').click(transformHash); + + $('.related-to', '.metaInfo').click(function(){ + location.hash = $(this).find('a').attr('href').split('#')[1]; + }); +} \ No newline at end of file diff --git a/doc/template/resources/javascripts/disqus-ext.js b/doc/template/resources/javascripts/disqus-ext.js new file mode 100644 index 00000000..6bb7ff4e --- /dev/null +++ b/doc/template/resources/javascripts/disqus-ext.js @@ -0,0 +1,17 @@ +function setupDisqus(href) { + var disqus_shortname = 'aceapi'; + + //var paths = window.location.pathname.split("/"); + //var fileName = paths[paths.length - 2] + "/" + paths[paths.length - 1]; + + //var disqus_identifier = fileName; + var disqus_identifier = href.substring(2); + + (function() { + if (document.getElementById("disqusScript") === null) { + 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/template/resources/javascripts/jquery-scrollspy.js b/doc/template/resources/javascripts/jquery-scrollspy.js new file mode 100644 index 00000000..71b4a363 --- /dev/null +++ b/doc/template/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/doc/template/resources/javascripts/jquery.collapse.js b/doc/template/resources/javascripts/jquery.collapse.js new file mode 100644 index 00000000..427ee5fa --- /dev/null +++ b/doc/template/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/doc/template/resources/javascripts/jquery.cookie.js b/doc/template/resources/javascripts/jquery.cookie.js new file mode 100644 index 00000000..6df1faca --- /dev/null +++ b/doc/template/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/doc/template/resources/javascripts/plugins.js b/doc/template/resources/javascripts/plugins.js new file mode 100644 index 00000000..efda459c --- /dev/null +++ b/doc/template/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/doc/template/resources/javascripts/prettify-extension.js b/doc/template/resources/javascripts/prettify-extension.js new file mode 100644 index 00000000..ca8458dc --- /dev/null +++ b/doc/template/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/doc/template/resources/javascripts/prettify.js b/doc/template/resources/javascripts/prettify.js
    new file mode 100644
    index 00000000..eef5ad7e
    --- /dev/null
    +++ b/doc/template/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 1010) sx = 1010 - document.documentElement.offsetWidth;
    +    }
    +    else sx = 0;
    +
    +    $('span.methodClicker, article.article, i.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);
    +    });
    +    
    +    function showMethodContent() {
    +        var locationHash = location.hash.replace(/^#/, '').replace(/\./g, '\\.');
    +        var equalsPos = location.hash.indexOf("=");
    +        
    +        if (equalsPos >=0) {
    +            locationHash = locationHash.substring(0, location.hash.indexOf("="));
    +        }
    +        
    +        var $clickerEl = $('span#' + locationHash);
    +        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.indexOf("section") >= 1) {
    +        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/wiki b/doc/wiki
    new file mode 160000
    index 00000000..d93670b4
    --- /dev/null
    +++ b/doc/wiki
    @@ -0,0 +1 @@
    +Subproject commit d93670b47d776987b38bb2c31777c4e488338fac
    diff --git a/experiments/animate_folding.html b/experiments/animate_folding.html
    new file mode 100644
    index 00000000..ea3f08ec
    --- /dev/null
    +++ b/experiments/animate_folding.html
    @@ -0,0 +1,249 @@
    +
    +
    +
    +
    +
    +
    +  
    +  
    +  Editor
    +  
    +
    +
    +
    +
    +
    +
    + + + + + + + diff --git a/experiments/basic_animation.html b/experiments/basic_animation.html new file mode 100644 index 00000000..85df5ab1 --- /dev/null +++ b/experiments/basic_animation.html @@ -0,0 +1,191 @@ + + + + + + + + + +
    +
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, + sed diam nonummy nibh euismod tincidunt ut laoreet dolore + magna aliquam erat volutpat. Ut wisi enim ad minim veniam, + quis nostrud exerci tation ullamcorper suscipit lobortis nisl + ut aliquip ex ea commodo consequat. Duis autem vel eum iriure + dolor in hendrerit in vulputate velit esse molestie consequat, + vel illum dolore eu feugiat nulla facilisis at vero eros et + accumsan et iusto odio dignissim qui blandit praesent luptatum + zzril delenit augue duis dolore te feugait nulla facilisi. + Nam liber tempor cum soluta nobis eleifend option congue + nihil imperdiet doming id quod mazim placerat facer possim + assum. Typi non habent claritatem insitam; est usus legentis + in iis qui facit eorum claritatem. Investigationes + demonstraverunt lectores legere me lius quod ii legunt saepius. + Claritas est etiam processus dynamicus, qui sequitur mutationem + consuetudium lectorum. Mirum est notare quam littera gothica, + quam nunc putamus parum claram, anteposuerit litterarum formas + humanitatis per seacula quarta decima et quinta decima. Eodem + modo typi, qui nunc nobis videntur parum clari, fiant sollemnes + in futurum.
    +
    +
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, + sed diam nonummy nibh euismod tincidunt ut laoreet dolore + magna aliquam erat volutpat. Ut wisi enim ad minim veniam, + quis nostrud exerci tation ullamcorper suscipit lobortis nisl + ut aliquip ex ea commodo consequat. Duis autem vel eum iriure + dolor in hendrerit in vulputate velit esse molestie consequat, + vel illum dolore eu feugiat nulla facilisis at vero eros et + accumsan et iusto odio dignissim qui blandit praesent luptatum + zzril delenit augue duis dolore te feugait nulla facilisi. + Nam liber tempor cum soluta nobis eleifend option congue + nihil imperdiet doming id quod mazim placerat facer possim + assum. Typi non habent claritatem insitam; est usus legentis + in iis qui facit eorum claritatem. Investigationes + demonstraverunt lectores legere me lius quod ii legunt saepius. + Claritas est etiam processus dynamicus, qui sequitur mutationem + consuetudium lectorum. Mirum est notare quam littera gothica, + quam nunc putamus parum claram, anteposuerit litterarum formas + humanitatis per seacula quarta decima et quinta decima. Eodem + modo typi, qui nunc nobis videntur parum clari, fiant sollemnes + in futurum.
    +
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, + sed diam nonummy nibh euismod tincidunt ut laoreet dolore + magna aliquam erat volutpat. Ut wisi enim ad minim veniam, + quis nostrud exerci tation ullamcorper suscipit lobortis nisl + ut aliquip ex ea commodo consequat. Duis autem vel eum iriure + dolor in hendrerit in vulputate velit esse molestie consequat, + vel illum dolore eu feugiat nulla facilisis at vero eros et + accumsan et iusto odio dignissim qui blandit praesent luptatum + zzril delenit augue duis dolore te feugait nulla facilisi. + Nam liber tempor cum soluta nobis eleifend option congue + nihil imperdiet doming id quod mazim placerat facer possim + assum. Typi non habent claritatem insitam; est usus legentis + in iis qui facit eorum claritatem. Investigationes + demonstraverunt lectores legere me lius quod ii legunt saepius. + Claritas est etiam processus dynamicus, qui sequitur mutationem + consuetudium lectorum. Mirum est notare quam littera gothica, + quam nunc putamus parum claram, anteposuerit litterarum formas + humanitatis per seacula quarta decima et quinta decima. Eodem + modo typi, qui nunc nobis videntur parum clari, fiant sollemnes + in futurum.
    +
    +
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, + sed diam nonummy nibh euismod tincidunt ut laoreet dolore + magna aliquam erat volutpat. Ut wisi enim ad minim veniam, + quis nostrud exerci tation ullamcorper suscipit lobortis nisl + ut aliquip ex ea commodo consequat. Duis autem vel eum iriure + dolor in hendrerit in vulputate velit esse molestie consequat, + vel illum dolore eu feugiat nulla facilisis at vero eros et + accumsan et iusto odio dignissim qui blandit praesent luptatum + zzril delenit augue duis dolore te feugait nulla facilisi. + Nam liber tempor cum soluta nobis eleifend option congue + nihil imperdiet doming id quod mazim placerat facer possim + assum. Typi non habent claritatem insitam; est usus legentis + in iis qui facit eorum claritatem. Investigationes + demonstraverunt lectores legere me lius quod ii legunt saepius. + Claritas est etiam processus dynamicus, qui sequitur mutationem + consuetudium lectorum. Mirum est notare quam littera gothica, + quam nunc putamus parum claram, anteposuerit litterarum formas + humanitatis per seacula quarta decima et quinta decima. Eodem + modo typi, qui nunc nobis videntur parum clari, fiant sollemnes + in futurum.
    +
    + + + + + diff --git a/experiments/debug_mem_leak.html b/experiments/debug_mem_leak.html new file mode 100644 index 00000000..b8ee8726 --- /dev/null +++ b/experiments/debug_mem_leak.html @@ -0,0 +1,59 @@ + + + + + + + + +

    + +
    + + + \ No newline at end of file diff --git a/experiments/zenbg.png b/experiments/zenbg.png new file mode 100644 index 00000000..734ea912 Binary files /dev/null and b/experiments/zenbg.png differ diff --git a/index.html b/index.html index cea626a3..e2440eb1 100644 --- a/index.html +++ b/index.html @@ -1,359 +1,1345 @@ - + + + + + Ace - The High Performance Code Editor for the Web + + + + + - - - - Editor - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - -
    + + + + + + + Fork me on GitHub + +
    +
    +
    +
    +

    The high performance code editor for the web.

    + +
    +
    + +
    +
    +

    Built for Code

    +

    Ace is an embeddable code editor written in JavaScript. + It matches the features and performance of native + editors such as Sublime, Vim and TextMate. It can be easily embedded + in any web page and JavaScript application. Ace is maintained as the + primary editor for Cloud9 IDE + and is the successor of the Mozilla Skywriter (Bespin) project. +

    + +
    /**
    + * In fact, you're looking at ACE right now. Go ahead and play with it!
    + *
    + * We are currently showing off the JavaScript mode. ACE has support for 45
    + * language modes and 24 color themes!
    + */
     
    -    
    -
    - - +</style> +</head> +<body> - +<div id="editor">function foo(items) { + var x = "All this is syntax highlighted"; + return x; +}</div> + +<script src="/ace-builds/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script> +<script> + var editor = ace.edit("editor"); + editor.setTheme("ace/theme/monokai"); + editor.getSession().setMode("ace/mode/javascript"); +</script> +</body> +</html>
    +

    Now check out the How-To Guide for instructions on + common operations, such as setting a different language mode or + getting the contents from the editor. +

    +

    Loading Ace from a Local URL

    +

    If you want to clone and host Ace locally you can + use one of the pre-packaged versions. Just copy + one of src* subdirectories somewhere into your project, or use RequireJS to load the + contents of lib/ace folder as ace: +

    +

    The packaged version can also be loaded from CDN's such as jsDelivr or cdnjs. +

    +
    +
    +

    Working with Ace

    +

    In all of these examples Ace has been invoked + as shown in the embedding guide. +

    +

    Setting Themes

    +

    Themes are loaded on demand; all you have to do is pass the string name:

    +
    editor.setTheme("ace/theme/twilight");
    +

    > See all themes

    +

    Setting the Programming Language Mode

    +

    By default, the editor supports plain text mode. All other language modes are available as separate modules, loaded on demand like this:

    +
    editor.getSession().setMode("ace/mode/javascript");
    + +

    Common Operations

    +

    Set and get content:

    +
    editor.setValue("the new text here"); // or session.setValue
    +editor.getValue(); // or session.getValue
    +

    Get selected text:

    +
    editor.session.getTextRange(editor.getSelectionRange());
    +

    Insert at cursor:

    +
    editor.insert("Something cool");
    +

    Get the current cursor line and column:

    +
    editor.selection.getCursor();
    +

    Go to a line:

    +
    editor.gotoLine(lineNumber);
    +

    Get total number of lines:

    +
    editor.session.getLength();
    +

    Set the default tab size:

    +
    editor.getSession().setTabSize(4);
    +

    Use soft tabs:

    +
    editor.getSession().setUseSoftTabs(true);
    +

    Set the font size:

    +
    document.getElementById('editor').style.fontSize='12px';
    +

    Toggle word wrapping:

    +
    editor.getSession().setUseWrapMode(true);
    +

    Set line highlighting:

    +
    editor.setHighlightActiveLine(false);
    +

    Set the print margin visibility:

    +
    editor.setShowPrintMargin(false);
    +

    Set the editor to read-only:

    +
    editor.setReadOnly(true);  // false to make it editable
    +

    Triggering Resizes

    +

    Ace only resizes itself on window events. If you resize the editor div in another manner, and need Ace to resize, use the following:

    +
    editor.resize()
    +

    Searching

    +
    editor.find('needle',{
    +    backwards: false,
    +    wrap: false,
    +    caseSensitive: false,
    +    wholeWord: false,
    +    regExp: false
    +});
    +editor.findNext();
    +editor.findPrevious();
    +

    The following options are available to you for your search parameters:

    +
      +
    • + needle: The string or regular expression you're looking for +
    • +
    • + backwards: Whether to search backwards from where cursor currently is. Defaults to false. +
    • +
    • + wrap: Whether to wrap the search back to the beginning when it hits the end. Defaults to false. +
    • +
    • + caseSensitive: Whether the search ought to be case-sensitive. Defaults to false. +
    • +
    • + wholeWord: Whether the search matches only on whole words. Defaults to false. +
    • +
    • + range: The Range to search within. Set this to null for the whole document +
    • +
    • + regExp: Whether the search is a regular expression or not. Defaults to false. +
    • +
    • + start: The starting Range or cursor position to begin the search +
    • +
    • + skipCurrent: Whether or not to include the current line in the search. Default to false. +
    • +
    +

    Here's how you can perform a replace:

    +
    editor.find('foo');
    +editor.replace('bar');
    +

    And here's a replace all:

    +
    editor.replaceAll('bar');
    +

    (editor.replaceAll uses the needle set earlier by editor.find('needle', ...)

    +

    Listening to Events

    +

    To listen for an onchange:

    +
    editor.getSession().on('change', function(e) {
    +    // e.type, etc
    +});
    +

    To listen for an selection change:

    +
    editor.getSession().selection.on('changeSelection', function(e) {
    +});
    +

    To listen for a cursor change:

    +
    editor.getSession().selection.on('changeCursor', function(e) {
    +});
    +

    Adding New Commands and Keybindings

    +

    To assign key bindings to a custom function:

    +
    editor.commands.addCommand({
    +    name: 'myCommand',
    +    bindKey: {win: 'Ctrl-M',  mac: 'Command-M'},
    +    exec: function(editor) {
    +        //...
    +    },
    +    readOnly: true // false if this command should not apply in readOnly mode
    +});
    +
    +
    +

    Creating a Syntax Highlighter for Ace

    +

    Creating a new syntax highlighter for Ace is extremly simple. You'll need to define two pieces of code: a new mode, and a new set of highlighting rules.

    +

    Where to Start

    +

    We recommend using the the Ace Mode Creator when defining your highlighter. This allows you to inspect your code's tokens, as well as providing a live preview of the syntax highlighter in action.

    +

    Defining a Mode

    +

    Every language needs a mode. A mode contains the paths to a language's syntax highlighting rules, indentation rules, and code folding rules. Without defining a mode, Ace won't know anything about the finer aspects of your language.

    +

    Here is the starter template we'll use to create a new mode:

    +
    define(function(require, exports, module) {
    +"use strict";
     
    -    
    +var Mode = function() {
    +    // set everything up
    +    this.HighlightRules = MyNewHighlightRules;
    +    this.$outdent = new MatchingBraceOutdent();
    +    this.foldingRules = new MyNewFoldMode();
    +};
    +oop.inherits(Mode, TextMode);
     
    -    
    +    this.autoOutdent = function(state, doc, row) {
    +        this.$outdent.autoOutdent(doc, row);
    +    };
    +    
    +    // create worker for live syntax checking
    +    this.createWorker = function(session) {
    +        var worker = new WorkerClient(["ace"], "ace/mode/mynew_worker", "NewWorker");
    +        worker.attachToDocument(session.getDocument());
    +        worker.on("errors", function(e) {
    +            session.setAnnotations(e.data);
    +        });
    +        return worker;
    +    };
    +    
    +}).call(Mode.prototype);
     
    -    
    +    // regexp must not have capturing parentheses. Use (?:) instead.
    +    // regexps are ordered -> the first match is used
    +   this.$rules = {
    +        "start" : [
    +            {
    +                token: <token>, // String, Array, or Function: the CSS token to apply
    +                regex: <regex>, // String or RegExp: the regexp to match
    +                next:  <next>   // [Optional] String: next state to enter
    +            }
    +        ]
    +    };
    +};
     
    -    
    +...
     
    -  
    -
    -    
    -
    -
    -
    -
    -
    -
    +    this.foldingRules = new MyFoldMode();
    +};
    +

    You'll be defining your code folding rules into the lib/ace/mode/folding folder. Here's a template that you can use to get started:

    +
    define(function(require, exports, module) {
    +"use strict";
     
    -
    -
    -  
    -
    -  
    -  
    -
    +    var range = session.getCommentFoldRange(row, i + match[0].length);
    +    range.end.column -= 2;
    +    return range;
    +}
    +

    Let's say we stumble across the code block hello_world() {. Our range object here becomes:

    +
    {
    +  startRow: 0,
    +  endRow: 0,
    +  startColumn: 0,
    +  endColumn: 13
    +}
    +

    Testing Your Highlighter

    +

    The best way to test your tokenizer is to see it live, right? To do that, you'll want to modify the live Ace demo to preview your changes. You can find this file in the root Ace directory with the name kitchen-sink.html.

    +
      +
    1. + add an entry to supportedModes in ace/ext/modelist.js +
    2. +
    3. +

      add a sample file to demo/kitchen-sink/docs/ with same name as the mode file +

    4. +
    +

    Once you set this up, you should be able to witness a live demonstration of your new highlighter.

    +

    Adding Automated Tests

    +

    Adding automated tests for a highlighter is trivial so you are not required to do it, but it can help during development.

    +

    In lib/ace/mode/_test create a file named

    text_<modeName>.txt
    with some example code. (You can skip this if the document you have added in demo/docs both looks good and covers various edge cases in your language syntax). +

    +

    Run node highlight_rules_test.js -gen to preserve current output of your tokenizer in tokens_<modeName>.json +

    +

    After this running highlight_rules_test.js optionalLanguageName will compare output of your tokenizer with the correct output you've created. +

    +

    Any files ending with the _test.js suffix are automatically run by Ace's Travis CI server.

    +
    +
    +
    +
    + +
    +
    +
    +

    Ace API Reference

    +

    Welcome to the Ace API Reference!

    +

    On the left, you'll find a list of all of our currently documented classes. + These is not a complete set of classes, but rather, the "core" set. For more + information on how to work with Ace, check out the embedding guide. +

    +

    Below is an ERD diagram describing some fundamentals about how the internals of Ace works:

    + +
    +
    +
    +
    +
    +

    Projects Using Ace

    +

    Ace is used all over the web in all kinds of production applications. Here is + just a small sampling:

    + +
    +
    +

    Support and User Resources

    +

    Aside from our GitHub page, here's a list of places you can find help for Ace:

    + +
    +
    +
    +
    +
    + + + + + + + + diff --git a/kitchen-sink.html b/kitchen-sink.html new file mode 100644 index 00000000..a8e1fb7b --- /dev/null +++ b/kitchen-sink.html @@ -0,0 +1,293 @@ + + + + + + Ace Kitchen Sink + + + + + + + + + +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + +
    +
    + + + + + +
    +
    +
    +
    + + + + + + + + + + + diff --git a/lib/ace/ace.js b/lib/ace/ace.js new file mode 100644 index 00000000..6c8a6126 --- /dev/null +++ b/lib/ace/ace.js @@ -0,0 +1,129 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/** + * The main class required to set up an Ace instance in the browser. + * + * @class Ace + **/ + +define(function(require, exports, module) { +"use strict"; + +require("./lib/fixoldbrowsers"); + +var dom = require("./lib/dom"); +var event = require("./lib/event"); + +var Editor = require("./editor").Editor; +var EditSession = require("./edit_session").EditSession; +var UndoManager = require("./undomanager").UndoManager; +var Renderer = require("./virtual_renderer").VirtualRenderer; + +// The following require()s are for inclusion in the built ace file +require("./worker/worker_client"); +require("./keyboard/hash_handler"); +require("./placeholder"); +require("./multi_select"); +require("./mode/folding/fold_mode"); +require("./theme/textmate"); +require("./ext/error_marker"); + +exports.config = require("./config"); + +/** + * Provides access to require in packed noconflict mode + * @param {String} moduleName + * @returns {Object} + * + **/ +exports.require = require; + +/** + * Embeds the Ace editor into the DOM, at the element provided by `el`. + * @param {String | DOMElement} el Either the id of an element, or the element itself + * + **/ +exports.edit = function(el) { + if (typeof(el) == "string") { + var _id = el; + el = document.getElementById(_id); + if (!el) + throw new Error("ace.edit can't find div #" + _id); + } + + if (el && el.env && el.env.editor instanceof Editor) + return el.env.editor; + + var value = ""; + if (el && /input|textarea/i.test(el.tagName)) { + var oldNode = el; + value = oldNode.value; + el = dom.createElement("pre"); + oldNode.parentNode.replaceChild(el, oldNode); + } else { + value = dom.getInnerText(el); + el.innerHTML = ''; + } + + var doc = exports.createEditSession(value); + + var editor = new Editor(new Renderer(el)); + editor.setSession(doc); + + var env = { + document: doc, + editor: editor, + onResize: editor.resize.bind(editor, null) + }; + if (oldNode) env.textarea = oldNode; + event.addListener(window, "resize", env.onResize); + editor.on("destroy", function() { + event.removeListener(window, "resize", env.onResize); + env.editor.container.env = null; // prevent memory leak on old ie + }); + editor.container.env = editor.env = env; + return editor; +}; + +/** + * Creates a new [[EditSession]], and returns the associated [[Document]]. + * @param {Document | String} text {:textParam} + * @param {TextMode} mode {:modeParam} + * + **/ +exports.createEditSession = function(text, mode) { + var doc = new EditSession(text, mode); + doc.setUndoManager(new UndoManager()); + return doc; +} +exports.EditSession = EditSession; +exports.UndoManager = UndoManager; +}); diff --git a/lib/ace/anchor.js b/lib/ace/anchor.js index e9f1836b..39b78e0f 100644 --- a/lib/ace/anchor.js +++ b/lib/ace/anchor.js @@ -1,172 +1,208 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var oop = require("pilot/oop"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; +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 - */ + * + * Defines a floating pointer in the document. Whenever text is inserted or deleted before the cursor, the position of the anchor is updated. + * + * @class Anchor + **/ + +/** + * Creates a new `Anchor` and associates it with a document. + * + * @param {Document} doc The document to associate with the anchor + * @param {Number} row The starting row position + * @param {Number} column The starting column position + * + * @constructor + **/ + var Anchor = exports.Anchor = function(doc, row, column) { - this.document = doc; + this.$onChange = this.onChange.bind(this); + this.attach(doc); if (typeof column == "undefined") this.setPosition(row.row, row.column); else this.setPosition(row, column); - - this.$onChange = this.onChange.bind(this); - doc.on("change", this.$onChange); }; (function() { oop.implement(this, EventEmitter); - + + /** + * Returns an object identifying the `row` and `column` position of the current anchor. + * @returns {Object} + **/ this.getPosition = function() { return this.$clipPositionToDocument(this.row, this.column); }; - + + /** + * + * Returns the current document. + * @returns {Document} + **/ this.getDocument = function() { return this.document; }; - - this.onChange = function(e) { - var delta = e.data; - var range = delta.range; - - if (range.start.row == range.end.row && range.start.row != this.row) - return; - - if (range.start.row > this.row) - return; - - if (range.start.row == this.row && range.start.column > this.column) - return; - - var row = this.row; - var column = this.column; - - if (delta.action === "insertText") { - if (range.start.row === row && range.start.column <= column) { - if (range.start.row === range.end.row) { - column += range.end.column - range.start.column; - } - else { - column -= range.start.column; - row += range.end.row - range.start.row; - } - } - else if (range.start.row !== range.end.row && range.start.row < row) { - row += range.end.row - range.start.row; - } - } else if (delta.action === "insertLines") { - if (range.start.row <= row) { - row += range.end.row - range.start.row; - } - } - else if (delta.action == "removeText") { - if (range.start.row == row && range.start.column < column) { - if (range.end.column >= column) - column = range.start.column; - else - column = Math.max(0, column - (range.end.column - range.start.column)); - - } else if (range.start.row !== range.end.row && range.start.row < row) { - if (range.end.row == row) { - column = Math.max(0, column - range.end.column) + range.start.column; - } - row -= (range.end.row - range.start.row); - } - else if (range.end.row == row) { - row -= range.end.row - range.start.row; - column = Math.max(0, column - range.end.column) + range.start.column; - } - } else if (delta.action == "removeLines") { - if (range.start.row <= row) { - if (range.end.row <= row) - row -= range.end.row - range.start.row; - else { - row = range.start.row; - column = 0; - } - } - } - this.setPosition(row, column, true); + /** + * experimental: allows anchor to stick to the next on the left + */ + this.$insertRight = false; + /** + * Fires whenever the anchor position changes. + * + * Both of these objects have a `row` and `column` property corresponding to the position. + * + * Events that can trigger this function include [[Anchor.setPosition `setPosition()`]]. + * + * @event change + * @param {Object} e An object containing information about the anchor position. It has two properties: + * - `old`: An object describing the old Anchor position + * - `value`: An object describing the new Anchor position + * + **/ + this.onChange = function(delta) { + if (delta.start.row == delta.end.row && delta.start.row != this.row) + return; + + if (delta.start.row > this.row) + return; + + var point = $getTransformedPoint(delta, {row: this.row, column: this.column}, this.$insertRight); + this.setPosition(point.row, point.column, true); }; + + function $pointsInOrder(point1, point2, equalPointsInOrder) { + var bColIsAfter = equalPointsInOrder ? point1.column <= point2.column : point1.column < point2.column; + return (point1.row < point2.row) || (point1.row == point2.row && bColIsAfter); + } + + function $getTransformedPoint(delta, point, moveIfEqual) { + // Get delta info. + var deltaIsInsert = delta.action == "insert"; + var deltaRowShift = (deltaIsInsert ? 1 : -1) * (delta.end.row - delta.start.row); + var deltaColShift = (deltaIsInsert ? 1 : -1) * (delta.end.column - delta.start.column); + var deltaStart = delta.start; + var deltaEnd = deltaIsInsert ? deltaStart : delta.end; // Collapse insert range. + + // DELTA AFTER POINT: No change needed. + if ($pointsInOrder(point, deltaStart, moveIfEqual)) { + return { + row: point.row, + column: point.column + }; + } + + // DELTA BEFORE POINT: Move point by delta shift. + if ($pointsInOrder(deltaEnd, point, !moveIfEqual)) { + return { + row: point.row + deltaRowShift, + column: point.column + (point.row == deltaEnd.row ? deltaColShift : 0) + }; + } + + // DELTA ENVELOPS POINT (delete only): Move point to delta start. + // TODO warn if delta.action != "remove" ? + + return { + row: deltaStart.row, + column: deltaStart.column + }; + } + /** + * Sets the anchor position to the specified row and column. If `noClip` is `true`, the position is not clipped. + * @param {Number} row The row index to move the anchor to + * @param {Number} column The column index to move the anchor to + * @param {Boolean} noClip Identifies if you want the position to be clipped + * + **/ this.setPosition = function(row, column, noClip) { + var pos; if (noClip) { pos = { row: row, column: column }; - } - else { + } else { pos = this.$clipPositionToDocument(row, column); } - + if (this.row == pos.row && this.column == pos.column) return; - + var old = { row: this.row, column: this.column }; - + this.row = pos.row; this.column = pos.column; - this._dispatchEvent("change", { + this._signal("change", { old: old, value: pos }); }; - + + /** + * When called, the `"change"` event listener is removed. + * + **/ this.detach = function() { this.document.removeEventListener("change", this.$onChange); }; - + this.attach = function(doc) { + this.document = doc || this.document; + this.document.on("change", this.$onChange); + }; + + /** + * Clips the anchor position to the specified row and column. + * @param {Number} row The row index to clip the anchor to + * @param {Number} column The column index to clip the anchor to + * + **/ this.$clipPositionToDocument = function(row, column) { var pos = {}; - + if (row >= this.document.getLength()) { pos.row = Math.max(0, this.document.getLength() - 1); pos.column = this.document.getLine(pos.row).length; @@ -179,13 +215,13 @@ var Anchor = exports.Anchor = function(doc, row, column) { pos.row = row; pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column)); } - + if (column < 0) pos.column = 0; - + return pos; }; - + }).call(Anchor.prototype); }); diff --git a/lib/ace/test/anchor_test.js b/lib/ace/anchor_test.js similarity index 53% rename from lib/ace/test/anchor_test.js rename to lib/ace/anchor_test.js index adeed67f..c0b97273 100644 --- a/lib/ace/test/anchor_test.js +++ b/lib/ace/anchor_test.js @@ -1,49 +1,46 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ -define(function(require, exports, module) { - -var Document = require("ace/document").Document; -var Anchor = require("ace/anchor").Anchor; -var Range = require("ace/range").Range; -var assert = require("./assertions"); -var async = require("asyncjs"); +if (typeof process !== "undefined") { + require("amd-loader"); +} -var Test = { +define(function(require, exports, module) { +"use strict"; + +var Document = require("./document").Document; +var Anchor = require("./anchor").Anchor; +var Range = require("./range").Range; +var assert = require("./test/assertions"); + +module.exports = { "test create anchor" : function() { var doc = new Document("juhu"); @@ -60,20 +57,55 @@ var Test = { doc.insert({row: 1, column: 1}, "123"); assert.position(anchor.getPosition(), 1, 7); }, + + "test insert text at anchor should not move anchor when insertRight is true": function() { + var doc = new Document("juhu\nkinners"); + var anchor = new Anchor(doc, 1, 4); + anchor.$insertRight = true; + + doc.insert({row: 1, column: 4}, "123"); + assert.position(anchor.getPosition(), 1, 4); + }, "test insert lines before cursor should move anchor row": function() { var doc = new Document("juhu\nkinners"); var anchor = new Anchor(doc, 1, 4); - doc.insertLines(1, ["123", "456"]); + doc.insertFullLines(1, ["123", "456"]); assert.position(anchor.getPosition(), 3, 4); }, + + "test insert lines at anchor position should move anchor down": function() { + var doc = new Document("juhu\nkinners"); + var anchor = new Anchor(doc, 1, 0); + + doc.insertLines(1, ["line"]); + assert.position(anchor.getPosition(), 2, 0); + }, + + "test insert lines at anchor position should not move anchor down when insertRight is true and column is 0": function() { + var doc = new Document("juhu\nkinners"); + var anchor = new Anchor(doc, 1, 0); + anchor.$insertRight = true; + + doc.insertLines(1, ["line"]); + assert.position(anchor.getPosition(), 1, 0); + }, + + "test insert lines at anchor row should move anchor down when column > 0": function() { + var doc = new Document("juhu\nkinners"); + var anchor = new Anchor(doc, 1, 2); + anchor.$insertRight = true; + + doc.insertLines(1, ["line"]); + assert.position(anchor.getPosition(), 2, 2); + }, "test insert new line before cursor should move anchor column": function() { var doc = new Document("juhu\nkinners"); var anchor = new Anchor(doc, 1, 4); - doc.insertNewLine({row: 0, column: 0}); + doc.insertMergedLines({row: 0, column: 0}, ['', '']); assert.position(anchor.getPosition(), 2, 4); }, @@ -81,7 +113,7 @@ var Test = { var doc = new Document("juhu\nkinners"); var anchor = new Anchor(doc, 1, 4); - doc.insertNewLine({row: 1, column: 2}); + doc.insertMergedLines({row: 1, column: 2}, ['', '']); assert.position(anchor.getPosition(), 2, 2); }, @@ -113,7 +145,7 @@ var Test = { var doc = new Document("juhu\n1\n2\nkinners"); var anchor = new Anchor(doc, 3, 4); - doc.removeLines(1, 2); + doc.removeFullLines(1, 2); assert.position(anchor.getPosition(), 1, 4); }, @@ -137,7 +169,7 @@ var Test = { var doc = new Document("juhu\nkinners\n123"); var anchor = new Anchor(doc, 1, 5); - doc.removeLines(1, 1); + doc.removeFullLines(1, 1); assert.position(anchor.getPosition(), 1, 0); }, @@ -170,14 +202,22 @@ var Test = { }); doc.remove(new Range(2, 0, 2, 1)); + }, + + "test insert/remove lines at the end of the document": function() { + var doc = new Document("juhu\nkinners\n123"); + var anchor = new Anchor(doc, 2, 4); + + doc.removeFullLines(0, 3); + assert.position(anchor.getPosition(), 0, 0); + doc.insertFullLines(0, ["a", "b", "c"]); + assert.position(anchor.getPosition(), 3, 0); + assert.equal(doc.getValue(), "a\nb\nc\n"); } }; -module.exports = require("asyncjs/test").testcase(Test); - }); if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec() + require("asyncjs").test.testcase(module.exports).exec() } diff --git a/lib/ace/apply_delta.js b/lib/ace/apply_delta.js new file mode 100644 index 00000000..98bfe148 --- /dev/null +++ b/lib/ace/apply_delta.js @@ -0,0 +1,108 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +function throwDeltaError(delta, errorText){ + console.log("Invalid Delta:", delta); + throw "Invalid Delta: " + errorText; +} + +function positionInDocument(docLines, position) { + return position.row >= 0 && position.row < docLines.length && + position.column >= 0 && position.column <= docLines[position.row].length; +} + +function validateDelta(docLines, delta) { + // Validate action string. + if (delta.action != "insert" && delta.action != "remove") + throwDeltaError(delta, "delta.action must be 'insert' or 'remove'"); + + // Validate lines type. + if (!(delta.lines instanceof Array)) + throwDeltaError(delta, "delta.lines must be an Array"); + + // Validate range type. + if (!delta.start || !delta.end) + throwDeltaError(delta, "delta.start/end must be an present"); + + // Validate that the start point is contained in the document. + var start = delta.start; + if (!positionInDocument(docLines, delta.start)) + throwDeltaError(delta, "delta.start must be contained in document"); + + // Validate that the end point is contained in the document (remove deltas only). + var end = delta.end; + if (delta.action == "remove" && !positionInDocument(docLines, end)) + throwDeltaError(delta, "delta.end must contained in document for 'remove' actions"); + + // Validate that the .range size matches the .lines size. + var numRangeRows = end.row - start.row; + var numRangeLastLineChars = (end.column - (numRangeRows == 0 ? start.column : 0)); + if (numRangeRows != delta.lines.length - 1 || delta.lines[numRangeRows].length != numRangeLastLineChars) + throwDeltaError(delta, "delta.range must match delta lines"); +} + +exports.applyDelta = function(docLines, delta, doNotValidate) { + // disabled validation since it breaks autocompletion popup + // if (!doNotValidate) + // validateDelta(docLines, delta); + + var row = delta.start.row; + var startColumn = delta.start.column; + var line = docLines[row] || ""; + switch (delta.action) { + case "insert": + var lines = delta.lines; + if (lines.length === 1) { + docLines[row] = line.substring(0, startColumn) + delta.lines[0] + line.substring(startColumn); + } else { + var args = [row, 1].concat(delta.lines); + docLines.splice.apply(docLines, args); + docLines[row] = line.substring(0, startColumn) + docLines[row]; + docLines[row + delta.lines.length - 1] += line.substring(startColumn); + } + break; + case "remove": + var endColumn = delta.end.column; + var endRow = delta.end.row; + if (row === endRow) { + docLines[row] = line.substring(0, startColumn) + line.substring(endColumn); + } else { + docLines.splice( + row, endRow - row + 1, + line.substring(0, startColumn) + docLines[endRow].substring(endColumn) + ); + } + break; + } +} +}); diff --git a/lib/ace/autocomplete.js b/lib/ace/autocomplete.js new file mode 100644 index 00000000..8e121f35 --- /dev/null +++ b/lib/ace/autocomplete.js @@ -0,0 +1,497 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var HashHandler = require("./keyboard/hash_handler").HashHandler; +var AcePopup = require("./autocomplete/popup").AcePopup; +var util = require("./autocomplete/util"); +var event = require("./lib/event"); +var lang = require("./lib/lang"); +var dom = require("./lib/dom"); +var snippetManager = require("./snippets").snippetManager; + +var Autocomplete = function() { + this.autoInsert = false; + this.autoSelect = true; + this.exactMatch = false; + this.gatherCompletionsId = 0; + this.keyboardHandler = new HashHandler(); + this.keyboardHandler.bindKeys(this.commands); + + this.blurListener = this.blurListener.bind(this); + this.changeListener = this.changeListener.bind(this); + this.mousedownListener = this.mousedownListener.bind(this); + this.mousewheelListener = this.mousewheelListener.bind(this); + + this.changeTimer = lang.delayedCall(function() { + this.updateCompletions(true); + }.bind(this)); + + this.tooltipTimer = lang.delayedCall(this.updateDocTooltip.bind(this), 50); +}; + +(function() { + + this.$init = function() { + this.popup = new AcePopup(document.body || document.documentElement); + this.popup.on("click", function(e) { + this.insertMatch(); + e.stop(); + }.bind(this)); + this.popup.focus = this.editor.focus.bind(this.editor); + this.popup.on("show", this.tooltipTimer.bind(null, null)); + this.popup.on("select", this.tooltipTimer.bind(null, null)); + this.popup.on("changeHoverMarker", this.tooltipTimer.bind(null, null)); + return this.popup; + }; + + this.getPopup = function() { + return this.popup || this.$init(); + }; + + this.openPopup = function(editor, prefix, keepPopupPosition) { + if (!this.popup) + this.$init(); + + this.popup.setData(this.completions.filtered); + + editor.keyBinding.addKeyboardHandler(this.keyboardHandler); + + var renderer = editor.renderer; + this.popup.setRow(this.autoSelect ? 0 : -1); + if (!keepPopupPosition) { + this.popup.setTheme(editor.getTheme()); + this.popup.setFontSize(editor.getFontSize()); + + var lineHeight = renderer.layerConfig.lineHeight; + + var pos = renderer.$cursorLayer.getPixelPosition(this.base, true); + pos.left -= this.popup.getTextLeftOffset(); + + var rect = editor.container.getBoundingClientRect(); + pos.top += rect.top - renderer.layerConfig.offset; + pos.left += rect.left - editor.renderer.scrollLeft; + pos.left += renderer.gutterWidth; + + this.popup.show(pos, lineHeight); + } else if (keepPopupPosition && !prefix) { + this.detach(); + } + }; + + this.detach = function() { + this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler); + this.editor.off("changeSelection", this.changeListener); + this.editor.off("blur", this.blurListener); + this.editor.off("mousedown", this.mousedownListener); + this.editor.off("mousewheel", this.mousewheelListener); + this.changeTimer.cancel(); + this.hideDocTooltip(); + + this.gatherCompletionsId += 1; + if (this.popup && this.popup.isOpen) + this.popup.hide(); + + if (this.base) + this.base.detach(); + this.activated = false; + this.completions = this.base = null; + }; + + this.changeListener = function(e) { + var cursor = this.editor.selection.lead; + if (cursor.row != this.base.row || cursor.column < this.base.column) { + this.detach(); + } + if (this.activated) + this.changeTimer.schedule(); + else + this.detach(); + }; + + this.blurListener = function(e) { + // we have to check if activeElement is a child of popup because + // on IE preventDefault doesn't stop scrollbar from being focussed + var el = document.activeElement; + var text = this.editor.textInput.getElement(); + var fromTooltip = e.relatedTarget && e.relatedTarget == this.tooltipNode; + var container = this.popup && this.popup.container; + if (el != text && el.parentNode != container && !fromTooltip + && el != this.tooltipNode && e.relatedTarget != text + ) { + this.detach(); + } + }; + + this.mousedownListener = function(e) { + this.detach(); + }; + + this.mousewheelListener = function(e) { + this.detach(); + }; + + this.goTo = function(where) { + var row = this.popup.getRow(); + var max = this.popup.session.getLength() - 1; + + switch(where) { + case "up": row = row <= 0 ? max : row - 1; break; + case "down": row = row >= max ? -1 : row + 1; break; + case "start": row = 0; break; + case "end": row = max; break; + } + + this.popup.setRow(row); + }; + + this.insertMatch = function(data) { + if (!data) + data = this.popup.getData(this.popup.getRow()); + if (!data) + return false; + + if (data.completer && data.completer.insertMatch) { + data.completer.insertMatch(this.editor, data); + } else { + if (this.completions.filterText) { + var ranges = this.editor.selection.getAllRanges(); + for (var i = 0, range; range = ranges[i]; i++) { + range.start.column -= this.completions.filterText.length; + this.editor.session.remove(range); + } + } + if (data.snippet) + snippetManager.insertSnippet(this.editor, data.snippet); + else + this.editor.execCommand("insertstring", data.value || data); + } + this.detach(); + }; + + + this.commands = { + "Up": function(editor) { editor.completer.goTo("up"); }, + "Down": function(editor) { editor.completer.goTo("down"); }, + "Ctrl-Up|Ctrl-Home": function(editor) { editor.completer.goTo("start"); }, + "Ctrl-Down|Ctrl-End": function(editor) { editor.completer.goTo("end"); }, + + "Esc": function(editor) { editor.completer.detach(); }, + "Return": function(editor) { return editor.completer.insertMatch(); }, + "Shift-Return": function(editor) { editor.completer.insertMatch(true); }, + "Tab": function(editor) { + var result = editor.completer.insertMatch(); + if (!result && !editor.tabstopManager) + editor.completer.goTo("down"); + else + return result; + }, + + "PageUp": function(editor) { editor.completer.popup.gotoPageUp(); }, + "PageDown": function(editor) { editor.completer.popup.gotoPageDown(); } + }; + + this.gatherCompletions = function(editor, callback) { + var session = editor.getSession(); + var pos = editor.getCursorPosition(); + + var line = session.getLine(pos.row); + var prefix = util.retrievePrecedingIdentifier(line, pos.column); + + this.base = session.doc.createAnchor(pos.row, pos.column - prefix.length); + this.base.$insertRight = true; + + var matches = []; + var total = editor.completers.length; + editor.completers.forEach(function(completer, i) { + completer.getCompletions(editor, session, pos, prefix, function(err, results) { + if (!err) + matches = matches.concat(results); + // Fetch prefix again, because they may have changed by now + var pos = editor.getCursorPosition(); + var line = session.getLine(pos.row); + callback(null, { + prefix: util.retrievePrecedingIdentifier(line, pos.column, results[0] && results[0].identifierRegex), + matches: matches, + finished: (--total === 0) + }); + }); + }); + return true; + }; + + this.showPopup = function(editor) { + if (this.editor) + this.detach(); + + this.activated = true; + + this.editor = editor; + if (editor.completer != this) { + if (editor.completer) + editor.completer.detach(); + editor.completer = this; + } + + editor.on("changeSelection", this.changeListener); + editor.on("blur", this.blurListener); + editor.on("mousedown", this.mousedownListener); + editor.on("mousewheel", this.mousewheelListener); + + this.updateCompletions(); + }; + + this.updateCompletions = function(keepPopupPosition) { + if (keepPopupPosition && this.base && this.completions) { + var pos = this.editor.getCursorPosition(); + var prefix = this.editor.session.getTextRange({start: this.base, end: pos}); + if (prefix == this.completions.filterText) + return; + this.completions.setFilter(prefix); + if (!this.completions.filtered.length) + return this.detach(); + if (this.completions.filtered.length == 1 + && this.completions.filtered[0].value == prefix + && !this.completions.filtered[0].snippet) + return this.detach(); + this.openPopup(this.editor, prefix, keepPopupPosition); + return; + } + + // Save current gatherCompletions session, session is close when a match is insert + var _id = this.gatherCompletionsId; + this.gatherCompletions(this.editor, function(err, results) { + // Only detach if result gathering is finished + var detachIfFinished = function() { + if (!results.finished) return; + return this.detach(); + }.bind(this); + + var prefix = results.prefix; + var matches = results && results.matches; + + if (!matches || !matches.length) + return detachIfFinished(); + + // Wrong prefix or wrong session -> ignore + if (prefix.indexOf(results.prefix) !== 0 || _id != this.gatherCompletionsId) + return; + + this.completions = new FilteredList(matches); + + if (this.exactMatch) + this.completions.exactMatch = true; + + this.completions.setFilter(prefix); + var filtered = this.completions.filtered; + + // No results + if (!filtered.length) + return detachIfFinished(); + + // One result equals to the prefix + if (filtered.length == 1 && filtered[0].value == prefix && !filtered[0].snippet) + return detachIfFinished(); + + // Autoinsert if one result + if (this.autoInsert && filtered.length == 1 && results.finished) + return this.insertMatch(filtered[0]); + + this.openPopup(this.editor, prefix, keepPopupPosition); + }.bind(this)); + }; + + this.cancelContextMenu = function() { + this.editor.$mouseHandler.cancelContextMenu(); + }; + + this.updateDocTooltip = function() { + var popup = this.popup; + var all = popup.data; + var selected = all && (all[popup.getHoveredRow()] || all[popup.getRow()]); + var doc = null; + if (!selected || !this.editor || !this.popup.isOpen) + return this.hideDocTooltip(); + this.editor.completers.some(function(completer) { + if (completer.getDocTooltip) + doc = completer.getDocTooltip(selected); + return doc; + }); + if (!doc) + doc = selected; + + if (typeof doc == "string") + doc = {docText: doc}; + if (!doc || !(doc.docHTML || doc.docText)) + return this.hideDocTooltip(); + this.showDocTooltip(doc); + }; + + this.showDocTooltip = function(item) { + if (!this.tooltipNode) { + this.tooltipNode = dom.createElement("div"); + this.tooltipNode.className = "ace_tooltip ace_doc-tooltip"; + this.tooltipNode.style.margin = 0; + this.tooltipNode.style.pointerEvents = "auto"; + this.tooltipNode.tabIndex = -1; + this.tooltipNode.onblur = this.blurListener.bind(this); + } + + var tooltipNode = this.tooltipNode; + if (item.docHTML) { + tooltipNode.innerHTML = item.docHTML; + } else if (item.docText) { + tooltipNode.textContent = item.docText; + } + + if (!tooltipNode.parentNode) + document.body.appendChild(tooltipNode); + var popup = this.popup; + var rect = popup.container.getBoundingClientRect(); + tooltipNode.style.top = popup.container.style.top; + tooltipNode.style.bottom = popup.container.style.bottom; + + if (window.innerWidth - rect.right < 320) { + tooltipNode.style.right = window.innerWidth - rect.left + "px"; + tooltipNode.style.left = ""; + } else { + tooltipNode.style.left = (rect.right + 1) + "px"; + tooltipNode.style.right = ""; + } + tooltipNode.style.display = "block"; + }; + + this.hideDocTooltip = function() { + this.tooltipTimer.cancel(); + if (!this.tooltipNode) return; + var el = this.tooltipNode; + if (!this.editor.isFocused() && document.activeElement == el) + this.editor.focus(); + this.tooltipNode = null; + if (el.parentNode) + el.parentNode.removeChild(el); + }; + +}).call(Autocomplete.prototype); + +Autocomplete.startCommand = { + name: "startAutocomplete", + exec: function(editor) { + if (!editor.completer) + editor.completer = new Autocomplete(); + editor.completer.autoInsert = false; + editor.completer.autoSelect = true; + editor.completer.showPopup(editor); + // prevent ctrl-space opening context menu on firefox on mac + editor.completer.cancelContextMenu(); + }, + bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space" +}; + +var FilteredList = function(array, filterText) { + this.all = array; + this.filtered = array; + this.filterText = filterText || ""; + this.exactMatch = false; +}; +(function(){ + this.setFilter = function(str) { + if (str.length > this.filterText && str.lastIndexOf(this.filterText, 0) === 0) + var matches = this.filtered; + else + var matches = this.all; + + this.filterText = str; + matches = this.filterCompletions(matches, this.filterText); + matches = matches.sort(function(a, b) { + return b.exactMatch - a.exactMatch || b.score - a.score; + }); + + // make unique + var prev = null; + matches = matches.filter(function(item){ + var caption = item.snippet || item.caption || item.value; + if (caption === prev) return false; + prev = caption; + return true; + }); + + this.filtered = matches; + }; + this.filterCompletions = function(items, needle) { + var results = []; + var upper = needle.toUpperCase(); + var lower = needle.toLowerCase(); + loop: for (var i = 0, item; item = items[i]; i++) { + var caption = item.value || item.caption || item.snippet; + if (!caption) continue; + var lastIndex = -1; + var matchMask = 0; + var penalty = 0; + var index, distance; + + if (this.exactMatch) { + if (needle !== caption.substr(0, needle.length)) + continue loop; + }else{ + // caption char iteration is faster in Chrome but slower in Firefox, so lets use indexOf + for (var j = 0; j < needle.length; j++) { + // TODO add penalty on case mismatch + var i1 = caption.indexOf(lower[j], lastIndex + 1); + var i2 = caption.indexOf(upper[j], lastIndex + 1); + index = (i1 >= 0) ? ((i2 < 0 || i1 < i2) ? i1 : i2) : i2; + if (index < 0) + continue loop; + distance = index - lastIndex - 1; + if (distance > 0) { + // first char mismatch should be more sensitive + if (lastIndex === -1) + penalty += 10; + penalty += distance; + } + matchMask = matchMask | (1 << index); + lastIndex = index; + } + } + item.matchMask = matchMask; + item.exactMatch = penalty ? 0 : 1; + item.score = (item.score || 0) - penalty; + results.push(item); + } + return results; + }; +}).call(FilteredList.prototype); + +exports.Autocomplete = Autocomplete; +exports.FilteredList = FilteredList; + +}); diff --git a/lib/ace/autocomplete/popup.js b/lib/ace/autocomplete/popup.js new file mode 100644 index 00000000..6c480b38 --- /dev/null +++ b/lib/ace/autocomplete/popup.js @@ -0,0 +1,344 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var Renderer = require("../virtual_renderer").VirtualRenderer; +var Editor = require("../editor").Editor; +var Range = require("../range").Range; +var event = require("../lib/event"); +var lang = require("../lib/lang"); +var dom = require("../lib/dom"); + +var $singleLineEditor = function(el) { + var renderer = new Renderer(el); + + renderer.$maxLines = 4; + + var editor = new Editor(renderer); + + editor.setHighlightActiveLine(false); + editor.setShowPrintMargin(false); + editor.renderer.setShowGutter(false); + editor.renderer.setHighlightGutterLine(false); + + editor.$mouseHandler.$focusWaitTimout = 0; + editor.$highlightTagPending = true; + + return editor; +}; + +var AcePopup = function(parentNode) { + var el = dom.createElement("div"); + var popup = new $singleLineEditor(el); + + if (parentNode) + parentNode.appendChild(el); + el.style.display = "none"; + popup.renderer.content.style.cursor = "default"; + popup.renderer.setStyle("ace_autocomplete"); + + popup.setOption("displayIndentGuides", false); + popup.setOption("dragDelay", 150); + + var noop = function(){}; + + popup.focus = noop; + popup.$isFocused = true; + + popup.renderer.$cursorLayer.restartTimer = noop; + popup.renderer.$cursorLayer.element.style.opacity = 0; + + popup.renderer.$maxLines = 8; + popup.renderer.$keepTextAreaAtCursor = false; + + popup.setHighlightActiveLine(false); + // set default highlight color + popup.session.highlight(""); + popup.session.$searchHighlight.clazz = "ace_highlight-marker"; + + popup.on("mousedown", function(e) { + var pos = e.getDocumentPosition(); + popup.selection.moveToPosition(pos); + selectionMarker.start.row = selectionMarker.end.row = pos.row; + e.stop(); + }); + + var lastMouseEvent; + var hoverMarker = new Range(-1,0,-1,Infinity); + var selectionMarker = new Range(-1,0,-1,Infinity); + selectionMarker.id = popup.session.addMarker(selectionMarker, "ace_active-line", "fullLine"); + popup.setSelectOnHover = function(val) { + if (!val) { + hoverMarker.id = popup.session.addMarker(hoverMarker, "ace_line-hover", "fullLine"); + } else if (hoverMarker.id) { + popup.session.removeMarker(hoverMarker.id); + hoverMarker.id = null; + } + }; + popup.setSelectOnHover(false); + popup.on("mousemove", function(e) { + if (!lastMouseEvent) { + lastMouseEvent = e; + return; + } + if (lastMouseEvent.x == e.x && lastMouseEvent.y == e.y) { + return; + } + lastMouseEvent = e; + lastMouseEvent.scrollTop = popup.renderer.scrollTop; + var row = lastMouseEvent.getDocumentPosition().row; + if (hoverMarker.start.row != row) { + if (!hoverMarker.id) + popup.setRow(row); + setHoverMarker(row); + } + }); + popup.renderer.on("beforeRender", function() { + if (lastMouseEvent && hoverMarker.start.row != -1) { + lastMouseEvent.$pos = null; + var row = lastMouseEvent.getDocumentPosition().row; + if (!hoverMarker.id) + popup.setRow(row); + setHoverMarker(row, true); + } + }); + popup.renderer.on("afterRender", function() { + var row = popup.getRow(); + var t = popup.renderer.$textLayer; + var selected = t.element.childNodes[row - t.config.firstRow]; + if (selected == t.selectedNode) + return; + if (t.selectedNode) + dom.removeCssClass(t.selectedNode, "ace_selected"); + t.selectedNode = selected; + if (selected) + dom.addCssClass(selected, "ace_selected"); + }); + var hideHoverMarker = function() { setHoverMarker(-1) }; + var setHoverMarker = function(row, suppressRedraw) { + if (row !== hoverMarker.start.row) { + hoverMarker.start.row = hoverMarker.end.row = row; + if (!suppressRedraw) + popup.session._emit("changeBackMarker"); + popup._emit("changeHoverMarker"); + } + }; + popup.getHoveredRow = function() { + return hoverMarker.start.row; + }; + + event.addListener(popup.container, "mouseout", hideHoverMarker); + popup.on("hide", hideHoverMarker); + popup.on("changeSelection", hideHoverMarker); + + popup.session.doc.getLength = function() { + return popup.data.length; + }; + popup.session.doc.getLine = function(i) { + var data = popup.data[i]; + if (typeof data == "string") + return data; + return (data && data.value) || ""; + }; + + var bgTokenizer = popup.session.bgTokenizer; + bgTokenizer.$tokenizeRow = function(row) { + var data = popup.data[row]; + var tokens = []; + if (!data) + return tokens; + if (typeof data == "string") + data = {value: data}; + if (!data.caption) + data.caption = data.value || data.name; + + var last = -1; + var flag, c; + for (var i = 0; i < data.caption.length; i++) { + c = data.caption[i]; + flag = data.matchMask & (1 << i) ? 1 : 0; + if (last !== flag) { + tokens.push({type: data.className || "" + ( flag ? "completion-highlight" : ""), value: c}); + last = flag; + } else { + tokens[tokens.length - 1].value += c; + } + } + + if (data.meta) { + var maxW = popup.renderer.$size.scrollerWidth / popup.renderer.layerConfig.characterWidth; + var metaData = data.meta; + if (metaData.length + data.caption.length > maxW - 2) { + // trim meta to fit this popup and add ellipsis + metaData = metaData.substr(0, maxW - data.caption.length - 3) + "\u2026" + } + tokens.push({type: "rightAlignedText", value: metaData}); + } + return tokens; + }; + bgTokenizer.$updateOnChange = noop; + bgTokenizer.start = noop; + + popup.session.$computeWidth = function() { + return this.screenWidth = 0; + }; + + popup.$blockScrolling = Infinity; + + // public + popup.isOpen = false; + popup.isTopdown = false; + + popup.data = []; + popup.setData = function(list) { + popup.setValue(lang.stringRepeat("\n", list.length), -1); + popup.data = list || []; + popup.setRow(0); + }; + popup.getData = function(row) { + return popup.data[row]; + }; + + popup.getRow = function() { + return selectionMarker.start.row; + }; + popup.setRow = function(line) { + line = Math.max(-1, Math.min(this.data.length, line)); + if (selectionMarker.start.row != line) { + popup.selection.clearSelection(); + selectionMarker.start.row = selectionMarker.end.row = line || 0; + popup.session._emit("changeBackMarker"); + popup.moveCursorTo(line || 0, 0); + if (popup.isOpen) + popup._signal("select"); + } + }; + + popup.on("changeSelection", function() { + if (popup.isOpen) + popup.setRow(popup.selection.lead.row); + popup.renderer.scrollCursorIntoView(); + }); + + popup.hide = function() { + this.container.style.display = "none"; + this._signal("hide"); + popup.isOpen = false; + }; + popup.show = function(pos, lineHeight, topdownOnly) { + var el = this.container; + var screenHeight = window.innerHeight; + var screenWidth = window.innerWidth; + var renderer = this.renderer; + // var maxLines = Math.min(renderer.$maxLines, this.session.getLength()); + var maxH = renderer.$maxLines * lineHeight * 1.4; + var top = pos.top + this.$borderSize; + if (top + maxH > screenHeight - lineHeight && !topdownOnly) { + el.style.top = ""; + el.style.bottom = screenHeight - top + "px"; + popup.isTopdown = false; + } else { + top += lineHeight; + el.style.top = top + "px"; + el.style.bottom = ""; + popup.isTopdown = true; + } + + el.style.display = ""; + this.renderer.$textLayer.checkForSizeChanges(); + + var left = pos.left; + if (left + el.offsetWidth > screenWidth) + left = screenWidth - el.offsetWidth; + + el.style.left = left + "px"; + + this._signal("show"); + lastMouseEvent = null; + popup.isOpen = true; + }; + + popup.getTextLeftOffset = function() { + return this.$borderSize + this.renderer.$padding + this.$imageSize; + }; + + popup.$imageSize = 0; + popup.$borderSize = 1; + + return popup; +}; + +dom.importCssString("\ +.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\ + background-color: #CAD6FA;\ + z-index: 1;\ +}\ +.ace_editor.ace_autocomplete .ace_line-hover {\ + border: 1px solid #abbffe;\ + margin-top: -1px;\ + background: rgba(233,233,253,0.4);\ +}\ +.ace_editor.ace_autocomplete .ace_line-hover {\ + position: absolute;\ + z-index: 2;\ +}\ +.ace_editor.ace_autocomplete .ace_scroller {\ + background: none;\ + border: none;\ + box-shadow: none;\ +}\ +.ace_rightAlignedText {\ + color: gray;\ + display: inline-block;\ + position: absolute;\ + right: 4px;\ + text-align: right;\ + z-index: -1;\ +}\ +.ace_editor.ace_autocomplete .ace_completion-highlight{\ + color: #000;\ + text-shadow: 0 0 0.01em;\ +}\ +.ace_editor.ace_autocomplete {\ + width: 280px;\ + z-index: 200000;\ + background: #fbfbfb;\ + color: #444;\ + border: 1px lightgray solid;\ + position: fixed;\ + box-shadow: 2px 3px 5px rgba(0,0,0,.2);\ + line-height: 1.4;\ +}"); + +exports.AcePopup = AcePopup; + +}); diff --git a/lib/ace/autocomplete/text_completer.js b/lib/ace/autocomplete/text_completer.js new file mode 100644 index 00000000..17a4bdad --- /dev/null +++ b/lib/ace/autocomplete/text_completer.js @@ -0,0 +1,78 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + var Range = require("../range").Range; + + var splitRegex = /[^a-zA-Z_0-9\$\-\u00C0-\u1FFF\u2C00-\uD7FF\w]+/; + + function getWordIndex(doc, pos) { + var textBefore = doc.getTextRange(Range.fromPoints({row: 0, column:0}, pos)); + return textBefore.split(splitRegex).length - 1; + } + + /** + * Does a distance analysis of the word `prefix` at position `pos` in `doc`. + * @return Map + */ + function wordDistance(doc, pos) { + var prefixPos = getWordIndex(doc, pos); + var words = doc.getValue().split(splitRegex); + var wordScores = Object.create(null); + + var currentWord = words[prefixPos]; + + words.forEach(function(word, idx) { + if (!word || word === currentWord) return; + + var distance = Math.abs(prefixPos - idx); + var score = words.length - distance; + if (wordScores[word]) { + wordScores[word] = Math.max(score, wordScores[word]); + } else { + wordScores[word] = score; + } + }); + return wordScores; + } + + exports.getCompletions = function(editor, session, pos, prefix, callback) { + var wordScore = wordDistance(session, pos, prefix); + var wordList = Object.keys(wordScore); + callback(null, wordList.map(function(word) { + return { + caption: word, + value: word, + score: wordScore[word], + meta: "local" + }; + })); + }; +}); diff --git a/lib/ace/autocomplete/util.js b/lib/ace/autocomplete/util.js new file mode 100644 index 00000000..767b983e --- /dev/null +++ b/lib/ace/autocomplete/util.js @@ -0,0 +1,74 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +exports.parForEach = function(array, fn, callback) { + var completed = 0; + var arLength = array.length; + if (arLength === 0) + callback(); + for (var i = 0; i < arLength; i++) { + fn(array[i], function(result, err) { + completed++; + if (completed === arLength) + callback(result, err); + }); + } +}; + +var ID_REGEX = /[a-zA-Z_0-9\$\-\u00A2-\uFFFF]/; + +exports.retrievePrecedingIdentifier = function(text, pos, regex) { + regex = regex || ID_REGEX; + var buf = []; + for (var i = pos-1; i >= 0; i--) { + if (regex.test(text[i])) + buf.push(text[i]); + else + break; + } + return buf.reverse().join(""); +}; + +exports.retrieveFollowingIdentifier = function(text, pos, regex) { + regex = regex || ID_REGEX; + var buf = []; + for (var i = pos; i < text.length; i++) { + if (regex.test(text[i])) + buf.push(text[i]); + else + break; + } + return buf; +}; + +}); diff --git a/lib/ace/background_tokenizer.js b/lib/ace/background_tokenizer.js index 6e2bf669..ea4ddd0f 100644 --- a/lib/ace/background_tokenizer.js +++ b/lib/ace/background_tokenizer.js @@ -1,48 +1,60 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var oop = require("pilot/oop"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; +var oop = require("./lib/oop"); +var EventEmitter = require("./lib/event_emitter").EventEmitter; + + +/** + * 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. + * + * @class BackgroundTokenizer + **/ + +/** + * Creates a new `BackgroundTokenizer` object. + * @param {Tokenizer} tokenizer The tokenizer to use + * @param {Editor} editor The editor to associate with + * + * @constructor + **/ var BackgroundTokenizer = function(tokenizer, editor) { - this.running = false; + this.running = false; this.lines = []; + this.states = []; this.currentLine = 0; this.tokenizer = tokenizer; @@ -52,31 +64,35 @@ var BackgroundTokenizer = function(tokenizer, editor) { if (!self.running) { return; } var workerStart = new Date(); - var startLine = self.currentLine; + var currentLine = self.currentLine; + var endLine = -1; var doc = self.doc; - var processedLines = 0; - var lastVisibleRow = editor.getLastVisibleRow(); - + var startLine = currentLine; + while (self.lines[currentLine]) + currentLine++; + var len = doc.getLength(); - while (self.currentLine < len) { - self.lines[self.currentLine] = self.$tokenizeRows(self.currentLine, self.currentLine)[0]; - self.currentLine++; + var processedLines = 0; + self.running = false; + while (currentLine < len) { + self.$tokenizeRow(currentLine); + endLine = currentLine; + do { + currentLine++; + } while (self.lines[currentLine]); // only check every 5 lines - processedLines += 1; - if ((processedLines % 5 == 0) && (new Date() - workerStart) > 20) { - self.fireUpdateEvent(startLine, self.currentLine-1); - - var timeout = self.currentLine < lastVisibleRow ? 20 : 100; - self.running = setTimeout(self.$worker, timeout); - return; + processedLines ++; + if ((processedLines % 5 === 0) && (new Date() - workerStart) > 20) { + self.running = setTimeout(self.$worker, 20); + break; } } - - self.running = false; - - self.fireUpdateEvent(startLine, len - 1); + self.currentLine = currentLine; + + if (startLine <= endLine) + self.fireUpdateEvent(startLine, endLine); }; }; @@ -84,86 +100,146 @@ var BackgroundTokenizer = function(tokenizer, editor) { oop.implement(this, EventEmitter); + /** + * Sets a new tokenizer for this object. + * + * @param {Tokenizer} tokenizer The new tokenizer to use + * + **/ this.setTokenizer = function(tokenizer) { this.tokenizer = tokenizer; this.lines = []; + this.states = []; this.start(0); }; + /** + * Sets a new document to associate with this object. + * @param {Document} doc The new document to associate with + **/ this.setDocument = function(doc) { this.doc = doc; this.lines = []; + this.states = []; this.stop(); }; + /** + * Fires whenever the background tokeniziers between a range of rows are going to be updated. + * + * @event update + * @param {Object} e An object containing two properties, `first` and `last`, which indicate the rows of the region being updated. + * + **/ + /** + * Emits the `'update'` event. `firstRow` and `lastRow` are used to define the boundaries of the region to be updated. + * @param {Number} firstRow The starting row region + * @param {Number} lastRow The final row region + * + **/ this.fireUpdateEvent = function(firstRow, lastRow) { var data = { first: firstRow, last: lastRow }; - this._dispatchEvent("update", {data: data}); + this._signal("update", {data: data}); }; + /** + * Starts tokenizing at the row indicated. + * + * @param {Number} startRow The row to start at + * + **/ this.start = function(startRow) { - this.currentLine = Math.min(startRow || 0, this.currentLine, - this.doc.getLength()); + this.currentLine = Math.min(startRow || 0, this.currentLine, this.doc.getLength()); // remove all cached items below this line this.lines.splice(this.currentLine, this.lines.length); + this.states.splice(this.currentLine, this.states.length); this.stop(); // pretty long delay to prevent the tokenizer from interfering with the user this.running = setTimeout(this.$worker, 700); }; + + this.scheduleStart = function() { + if (!this.running) + this.running = setTimeout(this.$worker, 700); + } + this.$updateOnChange = function(delta) { + var startRow = delta.start.row; + var len = delta.end.row - startRow; + + if (len === 0) { + this.lines[startRow] = null; + } else if (delta.action == "remove") { + this.lines.splice(startRow, len + 1, null); + this.states.splice(startRow, len + 1, null); + } else { + var args = Array(len + 1); + args.unshift(startRow, 1); + this.lines.splice.apply(this.lines, args); + this.states.splice.apply(this.states, args); + } + + this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength()); + + this.stop(); + }; + + /** + * Stops tokenizing. + * + **/ this.stop = function() { if (this.running) clearTimeout(this.running); this.running = false; }; - this.getTokens = function(firstRow, lastRow) { - return this.$tokenizeRows(firstRow, lastRow); + /** + * Gives list of tokens of the row. (tokens are cached) + * + * @param {Number} row The row to get tokens at + * + * + * + **/ + this.getTokens = function(row) { + return this.lines[row] || this.$tokenizeRow(row); }; + /** + * [Returns the state of tokenization at the end of a row.]{: #BackgroundTokenizer.getState} + * + * @param {Number} row The row to get state at + **/ this.getState = function(row) { - return this.$tokenizeRows(row, row)[0].state; + if (this.currentLine == row) + this.$tokenizeRow(row); + return this.states[row] || "start"; }; - this.$tokenizeRows = function(firstRow, lastRow) { - if (!this.doc) - return []; - - var rows = []; + this.$tokenizeRow = function(row) { + var line = this.doc.getLine(row); + var state = this.states[row - 1]; - // determine start state - var state = "start"; - var doCache = false; - if (firstRow > 0 && this.lines[firstRow - 1]) { - state = this.lines[firstRow - 1].state; - doCache = true; + var data = this.tokenizer.getLineTokens(line, state, row); + + if (this.states[row] + "" !== data.state + "") { + this.states[row] = data.state; + this.lines[row + 1] = null; + if (this.currentLine > row + 1) + this.currentLine = row + 1; + } else if (this.currentLine == row) { + this.currentLine = row + 1; } - var lines = this.doc.getLines(firstRow, lastRow); - for (var row=firstRow; row<=lastRow; row++) { - if (!this.lines[row]) { - var tokens = this.tokenizer.getLineTokens(lines[row-firstRow] || "", state); - var state = tokens.state; - rows.push(tokens); - - if (doCache) { - this.lines[row] = tokens; - } - } - else { - var tokens = this.lines[row]; - state = tokens.state; - rows.push(tokens); - } - } - return rows; + return this.lines[row] = data.tokens; }; }).call(BackgroundTokenizer.prototype); diff --git a/lib/ace/background_tokenizer_test.js b/lib/ace/background_tokenizer_test.js new file mode 100644 index 00000000..fd738d06 --- /dev/null +++ b/lib/ace/background_tokenizer_test.js @@ -0,0 +1,128 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { +"use strict"; + +var EditSession = require("./edit_session").EditSession; +var JavaScriptMode = require("./mode/javascript").Mode; +var Range = require("./range").Range; +var assert = require("./test/assertions"); + +function forceTokenize(session){ + for (var i = 0, l = session.getLength(); i < l; i++) + session.getTokens(i) +} + +function testStates(session, states) { + for (var i = 0, l = session.getLength(); i < l; i++) + assert.equal(session.bgTokenizer.states[i], states[i]) + assert.ok(l == states.length) +} + +module.exports = { + + "test background tokenizer update on session change" : function() { + var doc = new EditSession([ + "/*", + "*/", + "var juhu" + ]); + doc.setMode("./mode/javascript") + + forceTokenize(doc) + testStates(doc, ["comment_regex_allowed", "start", "no_regex"]) + + doc.remove(new Range(0,2,1,2)) + testStates(doc, [null, "no_regex"]) + + forceTokenize(doc) + testStates(doc, ["comment_regex_allowed", "comment_regex_allowed"]) + + doc.insert({row:0, column:2}, "\n*/") + testStates(doc, [undefined, undefined, "comment_regex_allowed"]) + + forceTokenize(doc) + testStates(doc, ["comment_regex_allowed", "start", "no_regex"]) + }, + "test background tokenizer sends update event" : function() { + var doc = new EditSession([ + "/*", + "var", + "juhu", + "*/" + ]); + doc.setMode("./mode/javascript"); + + var updateEvent = null; + doc.bgTokenizer.on("update", function(e) { + updateEvent = e.data; + }); + function checkEvent(first, last) { + assert.ok(!updateEvent, "unneccessary update event"); + doc.bgTokenizer.running = 1; + doc.bgTokenizer.$worker(); + assert.ok(updateEvent); + assert.equal([first, last] + "", + [updateEvent.first, updateEvent.last] + "") + updateEvent = null; + } + + forceTokenize(doc); + var comment = "comment_regex_allowed"; + testStates(doc, [comment, comment, comment, "start"]); + + doc.remove(new Range(0,0,0,2)); + testStates(doc, [comment, comment, comment, "start"]); + + checkEvent(0, 3); + testStates(doc, ["start", "no_regex", "no_regex", "regex"]); + + // insert /* and and press down several times quickly + doc.insert({row:0, column:0}, "/*"); + doc.getTokens(0); + doc.getTokens(1); + doc.getTokens(2); + checkEvent(0, 3); + + forceTokenize(doc); + testStates(doc, [comment, comment, comment, "start"]); + } +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} diff --git a/lib/ace/commands/command_manager.js b/lib/ace/commands/command_manager.js new file mode 100644 index 00000000..df30ef9b --- /dev/null +++ b/lib/ace/commands/command_manager.js @@ -0,0 +1,118 @@ +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var MultiHashHandler = require("../keyboard/hash_handler").MultiHashHandler; +var EventEmitter = require("../lib/event_emitter").EventEmitter; + +/** + * @class CommandManager + * + **/ + +/** + * new CommandManager(platform, commands) + * @param {String} platform Identifier for the platform; must be either `"mac"` or `"win"` + * @param {Array} commands A list of commands + * + **/ + +var CommandManager = function(platform, commands) { + MultiHashHandler.call(this, commands, platform); + this.byName = this.commands; + this.setDefaultHandler("exec", function(e) { + return e.command.exec(e.editor, e.args || {}); + }); +}; + +oop.inherits(CommandManager, MultiHashHandler); + +(function() { + + oop.implement(this, EventEmitter); + + this.exec = function(command, editor, args) { + if (Array.isArray(command)) { + for (var i = command.length; i--; ) { + if (this.exec(command[i], editor, args)) return true; + } + return false; + } + + if (typeof command === "string") + command = this.commands[command]; + + if (!command) + return false; + + if (editor && editor.$readOnly && !command.readOnly) + return false; + + var e = {editor: editor, command: command, args: args}; + e.returnValue = this._emit("exec", e); + this._signal("afterExec", e); + + return e.returnValue === false ? false : true; + }; + + this.toggleRecording = function(editor) { + if (this.$inReplay) + return; + + editor && editor._emit("changeStatus"); + if (this.recording) { + this.macro.pop(); + this.removeEventListener("exec", this.$addCommandToMacro); + + if (!this.macro.length) + this.macro = this.oldMacro; + + return this.recording = false; + } + if (!this.$addCommandToMacro) { + this.$addCommandToMacro = function(e) { + this.macro.push([e.command, e.args]); + }.bind(this); + } + + this.oldMacro = this.macro; + this.macro = []; + this.on("exec", this.$addCommandToMacro); + return this.recording = true; + }; + + this.replay = function(editor) { + if (this.$inReplay || !this.macro) + return; + + if (this.recording) + return this.toggleRecording(editor); + + try { + this.$inReplay = true; + this.macro.forEach(function(x) { + if (typeof x == "string") + this.exec(x, editor); + else + this.exec(x[0], editor, x[1]); + }, this); + } finally { + this.$inReplay = false; + } + }; + + this.trimMacro = function(m) { + return m.map(function(x){ + if (typeof x[0] != "string") + x[0] = x[0].name; + if (!x[1]) + x = x[0]; + return x; + }); + }; + +}).call(CommandManager.prototype); + +exports.CommandManager = CommandManager; + +}); diff --git a/lib/ace/commands/command_manager_test.js b/lib/ace/commands/command_manager_test.js new file mode 100644 index 00000000..902600be --- /dev/null +++ b/lib/ace/commands/command_manager_test.js @@ -0,0 +1,199 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { +"use strict"; + +var CommandManager = require("./command_manager").CommandManager; +var keys = require("../lib/keys"); +var assert = require("../test/assertions"); + +module.exports = { + + setUp: function() { + this.command = { + name: "gotoline", + bindKey: { + mac: "Command-L", + win: "Ctrl-L" + }, + called: false, + exec: function(editor) { this.called = true; } + }; + + this.cm = new CommandManager("mac", [this.command]); + }, + + "test: register command": function() { + this.cm.exec("gotoline"); + assert.ok(this.command.called); + }, + + "test: mac hotkeys": function() { + var command = this.cm.findKeyCommand(keys.KEY_MODS.command, "l"); + assert.equal(command, this.command); + + var command = this.cm.findKeyCommand(keys.KEY_MODS.ctrl, "l"); + assert.equal(command, undefined); + }, + + "test: win hotkeys": function() { + var cm = new CommandManager("win", [this.command]); + + var command = cm.findKeyCommand(keys.KEY_MODS.command, "l"); + assert.equal(command, undefined); + + var command = cm.findKeyCommand(keys.KEY_MODS.ctrl, "l"); + assert.equal(command, this.command); + }, + + "test: remove command by object": function() { + this.cm.removeCommand(this.command); + + this.cm.exec("gotoline"); + assert.ok(!this.command.called); + + var command = this.cm.findKeyCommand(keys.KEY_MODS.command, "l"); + assert.equal(command, null); + }, + + "test: remove command by name": function() { + this.cm.removeCommand("gotoline"); + + this.cm.exec("gotoline"); + assert.ok(!this.command.called); + + var command = this.cm.findKeyCommand(keys.KEY_MODS.command, "l"); + assert.equal(command, null); + }, + + "test: adding a new command with the same name as an existing one should remove the old one first": function() { + var command = { + name: "gotoline", + bindKey: { + mac: "Command-L", + win: "Ctrl-L" + }, + called: false, + exec: function(editor) { this.called = true; } + }; + this.cm.addCommand(command); + + this.cm.exec("gotoline"); + assert.ok(command.called); + assert.ok(!this.command.called); + + assert.equal(this.cm.findKeyCommand(keys.KEY_MODS.command, "l"), command); + }, + + "test: adding commands and recording a macro": function() { + var called = ""; + this.cm.addCommands({ + togglerecording: function(editor) { + editor.cm.toggleRecording(editor); + }, + replay: function(editor) { + editor.cm.replay(); + }, + cm1: function(editor, arg) { + called += "1" + (arg || ""); + }, + cm2: function(editor) { + called += "2"; + } + }); + + + var statusUpdateEmitted = false; + this._emit = function() {statusUpdateEmitted = true}; + + this.cm.exec("togglerecording", this); + assert.ok(this.cm.recording); + assert.ok(statusUpdateEmitted); + + this.cm.exec("cm1", this, "-"); + this.cm.exec("cm2"); + this.cm.exec("replay", this); + assert.ok(!this.cm.recording); + assert.equal(called, "1-2"); + + called = ""; + this.cm.exec("replay", this); + assert.equal(called, "1-2"); + }, + + "test: bindkeys": function() { + this.cm.bindKeys({ + "Ctrl-L|Command-C": "cm1", + "Ctrl-R": "cm2" + }); + + var command = this.cm.findKeyCommand(keys.KEY_MODS.command, "c"); + assert.equal(command, "cm1"); + + var command = this.cm.findKeyCommand(keys.KEY_MODS.ctrl, "r"); + assert.equal(command, "cm2"); + + this.cm.bindKeys({ + "Ctrl-R": null + }); + + var command = this.cm.findKeyCommand(keys.KEY_MODS.ctrl, "r"); + assert.equal(command, null); + }, + + "test: binding keys without modifiers": function() { + this.cm.bindKeys({ + "R": "cm1", + "Shift-r": "cm2", + "Return": "cm4", + "Enter": "cm3" + }); + + var command = this.cm.findKeyCommand(-1, "r"); + assert.equal(command, "cm1"); + + var command = this.cm.findKeyCommand(-1, "R"); + assert.equal(command, "cm2"); + + var command = this.cm.findKeyCommand(0, "return"); + assert.equal(command + "", ["cm4", "cm3"] + ""); + } +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec(); +} diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index 9a748a39..de14df85 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -1,315 +1,737 @@ -/* vim:ts=4:sts=4:sw=4: - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * Mihai Sucan - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var lang = require("pilot/lang"); -var canon = require("pilot/canon"); +var lang = require("../lib/lang"); +var config = require("../config"); +var Range = require("../range").Range; -canon.addCommand({ - name: "null", - exec: function(env, args, request) { } -}); +function bindKey(win, mac) { + return {win: win, mac: mac}; +} -canon.addCommand({ +/* + multiSelectAction: "forEach"|"forEachLine"|function|undefined, + scrollIntoView: true|"cursor"|"center"|"selectionPart" +*/ +exports.commands = [{ + name: "showSettingsMenu", + bindKey: bindKey("Ctrl-,", "Command-,"), + exec: function(editor) { + config.loadModule("ace/ext/settings_menu", function(module) { + module.init(editor); + editor.showSettingsMenu(); + }); + }, + readOnly: true +}, { + name: "goToNextError", + bindKey: bindKey("Alt-E", "Ctrl-E"), + exec: function(editor) { + config.loadModule("ace/ext/error_marker", function(module) { + module.showErrorMarker(editor, 1); + }); + }, + scrollIntoView: "animate", + readOnly: true +}, { + name: "goToPreviousError", + bindKey: bindKey("Alt-Shift-E", "Ctrl-Shift-E"), + exec: function(editor) { + config.loadModule("ace/ext/error_marker", function(module) { + module.showErrorMarker(editor, -1); + }); + }, + scrollIntoView: "animate", + readOnly: true +}, { name: "selectall", - exec: function(env, args, request) { env.editor.selectAll(); } -}); -canon.addCommand({ - name: "removeline", - exec: function(env, args, request) { env.editor.removeLines(); } -}); -canon.addCommand({ - name: "gotoline", - exec: function(env, args, request) { - var line = parseInt(prompt("Enter line number:")); - if (!isNaN(line)) { - env.editor.gotoLine(line); - } - } -}); -canon.addCommand({ - name: "togglecomment", - exec: function(env, args, request) { env.editor.toggleCommentLines(); } -}); -canon.addCommand({ - name: "findnext", - exec: function(env, args, request) { env.editor.findNext(); } -}); -canon.addCommand({ - name: "findprevious", - exec: function(env, args, request) { env.editor.findPrevious(); } -}); -canon.addCommand({ - name: "find", - exec: function(env, args, request) { - var needle = prompt("Find:"); - env.editor.find(needle); - } -}); -canon.addCommand({ - name: "replace", - exec: function(env, args, request) { - var needle = prompt("Find:"); - if (!needle) - return; - var replacement = prompt("Replacement:"); - if (!replacement) - return; - env.editor.replace(replacement, {needle: needle}); - } -}); -canon.addCommand({ - name: "replaceall", - exec: function(env, args, request) { - var needle = prompt("Find:"); - if (!needle) - return; - var replacement = prompt("Replacement:"); - if (!replacement) - return; - env.editor.replaceAll(replacement, {needle: needle}); - } -}); -canon.addCommand({ - name: "undo", - exec: function(env, args, request) { env.editor.undo(); } -}); -canon.addCommand({ - name: "redo", - exec: function(env, args, request) { env.editor.redo(); } -}); -canon.addCommand({ - name: "redo", - exec: function(env, args, request) { env.editor.redo(); } -}); -canon.addCommand({ - name: "overwrite", - exec: function(env, args, request) { env.editor.toggleOverwrite(); } -}); -canon.addCommand({ - name: "copylinesup", - exec: function(env, args, request) { env.editor.copyLinesUp(); } -}); -canon.addCommand({ - name: "movelinesup", - exec: function(env, args, request) { env.editor.moveLinesUp(); } -}); -canon.addCommand({ - name: "selecttostart", - exec: function(env, args, request) { env.editor.getSelection().selectFileStart(); } -}); -canon.addCommand({ - name: "gotostart", - exec: function(env, args, request) { env.editor.navigateFileStart(); } -}); -canon.addCommand({ - name: "selectup", - exec: function(env, args, request) { env.editor.getSelection().selectUp(); } -}); -canon.addCommand({ - name: "golineup", - exec: function(env, args, request) { env.editor.navigateUp(args.times); } -}); -canon.addCommand({ - name: "copylinesdown", - exec: function(env, args, request) { env.editor.copyLinesDown(); } -}); -canon.addCommand({ - name: "movelinesdown", - exec: function(env, args, request) { env.editor.moveLinesDown(); } -}); -canon.addCommand({ - name: "selecttoend", - exec: function(env, args, request) { env.editor.getSelection().selectFileEnd(); } -}); -canon.addCommand({ - name: "gotoend", - exec: function(env, args, request) { env.editor.navigateFileEnd(); } -}); -canon.addCommand({ - name: "selectdown", - exec: function(env, args, request) { env.editor.getSelection().selectDown(); } -}); -canon.addCommand({ - name: "golinedown", - exec: function(env, args, request) { env.editor.navigateDown(args.times); } -}); -canon.addCommand({ - name: "selectwordleft", - exec: function(env, args, request) { env.editor.getSelection().selectWordLeft(); } -}); -canon.addCommand({ - name: "gotowordleft", - exec: function(env, args, request) { env.editor.navigateWordLeft(); } -}); -canon.addCommand({ - name: "selecttolinestart", - exec: function(env, args, request) { env.editor.getSelection().selectLineStart(); } -}); -canon.addCommand({ - name: "gotolinestart", - exec: function(env, args, request) { env.editor.navigateLineStart(); } -}); -canon.addCommand({ - name: "selectleft", - exec: function(env, args, request) { env.editor.getSelection().selectLeft(); } -}); -canon.addCommand({ - name: "gotoleft", - exec: function(env, args, request) { env.editor.navigateLeft(args.times); } -}); -canon.addCommand({ - name: "selectwordright", - exec: function(env, args, request) { env.editor.getSelection().selectWordRight(); } -}); -canon.addCommand({ - name: "gotowordright", - exec: function(env, args, request) { env.editor.navigateWordRight(); } -}); -canon.addCommand({ - name: "selecttolineend", - exec: function(env, args, request) { env.editor.getSelection().selectLineEnd(); } -}); -canon.addCommand({ - name: "gotolineend", - exec: function(env, args, request) { env.editor.navigateLineEnd(); } -}); -canon.addCommand({ - name: "selectright", - exec: function(env, args, request) { env.editor.getSelection().selectRight(); } -}); -canon.addCommand({ - name: "gotoright", - exec: function(env, args, request) { env.editor.navigateRight(args.times); } -}); -canon.addCommand({ - name: "selectpagedown", - exec: function(env, args, request) { env.editor.selectPageDown(); } -}); -canon.addCommand({ - name: "pagedown", - exec: function(env, args, request) { env.editor.scrollPageDown(); } -}); -canon.addCommand({ - name: "gotopagedown", - exec: function(env, args, request) { env.editor.gotoPageDown(); } -}); -canon.addCommand({ - name: "selectpageup", - exec: function(env, args, request) { env.editor.selectPageUp(); } -}); -canon.addCommand({ - name: "pageup", - exec: function(env, args, request) { env.editor.scrollPageUp(); } -}); -canon.addCommand({ - name: "gotopageup", - exec: function(env, args, request) { env.editor.gotoPageUp(); } -}); -canon.addCommand({ - name: "selectlinestart", - exec: function(env, args, request) { env.editor.getSelection().selectLineStart(); } -}); -canon.addCommand({ - name: "gotolinestart", - exec: function(env, args, request) { env.editor.navigateLineStart(); } -}); -canon.addCommand({ - name: "selectlineend", - exec: function(env, args, request) { env.editor.getSelection().selectLineEnd(); } -}); -canon.addCommand({ - name: "gotolineend", - exec: function(env, args, request) { env.editor.navigateLineEnd(); } -}); -canon.addCommand({ - name: "del", - exec: function(env, args, request) { env.editor.removeRight(); } -}); -canon.addCommand({ - name: "backspace", - exec: function(env, args, request) { env.editor.removeLeft(); } -}); -canon.addCommand({ - name: "removetolinestart", - exec: function(env, args, request) { env.editor.removeToLineStart(); } -}); -canon.addCommand({ - name: "removetolineend", - exec: function(env, args, request) { env.editor.removeToLineEnd(); } -}); -canon.addCommand({ - name: "removewordleft", - exec: function(env, args, request) { env.editor.removeWordLeft(); } -}); -canon.addCommand({ - name: "removewordright", - exec: function(env, args, request) { env.editor.removeWordRight(); } -}); -canon.addCommand({ - name: "outdent", - exec: function(env, args, request) { env.editor.blockOutdent(); } -}); -canon.addCommand({ - name: "indent", - exec: function(env, args, request) { env.editor.indent(); } -}); -canon.addCommand({ - name: "inserttext", - exec: function(env, args, request) { - env.editor.insert(lang.stringRepeat(args.text || "", args.times || 1)); - } -}); -canon.addCommand({ + bindKey: bindKey("Ctrl-A", "Command-A"), + exec: function(editor) { editor.selectAll(); }, + readOnly: true +}, { name: "centerselection", - exec: function(env, args, request) { env.editor.centerSelection(); } -}); -canon.addCommand({ + bindKey: bindKey(null, "Ctrl-L"), + exec: function(editor) { editor.centerSelection(); }, + readOnly: true +}, { + name: "gotoline", + bindKey: bindKey("Ctrl-L", "Command-L"), + exec: function(editor) { + var line = parseInt(prompt("Enter line number:"), 10); + if (!isNaN(line)) { + editor.gotoLine(line); + } + }, + readOnly: true +}, { + name: "fold", + bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"), + exec: function(editor) { editor.session.toggleFold(false); }, + multiSelectAction: "forEach", + scrollIntoView: "center", + readOnly: true +}, { + name: "unfold", + bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"), + exec: function(editor) { editor.session.toggleFold(true); }, + multiSelectAction: "forEach", + scrollIntoView: "center", + readOnly: true +}, { + name: "toggleFoldWidget", + bindKey: bindKey("F2", "F2"), + exec: function(editor) { editor.session.toggleFoldWidget(); }, + multiSelectAction: "forEach", + scrollIntoView: "center", + readOnly: true +}, { + name: "toggleParentFoldWidget", + bindKey: bindKey("Alt-F2", "Alt-F2"), + exec: function(editor) { editor.session.toggleFoldWidget(true); }, + multiSelectAction: "forEach", + scrollIntoView: "center", + readOnly: true +}, { + name: "foldall", + bindKey: bindKey(null, "Ctrl-Command-Option-0"), + exec: function(editor) { editor.session.foldAll(); }, + scrollIntoView: "center", + readOnly: true +}, { + name: "foldOther", + bindKey: bindKey("Alt-0", "Command-Option-0"), + exec: function(editor) { + editor.session.foldAll(); + editor.session.unfold(editor.selection.getAllRanges()); + }, + scrollIntoView: "center", + readOnly: true +}, { + name: "unfoldall", + bindKey: bindKey("Alt-Shift-0", "Command-Option-Shift-0"), + exec: function(editor) { editor.session.unfold(); }, + scrollIntoView: "center", + readOnly: true +}, { + name: "findnext", + bindKey: bindKey("Ctrl-K", "Command-G"), + exec: function(editor) { editor.findNext(); }, + multiSelectAction: "forEach", + scrollIntoView: "center", + readOnly: true +}, { + name: "findprevious", + bindKey: bindKey("Ctrl-Shift-K", "Command-Shift-G"), + exec: function(editor) { editor.findPrevious(); }, + multiSelectAction: "forEach", + scrollIntoView: "center", + readOnly: true +}, { + name: "selectOrFindNext", + bindKey: bindKey("Alt-K", "Ctrl-G"), + exec: function(editor) { + if (editor.selection.isEmpty()) + editor.selection.selectWord(); + else + editor.findNext(); + }, + readOnly: true +}, { + name: "selectOrFindPrevious", + bindKey: bindKey("Alt-Shift-K", "Ctrl-Shift-G"), + exec: function(editor) { + if (editor.selection.isEmpty()) + editor.selection.selectWord(); + else + editor.findPrevious(); + }, + readOnly: true +}, { + name: "find", + bindKey: bindKey("Ctrl-F", "Command-F"), + exec: function(editor) { + config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor)}); + }, + readOnly: true +}, { + name: "overwrite", + bindKey: "Insert", + exec: function(editor) { editor.toggleOverwrite(); }, + readOnly: true +}, { + name: "selecttostart", + bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Up"), + exec: function(editor) { editor.getSelection().selectFileStart(); }, + multiSelectAction: "forEach", + readOnly: true, + scrollIntoView: "animate", + aceCommandGroup: "fileJump" +}, { + name: "gotostart", + bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"), + exec: function(editor) { editor.navigateFileStart(); }, + multiSelectAction: "forEach", + readOnly: true, + scrollIntoView: "animate", + aceCommandGroup: "fileJump" +}, { + name: "selectup", + bindKey: bindKey("Shift-Up", "Shift-Up"), + exec: function(editor) { editor.getSelection().selectUp(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "golineup", + bindKey: bindKey("Up", "Up|Ctrl-P"), + exec: function(editor, args) { editor.navigateUp(args.times); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selecttoend", + bindKey: bindKey("Ctrl-Shift-End", "Command-Shift-Down"), + exec: function(editor) { editor.getSelection().selectFileEnd(); }, + multiSelectAction: "forEach", + readOnly: true, + scrollIntoView: "animate", + aceCommandGroup: "fileJump" +}, { + name: "gotoend", + bindKey: bindKey("Ctrl-End", "Command-End|Command-Down"), + exec: function(editor) { editor.navigateFileEnd(); }, + multiSelectAction: "forEach", + readOnly: true, + scrollIntoView: "animate", + aceCommandGroup: "fileJump" +}, { + name: "selectdown", + bindKey: bindKey("Shift-Down", "Shift-Down"), + exec: function(editor) { editor.getSelection().selectDown(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "golinedown", + bindKey: bindKey("Down", "Down|Ctrl-N"), + exec: function(editor, args) { editor.navigateDown(args.times); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectwordleft", + bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"), + exec: function(editor) { editor.getSelection().selectWordLeft(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "gotowordleft", + bindKey: bindKey("Ctrl-Left", "Option-Left"), + exec: function(editor) { editor.navigateWordLeft(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selecttolinestart", + bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left"), + exec: function(editor) { editor.getSelection().selectLineStart(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "gotolinestart", + bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"), + exec: function(editor) { editor.navigateLineStart(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectleft", + bindKey: bindKey("Shift-Left", "Shift-Left"), + exec: function(editor) { editor.getSelection().selectLeft(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "gotoleft", + bindKey: bindKey("Left", "Left|Ctrl-B"), + exec: function(editor, args) { editor.navigateLeft(args.times); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectwordright", + bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"), + exec: function(editor) { editor.getSelection().selectWordRight(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "gotowordright", + bindKey: bindKey("Ctrl-Right", "Option-Right"), + exec: function(editor) { editor.navigateWordRight(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selecttolineend", + bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right"), + exec: function(editor) { editor.getSelection().selectLineEnd(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "gotolineend", + bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"), + exec: function(editor) { editor.navigateLineEnd(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectright", + bindKey: bindKey("Shift-Right", "Shift-Right"), + exec: function(editor) { editor.getSelection().selectRight(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "gotoright", + bindKey: bindKey("Right", "Right|Ctrl-F"), + exec: function(editor, args) { editor.navigateRight(args.times); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectpagedown", + bindKey: "Shift-PageDown", + exec: function(editor) { editor.selectPageDown(); }, + readOnly: true +}, { + name: "pagedown", + bindKey: bindKey(null, "Option-PageDown"), + exec: function(editor) { editor.scrollPageDown(); }, + readOnly: true +}, { + name: "gotopagedown", + bindKey: bindKey("PageDown", "PageDown|Ctrl-V"), + exec: function(editor) { editor.gotoPageDown(); }, + readOnly: true +}, { + name: "selectpageup", + bindKey: "Shift-PageUp", + exec: function(editor) { editor.selectPageUp(); }, + readOnly: true +}, { + name: "pageup", + bindKey: bindKey(null, "Option-PageUp"), + exec: function(editor) { editor.scrollPageUp(); }, + readOnly: true +}, { + name: "gotopageup", + bindKey: "PageUp", + exec: function(editor) { editor.gotoPageUp(); }, + readOnly: true +}, { + name: "scrollup", + bindKey: bindKey("Ctrl-Up", null), + exec: function(e) { e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight); }, + readOnly: true +}, { + name: "scrolldown", + bindKey: bindKey("Ctrl-Down", null), + exec: function(e) { e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight); }, + readOnly: true +}, { + name: "selectlinestart", + bindKey: "Shift-Home", + exec: function(editor) { editor.getSelection().selectLineStart(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectlineend", + bindKey: "Shift-End", + exec: function(editor) { editor.getSelection().selectLineEnd(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "togglerecording", + bindKey: bindKey("Ctrl-Alt-E", "Command-Option-E"), + exec: function(editor) { editor.commands.toggleRecording(editor); }, + readOnly: true +}, { + name: "replaymacro", + bindKey: bindKey("Ctrl-Shift-E", "Command-Shift-E"), + exec: function(editor) { editor.commands.replay(editor); }, + readOnly: true +}, { + name: "jumptomatching", + bindKey: bindKey("Ctrl-P", "Ctrl-P"), + exec: function(editor) { editor.jumpToMatching(); }, + multiSelectAction: "forEach", + scrollIntoView: "animate", + readOnly: true +}, { + name: "selecttomatching", + bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"), + exec: function(editor) { editor.jumpToMatching(true); }, + multiSelectAction: "forEach", + scrollIntoView: "animate", + readOnly: true +}, { + name: "expandToMatching", + bindKey: bindKey("Ctrl-Shift-M", "Ctrl-Shift-M"), + exec: function(editor) { editor.jumpToMatching(true, true); }, + multiSelectAction: "forEach", + scrollIntoView: "animate", + readOnly: true +}, { + name: "passKeysToBrowser", + bindKey: bindKey(null, null), + exec: function() {}, + passEvent: true, + readOnly: true +}, { + name: "copy", + exec: function(editor) { + // placeholder for replay macro + }, + readOnly: true +}, + +// commands disabled in readOnly mode +{ + name: "cut", + exec: function(editor) { + var range = editor.getSelectionRange(); + editor._emit("cut", range); + + if (!editor.selection.isEmpty()) { + editor.session.remove(range); + editor.clearSelection(); + } + }, + scrollIntoView: "cursor", + multiSelectAction: "forEach" +}, { + name: "paste", + exec: function(editor, args) { + editor.$handlePaste(args); + }, + scrollIntoView: "cursor" +}, { + name: "removeline", + bindKey: bindKey("Ctrl-D", "Command-D"), + exec: function(editor) { editor.removeLines(); }, + scrollIntoView: "cursor", + multiSelectAction: "forEachLine" +}, { + name: "duplicateSelection", + bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"), + exec: function(editor) { editor.duplicateSelection(); }, + scrollIntoView: "cursor", + multiSelectAction: "forEach" +}, { + name: "sortlines", + bindKey: bindKey("Ctrl-Alt-S", "Command-Alt-S"), + exec: function(editor) { editor.sortLines(); }, + scrollIntoView: "selection", + multiSelectAction: "forEachLine" +}, { + name: "togglecomment", + bindKey: bindKey("Ctrl-/", "Command-/"), + exec: function(editor) { editor.toggleCommentLines(); }, + multiSelectAction: "forEachLine", + scrollIntoView: "selectionPart" +}, { + name: "toggleBlockComment", + bindKey: bindKey("Ctrl-Shift-/", "Command-Shift-/"), + exec: function(editor) { editor.toggleBlockComment(); }, + multiSelectAction: "forEach", + scrollIntoView: "selectionPart" +}, { + name: "modifyNumberUp", + bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"), + exec: function(editor) { editor.modifyNumber(1); }, + scrollIntoView: "cursor", + multiSelectAction: "forEach" +}, { + name: "modifyNumberDown", + bindKey: bindKey("Ctrl-Shift-Down", "Alt-Shift-Down"), + exec: function(editor) { editor.modifyNumber(-1); }, + scrollIntoView: "cursor", + multiSelectAction: "forEach" +}, { + name: "replace", + bindKey: bindKey("Ctrl-H", "Command-Option-F"), + exec: function(editor) { + config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor, true)}); + } +}, { + name: "undo", + bindKey: bindKey("Ctrl-Z", "Command-Z"), + exec: function(editor) { editor.undo(); } +}, { + name: "redo", + bindKey: bindKey("Ctrl-Shift-Z|Ctrl-Y", "Command-Shift-Z|Command-Y"), + exec: function(editor) { editor.redo(); } +}, { + name: "copylinesup", + bindKey: bindKey("Alt-Shift-Up", "Command-Option-Up"), + exec: function(editor) { editor.copyLinesUp(); }, + scrollIntoView: "cursor" +}, { + name: "movelinesup", + bindKey: bindKey("Alt-Up", "Option-Up"), + exec: function(editor) { editor.moveLinesUp(); }, + scrollIntoView: "cursor" +}, { + name: "copylinesdown", + bindKey: bindKey("Alt-Shift-Down", "Command-Option-Down"), + exec: function(editor) { editor.copyLinesDown(); }, + scrollIntoView: "cursor" +}, { + name: "movelinesdown", + bindKey: bindKey("Alt-Down", "Option-Down"), + exec: function(editor) { editor.moveLinesDown(); }, + scrollIntoView: "cursor" +}, { + name: "del", + bindKey: bindKey("Delete", "Delete|Ctrl-D|Shift-Delete"), + exec: function(editor) { editor.remove("right"); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "backspace", + bindKey: bindKey( + "Shift-Backspace|Backspace", + "Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H" + ), + exec: function(editor) { editor.remove("left"); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "cut_or_delete", + bindKey: bindKey("Shift-Delete", null), + exec: function(editor) { + if (editor.selection.isEmpty()) { + editor.remove("left"); + } else { + return false; + } + }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "removetolinestart", + bindKey: bindKey("Alt-Backspace", "Command-Backspace"), + exec: function(editor) { editor.removeToLineStart(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "removetolineend", + bindKey: bindKey("Alt-Delete", "Ctrl-K"), + exec: function(editor) { editor.removeToLineEnd(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "removewordleft", + bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"), + exec: function(editor) { editor.removeWordLeft(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "removewordright", + bindKey: bindKey("Ctrl-Delete", "Alt-Delete"), + exec: function(editor) { editor.removeWordRight(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "outdent", + bindKey: bindKey("Shift-Tab", "Shift-Tab"), + exec: function(editor) { editor.blockOutdent(); }, + multiSelectAction: "forEach", + scrollIntoView: "selectionPart" +}, { + name: "indent", + bindKey: bindKey("Tab", "Tab"), + exec: function(editor) { editor.indent(); }, + multiSelectAction: "forEach", + scrollIntoView: "selectionPart" +}, { + name: "blockoutdent", + bindKey: bindKey("Ctrl-[", "Ctrl-["), + exec: function(editor) { editor.blockOutdent(); }, + multiSelectAction: "forEachLine", + scrollIntoView: "selectionPart" +}, { + name: "blockindent", + bindKey: bindKey("Ctrl-]", "Ctrl-]"), + exec: function(editor) { editor.blockIndent(); }, + multiSelectAction: "forEachLine", + scrollIntoView: "selectionPart" +}, { + name: "insertstring", + exec: function(editor, str) { editor.insert(str); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "inserttext", + exec: function(editor, args) { + editor.insert(lang.stringRepeat(args.text || "", args.times || 1)); + }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { name: "splitline", - exec: function(env, args, request) { env.editor.splitLine(); } -}); -canon.addCommand({ + bindKey: bindKey(null, "Ctrl-O"), + exec: function(editor) { editor.splitLine(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { name: "transposeletters", - exec: function(env, args, request) { env.editor.transposeLetters(); } -}); + bindKey: bindKey("Ctrl-T", "Ctrl-T"), + exec: function(editor) { editor.transposeLetters(); }, + multiSelectAction: function(editor) {editor.transposeSelections(1); }, + scrollIntoView: "cursor" +}, { + name: "touppercase", + bindKey: bindKey("Ctrl-U", "Ctrl-U"), + exec: function(editor) { editor.toUpperCase(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "tolowercase", + bindKey: bindKey("Ctrl-Shift-U", "Ctrl-Shift-U"), + exec: function(editor) { editor.toLowerCase(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "expandtoline", + bindKey: bindKey("Ctrl-Shift-L", "Command-Shift-L"), + exec: function(editor) { + var range = editor.selection.getRange(); + range.start.column = range.end.column = 0; + range.end.row++; + editor.selection.setRange(range, false); + }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "joinlines", + bindKey: bindKey(null, null), + exec: function(editor) { + var isBackwards = editor.selection.isBackwards(); + var selectionStart = isBackwards ? editor.selection.getSelectionLead() : editor.selection.getSelectionAnchor(); + var selectionEnd = isBackwards ? editor.selection.getSelectionAnchor() : editor.selection.getSelectionLead(); + var firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length; + var selectedText = editor.session.doc.getTextRange(editor.selection.getRange()); + var selectedCount = selectedText.replace(/\n\s*/, " ").length; + var insertLine = editor.session.doc.getLine(selectionStart.row); + + for (var i = selectionStart.row + 1; i <= selectionEnd.row + 1; i++) { + var curLine = lang.stringTrimLeft(lang.stringTrimRight(editor.session.doc.getLine(i))); + if (curLine.length !== 0) { + curLine = " " + curLine; + } + insertLine += curLine; + } + + if (selectionEnd.row + 1 < (editor.session.doc.getLength() - 1)) { + // Don't insert a newline at the end of the document + insertLine += editor.session.doc.getNewLineCharacter(); + } + + editor.clearSelection(); + editor.session.doc.replace(new Range(selectionStart.row, 0, selectionEnd.row + 2, 0), insertLine); + + if (selectedCount > 0) { + // Select the text that was previously selected + editor.selection.moveCursorTo(selectionStart.row, selectionStart.column); + editor.selection.selectTo(selectionStart.row, selectionStart.column + selectedCount); + } else { + // If the joined line had something in it, start the cursor at that something + firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length > firstLineEndCol ? (firstLineEndCol + 1) : firstLineEndCol; + editor.selection.moveCursorTo(selectionStart.row, firstLineEndCol); + } + }, + multiSelectAction: "forEach", + readOnly: true +}, { + name: "invertSelection", + bindKey: bindKey(null, null), + exec: function(editor) { + var endRow = editor.session.doc.getLength() - 1; + var endCol = editor.session.doc.getLine(endRow).length; + var ranges = editor.selection.rangeList.ranges; + var newRanges = []; + + // If multiple selections don't exist, rangeList will return 0 so replace with single range + if (ranges.length < 1) { + ranges = [editor.selection.getRange()]; + } + + for (var i = 0; i < ranges.length; i++) { + if (i == (ranges.length - 1)) { + // The last selection must connect to the end of the document, unless it already does + if (!(ranges[i].end.row === endRow && ranges[i].end.column === endCol)) { + newRanges.push(new Range(ranges[i].end.row, ranges[i].end.column, endRow, endCol)); + } + } + + if (i === 0) { + // The first selection must connect to the start of the document, unless it already does + if (!(ranges[i].start.row === 0 && ranges[i].start.column === 0)) { + newRanges.push(new Range(0, 0, ranges[i].start.row, ranges[i].start.column)); + } + } else { + newRanges.push(new Range(ranges[i-1].end.row, ranges[i-1].end.column, ranges[i].start.row, ranges[i].start.column)); + } + } + + editor.exitMultiSelectMode(); + editor.clearSelection(); + + for(var i = 0; i < newRanges.length; i++) { + editor.selection.addRange(newRanges[i], false); + } + }, + readOnly: true, + scrollIntoView: "none" +}]; }); diff --git a/lib/ace/commands/incremental_search_commands.js b/lib/ace/commands/incremental_search_commands.js new file mode 100644 index 00000000..59083a85 --- /dev/null +++ b/lib/ace/commands/incremental_search_commands.js @@ -0,0 +1,213 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var config = require("../config"); +var oop = require("../lib/oop"); +var HashHandler = require("../keyboard/hash_handler").HashHandler; +var occurStartCommand = require("./occur_commands").occurStartCommand; + +// These commands can be installed in a normal key handler to start iSearch: +exports.iSearchStartCommands = [{ + name: "iSearch", + bindKey: {win: "Ctrl-F", mac: "Command-F"}, + exec: function(editor, options) { + config.loadModule(["core", "ace/incremental_search"], function(e) { + var iSearch = e.iSearch = e.iSearch || new e.IncrementalSearch(); + iSearch.activate(editor, options.backwards); + if (options.jumpToFirstMatch) iSearch.next(options); + }); + }, + readOnly: true +}, { + name: "iSearchBackwards", + exec: function(editor, jumpToNext) { editor.execCommand('iSearch', {backwards: true}); }, + readOnly: true +}, { + name: "iSearchAndGo", + bindKey: {win: "Ctrl-K", mac: "Command-G"}, + exec: function(editor, jumpToNext) { editor.execCommand('iSearch', {jumpToFirstMatch: true, useCurrentOrPrevSearch: true}); }, + readOnly: true +}, { + name: "iSearchBackwardsAndGo", + bindKey: {win: "Ctrl-Shift-K", mac: "Command-Shift-G"}, + exec: function(editor) { editor.execCommand('iSearch', {jumpToFirstMatch: true, backwards: true, useCurrentOrPrevSearch: true}); }, + readOnly: true +}]; + +// These commands are only available when incremental search mode is active: +exports.iSearchCommands = [{ + name: "restartSearch", + bindKey: {win: "Ctrl-F", mac: "Command-F"}, + exec: function(iSearch) { + iSearch.cancelSearch(true); + } +}, { + name: "searchForward", + bindKey: {win: "Ctrl-S|Ctrl-K", mac: "Ctrl-S|Command-G"}, + exec: function(iSearch, options) { + options.useCurrentOrPrevSearch = true; + iSearch.next(options); + } +}, { + name: "searchBackward", + bindKey: {win: "Ctrl-R|Ctrl-Shift-K", mac: "Ctrl-R|Command-Shift-G"}, + exec: function(iSearch, options) { + options.useCurrentOrPrevSearch = true; + options.backwards = true; + iSearch.next(options); + } +}, { + name: "extendSearchTerm", + exec: function(iSearch, string) { + iSearch.addString(string); + } +}, { + name: "extendSearchTermSpace", + bindKey: "space", + exec: function(iSearch) { iSearch.addString(' '); } +}, { + name: "shrinkSearchTerm", + bindKey: "backspace", + exec: function(iSearch) { + iSearch.removeChar(); + } +}, { + name: 'confirmSearch', + bindKey: 'return', + exec: function(iSearch) { iSearch.deactivate(); } +}, { + name: 'cancelSearch', + bindKey: 'esc|Ctrl-G', + exec: function(iSearch) { iSearch.deactivate(true); } +}, { + name: 'occurisearch', + bindKey: 'Ctrl-O', + exec: function(iSearch) { + var options = oop.mixin({}, iSearch.$options); + iSearch.deactivate(); + occurStartCommand.exec(iSearch.$editor, options); + } +}, { + name: "yankNextWord", + bindKey: "Ctrl-w", + exec: function(iSearch) { + var ed = iSearch.$editor, + range = ed.selection.getRangeOfMovements(function(sel) { sel.moveCursorWordRight(); }), + string = ed.session.getTextRange(range); + iSearch.addString(string); + } +}, { + name: "yankNextChar", + bindKey: "Ctrl-Alt-y", + exec: function(iSearch) { + var ed = iSearch.$editor, + range = ed.selection.getRangeOfMovements(function(sel) { sel.moveCursorRight(); }), + string = ed.session.getTextRange(range); + iSearch.addString(string); + } +}, { + name: 'recenterTopBottom', + bindKey: 'Ctrl-l', + exec: function(iSearch) { iSearch.$editor.execCommand('recenterTopBottom'); } +}, { + name: 'selectAllMatches', + bindKey: 'Ctrl-space', + exec: function(iSearch) { + var ed = iSearch.$editor, + hl = ed.session.$isearchHighlight, + ranges = hl && hl.cache ? hl.cache + .reduce(function(ranges, ea) { + return ranges.concat(ea ? ea : []); }, []) : []; + iSearch.deactivate(false); + ranges.forEach(ed.selection.addRange.bind(ed.selection)); + } +}, { + name: 'searchAsRegExp', + bindKey: 'Alt-r', + exec: function(iSearch) { + iSearch.convertNeedleToRegExp(); + } +}].map(function(cmd) { + cmd.readOnly = true; + cmd.isIncrementalSearchCommand = true; + cmd.scrollIntoView = "animate-cursor"; + return cmd; +}); + +function IncrementalSearchKeyboardHandler(iSearch) { + this.$iSearch = iSearch; +} + +oop.inherits(IncrementalSearchKeyboardHandler, HashHandler); + +(function() { + + this.attach = function(editor) { + var iSearch = this.$iSearch; + HashHandler.call(this, exports.iSearchCommands, editor.commands.platform); + this.$commandExecHandler = editor.commands.addEventListener('exec', function(e) { + if (!e.command.isIncrementalSearchCommand) return undefined; + e.stopPropagation(); + e.preventDefault(); + var scrollTop = editor.session.getScrollTop(); + var result = e.command.exec(iSearch, e.args || {}); + editor.renderer.scrollCursorIntoView(null, 0.5); + editor.renderer.animateScrolling(scrollTop); + return result; + }); + }; + + this.detach = function(editor) { + if (!this.$commandExecHandler) return; + editor.commands.removeEventListener('exec', this.$commandExecHandler); + delete this.$commandExecHandler; + }; + + var handleKeyboard$super = this.handleKeyboard; + this.handleKeyboard = function(data, hashId, key, keyCode) { + if (((hashId === 1/*ctrl*/ || hashId === 8/*command*/) && key === 'v') + || (hashId === 1/*ctrl*/ && key === 'y')) return null; + var cmd = handleKeyboard$super.call(this, data, hashId, key, keyCode); + if (cmd.command) { return cmd; } + if (hashId == -1) { + var extendCmd = this.commands.extendSearchTerm; + if (extendCmd) { return {command: extendCmd, args: key}; } + } + return {command: "null", passEvent: hashId == 0 || hashId == 4}; + }; + +}).call(IncrementalSearchKeyboardHandler.prototype); + + +exports.IncrementalSearchKeyboardHandler = IncrementalSearchKeyboardHandler; + +}); diff --git a/lib/ace/commands/multi_select_commands.js b/lib/ace/commands/multi_select_commands.js new file mode 100644 index 00000000..ba6392bc --- /dev/null +++ b/lib/ace/commands/multi_select_commands.js @@ -0,0 +1,113 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +// commands to enter multiselect mode +exports.defaultCommands = [{ + name: "addCursorAbove", + exec: function(editor) { editor.selectMoreLines(-1); }, + bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"}, + scrollIntoView: "cursor", + readonly: true +}, { + name: "addCursorBelow", + exec: function(editor) { editor.selectMoreLines(1); }, + bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"}, + scrollIntoView: "cursor", + readonly: true +}, { + name: "addCursorAboveSkipCurrent", + exec: function(editor) { editor.selectMoreLines(-1, true); }, + bindKey: {win: "Ctrl-Alt-Shift-Up", mac: "Ctrl-Alt-Shift-Up"}, + scrollIntoView: "cursor", + readonly: true +}, { + name: "addCursorBelowSkipCurrent", + exec: function(editor) { editor.selectMoreLines(1, true); }, + bindKey: {win: "Ctrl-Alt-Shift-Down", mac: "Ctrl-Alt-Shift-Down"}, + scrollIntoView: "cursor", + readonly: true +}, { + name: "selectMoreBefore", + exec: function(editor) { editor.selectMore(-1); }, + bindKey: {win: "Ctrl-Alt-Left", mac: "Ctrl-Alt-Left"}, + scrollIntoView: "cursor", + readonly: true +}, { + name: "selectMoreAfter", + exec: function(editor) { editor.selectMore(1); }, + bindKey: {win: "Ctrl-Alt-Right", mac: "Ctrl-Alt-Right"}, + scrollIntoView: "cursor", + readonly: true +}, { + name: "selectNextBefore", + exec: function(editor) { editor.selectMore(-1, true); }, + bindKey: {win: "Ctrl-Alt-Shift-Left", mac: "Ctrl-Alt-Shift-Left"}, + scrollIntoView: "cursor", + readonly: true +}, { + name: "selectNextAfter", + exec: function(editor) { editor.selectMore(1, true); }, + bindKey: {win: "Ctrl-Alt-Shift-Right", mac: "Ctrl-Alt-Shift-Right"}, + scrollIntoView: "cursor", + readonly: true +}, { + name: "splitIntoLines", + exec: function(editor) { editor.multiSelect.splitIntoLines(); }, + bindKey: {win: "Ctrl-Alt-L", mac: "Ctrl-Alt-L"}, + readonly: true +}, { + name: "alignCursors", + exec: function(editor) { editor.alignCursors(); }, + bindKey: {win: "Ctrl-Alt-A", mac: "Ctrl-Alt-A"}, + scrollIntoView: "cursor" +}, { + name: "findAll", + exec: function(editor) { editor.findAll(); }, + bindKey: {win: "Ctrl-Alt-K", mac: "Ctrl-Alt-G"}, + scrollIntoView: "cursor", + readonly: true +}]; + +// commands active only in multiselect mode +exports.multiSelectCommands = [{ + name: "singleSelection", + bindKey: "esc", + exec: function(editor) { editor.exitMultiSelectMode(); }, + scrollIntoView: "cursor", + readonly: true, + isAvailable: function(editor) {return editor && editor.inMultiSelectMode} +}]; + +var HashHandler = require("../keyboard/hash_handler").HashHandler; +exports.keyboardHandler = new HashHandler(exports.multiSelectCommands); + +}); diff --git a/lib/ace/commands/occur_commands.js b/lib/ace/commands/occur_commands.js new file mode 100644 index 00000000..b45fbf61 --- /dev/null +++ b/lib/ace/commands/occur_commands.js @@ -0,0 +1,110 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var config = require("../config"), + Occur = require("../occur").Occur; + +// These commands can be installed in a normal command handler to start occur: +var occurStartCommand = { + name: "occur", + exec: function(editor, options) { + var alreadyInOccur = !!editor.session.$occur; + var occurSessionActive = new Occur().enter(editor, options); + if (occurSessionActive && !alreadyInOccur) + OccurKeyboardHandler.installIn(editor); + }, + readOnly: true +}; + +var occurCommands = [{ + name: "occurexit", + bindKey: 'esc|Ctrl-G', + exec: function(editor) { + var occur = editor.session.$occur; + if (!occur) return; + occur.exit(editor, {}); + if (!editor.session.$occur) OccurKeyboardHandler.uninstallFrom(editor); + }, + readOnly: true +}, { + name: "occuraccept", + bindKey: 'enter', + exec: function(editor) { + var occur = editor.session.$occur; + if (!occur) return; + occur.exit(editor, {translatePosition: true}); + if (!editor.session.$occur) OccurKeyboardHandler.uninstallFrom(editor); + }, + readOnly: true +}]; + +var HashHandler = require("../keyboard/hash_handler").HashHandler; +var oop = require("../lib/oop"); + + +function OccurKeyboardHandler() {} + +oop.inherits(OccurKeyboardHandler, HashHandler); + +;(function() { + + this.isOccurHandler = true; + + this.attach = function(editor) { + HashHandler.call(this, occurCommands, editor.commands.platform); + this.$editor = editor; + } + + var handleKeyboard$super = this.handleKeyboard; + this.handleKeyboard = function(data, hashId, key, keyCode) { + var cmd = handleKeyboard$super.call(this, data, hashId, key, keyCode); + return (cmd && cmd.command) ? cmd : undefined; + } + +}).call(OccurKeyboardHandler.prototype); + +OccurKeyboardHandler.installIn = function(editor) { + var handler = new this(); + editor.keyBinding.addKeyboardHandler(handler); + editor.commands.addCommands(occurCommands); +} + +OccurKeyboardHandler.uninstallFrom = function(editor) { + editor.commands.removeCommands(occurCommands); + var handler = editor.getKeyboardHandler(); + if (handler.isOccurHandler) + editor.keyBinding.removeKeyboardHandler(handler); +} + +exports.occurStartCommand = occurStartCommand; + +}); diff --git a/lib/ace/config.js b/lib/ace/config.js new file mode 100644 index 00000000..fe9312fd --- /dev/null +++ b/lib/ace/config.js @@ -0,0 +1,202 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"no use strict"; + +var lang = require("./lib/lang"); +var oop = require("./lib/oop"); +var net = require("./lib/net"); +var AppConfig = require("./lib/app_config").AppConfig; + +module.exports = exports = new AppConfig(); + +var global = (function() { + return this || typeof window != "undefined" && window; +})(); + +var options = { + packaged: false, + workerPath: null, + modePath: null, + themePath: null, + basePath: "", + suffix: ".js", + $moduleUrls: {} +}; + +exports.get = function(key) { + if (!options.hasOwnProperty(key)) + throw new Error("Unknown config key: " + key); + + return options[key]; +}; + +exports.set = function(key, value) { + if (!options.hasOwnProperty(key)) + throw new Error("Unknown config key: " + key); + + options[key] = value; +}; + +exports.all = function() { + return lang.copyObject(options); +}; + +// module loading +exports.moduleUrl = function(name, component) { + if (options.$moduleUrls[name]) + return options.$moduleUrls[name]; + + var parts = name.split("/"); + component = component || parts[parts.length - 2] || ""; + + // todo make this configurable or get rid of '-' + var sep = component == "snippets" ? "/" : "-"; + var base = parts[parts.length - 1]; + if (component == "worker" && sep == "-") { + var re = new RegExp("^" + component + "[\\-_]|[\\-_]" + component + "$", "g"); + base = base.replace(re, ""); + } + + if ((!base || base == component) && parts.length > 1) + base = parts[parts.length - 2]; + var path = options[component + "Path"]; + if (path == null) { + path = options.basePath; + } else if (sep == "/") { + component = sep = ""; + } + if (path && path.slice(-1) != "/") + path += "/"; + return path + component + sep + base + this.get("suffix"); +}; + +exports.setModuleUrl = function(name, subst) { + return options.$moduleUrls[name] = subst; +}; + +exports.$loading = {}; +exports.loadModule = function(moduleName, onLoad) { + var module, moduleType; + if (Array.isArray(moduleName)) { + moduleType = moduleName[0]; + moduleName = moduleName[1]; + } + + try { + module = require(moduleName); + } catch (e) {} + // require(moduleName) can return empty object if called after require([moduleName], callback) + if (module && !exports.$loading[moduleName]) + return onLoad && onLoad(module); + + if (!exports.$loading[moduleName]) + exports.$loading[moduleName] = []; + + exports.$loading[moduleName].push(onLoad); + + if (exports.$loading[moduleName].length > 1) + return; + + var afterLoad = function() { + require([moduleName], function(module) { + exports._emit("load.module", {name: moduleName, module: module}); + var listeners = exports.$loading[moduleName]; + exports.$loading[moduleName] = null; + listeners.forEach(function(onLoad) { + onLoad && onLoad(module); + }); + }); + }; + + if (!exports.get("packaged")) + return afterLoad(); + net.loadScript(exports.moduleUrl(moduleName, moduleType), afterLoad); +}; + +// initialization +function init(packaged) { + options.packaged = packaged || require.packaged || module.packaged || (global.define && define.packaged); + + if (!global.document) + return ""; + + var scriptOptions = {}; + var scriptUrl = ""; + + // Use currentScript.ownerDocument in case this file was loaded from imported document. (HTML Imports) + var currentScript = (document.currentScript || document._currentScript ); // native or polyfill + var currentDocument = currentScript && currentScript.ownerDocument || document; + + var scripts = currentDocument.getElementsByTagName("script"); + for (var i=0; i .ace_gutter-cell { + padding-right: 13px; +} + +.ace_fold-widget { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + + margin: 0 -12px 0 1px; + display: none; + width: 11px; + vertical-align: top; + + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg=="); + background-repeat: no-repeat; + background-position: center; + + border-radius: 3px; + + border: 1px solid transparent; + cursor: pointer; +} + +.ace_folding-enabled .ace_fold-widget { + display: inline-block; +} + +.ace_fold-widget.ace_end { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg=="); +} + +.ace_fold-widget.ace_closed { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA=="); +} + +.ace_fold-widget:hover { + border: 1px solid rgba(0, 0, 0, 0.3); + background-color: rgba(255, 255, 255, 0.2); + box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7); +} + +.ace_fold-widget:active { + border: 1px solid rgba(0, 0, 0, 0.4); + background-color: rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8); +} +/** + * Dark version for fold widgets + */ +.ace_dark .ace_fold-widget { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC"); +} +.ace_dark .ace_fold-widget.ace_end { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg=="); +} +.ace_dark .ace_fold-widget.ace_closed { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg=="); +} +.ace_dark .ace_fold-widget:hover { + box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2); + background-color: rgba(255, 255, 255, 0.1); +} +.ace_dark .ace_fold-widget:active { + box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2); +} + +.ace_fold-widget.ace_invalid { + background-color: #FFB4B4; + border-color: #DE5555; +} + +.ace_fade-fold-widgets .ace_fold-widget { + -webkit-transition: opacity 0.4s ease 0.05s; + transition: opacity 0.4s ease 0.05s; + opacity: 0; +} + +.ace_fade-fold-widgets:hover .ace_fold-widget { + -webkit-transition: opacity 0.05s ease 0.05s; + transition: opacity 0.05s ease 0.05s; + opacity:1; +} + +.ace_underline { + text-decoration: underline; +} + +.ace_bold { + font-weight: bold; +} + +.ace_nobold .ace_bold { + font-weight: normal; +} + +.ace_italic { + font-style: italic; +} + + +.ace_error-marker { + background-color: rgba(255, 0, 0,0.2); + position: absolute; + z-index: 9; +} + +.ace_highlight-marker { + background-color: rgba(255, 255, 0,0.2); + position: absolute; + z-index: 8; +} + +/* +styles = [] +for (var i = 1; i < 16; i++) { + styles.push(".ace_br" + i + "{" + ( + ["top-left", "top-right", "bottom-right", "bottom-left"] + ).map(function(x, j) { + return i & (1< (http://jeditoolkit.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var settings = require("ace/settings/default-settings") - -exports.startup = function startup(data, reason) { - settings.startup(data, reason) -} - -exports.shutdown = function shutdown(data, reason) { - settings.shutdown(data, reason) -} - -}) diff --git a/lib/ace/document.js b/lib/ace/document.js index 3fd06c53..7b3e6221 100644 --- a/lib/ace/document.js +++ b/lib/ace/document.js @@ -1,59 +1,67 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var oop = require("pilot/oop"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; -var Range = require("ace/range").Range; -var Anchor = require("ace/anchor").Anchor; +var oop = require("./lib/oop"); +var applyDelta = require("./apply_delta").applyDelta; +var EventEmitter = require("./lib/event_emitter").EventEmitter; +var Range = require("./range").Range; +var Anchor = require("./anchor").Anchor; -var Document = function(text) { - this.$lines = []; +/** + * Contains the text of the document. Document can be attached to several [[EditSession `EditSession`]]s. + * At its core, `Document`s are just an array of strings, with each row in the document matching up to the array index. + * + * @class Document + **/ + +/** + * + * Creates a new `Document`. If `text` is included, the `Document` contains those strings; otherwise, it's empty. + * @param {String | Array} text The starting text + * @constructor + **/ + +var Document = function(textOrLines) { + this.$lines = [""]; - if (Array.isArray(text)) { - this.insertLines(0, text); - } // There has to be one line at least in the document. If you pass an empty // string to the insert function, nothing will happen. Workaround. - else if (text.length == 0) { + if (textOrLines.length === 0) { this.$lines = [""]; + } else if (Array.isArray(textOrLines)) { + this.insertMergedLines({row: 0, column: 0}, textOrLines); } else { - this.insert({row: 0, column:0}, text); + this.insert({row: 0, column:0}, textOrLines); } }; @@ -61,290 +69,461 @@ var Document = function(text) { oop.implement(this, EventEmitter); + /** + * Replaces all the lines in the current `Document` with the value of `text`. + * + * @param {String} text The text to use + **/ 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); + var len = this.getLength() - 1; + this.remove(new Range(0, 0, len, this.getLine(len).length)); + this.insert({row: 0, column: 0}, text); }; - + + /** + * Returns all the lines in the document as a single string, joined by the new line character. + **/ this.getValue = function() { return this.getAllLines().join(this.getNewLineCharacter()); }; - + + /** + * Creates a new `Anchor` to define a floating point in the document. + * @param {Number} row The row number to use + * @param {Number} column The column number to use + * + **/ this.createAnchor = function(row, column) { return new Anchor(this, row, column); }; + /** + * Splits a string of text on any newline (`\n`) or carriage-return (`\r`) characters. + * + * @method $split + * @param {String} text The text to work with + * @returns {String} A String array, with each index containing a piece of the original `text` string. + * + **/ + // check for IE split bug - if ("aaa".split(/a/).length == 0) + if ("aaa".split(/a/).length === 0) { this.$split = function(text) { return text.replace(/\r\n|\r/g, "\n").split("\n"); - } - else + }; + } else { this.$split = function(text) { return text.split(/\r\n|\r|\n/); }; + } this.$detectNewLine = function(text) { - var match = text.match(/^.*?(\r?\n)/m); - if (match) { - this.$autoNewLine = match[1]; - } else { - this.$autoNewLine = "\n"; + var match = text.match(/^.*?(\r\n|\r|\n)/m); + this.$autoNewLine = match ? match[1] : "\n"; + this._signal("changeNewLineMode"); + }; + + /** + * Returns the newline character that's being used, depending on the value of `newLineMode`. + * @returns {String} If `newLineMode == windows`, `\r\n` is returned. + * If `newLineMode == unix`, `\n` is returned. + * If `newLineMode == auto`, the value of `autoNewLine` is returned. + * + **/ + this.getNewLineCharacter = function() { + switch (this.$newLineMode) { + case "windows": + return "\r\n"; + case "unix": + return "\n"; + default: + return this.$autoNewLine || "\n"; } }; - this.getNewLineCharacter = function() { - switch (this.$newLineMode) { - case "windows": - return "\r\n"; - - case "unix": - return "\n"; - - case "auto": - return this.$autoNewLine; - } - }, - - this.$autoNewLine = "\n"; + this.$autoNewLine = ""; this.$newLineMode = "auto"; + /** + * [Sets the new line mode.]{: #Document.setNewLineMode.desc} + * @param {String} newLineMode [The newline mode to use; can be either `windows`, `unix`, or `auto`]{: #Document.setNewLineMode.param} + * + **/ this.setNewLineMode = function(newLineMode) { - if (this.$newLineMode === newLineMode) return; + if (this.$newLineMode === newLineMode) + return; this.$newLineMode = newLineMode; + this._signal("changeNewLineMode"); }; + /** + * [Returns the type of newlines being used; either `windows`, `unix`, or `auto`]{: #Document.getNewLineMode} + * @returns {String} + **/ this.getNewLineMode = function() { return this.$newLineMode; }; + /** + * Returns `true` if `text` is a newline character (either `\r\n`, `\r`, or `\n`). + * @param {String} text The text to check + * + **/ 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 - */ + * Returns a verbatim copy of the given line as it is in the document + * @param {Number} row The row index to retrieve + * + **/ this.getLine = function(row) { - return this.getLines(row, row + 1)[0] || ""; + return this.$lines[row] || ""; }; + /** + * Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`. + * @param {Number} firstRow The first row index to retrieve + * @param {Number} lastRow The final row index to retrieve + * + **/ 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! - */ + * Returns all lines in the document as string array. + **/ this.getAllLines = function() { return this.getLines(0, this.getLength()); }; + /** + * Returns the number of rows in the document. + **/ this.getLength = function() { return this.$lines.length; }; + /** + * Returns all the text within `range` as a single string. + * @param {Range} range The range to work with. + * + * @returns {String} + **/ 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)); - return lines.join(this.getNewLineCharacter()); + return this.getLinesForRange(range).join(this.getNewLineCharacter()); + }; + + /** + * Returns all the text within `range` as an array of lines. + * @param {Range} range The range to work with. + * + * @returns {Array} + **/ + this.getLinesForRange = function(range) { + var lines; + if (range.start.row === range.end.row) { + // Handle a single-line range. + lines = [this.getLine(range.start.row).substring(range.start.column, range.end.column)]; + } else { + // Handle a multi-line range. + lines = this.getLines(range.start.row, range.end.row); + lines[0] = (lines[0] || "").substring(range.start.column); + var l = lines.length - 1; + if (range.end.row - range.start.row == l) + lines[l] = lines[l].substring(0, range.end.column); } + return lines; }; + // Deprecated methods retained for backwards compatibility. + this.insertLines = function(row, lines) { + console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."); + return this.insertFullLines(row, lines); + }; + this.removeLines = function(firstRow, lastRow) { + console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."); + return this.removeFullLines(firstRow, lastRow); + }; + this.insertNewLine = function(position) { + console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, [\'\', \'\']) instead."); + return this.insertMergedLines(position, ["", ""]); + }; + + /** + * Inserts a block of `text` at the indicated `position`. + * @param {Object} position The position to start inserting at; it's an object that looks like `{ row: row, column: column}` + * @param {String} text A chunk of text to insert + * @returns {Object} The position ({row, column}) of the last line of `text`. If the length of `text` is 0, this function simply returns `position`. + * + **/ + this.insert = function(position, text) { + // Only detect new lines if the document has no line break yet. + if (this.getLength() <= 1) + this.$detectNewLine(text); + + return this.insertMergedLines(position, this.$split(text)); + }; + + /** + * Inserts `text` into the `position` at the current row. This method also triggers the `"change"` event. + * + * This differs from the `insert` method in two ways: + * 1. This does NOT handle newline characters (single-line text only). + * 2. This is faster than the `insert` method for single-line text insertions. + * + * @param {Object} position The position to insert at; it's an object that looks like `{ row: row, column: column}` + * @param {String} text A chunk of text + * @returns {Object} Returns an object containing the final row and column, like this: + * ``` + * {row: endRow, column: 0} + * ``` + **/ + this.insertInLine = function(position, text) { + var start = this.clippedPos(position.row, position.column); + var end = this.pos(position.row, position.column + text.length); + + this.applyDelta({ + start: start, + end: end, + action: "insert", + lines: [text] + }, true); + + return this.clonePos(end); + }; + + this.clippedPos = function(row, column) { + var length = this.getLength(); + if (row === undefined) { + row = length; + } else if (row < 0) { + row = 0; + } else if (row >= length) { + row = length - 1; + column = undefined; + } + var line = this.getLine(row); + if (column == undefined) + column = line.length; + column = Math.min(Math.max(column, 0), line.length); + return {row: row, column: column}; + }; + + this.clonePos = function(pos) { + return {row: pos.row, column: pos.column}; + }; + + this.pos = function(row, column) { + return {row: row, column: column}; + }; + this.$clipPosition = function(position) { var length = this.getLength(); if (position.row >= length) { position.row = Math.max(0, length - 1); - position.column = this.getLine(length-1).length; + position.column = this.getLine(length - 1).length; + } else { + position.row = Math.max(0, position.row); + position.column = Math.min(Math.max(position.column, 0), this.getLine(position.row).length); } return position; - } - - this.insert = function(position, text) { - if (text.length == 0) - return position; - - position = this.$clipPosition(position); - - if (this.getLength() <= 1) - this.$detectNewLine(text); - - var lines = this.$split(text); - var firstLine = lines.splice(0, 1)[0]; - var lastLine = lines.length == 0 ? null : lines.splice(lines.length - 1, 1)[0]; - - position = this.insertInLine(position, firstLine); - if (lastLine !== null) { - position = this.insertNewLine(position); // terminate first line - position = this.insertLines(position.row, lines); - position = this.insertInLine(position, lastLine || ""); - } - return position; - }; - - this.insertLines = function(row, lines) { - if (lines.length == 0) - return {row: row, column: 0}; - - var args = [row, 0]; - args.push.apply(args, lines); - this.$lines.splice.apply(this.$lines, args); - - var range = new Range(row, 0, row + lines.length, 0); - var delta = { - action: "insertLines", - range: range, - lines: lines - }; - this._dispatchEvent("change", { data: delta }); - return range.end; - }, - - this.insertNewLine = function(position) { - position = this.$clipPosition(position); - var line = this.$lines[position.row] || ""; - this.$lines[position.row] = line.substring(0, position.column); - this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length)); - - var end = { - row : position.row + 1, - column : 0 - }; - - var delta = { - action: "insertText", - range: Range.fromPoints(position, end), - text: this.getNewLineCharacter() - }; - this._dispatchEvent("change", { data: delta }); - - return end; - }; - - this.insertInLine = function(position, text) { - if (text.length == 0) - return position; - - var line = this.$lines[position.row] || ""; - this.$lines[position.row] = line.substring(0, position.column) + text - + line.substring(position.column); - - var end = { - row : position.row, - column : position.column + text.length - }; - - var delta = { - action: "insertText", - range: Range.fromPoints(position, end), - text: text - }; - this._dispatchEvent("change", { data: delta }); - - return end; - }; - - this.remove = function(range) { - // clip to document - range.start = this.$clipPosition(range.start); - range.end = this.$clipPosition(range.end); - - if (range.isEmpty()) - return range.start; - - var firstRow = range.start.row; - var lastRow = range.end.row; - - if (range.isMultiLine()) { - var firstFullRow = range.start.column == 0 ? firstRow : firstRow + 1; - var lastFullRow = lastRow - 1; - - if (range.end.column > 0) - this.removeInLine(lastRow, 0, range.end.column); - - if (lastFullRow >= firstFullRow) - this.removeLines(firstFullRow, lastFullRow); - - if (firstFullRow != firstRow) { - this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length); - this.removeNewLine(range.start.row); - } - } - else { - this.removeInLine(firstRow, range.start.column, range.end.column); - } - return range.start; - }; - - this.removeInLine = function(row, startColumn, endColumn) { - if (startColumn == endColumn) - return; - - var range = new Range(row, startColumn, row, endColumn); - var line = this.getLine(row); - var removed = line.substring(startColumn, endColumn); - var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length); - this.$lines.splice(row, 1, newLine); - - var delta = { - action: "removeText", - range: range, - text: removed - }; - this._dispatchEvent("change", { data: delta }); - return range.start; }; /** - * Removes a range of full lines + * Fires whenever the document changes. + * + * Several methods trigger different `"change"` events. Below is a list of each action type, followed by each property that's also available: + * + * * `"insert"` + * * `range`: the [[Range]] of the change within the document + * * `lines`: the lines being added + * * `"remove"` + * * `range`: the [[Range]] of the change within the document + * * `lines`: the lines being removed + * + * @event change + * @param {Object} e Contains at least one property called `"action"`. `"action"` indicates the action that triggered the change. Each action also has a set of additional properties. + * + **/ + + /** + * Inserts the elements in `lines` into the document as full lines (does not merge with existing line), starting at the row index given by `row`. This method also triggers the `"change"` event. + * @param {Number} row The index of the row to insert at + * @param {Array} lines An array of strings + * @returns {Object} Contains 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} + * ``` + * + **/ + this.insertFullLines = function(row, lines) { + // Clip to document. + // Allow one past the document end. + row = Math.min(Math.max(row, 0), this.getLength()); + + // Calculate insertion point. + var column = 0; + if (row < this.getLength()) { + // Insert before the specified row. + lines = lines.concat([""]); + column = 0; + } else { + // Insert after the last row in the document. + lines = [""].concat(lines); + row--; + column = this.$lines[row].length; + } + + // Insert. + this.insertMergedLines({row: row, column: column}, lines); + }; + + /** + * Inserts the elements in `lines` into the document, starting at the position index given by `row`. This method also triggers the `"change"` event. + * @param {Number} row The index of the row to insert at + * @param {Array} lines An array of strings + * @returns {Object} Contains 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} + * ``` + * + **/ + this.insertMergedLines = function(position, lines) { + var start = this.clippedPos(position.row, position.column); + var end = { + row: start.row + lines.length - 1, + column: (lines.length == 1 ? start.column : 0) + lines[lines.length - 1].length + }; + + this.applyDelta({ + start: start, + end: end, + action: "insert", + lines: lines + }); + + return this.clonePos(end); + }; + + /** + * Removes the `range` from the document. + * @param {Range} range A specified Range to remove + * @returns {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`. + * + **/ + this.remove = function(range) { + var start = this.clippedPos(range.start.row, range.start.column); + var end = this.clippedPos(range.end.row, range.end.column); + this.applyDelta({ + start: start, + end: end, + action: "remove", + lines: this.getLinesForRange({start: start, end: end}) + }); + return this.clonePos(start); + }; + + /** + * Removes the specified columns from the `row`. This method also triggers a `"change"` event. + * @param {Number} row The row to remove from + * @param {Number} startColumn The column to start removing at + * @param {Number} endColumn The column to stop removing at + * @returns {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. * - * @param firstRow {Integer} The first row to be removed - * @param lastRow {Integer} The last row to be removed - * @return {String[]} The removed lines - */ - this.removeLines = function(firstRow, lastRow) { - var range = new Range(firstRow, 0, lastRow + 1, 0); - var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1); - - var delta = { - action: "removeLines", - range: range, - nl: this.getNewLineCharacter(), - lines: removed - }; - this._dispatchEvent("change", { data: delta }); - return removed; + **/ + this.removeInLine = function(row, startColumn, endColumn) { + var start = this.clippedPos(row, startColumn); + var end = this.clippedPos(row, endColumn); + + this.applyDelta({ + start: start, + end: end, + action: "remove", + lines: this.getLinesForRange({start: start, end: end}) + }, true); + + return this.clonePos(start); }; + /** + * Removes a range of full lines. This method also triggers the `"change"` event. + * @param {Number} firstRow The first row to be removed + * @param {Number} lastRow The last row to be removed + * @returns {[String]} Returns all the removed lines. + * + **/ + this.removeFullLines = function(firstRow, lastRow) { + // Clip to document. + firstRow = Math.min(Math.max(0, firstRow), this.getLength() - 1); + lastRow = Math.min(Math.max(0, lastRow ), this.getLength() - 1); + + // Calculate deletion range. + // Delete the ending new line unless we're at the end of the document. + // If we're at the end of the document, delete the starting new line. + var deleteFirstNewLine = lastRow == this.getLength() - 1 && firstRow > 0; + var deleteLastNewLine = lastRow < this.getLength() - 1; + var startRow = ( deleteFirstNewLine ? firstRow - 1 : firstRow ); + var startCol = ( deleteFirstNewLine ? this.getLine(startRow).length : 0 ); + var endRow = ( deleteLastNewLine ? lastRow + 1 : lastRow ); + var endCol = ( deleteLastNewLine ? 0 : this.getLine(endRow).length ); + var range = new Range(startRow, startCol, endRow, endCol); + + // Store delelted lines with bounding newlines ommitted (maintains previous behavior). + var deletedLines = this.$lines.slice(firstRow, lastRow + 1); + + this.applyDelta({ + start: range.start, + end: range.end, + action: "remove", + lines: this.getLinesForRange(range) + }); + + // Return the deleted lines. + return deletedLines; + }; + + /** + * Removes the new line between `row` and the row immediately following it. This method also triggers the `"change"` event. + * @param {Number} row The row to check + * + **/ this.removeNewLine = function(row) { - var firstLine = this.getLine(row); - var secondLine = this.getLine(row+1); - - var range = new Range(row, firstLine.length, row+1, 0); - var line = firstLine + secondLine; - - this.$lines.splice(row, 2, line); - - var delta = { - action: "removeText", - range: range, - text: this.getNewLineCharacter() - }; - this._dispatchEvent("change", { data: delta }); + if (row < this.getLength() - 1 && row >= 0) { + this.applyDelta({ + start: this.pos(row, this.getLine(row).length), + end: this.pos(row + 1, 0), + action: "remove", + lines: ["", ""] + }); + } }; + /** + * Replaces a range in the document with the new `text`. + * @param {Range} range A specified Range to replace + * @param {String} text The new text to use as a replacement + * @returns {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. + * + **/ this.replace = function(range, text) { - if (text.length == 0 && range.isEmpty()) + if (!range instanceof Range) + range = Range.fromPoints(range.start, range.end); + if (text.length === 0 && range.isEmpty()) return range.start; // Shortcut: If the text we want to insert is the same as it is already @@ -353,47 +532,159 @@ var Document = function(text) { return range.end; this.remove(range); + var end; if (text) { - var end = this.insert(range.start, text); + end = this.insert(range.start, text); } else { end = range.start; } - + return end; }; + /** + * Applies all changes in `deltas` to the document. + * @param {Array} deltas An array of delta objects (can include "insert" and "remove" actions) + **/ this.applyDeltas = function(deltas) { for (var i=0; i=0; i--) { - var delta = deltas[i]; - var range = Range.fromPoints(delta.range.start, delta.range.end); - - if (delta.action == "insertLines") - this.removeLines(range.start.row, range.end.row - 1) - else if (delta.action == "insertText") - this.remove(range) - else if (delta.action == "removeLines") - this.insertLines(range.start.row, delta.lines) - else if (delta.action == "removeText") - this.insert(range.start, delta.text) + this.revertDelta(deltas[i]); } }; + + /** + * Applies `delta` to the document. + * @param {Object} delta A delta object (can include "insert" and "remove" actions) + **/ + this.applyDelta = function(delta, doNotValidate) { + var isInsert = delta.action == "insert"; + // An empty range is a NOOP. + if (isInsert ? delta.lines.length <= 1 && !delta.lines[0] + : !Range.comparePoints(delta.start, delta.end)) { + return; + } + + if (isInsert && delta.lines.length > 20000) + this.$splitAndapplyLargeDelta(delta, 20000); + + // Apply. + applyDelta(this.$lines, delta, doNotValidate); + this._signal("change", delta); + }; + + this.$splitAndapplyLargeDelta = function(delta, MAX) { + // Split large insert deltas. This is necessary because: + // 1. We need to support splicing delta lines into the document via $lines.splice.apply(...) + // 2. fn.apply() doesn't work for a large number of params. The smallest threshold is on chrome 40 ~42000. + // we use 20000 to leave some space for actual stack + // + // To Do: Ideally we'd be consistent and also split 'delete' deltas. We don't do this now, because delete + // delta handling is too slow. If we make delete delta handling faster we can split all large deltas + // as shown in https://gist.github.com/aldendaniels/8367109#file-document-snippet-js + // If we do this, update validateDelta() to limit the number of lines in a delete delta. + var lines = delta.lines; + var l = lines.length; + var row = delta.start.row; + var column = delta.start.column; + var from = 0, to = 0; + do { + from = to; + to += MAX - 1; + var chunk = lines.slice(from, to); + if (to > l) { + // Update remaining delta. + delta.lines = chunk; + delta.start.row = row + from; + delta.start.column = column; + break; + } + chunk.push(""); + this.applyDelta({ + start: this.pos(row + from, column), + end: this.pos(row + to, column = 0), + action: delta.action, + lines: chunk + }, true); + } while(true); + }; + + /** + * Reverts `delta` from the document. + * @param {Object} delta A delta object (can include "insert" and "remove" actions) + **/ + this.revertDelta = function(delta) { + this.applyDelta({ + start: this.clonePos(delta.start), + end: this.clonePos(delta.end), + action: (delta.action == "insert" ? "remove" : "insert"), + lines: delta.lines.slice() + }); + }; + + /** + * Converts an index position in a document to a `{row, column}` object. + * + * Index refers to the "absolute position" of a character in the document. For example: + * + * ```javascript + * var x = 0; // 10 characters, plus one for newline + * var y = -1; + * ``` + * + * Here, `y` is an index 15: 11 characters for the first row, and 5 characters until `y` in the second. + * + * @param {Number} index An index to convert + * @param {Number} startRow=0 The row from which to start the conversion + * @returns {Object} A `{row, column}` object of the `index` position + */ + this.indexToPosition = function(index, startRow) { + var lines = this.$lines || this.getAllLines(); + var newlineLength = this.getNewLineCharacter().length; + for (var i = startRow || 0, l = lines.length; i < l; i++) { + index -= lines[i].length + newlineLength; + if (index < 0) + return {row: i, column: index + lines[i].length + newlineLength}; + } + return {row: l-1, column: lines[l-1].length}; + }; + + /** + * Converts the `{row, column}` position in a document to the character's index. + * + * Index refers to the "absolute position" of a character in the document. For example: + * + * ```javascript + * var x = 0; // 10 characters, plus one for newline + * var y = -1; + * ``` + * + * Here, `y` is an index 15: 11 characters for the first row, and 5 characters until `y` in the second. + * + * @param {Object} pos The `{row, column}` to convert + * @param {Number} startRow=0 The row from which to start the conversion + * @returns {Number} The index position in the document + */ + this.positionToIndex = function(pos, startRow) { + var lines = this.$lines || this.getAllLines(); + var newlineLength = this.getNewLineCharacter().length; + var index = 0; + var row = Math.min(pos.row, lines.length); + for (var i = startRow || 0; i < row; ++i) + index += lines[i].length + newlineLength; + + return index + pos.column; + }; }).call(Document.prototype); diff --git a/lib/ace/test/document_test.js b/lib/ace/document_test.js similarity index 65% rename from lib/ace/test/document_test.js rename to lib/ace/document_test.js index ab4447a6..ada56cd2 100644 --- a/lib/ace/test/document_test.js +++ b/lib/ace/document_test.js @@ -1,55 +1,52 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ -define(function(require, exports, module) { - -var Document = require("../document").Document, - Range = require("../range").Range, - assert = require("./assertions"), - async = require("asyncjs"); +if (typeof process !== "undefined") { + require("amd-loader"); + require("./test/mockdom"); +} -var Test = { +define(function(require, exports, module) { +"use strict"; + +var Document = require("./document").Document; +var Range = require("./range").Range; +var assert = require("./test/assertions"); + +module.exports = { "test: insert text in line" : function() { var doc = new Document(["12", "34"]); var deltas = []; - doc.on("change", function(e) { deltas.push(e.data); }); + doc.on("change", function(e) { deltas.push(e); }); doc.insert({row: 0, column: 1}, "juhu"); assert.equal(doc.getValue(), ["1juhu2", "34"].join("\n")); @@ -66,9 +63,9 @@ var Test = { var doc = new Document(["12", "34"]); var deltas = []; - doc.on("change", function(e) { deltas.push(e.data); }); + doc.on("change", function(e) { deltas.push(e); }); - doc.insertNewLine({row: 0, column: 1}); + doc.insertMergedLines({row: 0, column: 1}, ['', '']); assert.equal(doc.getValue(), ["1", "2", "34"].join("\n")); var d = deltas.concat(); @@ -83,9 +80,9 @@ var Test = { var doc = new Document(["12", "34"]); var deltas = []; - doc.on("change", function(e) { deltas.push(e.data); }); + doc.on("change", function(e) { deltas.push(e); }); - doc.insertLines(0, ["aa", "bb"]); + doc.insertFullLines(0, ["aa", "bb"]); assert.equal(doc.getValue(), ["aa", "bb", "12", "34"].join("\n")); var d = deltas.concat(); @@ -100,9 +97,9 @@ var Test = { var doc = new Document(["12", "34"]); var deltas = []; - doc.on("change", function(e) { deltas.push(e.data); }); + doc.on("change", function(e) { deltas.push(e); }); - doc.insertLines(2, ["aa", "bb"]); + doc.insertFullLines(2, ["aa", "bb"]); assert.equal(doc.getValue(), ["12", "34", "aa", "bb"].join("\n")); }, @@ -110,9 +107,9 @@ var Test = { var doc = new Document(["12", "34"]); var deltas = []; - doc.on("change", function(e) { deltas.push(e.data); }); + doc.on("change", function(e) { deltas.push(e); }); - doc.insertLines(1, ["aa", "bb"]); + doc.insertFullLines(1, ["aa", "bb"]); assert.equal(doc.getValue(), ["12", "aa", "bb", "34"].join("\n")); var d = deltas.concat(); @@ -127,7 +124,7 @@ var Test = { var doc = new Document(["12", "34"]); var deltas = []; - doc.on("change", function(e) { deltas.push(e.data); }); + doc.on("change", function(e) { deltas.push(e); }); doc.insert({row: 0, column: 0}, "aa\nbb\ncc"); assert.equal(doc.getValue(), ["aa", "bb", "cc12", "34"].join("\n")); @@ -144,9 +141,9 @@ var Test = { var doc = new Document(["12", "34"]); var deltas = []; - doc.on("change", function(e) { deltas.push(e.data); }); + doc.on("change", function(e) { deltas.push(e); }); - doc.insert({row: 2, column: 0}, "aa\nbb\ncc"); + doc.insert({row: 1, column: 2}, "aa\nbb\ncc"); assert.equal(doc.getValue(), ["12", "34aa", "bb", "cc"].join("\n")); var d = deltas.concat(); @@ -161,7 +158,7 @@ var Test = { var doc = new Document(["12", "34"]); var deltas = []; - doc.on("change", function(e) { deltas.push(e.data); }); + doc.on("change", function(e) { deltas.push(e); }); doc.insert({row: 0, column: 1}, "aa\nbb\ncc"); assert.equal(doc.getValue(), ["1aa", "bb", "cc2", "34"].join("\n")); @@ -178,7 +175,7 @@ var Test = { var doc = new Document(["1234", "5678"]); var deltas = []; - doc.on("change", function(e) { deltas.push(e.data); }); + doc.on("change", function(e) { deltas.push(e); }); doc.remove(new Range(0, 1, 0, 3)); assert.equal(doc.getValue(), ["14", "5678"].join("\n")); @@ -195,7 +192,7 @@ var Test = { var doc = new Document(["1234", "5678"]); var deltas = []; - doc.on("change", function(e) { deltas.push(e.data); }); + doc.on("change", function(e) { deltas.push(e); }); doc.remove(new Range(0, 4, 1, 0)); assert.equal(doc.getValue(), ["12345678"].join("\n")); @@ -212,7 +209,7 @@ var Test = { var doc = new Document(["1234", "5678", "abcd"]); var deltas = []; - doc.on("change", function(e) { deltas.push(e.data); }); + doc.on("change", function(e) { deltas.push(e); }); doc.remove(new Range(0, 2, 2, 2)); assert.equal(doc.getValue(), ["12cd"].join("\n")); @@ -229,7 +226,7 @@ var Test = { var doc = new Document(["1234", "5678", "abcd"]); var deltas = []; - doc.on("change", function(e) { deltas.push(e.data); }); + doc.on("change", function(e) { deltas.push(e); }); doc.remove(new Range(1, 0, 3, 0)); assert.equal(doc.getValue(), ["1234", ""].join("\n")); @@ -238,7 +235,7 @@ var Test = { "test: remove lines should return the removed lines" : function() { var doc = new Document(["1234", "5678", "abcd"]); - var removed = doc.removeLines(1, 2); + var removed = doc.removeFullLines(1, 2); assert.equal(removed.join("\n"), ["5678", "abcd"].join("\n")); }, @@ -299,14 +296,40 @@ var Test = { "test: empty document has to contain one line": function() { var doc = new Document(""); assert.equal(doc.$lines.length, 1); + }, + + "test: ignore empty delta": function() { + var doc = new Document(""); + doc.on("change", function() { + throw "should ignore empty delta"; + }) + doc.insert({row: 0, column: 0}, ""); + doc.insert({row: 1, column: 1}, ""); + doc.remove({start: {row: 1, column: 1}, end: {row: 1, column: 1}}); + }, + + "test: inserting huge delta": function() { + var doc = new Document(""); + var val = ""; + var MAX = 0xF000; + for (var i = 0; i < 10 * MAX; i++) { + val += i + "\n" + } + doc.setValue(val); + assert.equal(doc.getValue(), val); + + for (var i = 3 * MAX + 2; i >= 3 * MAX - 2; i--) { + val = doc.getLines(0, i).join("\n"); + doc.setValue("\nab"); + assert.equal(doc.getValue(), "\nab"); + doc.insert({row: 1, column: 1}, val); + assert.equal(doc.getValue(), "\na" + val + "b"); + } } }; -module.exports = require("asyncjs/test").testcase(Test); - }); if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec() + require("asyncjs").test.testcase(module.exports).exec() } diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index 5a886b63..2aa9b378 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -1,69 +1,169 @@ -/* vim:ts=4:sts=4:sw=4: - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Mihai Sucan - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var oop = require("pilot/oop"); -var lang = require("pilot/lang"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; -var Selection = require("ace/selection").Selection; -var TextMode = require("ace/mode/text").Mode; -var Range = require("ace/range").Range; -var Document = require("ace/document").Document; +var oop = require("./lib/oop"); +var lang = require("./lib/lang"); +var config = require("./config"); +var EventEmitter = require("./lib/event_emitter").EventEmitter; +var Selection = require("./selection").Selection; +var TextMode = require("./mode/text").Mode; +var Range = require("./range").Range; +var Document = require("./document").Document; +var BackgroundTokenizer = require("./background_tokenizer").BackgroundTokenizer; +var SearchHighlight = require("./search_highlight").SearchHighlight; + +/** + * Stores all the data about [[Editor `Editor`]] state providing easy way to change editors state. + * + * `EditSession` can be attached to only one [[Document `Document`]]. Same `Document` can be attached to several `EditSession`s. + * @class EditSession + **/ + +//{ events +/** + * + * Emitted when the document changes. + * @event change + * @param {Object} e An object containing a `delta` of information about the change. + **/ +/** + * Emitted when the tab size changes, via [[EditSession.setTabSize]]. + * + * @event changeTabSize + **/ +/** + * Emitted when the ability to overwrite text changes, via [[EditSession.setOverwrite]]. + * + * @event changeOverwrite + **/ +/** + * Emitted when the gutter changes, either by setting or removing breakpoints, or when the gutter decorations change. + * + * @event changeBreakpoint + **/ +/** + * Emitted when a front marker changes. + * + * @event changeFrontMarker + **/ +/** + * Emitted when a back marker changes. + * + * @event changeBackMarker + **/ +/** + * Emitted when an annotation changes, like through [[EditSession.setAnnotations]]. + * + * @event changeAnnotation + **/ +/** + * Emitted when a background tokenizer asynchronously processes new rows. + * @event tokenizerUpdate + * + * @param {Object} e An object containing one property, `"data"`, that contains information about the changing rows + * + **/ +/** + * Emitted when the current mode changes. + * + * @event changeMode + * + **/ +/** + * Emitted when the wrap mode changes. + * + * @event changeWrapMode + * + **/ +/** + * Emitted when the wrapping limit changes. + * + * @event changeWrapLimit + * + **/ +/** + * Emitted when a code fold is added or removed. + * + * @event changeFold + * + **/ + /** + * Emitted when the scroll top changes. + * @event changeScrollTop + * + * @param {Number} scrollTop The new scroll top value + **/ +/** + * Emitted when the scroll left changes. + * @event changeScrollLeft + * + * @param {Number} scrollLeft The new scroll left value + **/ +//} + +/** + * + * Sets up a new `EditSession` and associates it with the given `Document` and `TextMode`. + * @param {Document | String} text [If `text` is a `Document`, it associates the `EditSession` with it. Otherwise, a new `Document` is created, with the initial text]{: #textParam} + * @param {TextMode} mode [The inital language mode to use for the document]{: #modeParam} + * + * @constructor + **/ var EditSession = function(text, mode) { - this.$modified = true; this.$breakpoints = []; + this.$decorations = []; this.$frontMarkers = {}; this.$backMarkers = {}; this.$markerId = 1; - this.$wrapData = []; + this.$undoSelect = true; - if (text instanceof Document) { - this.setDocument(text); - } else { - this.setDocument(new Document(text)); - } + this.$foldData = []; + this.$foldData.toString = function() { + return this.join("\n"); + }; + this.on("changeFold", this.onChangeFold.bind(this)); + this.$onChange = this.onChange.bind(this); + if (typeof text != "object" || !text.getLine) + text = new Document(text); + + this.setDocument(text); this.selection = new Selection(this); - if (mode) - this.setMode(mode); + + config.resetOptions(this); + this.setMode(mode); + config._signal("session", this); }; @@ -71,76 +171,273 @@ var EditSession = function(text, mode) { oop.implement(this, EventEmitter); + /** + * Sets the `EditSession` to point to a new `Document`. If a `BackgroundTokenizer` exists, it also points to `doc`. + * + * @param {Document} doc The new `Document` to use + * + **/ this.setDocument = function(doc) { if (this.doc) - throw new Error("Document is already set"); + this.doc.removeListener("change", this.$onChange); this.doc = doc; - doc.on("change", this.onChange.bind(this)); + doc.on("change", this.$onChange); + + if (this.bgTokenizer) + this.bgTokenizer.setDocument(this.getDocument()); + + this.resetCaches(); }; + /** + * Returns the `Document` associated with this session. + * @return {Document} + **/ this.getDocument = function() { return this.doc; }; - this.onChange = function(e) { - var delta = e.data; + /** + * @param {Number} row The row to work with + * + **/ + this.$resetRowCache = function(docRow) { + if (!docRow) { + this.$docRowCache = []; + this.$screenRowCache = []; + return; + } + var l = this.$docRowCache.length; + var i = this.$getRowCacheIndex(this.$docRowCache, docRow) + 1; + if (l > i) { + this.$docRowCache.splice(i, l); + this.$screenRowCache.splice(i, l); + } + }; + + this.$getRowCacheIndex = function(cacheArray, val) { + var low = 0; + var hi = cacheArray.length - 1; + + while (low <= hi) { + var mid = (low + hi) >> 1; + var c = cacheArray[mid]; + + if (val > c) + low = mid + 1; + else if (val < c) + hi = mid - 1; + else + return mid; + } + + return low -1; + }; + + this.resetCaches = function() { this.$modified = true; + this.$wrapData = []; + this.$rowLengthCache = []; + this.$resetRowCache(0); + if (this.bgTokenizer) + this.bgTokenizer.start(0); + }; + + this.onChangeFold = function(e) { + var fold = e.data; + this.$resetRowCache(fold.start.row); + }; + + this.onChange = function(delta) { + this.$modified = true; + + this.$resetRowCache(delta.start.row); + + var removedFolds = this.$updateInternalDataOnChange(delta); if (!this.$fromUndo && this.$undoManager && !delta.ignore) { - this.$deltas.push(delta); + this.$deltasDoc.push(delta); + if (removedFolds && removedFolds.length != 0) { + this.$deltasFold.push({ + action: "removeFolds", + folds: removedFolds + }); + } + this.$informUndoManager.schedule(); } - this.$updateWrapDataOnChange(e); - this._dispatchEvent("change", e); + this.bgTokenizer && this.bgTokenizer.$updateOnChange(delta); + this._signal("change", delta); }; + /** + * Sets the session text. + * @param {String} text The new text to place + * + **/ this.setValue = function(text) { this.doc.setValue(text); + this.selection.moveTo(0, 0); + + this.$resetRowCache(0); this.$deltas = []; + this.$deltasDoc = []; + this.$deltasFold = []; + this.setUndoManager(this.$undoManager); this.getUndoManager().reset(); }; + /** + * Returns the current [[Document `Document`]] as a string. + * @method toString + * @returns {String} + * @alias EditSession.getValue + * + **/ + + /** + * Returns the current [[Document `Document`]] as a string. + * @method getValue + * @returns {String} + * @alias EditSession.toString + **/ this.getValue = this.toString = function() { return this.doc.getValue(); }; + /** + * Returns the string of the current selection. + **/ this.getSelection = function() { return this.selection; }; + /** + * {:BackgroundTokenizer.getState} + * @param {Number} row The row to start at + * + * @related BackgroundTokenizer.getState + **/ + this.getState = function(row) { + return this.bgTokenizer.getState(row); + }; + + /** + * Starts tokenizing at the row indicated. Returns a list of objects of the tokenized rows. + * @param {Number} row The row to start at + * + * + * + **/ + this.getTokens = function(row) { + return this.bgTokenizer.getTokens(row); + }; + + /** + * Returns an object indicating the token at the current row. The object has two properties: `index` and `start`. + * @param {Number} row The row number to retrieve from + * @param {Number} column The column number to retrieve from + * + * + **/ + this.getTokenAt = function(row, column) { + var tokens = this.bgTokenizer.getTokens(row); + var token, c = 0; + if (column == null) { + i = tokens.length - 1; + c = this.getLine(row).length; + } else { + for (var i = 0; i < tokens.length; i++) { + c += tokens[i].value.length; + if (c >= column) + break; + } + } + token = tokens[i]; + if (!token) + return null; + token.index = i; + token.start = c - token.value.length; + return token; + }; + + /** + * Sets the undo manager. + * @param {UndoManager} undoManager The new undo manager + * + * + **/ this.setUndoManager = function(undoManager) { this.$undoManager = undoManager; this.$deltas = []; + this.$deltasDoc = []; + this.$deltasFold = []; - if (this.$informUndoManager) { + if (this.$informUndoManager) this.$informUndoManager.cancel(); - } if (undoManager) { var self = this; - this.$informUndoManager = lang.deferredCall(function() { - if (self.$deltas.length > 0) - undoManager.execute({ - action : "aceupdate", - args : [self.$deltas, self] + + this.$syncInformUndoManager = function() { + self.$informUndoManager.cancel(); + + if (self.$deltasFold.length) { + self.$deltas.push({ + group: "fold", + deltas: self.$deltasFold }); + self.$deltasFold = []; + } + + if (self.$deltasDoc.length) { + self.$deltas.push({ + group: "doc", + deltas: self.$deltasDoc + }); + self.$deltasDoc = []; + } + + if (self.$deltas.length > 0) { + undoManager.execute({ + action: "aceupdate", + args: [self.$deltas, self], + merge: self.mergeUndoDeltas + }); + } + self.mergeUndoDeltas = false; self.$deltas = []; - }); + }; + this.$informUndoManager = lang.delayedCall(this.$syncInformUndoManager); } }; + /** + * starts a new group in undo history + **/ + this.markUndoGroup = function() { + if (this.$syncInformUndoManager) + this.$syncInformUndoManager(); + }; + this.$defaultUndoManager = { undo: function() {}, redo: function() {}, reset: function() {} }; + /** + * Returns the current undo manager. + **/ this.getUndoManager = function() { return this.$undoManager || this.$defaultUndoManager; - }, + }; + /** + * 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()); @@ -149,81 +446,169 @@ var EditSession = function(text, mode) { } }; - this.$useSoftTabs = true; - this.setUseSoftTabs = function(useSoftTabs) { - if (this.$useSoftTabs === useSoftTabs) return; - - this.$useSoftTabs = useSoftTabs; + /** + /** + * Pass `true` to enable the use of soft tabs. Soft tabs means you're using spaces instead of the tab character (`'\t'`). + * @param {Boolean} useSoftTabs Value indicating whether or not to use soft tabs + **/ + this.setUseSoftTabs = function(val) { + this.setOption("useSoftTabs", val); }; - + /** + * Returns `true` if soft tabs are being used, `false` otherwise. + * @returns {Boolean} + **/ this.getUseSoftTabs = function() { - return this.$useSoftTabs; + // todo might need more general way for changing settings from mode, but this is ok for now + return this.$useSoftTabs && !this.$mode.$indentWithTabs; }; - - this.$tabSize = 4; + /** + * 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. + * @param {Number} tabSize The new tab size + **/ this.setTabSize = function(tabSize) { - if (isNaN(tabSize) || this.$tabSize === tabSize) return; - - this.$modified = true; - this.$tabSize = tabSize; - this._dispatchEvent("changeTabSize"); + this.setOption("tabSize", tabSize); }; - + /** + * Returns the current tab size. + **/ this.getTabSize = function() { return this.$tabSize; }; + /** + * Returns `true` if the character at the position is a soft tab. + * @param {Object} position The position to check + * + * + **/ this.isTabStop = function(position) { - return this.$useSoftTabs && (position.column % this.$tabSize == 0); + return this.$useSoftTabs && (position.column % this.$tabSize === 0); }; this.$overwrite = false; + /** + * 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. + * + * @param {Boolean} overwrite Defines wheter or not to set overwrites + * + * + **/ this.setOverwrite = function(overwrite) { - if (this.$overwrite == overwrite) return; - - this.$overwrite = overwrite; - this._dispatchEvent("changeOverwrite"); + this.setOption("overwrite", overwrite); }; + /** + * Returns `true` if overwrites are enabled; `false` otherwise. + **/ this.getOverwrite = function() { return this.$overwrite; }; + /** + * Sets the value of overwrite to the opposite of whatever it currently is. + **/ this.toggleOverwrite = function() { this.setOverwrite(!this.$overwrite); }; + /** + * Adds `className` to the `row`, to be used for CSS stylings and whatnot. + * @param {Number} row The row number + * @param {String} className The class to add + * + * + **/ + this.addGutterDecoration = function(row, className) { + if (!this.$decorations[row]) + this.$decorations[row] = ""; + this.$decorations[row] += " " + className; + this._signal("changeBreakpoint", {}); + }; + + /** + * Removes `className` from the `row`. + * @param {Number} row The row number + * @param {String} className The class to add + * + * + **/ + this.removeGutterDecoration = function(row, className) { + this.$decorations[row] = (this.$decorations[row] || "").replace(" " + className, ""); + this._signal("changeBreakpoint", {}); + }; + + /** + * Returns an array of numbers, indicating which rows have breakpoints. + * @returns {[Number]} + **/ this.getBreakpoints = function() { return this.$breakpoints; }; + /** + * Sets a breakpoint on every row number given by `rows`. This function also emites the `'changeBreakpoint'` event. + * @param {Array} rows An array of row indices + * + * + * + **/ this.setBreakpoints = function(rows) { this.$breakpoints = []; for (var i=0; i 0) { + if (column > 0) inToken = !!line.charAt(column - 1).match(this.tokenRe); - } - if (!inToken) { + if (!inToken) inToken = !!line.charAt(column).match(this.tokenRe); - } - var re = inToken ? this.tokenRe : this.nonTokenRe; + if (inToken) + var re = this.tokenRe; + else if (/^\s+$/.test(line.slice(column-1, column+1))) + var re = /\s/; + else + var re = this.nonTokenRe; var start = column; if (start > 0) { @@ -336,351 +799,593 @@ var EditSession = function(text, mode) { return new Range(row, start, row, end); }; + /** + * Gets the range of a word, including its right whitespace. + * @param {Number} row The row number to start from + * @param {Number} column The column number to start from + * + * @return {Range} + **/ + this.getAWordRange = function(row, column) { + var wordRange = this.getWordRange(row, column); + var line = this.getLine(wordRange.end.row); + + while (line.charAt(wordRange.end.column).match(/[ \t]/)) { + wordRange.end.column += 1; + } + return wordRange; + }; + + /** + * {:Document.setNewLineMode.desc} + * @param {String} newLineMode {:Document.setNewLineMode.param} + * + * + * @related Document.setNewLineMode + **/ this.setNewLineMode = function(newLineMode) { this.doc.setNewLineMode(newLineMode); }; + /** + * + * Returns the current new line mode. + * @returns {String} + * @related Document.getNewLineMode + **/ this.getNewLineMode = function() { return this.doc.getNewLineMode(); }; - this.$useWorker = false; - this.setUseWorker = function(useWorker) { - if (this.$useWorker == useWorker) + /** + * Identifies if you want to use a worker for the `EditSession`. + * @param {Boolean} useWorker Set to `true` to use a worker + * + **/ + this.setUseWorker = function(useWorker) { this.setOption("useWorker", useWorker); }; + + /** + * Returns `true` if workers are being used. + **/ + this.getUseWorker = function() { return this.$useWorker; }; + + /** + * 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); + this._signal("tokenizerUpdate", e); + }; + + this.$modes = {}; + + /** + * 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. + * @param {TextMode} mode Set a new text mode + * @param {cb} optional callback + * + **/ + this.$mode = null; + this.$modeId = null; + this.setMode = function(mode, cb) { + if (mode && typeof mode === "object") { + if (mode.getTokenizer) + return this.$onChangeMode(mode); + var options = mode; + var path = options.path; + } else { + path = mode || "ace/mode/text"; + } + + // this is needed if ace isn't on require path (e.g tests in node) + if (!this.$modes["ace/mode/text"]) + this.$modes["ace/mode/text"] = new TextMode(); + + if (this.$modes[path] && !options) { + this.$onChangeMode(this.$modes[path]); + cb && cb(); + return; + } + // load on demand + this.$modeId = path; + config.loadModule(["mode", path], function(m) { + if (this.$modeId !== path) + return cb && cb(); + if (this.$modes[path] && !options) { + this.$onChangeMode(this.$modes[path]); + } else if (m && m.Mode) { + m = new m.Mode(options); + if (!options) { + this.$modes[path] = m; + m.$id = path; + } + this.$onChangeMode(m); + } + cb && cb(); + }.bind(this)); + + // set mode to text until loading is finished + if (!this.$mode) + this.$onChangeMode(this.$modes["ace/mode/text"], true); + }; + + this.$onChangeMode = function(mode, $isPlaceholder) { + if (!$isPlaceholder) + this.$modeId = mode.$id; + if (this.$mode === mode) return; - if (useWorker && !this.$worker && window.Worker) - this.$worker = mode.createWorker(this); - - if (!useWorker && this.$worker) { - this.$worker.terminate(); - this.$worker = null; - } - }; - - this.getUseWorker = function() { - return this.$useWorker; - }; - - this.$mode = null; - this.setMode = function(mode) { - if (this.$mode === mode) return; - - if (this.$worker) - this.$worker.terminate(); - - if (this.$useWorker && window.Worker && !require.noWorker) - this.$worker = mode.createWorker(this); - else - this.$worker = null; - this.$mode = mode; - this._dispatchEvent("changeMode"); + + this.$stopWorker(); + + if (this.$useWorker) + this.$startWorker(); + + var tokenizer = mode.getTokenizer(); + + if(tokenizer.addEventListener !== undefined) { + var onReloadTokenizer = this.onReloadTokenizer.bind(this); + tokenizer.addEventListener("update", onReloadTokenizer); + } + + if (!this.bgTokenizer) { + this.bgTokenizer = new BackgroundTokenizer(tokenizer); + var _self = this; + this.bgTokenizer.addEventListener("update", function(e) { + _self._signal("tokenizerUpdate", e); + }); + } else { + this.bgTokenizer.setTokenizer(tokenizer); + } + + this.bgTokenizer.setDocument(this.getDocument()); + + this.tokenRe = mode.tokenRe; + this.nonTokenRe = mode.nonTokenRe; + + + if (!$isPlaceholder) { + // experimental method, used by c9 findiniles + if (mode.attachToSession) + mode.attachToSession(this); + this.$options.wrapMethod.set.call(this, this.$wrapMethod); + this.$setFolding(mode.foldingRules); + this.bgTokenizer.start(0); + this._emit("changeMode"); + } }; - this.getMode = function() { - if (!this.$mode) { - this.$mode = new TextMode(); + this.$stopWorker = function() { + if (this.$worker) { + this.$worker.terminate(); + this.$worker = null; } + }; + + this.$startWorker = function() { + try { + this.$worker = this.$mode.createWorker(this); + } catch (e) { + config.warn("Could not load worker", e); + this.$worker = null; + } + }; + + /** + * Returns the current text mode. + * @returns {TextMode} The current text mode + **/ + this.getMode = function() { return this.$mode; }; this.$scrollTop = 0; - this.setScrollTopRow = function(scrollTopRow) { - if (this.$scrollTop === scrollTopRow) return; + /** + * This function sets the scroll top value. It also emits the `'changeScrollTop'` event. + * @param {Number} scrollTop The new scroll top value + * + **/ + this.setScrollTop = function(scrollTop) { + // TODO: should we force integer lineheight instead? scrollTop = Math.round(scrollTop); + if (this.$scrollTop === scrollTop || isNaN(scrollTop)) + return; - this.$scrollTop = scrollTopRow; - this._dispatchEvent("changeScrollTop"); + this.$scrollTop = scrollTop; + this._signal("changeScrollTop", scrollTop); }; - this.getScrollTopRow = function() { + /** + * [Returns the value of the distance between the top of the editor and the topmost part of the visible content.]{: #EditSession.getScrollTop} + * @returns {Number} + **/ + this.getScrollTop = function() { return this.$scrollTop; }; - this.getWidth = function() { - this.$computeWidth(); - return this.width; + this.$scrollLeft = 0; + /** + * [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(scrollLeft); + if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft)) + return; + + this.$scrollLeft = scrollLeft; + this._signal("changeScrollLeft", scrollLeft); }; + /** + * [Returns the value of the distance between the left of the editor and the leftmost part of the visible content.]{: #EditSession.getScrollLeft} + * @returns {Number} + **/ + this.getScrollLeft = function() { + return this.$scrollLeft; + }; + + /** + * Returns the width of the screen. + * @returns {Number} + **/ this.getScreenWidth = function() { this.$computeWidth(); + if (this.lineWidgets) + return Math.max(this.getLineWidgetMaxWidth(), this.screenWidth); return this.screenWidth; }; + + this.getLineWidgetMaxWidth = function() { + if (this.lineWidgetsWidth != null) return this.lineWidgetsWidth; + var width = 0; + this.lineWidgets.forEach(function(w) { + if (w && w.screenWidth > width) + width = w.screenWidth; + }); + return this.lineWidgetWidth = width; + }; this.$computeWidth = function(force) { if (this.$modified || force) { this.$modified = false; + if (this.$useWrapMode) + return this.screenWidth = this.$wrapLimit; + var lines = this.doc.getAllLines(); - var longestLine = 0; + var cache = this.$rowLengthCache; var longestScreenLine = 0; - var tabSize = this.getTabSize(); + var foldIndex = 0; + var foldLine = this.$foldData[foldIndex]; + var foldStart = foldLine ? foldLine.start.row : Infinity; + var len = lines.length; - for ( var i = 0; i < lines.length; i++) { - var len = lines[i].length; - longestLine = Math.max(longestLine, len); + for (var i = 0; i < len; i++) { + if (i > foldStart) { + i = foldLine.end.row + 1; + if (i >= len) + break; + foldLine = this.$foldData[foldIndex++]; + foldStart = foldLine ? foldLine.start.row : Infinity; + } - lines[i].replace(/\t/g, function(m) { - len += tabSize-1; - return m; - }); - longestScreenLine = Math.max(longestScreenLine, len); - } - this.width = longestLine; - - if (this.$useWrapMode) { - this.screenWidth = this.$wrapLimit; - } else { - this.screenWidth = longestScreenLine; + if (cache[i] == null) + cache[i] = this.$getStringScreenWidth(lines[i])[0]; + + if (cache[i] > longestScreenLine) + longestScreenLine = cache[i]; } + this.screenWidth = longestScreenLine; } }; /** - * Get 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 + * @param {Number} row The row to retrieve from + * + * + * @returns {String} + * + **/ this.getLine = function(row) { return this.doc.getLine(row); }; /** - * Get a line as it is displayed on screen. Tabs are replaced by spaces. - */ - this.getDisplayLine = function(row) { - var tab = new Array(this.getTabSize()+1).join(" "); - return this.doc.getLine(row).replace(/\t/g, tab); - }; - + * Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`. + * @param {Number} firstRow The first row index to retrieve + * @param {Number} lastRow The final row index to retrieve + * + * @returns {[String]} + * + **/ this.getLines = function(firstRow, lastRow) { return this.doc.getLines(firstRow, lastRow); }; + /** + * Returns the number of rows in the document. + * @returns {Number} + **/ this.getLength = function() { return this.doc.getLength(); }; + /** + * {:Document.getTextRange.desc} + * @param {Range} range The range to work with + * + * @returns {String} + **/ this.getTextRange = function(range) { - return this.doc.getTextRange(range); - }; - - this.findMatchingBracket = function(position) { - if (position.column == 0) return null; - - var charBeforeCursor = this.getLine(position.row).charAt(position.column-1); - if (charBeforeCursor == "") return null; - - var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/); - if (!match) { - return null; - } - - if (match[1]) { - return this.$findClosingBracket(match[1], position); - } else { - return this.$findOpeningBracket(match[2], position); - } - }; - - this.$brackets = { - ")": "(", - "(": ")", - "]": "[", - "[": "]", - "{": "}", - "}": "{" - }; - - this.$findOpeningBracket = function(bracket, position) { - var openBracket = this.$brackets[bracket]; - - var column = position.column - 2; - var row = position.row; - var depth = 1; - - var line = this.getLine(row); - - while (true) { - while(column >= 0) { - var ch = line.charAt(column); - if (ch == openBracket) { - depth -= 1; - if (depth == 0) { - return {row: row, column: column}; - } - } - else if (ch == bracket) { - depth +=1; - } - column -= 1; - } - row -=1; - if (row < 0) break; - - var line = this.getLine(row); - var column = line.length-1; - } - return null; - }; - - this.$findClosingBracket = function(bracket, position) { - var closingBracket = this.$brackets[bracket]; - - var column = position.column; - var row = position.row; - var depth = 1; - - var line = this.getLine(row); - var lineCount = this.getLength(); - - while (true) { - while(column < line.length) { - var ch = line.charAt(column); - if (ch == closingBracket) { - depth -= 1; - if (depth == 0) { - return {row: row, column: column}; - } - } - else if (ch == bracket) { - depth +=1; - } - column += 1; - } - row +=1; - if (row >= lineCount) break; - - var line = this.getLine(row); - var column = 0; - } - return null; + return this.doc.getTextRange(range || this.selection.getRange()); }; + /** + * Inserts a block of `text` and the indicated `position`. + * @param {Object} position The position {row, column} to start inserting at + * @param {String} text A chunk of text to insert + * @returns {Object} The position of the last line of `text`. If the length of `text` is 0, this function simply returns `position`. + * + * + **/ this.insert = function(position, text) { return this.doc.insert(position, text); }; + /** + * Removes the `range` from the document. + * @param {Range} range A specified Range to remove + * @returns {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`. + * + * @related Document.remove + * + **/ this.remove = function(range) { return this.doc.remove(range); }; + + /** + * Removes a range of full lines. This method also triggers the `'change'` event. + * @param {Number} firstRow The first row to be removed + * @param {Number} lastRow The last row to be removed + * @returns {[String]} Returns all the removed lines. + * + * @related Document.removeFullLines + * + **/ + this.removeFullLines = function(firstRow, lastRow){ + return this.doc.removeFullLines(firstRow, lastRow); + }; - this.undoChanges = function(deltas) { + /** + * Reverts previous changes to your document. + * @param {Array} deltas An array of previous changes + * @param {Boolean} dontSelect [If `true`, doesn't select the range of where the change occured]{: #dontSelect} + * + * + * @returns {Range} + **/ + this.undoChanges = function(deltas, dontSelect) { if (!deltas.length) return; this.$fromUndo = true; - this.doc.revertDeltas(deltas); - this.$fromUndo = false; - - this.$setUndoSelection(deltas, true); - }, - - this.redoChanges = function(deltas) { - if (!deltas.length) - return; - - this.$fromUndo = true; - this.doc.applyDeltas(deltas); - this.$fromUndo = false; - - this.$setUndoSelection(deltas, false); - }, - - this.$setUndoSelection = function(deltas, isUndo) { - // invert deltas is they are an undo - if (isUndo) - deltas = deltas.map(function(delta) { - var d = { - range: delta.range - } - if (delta.action == "insertText" || delta.action == "insertLines") - d.action = "removeText" - else - d.action = "insertText" - return d; - }).reverse(); - - - var actions = [{}]; - - // collapse insert and remove operations - for (var i=0; i fromRange.end.column) + toRange.start.column += collDiff; + if (toRange.end.row == fromRange.end.row && toRange.end.column > fromRange.end.column) + toRange.end.column += collDiff; + } + if (rowDiff && toRange.start.row >= fromRange.end.row) { + toRange.start.row += rowDiff; + toRange.end.row += rowDiff; + } } - var endRow = toRow + fromRange.end.row - fromRange.start.row; - var endColumn = fromRange.isMultiLine() ? - fromRange.end.column : - toColumn + fromRange.end.column - fromRange.start.column; - - var toRange = new Range(toRow, toColumn, endRow, endColumn); - - this.insert(toRange.start, text); + toRange.end = this.insert(toRange.start, text); + if (folds.length) { + var oldStart = fromRange.start; + var newStart = toRange.start; + var rowDiff = newStart.row - oldStart.row; + var collDiff = newStart.column - oldStart.column; + this.addFolds(folds.map(function(x) { + x = x.clone(); + if (x.start.row == oldStart.row) + x.start.column += collDiff; + if (x.end.row == oldStart.row) + x.end.column += collDiff; + x.start.row += rowDiff; + x.end.row += rowDiff; + return x; + })); + } return toRange; }; + /** + * 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()`]]. + * @param {Number} startRow Starting row + * @param {Number} endRow Ending row + * @param {String} indentString The indent token + * + * + **/ 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); - } + for (var row=startRow; row<=endRow; row++) + this.doc.insertInLine({row: row, column: 0}, indentString); }; + /** + * Outdents all the rows defined by the `start` and `end` properties of `range`. + * @param {Range} range A range of rows + * + * + **/ this.outdentRows = function (range) { var rowRange = range.collapseRows(); var deleteRange = new Range(0, 0, 0, 0); @@ -705,37 +1410,129 @@ var EditSession = function(text, mode) { } }; + this.$moveLines = function(firstRow, lastRow, dir) { + firstRow = this.getRowFoldStart(firstRow); + lastRow = this.getRowFoldEnd(lastRow); + if (dir < 0) { + var row = this.getRowFoldStart(firstRow + dir); + if (row < 0) return 0; + var diff = row-firstRow; + } else if (dir > 0) { + var row = this.getRowFoldEnd(lastRow + dir); + if (row > this.doc.getLength()-1) return 0; + var diff = row-lastRow; + } else { + firstRow = this.$clipRowToDocument(firstRow); + lastRow = this.$clipRowToDocument(lastRow); + var diff = lastRow - firstRow + 1; + } + + var range = new Range(firstRow, 0, lastRow, Number.MAX_VALUE); + var folds = this.getFoldsInRange(range).map(function(x){ + x = x.clone(); + x.start.row += diff; + x.end.row += diff; + return x; + }); + + var lines = dir == 0 + ? this.doc.getLines(firstRow, lastRow) + : this.doc.removeFullLines(firstRow, lastRow); + this.doc.insertFullLines(firstRow+diff, lines); + folds.length && this.addFolds(folds); + return diff; + }; + /** + * Shifts all the lines in the document up one, starting from `firstRow` and ending at `lastRow`. + * @param {Number} firstRow The starting row to move up + * @param {Number} lastRow The final row to move up + * @returns {Number} If `firstRow` is less-than or equal to 0, this function returns 0. Otherwise, on success, it returns -1. + * + **/ this.moveLinesUp = function(firstRow, lastRow) { - if (firstRow <= 0) return 0; - - var removed = this.doc.removeLines(firstRow, lastRow); - this.doc.insertLines(firstRow - 1, removed); - return -1; + return this.$moveLines(firstRow, lastRow, -1); }; + /** + * Shifts all the lines in the document down one, starting from `firstRow` and ending at `lastRow`. + * @param {Number} firstRow The starting row to move down + * @param {Number} lastRow The final row to move down + * @returns {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; - - var removed = this.doc.removeLines(firstRow, lastRow); - this.doc.insertLines(firstRow+1, removed); - return 1; + return this.$moveLines(firstRow, lastRow, 1); }; + /** + * Duplicates all the text between `firstRow` and `lastRow`. + * @param {Number} firstRow The starting row to duplicate + * @param {Number} lastRow The final row to duplicate + * @returns {Number} Returns the number of new rows added; in other words, `lastRow - firstRow + 1`. + * + * + **/ this.duplicateLines = function(firstRow, lastRow) { - var firstRow = this.$clipRowToDocument(firstRow); - var lastRow = this.$clipRowToDocument(lastRow); - - var lines = this.getLines(firstRow, lastRow); - this.doc.insertLines(firstRow, lines); - - var addedRows = lastRow - firstRow + 1; - return addedRows; + return this.$moveLines(firstRow, lastRow, 0); }; + this.$clipRowToDocument = function(row) { return Math.max(0, Math.min(row, this.doc.getLength()-1)); }; + this.$clipColumnToRow = function(row, column) { + if (column < 0) + return 0; + return Math.min(this.doc.getLine(row).length, column); + }; + + + this.$clipPositionToDocument = function(row, column) { + column = Math.max(0, column); + + if (row < 0) { + row = 0; + column = 0; + } else { + var len = this.doc.getLength(); + if (row >= len) { + row = len - 1; + column = this.doc.getLine(len-1).length; + } else { + column = Math.min(this.doc.getLine(row).length, column); + } + } + + return { + row: row, + column: column + }; + }; + + this.$clipRangeToDocument = function(range) { + if (range.start.row < 0) { + range.start.row = 0; + range.start.column = 0; + } else { + range.start.column = this.$clipColumnToRow( + range.start.row, + range.start.column + ); + } + + var len = this.doc.getLength() - 1; + if (range.end.row > len) { + range.end.row = len; + range.end.column = this.doc.getLine(len).length; + } else { + range.end.column = this.$clipColumnToRow( + range.end.row, + range.end.column + ); + } + return range; + }; + // WRAPMODE this.$wrapLimit = 80; this.$useWrapMode = false; @@ -744,25 +1541,33 @@ var EditSession = function(text, mode) { max : null }; + /** + * Sets whether or not line wrapping is enabled. If `useWrapMode` is different than the current value, the `'changeWrapMode'` event is emitted. + * @param {Boolean} useWrapMode Enable (or disable) wrap mode + * + * + **/ this.setUseWrapMode = function(useWrapMode) { if (useWrapMode != this.$useWrapMode) { this.$useWrapMode = useWrapMode; this.$modified = true; + this.$resetRowCache(0); // If wrapMode is activaed, the wrapData array has to be initialized. if (useWrapMode) { var len = this.getLength(); - this.$wrapData = []; - for (i = 0; i < len; i++) { - this.$wrapData.push([]); - } + this.$wrapData = Array(len); this.$updateWrapData(0, len - 1); } - this._dispatchEvent("changeWrapMode"); + this._signal("changeWrapMode"); } }; + /** + * Returns `true` if wrap mode is being used; `false` otherwise. + * @returns {Boolean} + **/ this.getUseWrapMode = function() { return this.$useWrapMode; }; @@ -771,49 +1576,83 @@ 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. + /** + * 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. + * @param {Number} min The minimum wrap value (the left side wrap) + * @param {Number} max The maximum wrap value (the right side wrap) + * + * + **/ this.setWrapLimitRange = function(min, max) { if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) { - this.$wrapLimitRange.min = min; - this.$wrapLimitRange.max = max; + this.$wrapLimitRange = { min: min, max: max }; this.$modified = true; // This will force a recalculation of the wrap limit - this._dispatchEvent("changeWrapMode"); + if (this.$useWrapMode) + this._signal("changeWrapMode"); } }; - // 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) { + /** + * This should generally only be called by the renderer when a resize is detected. + * @param {Number} desiredLimit The new wrap limit + * @returns {Boolean} + * + * @private + **/ + this.adjustWrapLimit = function(desiredLimit, $printMargin) { + var limits = this.$wrapLimitRange; + if (limits.max < 0) + limits = {min: $printMargin, max: $printMargin}; + var wrapLimit = this.$constrainWrapLimit(desiredLimit, limits.min, limits.max); + if (wrapLimit != this.$wrapLimit && wrapLimit > 1) { this.$wrapLimit = wrapLimit; this.$modified = true; if (this.$useWrapMode) { this.$updateWrapData(0, this.getLength() - 1); - this._dispatchEvent("changeWrapLimit"); + this.$resetRowCache(0); + this._signal("changeWrapLimit"); } return true; } return false; }; - this.$constrainWrapLimit = function(wrapLimit) { - var min = this.$wrapLimitRange.min; + this.$constrainWrapLimit = function(wrapLimit, min, max) { if (min) wrapLimit = Math.max(min, wrapLimit); - var max = this.$wrapLimitRange.max; if (max) wrapLimit = Math.min(max, wrapLimit); - // What would a limit of 0 even mean? - return Math.max(1, wrapLimit); + return wrapLimit; }; + /** + * Returns the value of wrap limit. + * @returns {Number} The wrap limit. + **/ this.getWrapLimit = function() { return this.$wrapLimit; }; - + + /** + * Sets the line length for soft wrap in the editor. Lines will break + * at a minimum of the given length minus 20 chars and at a maximum + * of the given number of chars. + * @param {number} limit The maximum line length in chars, for soft wrapping lines. + */ + this.setWrapLimit = function (limit) { + this.setWrapLimitRange(limit, limit); + }; + + /** + * Returns an object that defines the minimum and maximum of the wrap limit; it looks something like this: + * + * { min: wrapLimitRange_min, max: wrapLimitRange_max } + * + * @returns {Object} + **/ this.getWrapLimitRange = function() { // Avoid unexpected mutation by returning a copy return { @@ -822,43 +1661,117 @@ var EditSession = function(text, mode) { }; }; - this.$updateWrapDataOnChange = function(e) { - if (!this.$useWrapMode) { - return; - } - - var len; - var action = e.data.action; - var firstRow = e.data.range.start.row, - lastRow = e.data.range.end.row; - - if (action.indexOf("Lines") != -1) { - if (action == "insertLines") { - lastRow = firstRow + (e.data.lines.length); - } else { - lastRow = firstRow; - } - len = e.data.lines.length; - } else { - len = lastRow - firstRow; - } - + this.$updateInternalDataOnChange = function(delta) { + var useWrapMode = this.$useWrapMode; + var action = delta.action; + var start = delta.start; + var end = delta.end; + var firstRow = start.row; + var lastRow = end.row; + var len = lastRow - firstRow; + var removedFolds = null; + + this.$updating = true; if (len != 0) { - if (action.indexOf("remove") != -1) { - this.$wrapData.splice(firstRow, len); + if (action === "remove") { + this[useWrapMode ? "$wrapData" : "$rowLengthCache"].splice(firstRow, len); + + var foldLines = this.$foldData; + removedFolds = this.getFoldsInRange(delta); + this.removeFolds(removedFolds); + + var foldLine = this.getFoldLine(end.row); + var idx = 0; + if (foldLine) { + foldLine.addRemoveChars(end.row, end.column, start.column - end.column); + foldLine.shiftRow(-len); + + var foldLineBefore = this.getFoldLine(firstRow); + if (foldLineBefore && foldLineBefore !== foldLine) { + foldLineBefore.merge(foldLine); + foldLine = foldLineBefore; + } + idx = foldLines.indexOf(foldLine) + 1; + } + + for (idx; idx < foldLines.length; idx++) { + var foldLine = foldLines[idx]; + if (foldLine.start.row >= end.row) { + foldLine.shiftRow(-len); + } + } + lastRow = firstRow; } else { - var args = [firstRow, 0]; - for (var i = 0; i < len; i++) args.push([]); - this.$wrapData.splice.apply(this.$wrapData, args); + var args = Array(len); + args.unshift(firstRow, 0); + var arr = useWrapMode ? this.$wrapData : this.$rowLengthCache + arr.splice.apply(arr, args); + + // If some new line is added inside of a foldLine, then split + // the fold line up. + var foldLines = this.$foldData; + var foldLine = this.getFoldLine(firstRow); + var idx = 0; + if (foldLine) { + var cmp = foldLine.range.compareInside(start.row, start.column); + // Inside of the foldLine range. Need to split stuff up. + if (cmp == 0) { + foldLine = foldLine.split(start.row, start.column); + if (foldLine) { + foldLine.shiftRow(len); + foldLine.addRemoveChars(lastRow, 0, end.column - start.column); + } + } else + // Infront of the foldLine but same row. Need to shift column. + if (cmp == -1) { + foldLine.addRemoveChars(firstRow, 0, end.column - start.column); + foldLine.shiftRow(len); + } + // Nothing to do if the insert is after the foldLine. + idx = foldLines.indexOf(foldLine) + 1; + } + + for (idx; idx < foldLines.length; idx++) { + var foldLine = foldLines[idx]; + if (foldLine.start.row >= firstRow) { + foldLine.shiftRow(len); + } + } + } + } else { + // Realign folds. E.g. if you add some new chars before a fold, the + // fold should "move" to the right. + len = Math.abs(delta.start.column - delta.end.column); + if (action === "remove") { + // Get all the folds in the change range and remove them. + removedFolds = this.getFoldsInRange(delta); + this.removeFolds(removedFolds); + + len = -len; + } + var foldLine = this.getFoldLine(firstRow); + if (foldLine) { + foldLine.addRemoveChars(firstRow, start.column, len); } } - if (this.$wrapData.length != this.doc.$lines.length) { - console.error("The length of doc.$lines and $wrapData have to be the same!"); + if (useWrapMode && this.$wrapData.length != this.doc.getLength()) { + console.error("doc.getLength() and $wrapData.length have to be the same!"); } + this.$updating = false; - this.$updateWrapData(firstRow, lastRow); + if (useWrapMode) + this.$updateWrapData(firstRow, lastRow); + else + this.$updateRowLengthCache(firstRow, lastRow); + + return removedFolds; + }; + + this.$updateRowLengthCache = function(firstRow, lastRow, b) { + this.$rowLengthCache[firstRow] = null; + this.$rowLengthCache[lastRow] = null; }; this.$updateWrapData = function(firstRow, lastRow) { @@ -866,32 +1779,92 @@ var EditSession = function(text, mode) { var tabSize = this.getTabSize(); var wrapData = this.$wrapData; var wrapLimit = this.$wrapLimit; + var tokens; + var foldLine; - for (var row = firstRow; row <= lastRow; row++) { - wrapData[row] = - this.$computeWrapSplits(lines[row], wrapLimit, tabSize); + var row = firstRow; + lastRow = Math.min(lastRow, lines.length - 1); + while (row <= lastRow) { + foldLine = this.getFoldLine(row, foldLine); + if (!foldLine) { + tokens = this.$getDisplayTokens(lines[row]); + wrapData[row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize); + row ++; + } else { + tokens = []; + foldLine.walk(function(placeholder, row, column, lastColumn) { + var walkTokens; + if (placeholder != null) { + walkTokens = this.$getDisplayTokens( + placeholder, tokens.length); + walkTokens[0] = PLACEHOLDER_START; + for (var i = 1; i < walkTokens.length; i++) { + walkTokens[i] = PLACEHOLDER_BODY; + } + } else { + walkTokens = this.$getDisplayTokens( + lines[row].substring(lastColumn, column), + tokens.length); + } + tokens = tokens.concat(walkTokens); + }.bind(this), + foldLine.end.row, + lines[foldLine.end.row].length + 1 + ); + + wrapData[foldLine.start.row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize); + row = foldLine.end.row + 1; + } } }; // "Tokens" var CHAR = 1, CHAR_EXT = 2, - SPACE = 3, - TAB = 4, - TAB_SPACE = 5; + PLACEHOLDER_START = 3, + PLACEHOLDER_BODY = 4, + PUNCTUATION = 9, + SPACE = 10, + TAB = 11, + TAB_SPACE = 12; - this.$computeWrapSplits = function(textLine, wrapLimit, tabSize) { - textLine = textLine.trimRight(); - if (textLine.length == 0) { + + this.$computeWrapSplits = function(tokens, wrapLimit, tabSize) { + if (tokens.length == 0) { return []; } - var tabSize = this.getTabSize(); var splits = []; - var tokens = this.$getDisplayTokens(textLine); var displayLength = tokens.length; var lastSplit = 0, lastDocSplit = 0; + var isCode = this.$wrapAsCode; + + var indentedSoftWrap = this.$indentedSoftWrap; + var maxIndent = wrapLimit <= Math.max(2 * tabSize, 8) + || indentedSoftWrap === false ? 0 : Math.floor(wrapLimit / 2); + + function getWrapIndent() { + var indentation = 0; + if (maxIndent === 0) + return indentation; + if (indentedSoftWrap) { + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + if (token == SPACE) + indentation += 1; + else if (token == TAB) + indentation += tabSize; + else if (token == TAB_SPACE) + continue; + else + break; + } + } + if (isCode && indentedSoftWrap !== false) + indentation += tabSize; + return Math.min(indentation, maxIndent); + } function addSplit(screenPos) { var displayed = tokens.slice(lastSplit, screenPos); @@ -899,176 +1872,270 @@ var EditSession = function(text, mode) { // and multipleWidth characters. var len = displayed.length; displayed.join(""). - // Get all the tabs. - replace(/4/g, function(m) { - len -= tabSize - 1; + // Get all the TAB_SPACEs. + replace(/12/g, function() { + len -= 1; }). - // Get all the multipleWidth characters. - replace(/2/g, function(m) { + // Get all the CHAR_EXT/multipleWidth characters. + replace(/2/g, function() { len -= 1; }); + if (!splits.length) { + indent = getWrapIndent(); + splits.indent = indent; + } lastDocSplit += len; splits.push(lastDocSplit); lastSplit = screenPos; } - - while (displayLength - lastSplit > wrapLimit) { + var indent = 0; + while (displayLength - lastSplit > wrapLimit - indent) { // This is, where the split should be. - var split = lastSplit + wrapLimit; + var split = lastSplit + wrapLimit - indent; - // If there is a space or tab at this split position. - if (tokens[split] >= SPACE) { + // If there is a space or tab at this split position, then making + // a split is simple. + if (tokens[split - 1] >= SPACE && tokens[split] >= SPACE) { + /* disabled see https://github.com/ajaxorg/ace/issues/1186 // Include all following spaces + tabs in this split as well. - while (tokens[split] >= SPACE) { + while (tokens[split] >= SPACE) { split ++; - } + } */ addSplit(split); - } else { - // Search for the first non space/tab token. + continue; + } + + // === ELSE === + // Check if split is inside of a placeholder. Placeholder are + // not splitable. Therefore, seek the beginning of the placeholder + // and try to place the split beofre the placeholder's start. + if (tokens[split] == PLACEHOLDER_START || tokens[split] == PLACEHOLDER_BODY) { + // Seek the start of the placeholder and do the split + // before the placeholder. By definition there always + // a PLACEHOLDER_START between split and lastSplit. for (split; split != lastSplit - 1; split--) { - if (tokens[split] >= SPACE) { - split++; + if (tokens[split] == PLACEHOLDER_START) { + // split++; << No incremental here as we want to + // have the position before the Placeholder. break; } } - // If we found one, then add the split. + + // If the PLACEHOLDER_START is not the index of the + // last split, then we can do the split if (split > lastSplit) { addSplit(split); + continue; } - // No space or tab around? Well, force a split then. - else { - addSplit(lastSplit + wrapLimit); + + // If the PLACEHOLDER_START IS the index of the last + // split, then we have to place the split after the + // placeholder. So, let's seek for the end of the placeholder. + split = lastSplit + wrapLimit; + for (split; split < tokens.length; split++) { + if (tokens[split] != PLACEHOLDER_BODY) { + break; + } + } + + // If spilt == tokens.length, then the placeholder is the last + // thing in the line and adding a new split doesn't make sense. + if (split == tokens.length) { + break; // Breaks the while-loop. + } + + // Finally, add the split... + addSplit(split); + continue; + } + + // === ELSE === + // Search for the first non space/tab/placeholder/punctuation token backwards. + var minSplit = Math.max(split - (wrapLimit -(wrapLimit>>2)), lastSplit - 1); + while (split > minSplit && tokens[split] < PLACEHOLDER_START) { + split --; + } + if (isCode) { + while (split > minSplit && tokens[split] < PLACEHOLDER_START) { + split --; + } + while (split > minSplit && tokens[split] == PUNCTUATION) { + split --; + } + } else { + while (split > minSplit && tokens[split] < SPACE) { + split --; } } + // If we found one, then add the split. + if (split > minSplit) { + addSplit(++split); + continue; + } + + // === ELSE === + split = lastSplit + wrapLimit; + // The split is inside of a CHAR or CHAR_EXT token and no space + // around -> force a split. + if (tokens[split] == CHAR_EXT) + split--; + addSplit(split - indent); } return splits; - } + }; - this.$getDisplayTokens = function(str) { + /** + * Given a string, returns an array of the display characters, including tabs and spaces. + * @param {String} str The string to check + * @param {Number} offset The value to start at + * + * + **/ + this.$getDisplayTokens = function(str, offset) { var arr = []; - var tabSize = this.getTabSize(); + var tabSize; + offset = offset || 0; for (var i = 0; i < str.length; i++) { - var c = str.charCodeAt(i); - // Tab - if (c == 9) { - arr.push(TAB); - for (var n = 1; n < tabSize; n++) { - arr.push(TAB_SPACE); - } - } - // Space - else if(c == 32) { - arr.push(SPACE); - } - // CJK characters - else if ( - c >= 0x3040 && c <= 0x309F || // Hiragana - c >= 0x30A0 && c <= 0x30FF || // Katakana - c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs - c >= 0xF900 && c <= 0xFAFF || - c >= 0x3400 && c <= 0x4DBF - ) { + var c = str.charCodeAt(i); + // Tab + if (c == 9) { + tabSize = this.getScreenTabSize(arr.length + offset); + arr.push(TAB); + for (var n = 1; n < tabSize; n++) { + arr.push(TAB_SPACE); + } + } + // Space + else if (c == 32) { + arr.push(SPACE); + } else if((c > 39 && c < 48) || (c > 57 && c < 64)) { + arr.push(PUNCTUATION); + } + // full width characters + else if (c >= 0x1100 && isFullWidth(c)) { arr.push(CHAR, CHAR_EXT); } else { arr.push(CHAR); } } return arr; + }; + + /** + * Calculates the width of the string `str` on the screen while assuming that the string starts at the first column on the screen. + * @param {String} str The string to calculate the screen width of + * @param {Number} maxScreenColumn + * @param {Number} screenColumn + * @returns {[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. + * + **/ + this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) { + if (maxScreenColumn == 0) + return [0, 0]; + if (maxScreenColumn == null) + maxScreenColumn = Infinity; + screenColumn = screenColumn || 0; + + var c, column; + for (column = 0; column < str.length; column++) { + c = str.charCodeAt(column); + // tab + if (c == 9) { + screenColumn += this.getScreenTabSize(screenColumn); + } + // full width characters + else if (c >= 0x1100 && isFullWidth(c)) { + screenColumn += 2; + } else { + screenColumn += 1; + } + if (screenColumn > maxScreenColumn) { + break; + } + } + + return [screenColumn, column]; + }; + + this.lineWidgets = null; + /** + * Returns number of screenrows in a wrapped line. + * @param {Number} row The row number to check + * + * @returns {Number} + **/ + this.getRowLength = function(row) { + if (this.lineWidgets) + var h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0; + else + h = 0 + if (!this.$useWrapMode || !this.$wrapData[row]) { + return 1 + h; + } else { + return this.$wrapData[row].length + 1 + h; + } + }; + this.getRowLineCount = function(row) { + if (!this.$useWrapMode || !this.$wrapData[row]) { + return 1; + } else { + return this.$wrapData[row].length + 1; + } + }; + + this.getRowWrapIndent = function(screenRow) { + if (this.$useWrapMode) { + var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE); + var splits = this.$wrapData[pos.row]; + return splits.length && splits[0] < pos.column ? splits.indent : 0; + } else { + return 0; + } } /** - * Calculates the width of the a string on the screen while assuming that - * the string starts at the first column on the screen. + * Returns the position (on screen) for the last character in the provided screen row. + * @param {Number} screenRow The screen row to check + * @returns {Number} * - * @param string str String to calculate the screen width of - * @return int number of columns for str on screen. - */ - this.$getStringScreenWidth = function(str) { - var screenColumn = 0; - var tabSize = this.getTabSize(); - - for (var i=0; i= 0x3040 && c <= 0x309F || // Hiragana - c >= 0x30A0 && c <= 0x30FF || // Katakana - c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs - c >= 0xF900 && c <= 0xFAFF || - c >= 0x3400 && c <= 0x4DBF - ) { - screenColumn += 2; - } else { - screenColumn += 1; - } - } - - return screenColumn; - } - - this.getRowHeight = function(config, row) { - var rows; - if (!this.$useWrapMode || !this.$wrapData[row]) { - rows = 1; - } else { - rows = this.$wrapData[row].length + 1; - } - - return rows * config.lineHeight; - } - - this.getScreenLastRowColumn = function(screenRow, returnDocPosition) { - if (!this.$useWrapMode) { - return this.$getStringScreenWidth(this.getLine(screenRow)); - } - - var rowData = this.$screenToDocumentRow(screenRow); - var docRow = rowData[0], - row = rowData[1]; - - var start, end; - if (this.$wrapData[docRow][row]) { - start = (this.$wrapData[docRow][row - 1] || 0); - end = this.$wrapData[docRow][row]; - returnDocPosition && end--; - } else { - end = this.getLine(docRow).length; - start = (this.$wrapData[docRow][row - 1] || 0); - } - if (!returnDocPosition) { - return this.$getStringScreenWidth(this.getLine(docRow).substring(start, end)); - } else { - return end; - } + * @related EditSession.documentToScreenColumn + **/ + this.getScreenLastRowColumn = function(screenRow) { + var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE); + return this.documentToScreenColumn(pos.row, pos.column); }; + /** + * For the given document row and column, this returns the column position of the last screen row. + * @param {Number} docRow + * + * @param {Number} docColumn + **/ this.getDocumentLastRowColumn = function(docRow, docColumn) { - if (!this.$useWrapMode) { - return this.getLine(docRow).length; - } - var screenRow = this.documentToScreenRow(docRow, docColumn); - return this.getScreenLastRowColumn(screenRow, true); - } - - this.getScreenFirstRowColumn = function(screenRow) { - if (!this.$useWrapMode) { - return 0; - } - - var rowData = this.$screenToDocumentRow(screenRow); - var docRow = rowData[0], - row = rowData[1]; - - return this.$wrapData[docRow][row - 1] || 0; + return this.getScreenLastRowColumn(screenRow); }; + /** + * For the given document row and column, this returns the document position of the last row. + * @param {Number} docRow + * @param {Number} docColumn + * + * + **/ + this.getDocumentLastRowColumnPosition = function(docRow, docColumn) { + var screenRow = this.documentToScreenRow(docRow, docColumn); + return this.screenToDocumentPosition(screenRow, Number.MAX_VALUE / 10); + }; + + /** + * For the given row, this returns the split data. + * @returns {String} + **/ this.getRowSplitData = function(row) { if (!this.$useWrapMode) { return undefined; @@ -1078,222 +2145,442 @@ var EditSession = function(text, mode) { }; /** - * - * @returns array - * - array[0]: The documentRow equivalent. - * - array[1]: The screenRowOffset to the first documentRow on the screen. - */ - this.$screenToDocumentRow = function(row) { - if (!this.$useWrapMode) { - return [row, 0]; - } - - var wrapData = this.$wrapData, linesCount = this.getLength(); - var docRow = 0; - while (docRow < linesCount && row >= wrapData[docRow].length + 1) { - row -= wrapData[docRow].length + 1; - docRow ++; - } - - return [docRow, row]; + * The distance to the next tab stop at the specified screen column. + * @param {Number} screenColumn The screen column to check + * + * + * @returns {Number} + **/ + this.getScreenTabSize = function(screenColumn) { + return this.$tabSize - screenColumn % this.$tabSize; }; - this.screenToDocumentRow = function(screenRow) { - return this.$screenToDocumentRow(screenRow)[0]; + + this.screenToDocumentRow = function(screenRow, screenColumn) { + return this.screenToDocumentPosition(screenRow, screenColumn).row; }; + this.screenToDocumentColumn = function(screenRow, screenColumn) { return this.screenToDocumentPosition(screenRow, screenColumn).column; }; - this.screenToDocumentPosition = function(row, 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} + * @param {Number} screenRow The screen row to check + * @param {Number} screenColumn The screen column to check + * @returns {Object} The object returned has two properties: `row` and `column`. + * + * + * @related EditSession.documentToScreenPosition + * + **/ + this.screenToDocumentPosition = function(screenRow, screenColumn) { + if (screenRow < 0) + return {row: 0, column: 0}; + var line; - var docRow; - var docColumn; - var remaining = column; - var linesCount = this.getLength(); - if (!this.$useWrapMode) { - docRow = row >= linesCount? linesCount-1 : (row < 0 ? 0 : row); - row = 0; - docColumn = 0; - line = this.getLine(docRow); + var docRow = 0; + var docColumn = 0; + var column; + var row = 0; + var rowLength = 0; + + var rowCache = this.$screenRowCache; + var i = this.$getRowCacheIndex(rowCache, screenRow); + var l = rowCache.length; + if (l && i >= 0) { + var row = rowCache[i]; + var docRow = this.$docRowCache[i]; + var doCache = screenRow > rowCache[l - 1]; } else { - var wrapData = this.$wrapData; - - var docRow = 0; - while (docRow < linesCount && row >= wrapData[docRow].length + 1) { - row -= wrapData[docRow].length + 1; - docRow ++; - } - - if (docRow >= linesCount) { - docRow = linesCount-1 - row = wrapData[docRow].length; - } - docColumn = wrapData[docRow][row - 1] || 0; - line = this.getLine(docRow).substring(docColumn); + var doCache = !l; } - var tabSize = this.getTabSize(); - for(var i = 0; i < line.length; i++) { - var c = line.charCodeAt(i); + var maxRow = this.getLength() - 1; + var foldLine = this.getNextFoldLine(docRow); + var foldStart = foldLine ? foldLine.start.row : Infinity; - if (remaining > 0) { - docColumn += 1; - // tab - if (c == 9) { - if (remaining >= tabSize) { - remaining -= tabSize; - } else { - remaining = 0; - docColumn -= 1; - } - } - // CJK characters - else if ( - c >= 0x3040 && c <= 0x309F || // Hiragana - c >= 0x30A0 && c <= 0x30FF || // Katakana - c >= 0x4E00 && c <= 0x9FFF || // Single CJK ideographs - c >= 0xF900 && c <= 0xFAFF || - c >= 0x3400 && c <= 0x4DBF - ) { - if (remaining >= 2) { - remaining -= 2; - } else { - remaining = 0; - docColumn -= 1; - } - } else { - remaining -= 1; - } - } else { + while (row <= screenRow) { + rowLength = this.getRowLength(docRow); + if (row + rowLength > screenRow || docRow >= maxRow) { break; + } else { + row += rowLength; + docRow++; + if (docRow > foldStart) { + docRow = foldLine.end.row+1; + foldLine = this.getNextFoldLine(docRow, foldLine); + foldStart = foldLine ? foldLine.start.row : Infinity; + } + } + + if (doCache) { + this.$docRowCache.push(docRow); + this.$screenRowCache.push(row); } } - // Clamp docColumn. + if (foldLine && foldLine.start.row <= docRow) { + line = this.getFoldDisplayLine(foldLine); + docRow = foldLine.start.row; + } else if (row + rowLength <= screenRow || docRow > maxRow) { + // clip at the end of the document + return { + row: maxRow, + column: this.getLine(maxRow).length + }; + } else { + line = this.getLine(docRow); + foldLine = null; + } + var wrapIndent = 0; if (this.$useWrapMode) { - column = wrapData[docRow][row] - if (docColumn >= column) { - // We remove one character at the end such that the docColumn - // position returned is not associated to the next row on the - // screen. - docColumn = column - 1; + var splits = this.$wrapData[docRow]; + if (splits) { + var splitIndex = Math.floor(screenRow - row); + column = splits[splitIndex]; + if(splitIndex > 0 && splits.length) { + wrapIndent = splits.indent; + docColumn = splits[splitIndex - 1] || splits[splits.length - 1]; + line = line.substring(docColumn); + } + } + } + + docColumn += this.$getStringScreenWidth(line, screenColumn - wrapIndent)[1]; + + // We remove one character at the end so that the docColumn + // position returned is not associated to the next row on the screen. + if (this.$useWrapMode && docColumn >= column) + docColumn = column - 1; + + if (foldLine) + return foldLine.idxToPosition(docColumn); + + return {row: docRow, column: docColumn}; + }; + + /** + * Converts document coordinates to screen coordinates. {:conversionConsiderations} + * @param {Number} docRow The document row to check + * @param {Number} docColumn The document column to check + * @returns {Object} The object returned by this method has two properties: `row` and `column`. + * + * + * @related EditSession.screenToDocumentPosition + * + **/ + this.documentToScreenPosition = function(docRow, docColumn) { + // Normalize the passed in arguments. + if (typeof docColumn === "undefined") + var pos = this.$clipPositionToDocument(docRow.row, docRow.column); + else + pos = this.$clipPositionToDocument(docRow, docColumn); + + docRow = pos.row; + docColumn = pos.column; + + var screenRow = 0; + var foldStartRow = null; + var fold = null; + + // Clamp the docRow position in case it's inside of a folded block. + fold = this.getFoldAt(docRow, docColumn, 1); + if (fold) { + docRow = fold.start.row; + docColumn = fold.start.column; + } + + var rowEnd, row = 0; + + + var rowCache = this.$docRowCache; + var i = this.$getRowCacheIndex(rowCache, docRow); + var l = rowCache.length; + if (l && i >= 0) { + var row = rowCache[i]; + var screenRow = this.$screenRowCache[i]; + var doCache = docRow > rowCache[l - 1]; + } else { + var doCache = !l; + } + + var foldLine = this.getNextFoldLine(row); + var foldStart = foldLine ?foldLine.start.row :Infinity; + + while (row < docRow) { + if (row >= foldStart) { + rowEnd = foldLine.end.row + 1; + if (rowEnd > docRow) + break; + foldLine = this.getNextFoldLine(rowEnd, foldLine); + foldStart = foldLine ?foldLine.start.row :Infinity; + } + else { + rowEnd = row + 1; + } + + screenRow += this.getRowLength(row); + row = rowEnd; + + if (doCache) { + this.$docRowCache.push(row); + this.$screenRowCache.push(screenRow); + } + } + + // Calculate the text line that is displayed in docRow on the screen. + var textLine = ""; + // Check if the final row we want to reach is inside of a fold. + if (foldLine && row >= foldStart) { + textLine = this.getFoldDisplayLine(foldLine, docRow, docColumn); + foldStartRow = foldLine.start.row; + } else { + textLine = this.getLine(docRow).substring(0, docColumn); + foldStartRow = docRow; + } + var wrapIndent = 0; + // Clamp textLine if in wrapMode. + if (this.$useWrapMode) { + var wrapRow = this.$wrapData[foldStartRow]; + if (wrapRow) { + var screenRowOffset = 0; + while (textLine.length >= wrapRow[screenRowOffset]) { + screenRow ++; + screenRowOffset++; + } + textLine = textLine.substring( + wrapRow[screenRowOffset - 1] || 0, textLine.length + ); + wrapIndent = screenRowOffset > 0 ? wrapRow.indent : 0; } - } else if (line) { - docColumn = Math.min(docColumn, line.length); } return { - row: docRow, - column: docColumn + row: screenRow, + column: wrapIndent + this.$getStringScreenWidth(textLine)[0] }; }; + /** + * For the given document row and column, returns the screen column. + * @param {Number} row + * @param {Number} docColumn + * @returns {Number} + * + **/ this.documentToScreenColumn = function(row, docColumn) { return this.documentToScreenPosition(row, docColumn).column; }; /** - * - * @return array[2] - * - array[0]: The number of the row on the screen (aka screenRow) - * - array[1]: The number of rows from the first docRow on the screen - * (aka screenRowOffset); - */ - this.$documentToScreenRow = function(docRow, docColumn) { - if (!this.$useWrapMode) { - return [docRow, 0]; - } - - var wrapData = this.$wrapData; - var screenRow = 0; - - // Handle special case where the row is outside of the range of lines. - if (docRow > wrapData.length - 1) { - return [ - this.getScreenLength(), - wrapData.length == 0 ? 0 : (wrapData[wrapData.length - 1].length - 1) - ]; - } - - for (var i = 0; i < docRow; i++) { - screenRow += wrapData[i].length + 1; - } - - var screenRowOffset = 0; - while (docColumn >= wrapData[docRow][screenRowOffset]) { - screenRow ++; - screenRowOffset++; - } - - return [screenRow, screenRowOffset]; - } - + * For the given document row and column, returns the screen row. + * @param {Number} docRow + * @param {Number} docColumn + * + * + **/ this.documentToScreenRow = function(docRow, docColumn) { - return this.$documentToScreenRow(docRow, docColumn)[0]; - } - - this.documentToScreenPosition = function(pos, column) { - var str; - var tabSize = this.getTabSize(); - - // Normalize the passed in arguments. - var row; - if (column != null) { - row = pos; - } else { - row = pos.row; - column = pos.column; - } - - if (!this.$useWrapMode) { - str = this.getLine(row).substring(0, column); - column = this.$getStringScreenWidth(str); - return { - row: row, - column: column - }; - } - - var rowData = this.$documentToScreenRow(row, column); - var screenRow = rowData[0]; - - if (row >= this.getLength()) { - return { - row: screenRow, - column: 0 - }; - } - - var split; - var wrapRowData = this.$wrapData[row]; - var screenColumn; - var screenRowOffset = rowData[1]; - - str = this.getLine(row).substring( - wrapRowData[screenRowOffset - 1] || 0, column); - screenColumn = this.$getStringScreenWidth(str); - - return { - row: screenRow, - column: screenColumn - }; + return this.documentToScreenPosition(docRow, docColumn).row; }; + /** + * Returns the length of the screen. + * @returns {Number} + **/ this.getScreenLength = function() { + var screenRows = 0; + var fold = null; if (!this.$useWrapMode) { - return this.getLength(); + screenRows = this.getLength(); + + // Remove the folded lines again. + var foldData = this.$foldData; + for (var i = 0; i < foldData.length; i++) { + fold = foldData[i]; + screenRows -= fold.end.row - fold.start.row; + } + } else { + var lastRow = this.$wrapData.length; + var row = 0, i = 0; + var fold = this.$foldData[i++]; + var foldStart = fold ? fold.start.row :Infinity; + + while (row < lastRow) { + var splits = this.$wrapData[row]; + screenRows += splits ? splits.length + 1 : 1; + row ++; + if (row > foldStart) { + row = fold.end.row+1; + fold = this.$foldData[i++]; + foldStart = fold ?fold.start.row :Infinity; + } + } } - var screenRows = 0; - for (var row = 0; row < this.$wrapData.length; row++) { - screenRows += this.$wrapData[row].length + 1; - } + // todo + if (this.lineWidgets) + screenRows += this.$getWidgetScreenLength(); + return screenRows; - } + }; + + /** + * @private + * + */ + this.$setFontMetrics = function(fm) { + // todo + }; + + this.destroy = function() { + if (this.bgTokenizer) { + this.bgTokenizer.setDocument(null); + this.bgTokenizer = null; + } + this.$stopWorker(); + }; + + // For every keystroke this gets called once per char in the whole doc!! + // Wouldn't hurt to make it a bit faster for c >= 0x1100 + function isFullWidth(c) { + if (c < 0x1100) + return false; + return c >= 0x1100 && c <= 0x115F || + c >= 0x11A3 && c <= 0x11A7 || + c >= 0x11FA && c <= 0x11FF || + c >= 0x2329 && c <= 0x232A || + c >= 0x2E80 && c <= 0x2E99 || + c >= 0x2E9B && c <= 0x2EF3 || + c >= 0x2F00 && c <= 0x2FD5 || + c >= 0x2FF0 && c <= 0x2FFB || + c >= 0x3000 && c <= 0x303E || + c >= 0x3041 && c <= 0x3096 || + c >= 0x3099 && c <= 0x30FF || + c >= 0x3105 && c <= 0x312D || + c >= 0x3131 && c <= 0x318E || + c >= 0x3190 && c <= 0x31BA || + c >= 0x31C0 && c <= 0x31E3 || + c >= 0x31F0 && c <= 0x321E || + c >= 0x3220 && c <= 0x3247 || + c >= 0x3250 && c <= 0x32FE || + c >= 0x3300 && c <= 0x4DBF || + c >= 0x4E00 && c <= 0xA48C || + c >= 0xA490 && c <= 0xA4C6 || + c >= 0xA960 && c <= 0xA97C || + c >= 0xAC00 && c <= 0xD7A3 || + c >= 0xD7B0 && c <= 0xD7C6 || + c >= 0xD7CB && c <= 0xD7FB || + c >= 0xF900 && c <= 0xFAFF || + c >= 0xFE10 && c <= 0xFE19 || + c >= 0xFE30 && c <= 0xFE52 || + c >= 0xFE54 && c <= 0xFE66 || + c >= 0xFE68 && c <= 0xFE6B || + c >= 0xFF01 && c <= 0xFF60 || + c >= 0xFFE0 && c <= 0xFFE6; + }; }).call(EditSession.prototype); +require("./edit_session/folding").Folding.call(EditSession.prototype); +require("./edit_session/bracket_match").BracketMatch.call(EditSession.prototype); + + +config.defineOptions(EditSession.prototype, "session", { + wrap: { + set: function(value) { + if (!value || value == "off") + value = false; + else if (value == "free") + value = true; + else if (value == "printMargin") + value = -1; + else if (typeof value == "string") + value = parseInt(value, 10) || false; + + if (this.$wrap == value) + return; + this.$wrap = value; + if (!value) { + this.setUseWrapMode(false); + } else { + var col = typeof value == "number" ? value : null; + this.setWrapLimitRange(col, col); + this.setUseWrapMode(true); + } + }, + get: function() { + if (this.getUseWrapMode()) { + if (this.$wrap == -1) + return "printMargin"; + if (!this.getWrapLimitRange().min) + return "free"; + return this.$wrap; + } + return "off"; + }, + handlesSet: true + }, + wrapMethod: { + // code|text|auto + set: function(val) { + val = val == "auto" + ? this.$mode.type != "text" + : val != "text"; + if (val != this.$wrapAsCode) { + this.$wrapAsCode = val; + if (this.$useWrapMode) { + this.$modified = true; + this.$resetRowCache(0); + this.$updateWrapData(0, this.getLength() - 1); + } + } + }, + initialValue: "auto" + }, + indentedSoftWrap: { initialValue: true }, + firstLineNumber: { + set: function() {this._signal("changeBreakpoint");}, + initialValue: 1 + }, + useWorker: { + set: function(useWorker) { + this.$useWorker = useWorker; + + this.$stopWorker(); + if (useWorker) + this.$startWorker(); + }, + initialValue: true + }, + useSoftTabs: {initialValue: true}, + tabSize: { + set: function(tabSize) { + if (isNaN(tabSize) || this.$tabSize === tabSize) return; + + this.$modified = true; + this.$rowLengthCache = []; + this.$tabSize = tabSize; + this._signal("changeTabSize"); + }, + initialValue: 4, + handlesSet: true + }, + overwrite: { + set: function(val) {this._signal("changeOverwrite");}, + initialValue: false + }, + newLineMode: { + set: function(val) {this.doc.setNewLineMode(val)}, + get: function() {return this.doc.getNewLineMode()}, + handlesSet: true + }, + mode: { + set: function(val) { this.setMode(val) }, + get: function() { return this.$modeId } + } +}); + exports.EditSession = EditSession; }); diff --git a/lib/ace/edit_session/bracket_match.js b/lib/ace/edit_session/bracket_match.js new file mode 100644 index 00000000..62a8499c --- /dev/null +++ b/lib/ace/edit_session/bracket_match.js @@ -0,0 +1,221 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var TokenIterator = require("../token_iterator").TokenIterator; +var Range = require("../range").Range; + + +function BracketMatch() { + + this.findMatchingBracket = function(position, chr) { + if (position.column == 0) return null; + + var charBeforeCursor = chr || this.getLine(position.row).charAt(position.column-1); + if (charBeforeCursor == "") return null; + + var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/); + if (!match) + return null; + + if (match[1]) + return this.$findClosingBracket(match[1], position); + else + return this.$findOpeningBracket(match[2], position); + }; + + this.getBracketRange = function(pos) { + var line = this.getLine(pos.row); + var before = true, range; + + var chr = line.charAt(pos.column-1); + var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/); + if (!match) { + chr = line.charAt(pos.column); + pos = {row: pos.row, column: pos.column + 1}; + match = chr && chr.match(/([\(\[\{])|([\)\]\}])/); + before = false; + } + if (!match) + return null; + + if (match[1]) { + var bracketPos = this.$findClosingBracket(match[1], pos); + if (!bracketPos) + return null; + range = Range.fromPoints(pos, bracketPos); + if (!before) { + range.end.column++; + range.start.column--; + } + range.cursor = range.end; + } else { + var bracketPos = this.$findOpeningBracket(match[2], pos); + if (!bracketPos) + return null; + range = Range.fromPoints(bracketPos, pos); + if (!before) { + range.start.column++; + range.end.column--; + } + range.cursor = range.start; + } + + return range; + }; + + this.$brackets = { + ")": "(", + "(": ")", + "]": "[", + "[": "]", + "{": "}", + "}": "{" + }; + + this.$findOpeningBracket = function(bracket, position, typeRe) { + var openBracket = this.$brackets[bracket]; + var depth = 1; + + var iterator = new TokenIterator(this, position.row, position.column); + var token = iterator.getCurrentToken(); + if (!token) + token = iterator.stepForward(); + if (!token) + return; + + if (!typeRe){ + typeRe = new RegExp( + "(\\.?" + + token.type.replace(".", "\\.").replace("rparen", ".paren") + .replace(/\b(?:end)\b/, "(?:start|begin|end)") + + ")+" + ); + } + + // Start searching in token, just before the character at position.column + var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2; + var value = token.value; + + while (true) { + + while (valueIndex >= 0) { + var chr = value.charAt(valueIndex); + if (chr == openBracket) { + depth -= 1; + if (depth == 0) { + return {row: iterator.getCurrentTokenRow(), + column: valueIndex + iterator.getCurrentTokenColumn()}; + } + } + else if (chr == bracket) { + depth += 1; + } + valueIndex -= 1; + } + + // Scan backward through the document, looking for the next token + // whose type matches typeRe + do { + token = iterator.stepBackward(); + } while (token && !typeRe.test(token.type)); + + if (token == null) + break; + + value = token.value; + valueIndex = value.length - 1; + } + + return null; + }; + + this.$findClosingBracket = function(bracket, position, typeRe) { + var closingBracket = this.$brackets[bracket]; + var depth = 1; + + var iterator = new TokenIterator(this, position.row, position.column); + var token = iterator.getCurrentToken(); + if (!token) + token = iterator.stepForward(); + if (!token) + return; + + if (!typeRe){ + typeRe = new RegExp( + "(\\.?" + + token.type.replace(".", "\\.").replace("lparen", ".paren") + .replace(/\b(?:start|begin)\b/, "(?:start|begin|end)") + + ")+" + ); + } + + // Start searching in token, after the character at position.column + var valueIndex = position.column - iterator.getCurrentTokenColumn(); + + while (true) { + + var value = token.value; + var valueLength = value.length; + while (valueIndex < valueLength) { + var chr = value.charAt(valueIndex); + if (chr == closingBracket) { + depth -= 1; + if (depth == 0) { + return {row: iterator.getCurrentTokenRow(), + column: valueIndex + iterator.getCurrentTokenColumn()}; + } + } + else if (chr == bracket) { + depth += 1; + } + valueIndex += 1; + } + + // Scan forward through the document, looking for the next token + // whose type matches typeRe + do { + token = iterator.stepForward(); + } while (token && !typeRe.test(token.type)); + + if (token == null) + break; + + valueIndex = 0; + } + + return null; + }; +} +exports.BracketMatch = BracketMatch; + +}); diff --git a/lib/ace/edit_session/fold.js b/lib/ace/edit_session/fold.js new file mode 100644 index 00000000..232101bd --- /dev/null +++ b/lib/ace/edit_session/fold.js @@ -0,0 +1,140 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var Range = require("../range").Range; +var RangeList = require("../range_list").RangeList; +var oop = require("../lib/oop") +/* + * Simple fold-data struct. + **/ +var Fold = exports.Fold = function(range, placeholder) { + this.foldLine = null; + this.placeholder = placeholder; + this.range = range; + this.start = range.start; + this.end = range.end; + + this.sameRow = range.start.row == range.end.row; + this.subFolds = this.ranges = []; +}; + +oop.inherits(Fold, RangeList); + +(function() { + + this.toString = function() { + return '"' + this.placeholder + '" ' + this.range.toString(); + }; + + this.setFoldLine = function(foldLine) { + this.foldLine = foldLine; + this.subFolds.forEach(function(fold) { + fold.setFoldLine(foldLine); + }); + }; + + this.clone = function() { + var range = this.range.clone(); + var fold = new Fold(range, this.placeholder); + this.subFolds.forEach(function(subFold) { + fold.subFolds.push(subFold.clone()); + }); + fold.collapseChildren = this.collapseChildren; + return fold; + }; + + this.addSubFold = function(fold) { + if (this.range.isEqual(fold)) + return; + + if (!this.range.containsRange(fold)) + throw new Error("A fold can't intersect already existing fold" + fold.range + this.range); + + // transform fold to local coordinates + consumeRange(fold, this.start); + + var row = fold.start.row, column = fold.start.column; + for (var i = 0, cmp = -1; i < this.subFolds.length; i++) { + cmp = this.subFolds[i].range.compare(row, column); + if (cmp != 1) + break; + } + var afterStart = this.subFolds[i]; + + if (cmp == 0) + return afterStart.addSubFold(fold); + + // cmp == -1 + var row = fold.range.end.row, column = fold.range.end.column; + for (var j = i, cmp = -1; j < this.subFolds.length; j++) { + cmp = this.subFolds[j].range.compare(row, column); + if (cmp != 1) + break; + } + var afterEnd = this.subFolds[j]; + + if (cmp == 0) + throw new Error("A fold can't intersect already existing fold" + fold.range + this.range); + + var consumedFolds = this.subFolds.splice(i, j - i, fold); + fold.setFoldLine(this.foldLine); + + return fold; + }; + + this.restoreRange = function(range) { + return restoreRange(range, this.start); + }; + +}).call(Fold.prototype); + +function consumePoint(point, anchor) { + point.row -= anchor.row; + if (point.row == 0) + point.column -= anchor.column; +} +function consumeRange(range, anchor) { + consumePoint(range.start, anchor); + consumePoint(range.end, anchor); +} +function restorePoint(point, anchor) { + if (point.row == 0) + point.column += anchor.column; + point.row += anchor.row; +} +function restoreRange(range, anchor) { + restorePoint(range.start, anchor); + restorePoint(range.end, anchor); +} + +}); diff --git a/lib/ace/edit_session/fold_line.js b/lib/ace/edit_session/fold_line.js new file mode 100644 index 00000000..9d73154d --- /dev/null +++ b/lib/ace/edit_session/fold_line.js @@ -0,0 +1,269 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var Range = require("../range").Range; + +/* + * If an array is passed in, the folds are expected to be sorted already. + */ +function FoldLine(foldData, folds) { + this.foldData = foldData; + if (Array.isArray(folds)) { + this.folds = folds; + } else { + folds = this.folds = [ folds ]; + } + + var last = folds[folds.length - 1]; + this.range = new Range(folds[0].start.row, folds[0].start.column, + last.end.row, last.end.column); + this.start = this.range.start; + this.end = this.range.end; + + this.folds.forEach(function(fold) { + fold.setFoldLine(this); + }, this); +} + +(function() { + /* + * Note: This doesn't update wrapData! + */ + this.shiftRow = function(shift) { + this.start.row += shift; + this.end.row += shift; + this.folds.forEach(function(fold) { + fold.start.row += shift; + fold.end.row += shift; + }); + }; + + this.addFold = function(fold) { + if (fold.sameRow) { + if (fold.start.row < this.startRow || fold.endRow > this.endRow) { + throw new Error("Can't add a fold to this FoldLine as it has no connection"); + } + this.folds.push(fold); + this.folds.sort(function(a, b) { + return -a.range.compareEnd(b.start.row, b.start.column); + }); + if (this.range.compareEnd(fold.start.row, fold.start.column) > 0) { + this.end.row = fold.end.row; + this.end.column = fold.end.column; + } else if (this.range.compareStart(fold.end.row, fold.end.column) < 0) { + this.start.row = fold.start.row; + this.start.column = fold.start.column; + } + } else if (fold.start.row == this.end.row) { + this.folds.push(fold); + this.end.row = fold.end.row; + this.end.column = fold.end.column; + } else if (fold.end.row == this.start.row) { + this.folds.unshift(fold); + this.start.row = fold.start.row; + this.start.column = fold.start.column; + } else { + throw new Error("Trying to add fold to FoldRow that doesn't have a matching row"); + } + fold.foldLine = this; + }; + + this.containsRow = function(row) { + return row >= this.start.row && row <= this.end.row; + }; + + this.walk = function(callback, endRow, endColumn) { + var lastEnd = 0, + folds = this.folds, + fold, + cmp, stop, isNewRow = true; + + if (endRow == null) { + endRow = this.end.row; + endColumn = this.end.column; + } + + for (var i = 0; i < folds.length; i++) { + fold = folds[i]; + + cmp = fold.range.compareStart(endRow, endColumn); + // This fold is after the endRow/Column. + if (cmp == -1) { + callback(null, endRow, endColumn, lastEnd, isNewRow); + return; + } + + stop = callback(null, fold.start.row, fold.start.column, lastEnd, isNewRow); + stop = !stop && callback(fold.placeholder, fold.start.row, fold.start.column, lastEnd); + + // If the user requested to stop the walk or endRow/endColumn is + // inside of this fold (cmp == 0), then end here. + if (stop || cmp === 0) { + return; + } + + // Note the new lastEnd might not be on the same line. However, + // it's the callback's job to recognize this. + isNewRow = !fold.sameRow; + lastEnd = fold.end.column; + } + callback(null, endRow, endColumn, lastEnd, isNewRow); + }; + + this.getNextFoldTo = function(row, column) { + var fold, cmp; + for (var i = 0; i < this.folds.length; i++) { + fold = this.folds[i]; + cmp = fold.range.compareEnd(row, column); + if (cmp == -1) { + return { + fold: fold, + kind: "after" + }; + } else if (cmp === 0) { + return { + fold: fold, + kind: "inside" + }; + } + } + return null; + }; + + this.addRemoveChars = function(row, column, len) { + var ret = this.getNextFoldTo(row, column), + fold, folds; + if (ret) { + fold = ret.fold; + if (ret.kind == "inside" + && fold.start.column != column + && fold.start.row != row) + { + //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); + if (i === 0) { + this.start.column += len; + } + for (i; i < folds.length; i++) { + fold = folds[i]; + fold.start.column += len; + if (!fold.sameRow) { + return; + } + fold.end.column += len; + } + this.end.column += len; + } + } + }; + + this.split = function(row, column) { + var pos = this.getNextFoldTo(row, column); + + if (!pos || pos.kind == "inside") + return null; + + var fold = pos.fold; + var folds = this.folds; + var foldData = this.foldData; + + var i = folds.indexOf(fold); + var foldBefore = folds[i - 1]; + this.end.row = foldBefore.end.row; + this.end.column = foldBefore.end.column; + + // Remove the folds after row/column and create a new FoldLine + // containing these removed folds. + folds = folds.splice(i, folds.length - i); + + var newFoldLine = new FoldLine(foldData, folds); + foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine); + return newFoldLine; + }; + + this.merge = function(foldLineNext) { + var folds = foldLineNext.folds; + for (var i = 0; i < folds.length; i++) { + this.addFold(folds[i]); + } + // Remove the foldLineNext - no longer needed, as + // it's merged now with foldLineNext. + var foldData = this.foldData; + foldData.splice(foldData.indexOf(foldLineNext), 1); + }; + + this.toString = function() { + var ret = [this.range.toString() + ": [" ]; + + this.folds.forEach(function(fold) { + ret.push(" " + fold.toString()); + }); + ret.push("]"); + return ret.join("\n"); + }; + + this.idxToPosition = function(idx) { + var lastFoldEndColumn = 0; + + for (var i = 0; i < this.folds.length; i++) { + var fold = this.folds[i]; + + idx -= fold.start.column - lastFoldEndColumn; + if (idx < 0) { + return { + row: fold.start.row, + column: fold.start.column + idx + }; + } + + idx -= fold.placeholder.length; + if (idx < 0) { + return fold.start; + } + + lastFoldEndColumn = fold.end.column; + } + + return { + row: this.end.row, + column: this.end.column + idx + }; + }; +}).call(FoldLine.prototype); + +exports.FoldLine = FoldLine; +}); diff --git a/lib/ace/edit_session/folding.js b/lib/ace/edit_session/folding.js new file mode 100644 index 00000000..77c0f22d --- /dev/null +++ b/lib/ace/edit_session/folding.js @@ -0,0 +1,857 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var Range = require("../range").Range; +var FoldLine = require("./fold_line").FoldLine; +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 + */ + this.getFoldAt = function(row, column, side) { + var foldLine = this.getFoldLine(row); + if (!foldLine) + return null; + + var folds = foldLine.folds; + for (var i = 0; i < folds.length; i++) { + var fold = folds[i]; + if (fold.range.contains(row, column)) { + if (side == 1 && fold.range.isEnd(row, column)) { + continue; + } else if (side == -1 && fold.range.isStart(row, column)) { + continue; + } + return fold; + } + } + }; + + /* + * Returns all folds in the given range. Note, that this will return folds + * + */ + this.getFoldsInRange = function(range) { + var start = range.start; + var end = range.end; + var foldLines = this.$foldData; + var foundFolds = []; + + start.column += 1; + end.column -= 1; + + for (var i = 0; i < foldLines.length; i++) { + var cmp = foldLines[i].range.compareRange(range); + if (cmp == 2) { + // Range is before foldLine. No intersection. This means, + // there might be other foldLines that intersect. + continue; + } + else if (cmp == -2) { + // Range is after foldLine. There can't be any other foldLines then, + // so let's give up. + break; + } + + var folds = foldLines[i].folds; + for (var j = 0; j < folds.length; j++) { + var fold = folds[j]; + cmp = fold.range.compareRange(range); + if (cmp == -2) { + break; + } else if (cmp == 2) { + continue; + } else + // WTF-state: Can happen due to -1/+1 to start/end column. + if (cmp == 42) { + break; + } + foundFolds.push(fold); + } + } + start.column -= 1; + end.column += 1; + + return foundFolds; + }; + + this.getFoldsInRangeList = function(ranges) { + if (Array.isArray(ranges)) { + var folds = []; + ranges.forEach(function(range) { + folds = folds.concat(this.getFoldsInRange(range)); + }, this); + } else { + var folds = this.getFoldsInRange(ranges); + } + return folds; + } + + /* + * Returns all folds in the document + */ + this.getAllFolds = function() { + var folds = []; + var foldLines = this.$foldData; + + for (var i = 0; i < foldLines.length; i++) + for (var j = 0; j < foldLines[i].folds.length; j++) + folds.push(foldLines[i].folds[j]); + + return folds; + }; + + /* + * Returns the string between folds at the given position. + * E.g. + * foob|arwolrd -> "bar" + * foobarwol|rd -> "world" + * foobarwolrd -> + * + * where | means the position of row/column + * + * The trim option determs if the return string should be trimed according + * to the "side" passed with the trim value: + * + * E.g. + * foob|arwolrd -trim=-1> "b" + * foobarwol|rd -trim=+1> "rld" + * fo|obarwolrd -trim=00> "foo" + */ + this.getFoldStringAt = function(row, column, trim, foldLine) { + foldLine = foldLine || this.getFoldLine(row); + if (!foldLine) + return null; + + var lastFold = { + end: { column: 0 } + }; + // TODO: Refactor to use getNextFoldTo function. + var str, fold; + for (var i = 0; i < foldLine.folds.length; i++) { + fold = foldLine.folds[i]; + var cmp = fold.range.compareEnd(row, column); + if (cmp == -1) { + str = this + .getLine(fold.start.row) + .substring(lastFold.end.column, fold.start.column); + break; + } + else if (cmp === 0) { + return null; + } + lastFold = fold; + } + if (!str) + str = this.getLine(fold.start.row).substring(lastFold.end.column); + + if (trim == -1) + return str.substring(0, column - lastFold.end.column); + else if (trim == 1) + return str.substring(column - lastFold.end.column); + else + return str; + }; + + this.getFoldLine = function(docRow, startFoldLine) { + var foldData = this.$foldData; + var i = 0; + if (startFoldLine) + i = foldData.indexOf(startFoldLine); + if (i == -1) + i = 0; + for (i; i < foldData.length; i++) { + var foldLine = foldData[i]; + if (foldLine.start.row <= docRow && foldLine.end.row >= docRow) { + return foldLine; + } else if (foldLine.end.row > docRow) { + return null; + } + } + return null; + }; + + // returns the fold which starts after or contains docRow + this.getNextFoldLine = function(docRow, startFoldLine) { + var foldData = this.$foldData; + var i = 0; + if (startFoldLine) + i = foldData.indexOf(startFoldLine); + if (i == -1) + i = 0; + for (i; i < foldData.length; i++) { + var foldLine = foldData[i]; + if (foldLine.end.row >= docRow) { + return foldLine; + } + } + return null; + }; + + this.getFoldedRowCount = function(first, last) { + var foldData = this.$foldData, rowCount = last-first+1; + for (var i = 0; i < foldData.length; i++) { + var foldLine = foldData[i], + end = foldLine.end.row, + start = foldLine.start.row; + if (end >= last) { + if(start < last) { + if(start >= first) + rowCount -= last-start; + else + rowCount = 0;//in one fold + } + break; + } else if(end >= first){ + if (start >= first) //fold inside range + rowCount -= end-start; + else + rowCount -= end-first+1; + } + } + return rowCount; + }; + + this.$addFoldLine = function(foldLine) { + this.$foldData.push(foldLine); + this.$foldData.sort(function(a, b) { + return a.start.row - b.start.row; + }); + return foldLine; + }; + + /** + * Adds a new fold. + * + * @returns + * The new created Fold object or an existing fold object in case the + * passed in range fits an existing fold exactly. + */ + this.addFold = function(placeholder, range) { + var foldData = this.$foldData; + var added = false; + var fold; + + if (placeholder instanceof Fold) + fold = placeholder; + else { + fold = new Fold(range, placeholder); + fold.collapseChildren = range.collapseChildren; + } + this.$clipRangeToDocument(fold.range); + + var startRow = fold.start.row; + var startColumn = fold.start.column; + var endRow = fold.end.row; + var endColumn = fold.end.column; + + // --- Some checking --- + if (!(startRow < endRow || + startRow == endRow && startColumn <= endColumn - 2)) + throw new Error("The range has to be at least 2 characters width"); + + var startFold = this.getFoldAt(startRow, startColumn, 1); + var endFold = this.getFoldAt(endRow, endColumn, -1); + if (startFold && endFold == startFold) + return startFold.addSubFold(fold); + + if (startFold && !startFold.range.isStart(startRow, startColumn)) + this.removeFold(startFold); + + if (endFold && !endFold.range.isEnd(endRow, endColumn)) + this.removeFold(endFold); + + // Check if there are folds in the range we create the new fold for. + var folds = this.getFoldsInRange(fold.range); + if (folds.length > 0) { + // Remove the folds from fold data. + this.removeFolds(folds); + // Add the removed folds as subfolds on the new fold. + folds.forEach(function(subFold) { + fold.addSubFold(subFold); + }); + } + + for (var i = 0; i < foldData.length; i++) { + var foldLine = foldData[i]; + if (endRow == foldLine.start.row) { + foldLine.addFold(fold); + added = true; + break; + } else if (startRow == foldLine.end.row) { + foldLine.addFold(fold); + added = true; + if (!fold.sameRow) { + // Check if we might have to merge two FoldLines. + var foldLineNext = foldData[i + 1]; + if (foldLineNext && foldLineNext.start.row == endRow) { + // We need to merge! + foldLine.merge(foldLineNext); + break; + } + } + break; + } else if (endRow <= foldLine.start.row) { + break; + } + } + + if (!added) + foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold)); + + if (this.$useWrapMode) + this.$updateWrapData(foldLine.start.row, foldLine.start.row); + else + this.$updateRowLengthCache(foldLine.start.row, foldLine.start.row); + + // Notify that fold data has changed. + this.$modified = true; + this._emit("changeFold", { data: fold, action: "add" }); + + return fold; + }; + + this.addFolds = function(folds) { + folds.forEach(function(fold) { + this.addFold(fold); + }, this); + }; + + this.removeFold = function(fold) { + var foldLine = fold.foldLine; + var startRow = foldLine.start.row; + var endRow = foldLine.end.row; + + var foldLines = this.$foldData; + var folds = foldLine.folds; + // Simple case where there is only one fold in the FoldLine such that + // the entire fold line can get removed directly. + if (folds.length == 1) { + foldLines.splice(foldLines.indexOf(foldLine), 1); + } else + // If the fold is the last fold of the foldLine, just remove it. + if (foldLine.range.isEnd(fold.end.row, fold.end.column)) { + folds.pop(); + foldLine.end.row = folds[folds.length - 1].end.row; + foldLine.end.column = folds[folds.length - 1].end.column; + } else + // If the fold is the first fold of the foldLine, just remove it. + if (foldLine.range.isStart(fold.start.row, fold.start.column)) { + folds.shift(); + foldLine.start.row = folds[0].start.row; + foldLine.start.column = folds[0].start.column; + } else + // We know there are more then 2 folds and the fold is not at the edge. + // This means, the fold is somewhere in between. + // + // If the fold is in one row, we just can remove it. + if (fold.sameRow) { + folds.splice(folds.indexOf(fold), 1); + } else + // The fold goes over more then one row. This means remvoing this fold + // will cause the fold line to get splitted up. newFoldLine is the second part + { + var newFoldLine = foldLine.split(fold.start.row, fold.start.column); + folds = newFoldLine.folds; + folds.shift(); + newFoldLine.start.row = folds[0].start.row; + newFoldLine.start.column = folds[0].start.column; + } + + if (!this.$updating) { + if (this.$useWrapMode) + this.$updateWrapData(startRow, endRow); + else + this.$updateRowLengthCache(startRow, endRow); + } + + // Notify that fold data has changed. + this.$modified = true; + this._emit("changeFold", { data: fold, action: "remove" }); + }; + + this.removeFolds = function(folds) { + // We need to clone the folds array passed in as it might be the folds + // array of a fold line and as we call this.removeFold(fold), folds + // are removed from folds and changes the current index. + var cloneFolds = []; + for (var i = 0; i < folds.length; i++) { + cloneFolds.push(folds[i]); + } + + cloneFolds.forEach(function(fold) { + this.removeFold(fold); + }, this); + this.$modified = true; + }; + + this.expandFold = function(fold) { + this.removeFold(fold); + fold.subFolds.forEach(function(subFold) { + fold.restoreRange(subFold); + this.addFold(subFold); + }, this); + if (fold.collapseChildren > 0) { + this.foldAll(fold.start.row+1, fold.end.row, fold.collapseChildren-1); + } + fold.subFolds = []; + }; + + this.expandFolds = function(folds) { + folds.forEach(function(fold) { + this.expandFold(fold); + }, this); + }; + + this.unfold = function(location, expandInner) { + var range, folds; + if (location == null) { + range = new Range(0, 0, this.getLength(), 0); + expandInner = true; + } else if (typeof location == "number") + range = new Range(location, 0, location, this.getLine(location).length); + else if ("row" in location) + range = Range.fromPoints(location, location); + else + range = location; + + folds = this.getFoldsInRangeList(range); + if (expandInner) { + this.removeFolds(folds); + } else { + var subFolds = folds; + // TODO: might be better to remove and add folds in one go instead of using + // expandFolds several times. + while (subFolds.length) { + this.expandFolds(subFolds); + subFolds = this.getFoldsInRangeList(range); + } + } + if (folds.length) + return folds; + }; + + /* + * 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. + **/ + this.isRowFolded = function(docRow, startFoldRow) { + return !!this.getFoldLine(docRow, startFoldRow); + }; + + this.getRowFoldEnd = function(docRow, startFoldRow) { + var foldLine = this.getFoldLine(docRow, startFoldRow); + return foldLine ? foldLine.end.row : docRow; + }; + + this.getRowFoldStart = function(docRow, startFoldRow) { + var foldLine = this.getFoldLine(docRow, startFoldRow); + return foldLine ? foldLine.start.row : docRow; + }; + + this.getFoldDisplayLine = function(foldLine, endRow, endColumn, startRow, startColumn) { + if (startRow == null) + startRow = foldLine.start.row; + if (startColumn == null) + startColumn = 0; + if (endRow == null) + endRow = foldLine.end.row; + if (endColumn == null) + endColumn = this.getLine(endRow).length; + + + // Build the textline using the FoldLine walker. + var doc = this.doc; + var textLine = ""; + + foldLine.walk(function(placeholder, row, column, lastColumn) { + if (row < startRow) + return; + if (row == startRow) { + if (column < startColumn) + return; + lastColumn = Math.max(startColumn, lastColumn); + } + + if (placeholder != null) { + textLine += placeholder; + } else { + textLine += doc.getLine(row).substring(lastColumn, column); + } + }, endRow, endColumn); + return textLine; + }; + + this.getDisplayLine = function(row, endColumn, startRow, startColumn) { + var foldLine = this.getFoldLine(row); + + if (!foldLine) { + var line; + line = this.doc.getLine(row); + return line.substring(startColumn || 0, endColumn || line.length); + } else { + return this.getFoldDisplayLine( + foldLine, row, endColumn, startRow, startColumn); + } + }; + + this.$cloneFoldData = function() { + var fd = []; + fd = this.$foldData.map(function(foldLine) { + var folds = foldLine.folds.map(function(fold) { + return fold.clone(); + }); + return new FoldLine(fd, folds); + }); + + return fd; + }; + + this.toggleFold = function(tryToUnfold) { + var selection = this.selection; + var range = selection.getRange(); + var fold; + var bracketPos; + + if (range.isEmpty()) { + var cursor = range.start; + fold = this.getFoldAt(cursor.row, cursor.column); + + if (fold) { + this.expandFold(fold); + return; + } else if (bracketPos = this.findMatchingBracket(cursor)) { + if (range.comparePoint(bracketPos) == 1) { + range.end = bracketPos; + } else { + range.start = bracketPos; + range.start.column++; + range.end.column--; + } + } else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) { + if (range.comparePoint(bracketPos) == 1) + range.end = bracketPos; + else + range.start = bracketPos; + + range.start.column++; + } else { + range = this.getCommentFoldRange(cursor.row, cursor.column) || range; + } + } else { + var folds = this.getFoldsInRange(range); + if (tryToUnfold && folds.length) { + this.expandFolds(folds); + return; + } else if (folds.length == 1 ) { + fold = folds[0]; + } + } + + if (!fold) + fold = this.getFoldAt(range.start.row, range.start.column); + + if (fold && fold.range.toString() == range.toString()) { + this.expandFold(fold); + return; + } + + var placeholder = "..."; + if (!range.isMultiLine()) { + placeholder = this.getTextRange(range); + if(placeholder.length < 4) + return; + placeholder = placeholder.trim().substring(0, 2) + ".."; + } + + this.addFold(placeholder, range); + }; + + this.getCommentFoldRange = function(row, column, dir) { + var iterator = new TokenIterator(this, row, column); + var token = iterator.getCurrentToken(); + if (token && /^comment|string/.test(token.type)) { + var range = new Range(); + var re = new RegExp(token.type.replace(/\..*/, "\\.")); + if (dir != 1) { + do { + token = iterator.stepBackward(); + } while(token && re.test(token.type)); + iterator.stepForward(); + } + + range.start.row = iterator.getCurrentTokenRow(); + range.start.column = iterator.getCurrentTokenColumn() + 2; + + iterator = new TokenIterator(this, row, column); + + if (dir != -1) { + do { + token = iterator.stepForward(); + } while(token && re.test(token.type)); + token = iterator.stepBackward(); + } else + token = iterator.getCurrentToken(); + + range.end.row = iterator.getCurrentTokenRow(); + range.end.column = iterator.getCurrentTokenColumn() + token.value.length - 2; + return range; + } + }; + + this.foldAll = function(startRow, endRow, depth) { + if (depth == undefined) + depth = 100000; // JSON.stringify doesn't hanle Infinity + var foldWidgets = this.foldWidgets; + if (!foldWidgets) + return; // mode doesn't support folding + endRow = endRow || this.getLength(); + startRow = startRow || 0; + for (var row = startRow; row < endRow; row++) { + if (foldWidgets[row] == null) + foldWidgets[row] = this.getFoldWidget(row); + if (foldWidgets[row] != "start") + continue; + + var range = this.getFoldWidgetRange(row); + // sometimes range can be incompatible with existing fold + // TODO change addFold to return null istead of throwing + if (range && range.isMultiLine() + && range.end.row <= endRow + && range.start.row >= startRow + ) { + row = range.end.row; + try { + // addFold can change the range + var fold = this.addFold("...", range); + if (fold) + fold.collapseChildren = depth; + } catch(e) {} + } + } + }; + + // structured folding + this.$foldStyles = { + "manual": 1, + "markbegin": 1, + "markbeginend": 1 + }; + this.$foldStyle = "markbegin"; + this.setFoldStyle = function(style) { + if (!this.$foldStyles[style]) + throw new Error("invalid fold style: " + style + "[" + Object.keys(this.$foldStyles).join(", ") + "]"); + + if (this.$foldStyle == style) + return; + + this.$foldStyle = style; + + if (style == "manual") + this.unfold(); + + // reset folding + var mode = this.$foldMode; + this.$setFolding(null); + this.$setFolding(mode); + }; + + this.$setFolding = function(foldMode) { + if (this.$foldMode == foldMode) + return; + + this.$foldMode = foldMode; + + this.off('change', this.$updateFoldWidgets); + this.off('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets); + this._emit("changeAnnotation"); + + if (!foldMode || this.$foldStyle == "manual") { + this.foldWidgets = null; + return; + } + + this.foldWidgets = []; + this.getFoldWidget = foldMode.getFoldWidget.bind(foldMode, this, this.$foldStyle); + this.getFoldWidgetRange = foldMode.getFoldWidgetRange.bind(foldMode, this, this.$foldStyle); + + this.$updateFoldWidgets = this.updateFoldWidgets.bind(this); + this.$tokenizerUpdateFoldWidgets = this.tokenizerUpdateFoldWidgets.bind(this); + this.on('change', this.$updateFoldWidgets); + this.on('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets); + }; + + this.getParentFoldRangeData = function (row, ignoreCurrent) { + var fw = this.foldWidgets; + if (!fw || (ignoreCurrent && fw[row])) + return {}; + + var i = row - 1, firstRange; + while (i >= 0) { + var c = fw[i]; + if (c == null) + c = fw[i] = this.getFoldWidget(i); + + if (c == "start") { + var range = this.getFoldWidgetRange(i); + if (!firstRange) + firstRange = range; + if (range && range.end.row >= row) + break; + } + i--; + } + + return { + range: i !== -1 && range, + firstRange: firstRange + }; + } + + this.onFoldWidgetClick = function(row, e) { + e = e.domEvent; + var options = { + children: e.shiftKey, + all: e.ctrlKey || e.metaKey, + siblings: e.altKey + }; + + var range = this.$toggleFoldWidget(row, options); + if (!range) { + var el = (e.target || e.srcElement) + if (el && /ace_fold-widget/.test(el.className)) + el.className += " ace_invalid"; + } + }; + + this.$toggleFoldWidget = function(row, options) { + if (!this.getFoldWidget) + return; + var type = this.getFoldWidget(row); + var line = this.getLine(row); + + var dir = type === "end" ? -1 : 1; + var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir); + + if (fold) { + if (options.children || options.all) + this.removeFold(fold); + else + this.expandFold(fold); + return; + } + + var range = this.getFoldWidgetRange(row, true); + // sometimes singleline folds can be missed by the code above + if (range && !range.isMultiLine()) { + fold = this.getFoldAt(range.start.row, range.start.column, 1); + if (fold && range.isEqual(fold.range)) { + this.removeFold(fold); + return; + } + } + + if (options.siblings) { + var data = this.getParentFoldRangeData(row); + if (data.range) { + var startRow = data.range.start.row + 1; + var endRow = data.range.end.row; + } + this.foldAll(startRow, endRow, options.all ? 10000 : 0); + } else if (options.children) { + endRow = range ? range.end.row : this.getLength(); + this.foldAll(row + 1, endRow, options.all ? 10000 : 0); + } else if (range) { + if (options.all) + range.collapseChildren = 10000; + this.addFold("...", range); + } + + return range; + }; + + + + this.toggleFoldWidget = function(toggleParent) { + var row = this.selection.getCursor().row; + row = this.getRowFoldStart(row); + var range = this.$toggleFoldWidget(row, {}); + + if (range) + return; + // handle toggleParent + var data = this.getParentFoldRangeData(row, true); + range = data.range || data.firstRange; + + if (range) { + row = range.start.row; + var fold = this.getFoldAt(row, this.getLine(row).length, 1); + + if (fold) { + this.removeFold(fold); + } else { + this.addFold("...", range); + } + } + }; + + this.updateFoldWidgets = function(delta) { + var firstRow = delta.start.row; + var len = delta.end.row - firstRow; + + if (len === 0) { + this.foldWidgets[firstRow] = null; + } else if (delta.action == 'remove') { + this.foldWidgets.splice(firstRow, len + 1, null); + } else { + var args = Array(len + 1); + args.unshift(firstRow, 1); + this.foldWidgets.splice.apply(this.foldWidgets, args); + } + }; + this.tokenizerUpdateFoldWidgets = function(e) { + var rows = e.data; + if (rows.first != rows.last) { + if (this.foldWidgets.length > rows.first) + this.foldWidgets.splice(rows.first, this.foldWidgets.length); + } + } +} + +exports.Folding = Folding; + +}); diff --git a/lib/ace/edit_session_test.js b/lib/ace/edit_session_test.js new file mode 100644 index 00000000..0b904b63 --- /dev/null +++ b/lib/ace/edit_session_test.js @@ -0,0 +1,1087 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); + require("./test/mockdom"); +} + +define(function(require, exports, module) { +"use strict"; + +var lang = require("./lib/lang"); +var EditSession = require("./edit_session").EditSession; +var Editor = require("./editor").Editor; +var UndoManager = require("./undomanager").UndoManager; +var MockRenderer = require("./test/mockrenderer").MockRenderer; +var Range = require("./range").Range; +var assert = require("./test/assertions"); +var JavaScriptMode = require("./mode/javascript").Mode; + +function createFoldTestSession() { + var lines = [ + "function foo(items) {", + " for (var i=0; i>", [1, 2], 1); + + // Test wrapping for punctuation in + EditSession.prototype.$wrapAsCode = false; + computeAndAssert("ab cde, Juhu kinners", [3, 8, 13, 19], 6); + + // test indented wrapping + EditSession.prototype.$indentedSoftWrap = true; + computeAndAssert("foo bar foo bar foo bara foo", [12, 25]); + computeAndAssert("fooooooooooooooooooooooooooo", [12, 24]); + computeAndAssert("\t\tfoo bar fooooooooooobooooooo", [6, 10, 16, 22, 28]); + computeAndAssert("\t\t\tfoo bar fooooooooooobooooooo", [3, 7, 11, 17, 23, 29]); + computeAndAssert("\tfoo \t \t \t \t bar", [6, 12]); // 14 + }, + + "test get longest line" : function() { + var session = new EditSession(["12"]); + session.setTabSize(4); + assert.equal(session.getScreenWidth(), 2); + + session.doc.insertMergedLines({row: 0, column: Infinity}, ['', '']); + session.doc.insertFullLines(1, ["123"]); + assert.equal(session.getScreenWidth(), 3); + + session.doc.insertMergedLines({row: 0, column: Infinity}, ['', '']); + session.doc.insertFullLines(1, ["\t\t"]); + + assert.equal(session.getScreenWidth(), 8); + + session.setTabSize(2); + assert.equal(session.getScreenWidth(), 4); + }, + + "test getDisplayString": function() { + var session = new EditSession(["12"]); + session.setTabSize(4); + + assert.equal(session.$getDisplayTokens("\t").length, 4); + assert.equal(session.$getDisplayTokens("abc").length, 3); + assert.equal(session.$getDisplayTokens("abc\t").length, 4); + }, + + "test issue 83": function() { + var session = new EditSession(""); + var editor = new Editor(new MockRenderer(), session); + var document = session.getDocument(); + + session.setUseWrapMode(true); + + document.insertFullLines(0, ["a", "b"]); + document.insertFullLines(2, ["c", "d"]); + document.removeFullLines(1, 2); + }, + + "test wrapMode init has to create wrapData array": function() { + var session = new EditSession("foo bar\nfoo bar"); + var editor = new Editor(new MockRenderer(), session); + var document = session.getDocument(); + + session.setUseWrapMode(true); + session.setWrapLimitRange(3, 3); + session.adjustWrapLimit(80); + + // Test if wrapData is there and was computed. + assert.equal(session.$wrapData.length, 2); + assert.equal(session.$wrapData[0].length, 1); + assert.equal(session.$wrapData[1].length, 1); + }, + + "test first line blank with wrap": function() { + var session = new EditSession("\nfoo"); + session.setUseWrapMode(true); + assert.equal(session.doc.getValue(), ["", "foo"].join("\n")); + }, + + "test first line blank with wrap 2" : function() { + var session = new EditSession(""); + session.setUseWrapMode(true); + session.setValue("\nfoo"); + + assert.equal(session.doc.getValue(), ["", "foo"].join("\n")); + }, + + "test fold getFoldDisplayLine": function() { + var session = createFoldTestSession(); + function assertDisplayLine(foldLine, str) { + var line = session.getLine(foldLine.end.row); + var displayLine = + session.getFoldDisplayLine(foldLine, foldLine.end.row, line.length); + assert.equal(displayLine, str); + } + + assertDisplayLine(session.$foldData[0], "function foo(args...) {") + assertDisplayLine(session.$foldData[1], " for (vfoo...ert(items[bar...\"juhu\");"); + }, + + "test foldLine idxToPosition": function() { + var session = createFoldTestSession(); + + function assertIdx2Pos(foldLineIdx, idx, row, column) { + var foldLine = session.$foldData[foldLineIdx]; + assert.position(foldLine.idxToPosition(idx), row, column); + } + +// "function foo(items) {", +// " for (var i=0; iThe cursor in this paragraph text will be offset by 1 row.

    ", + "

    Everything after this will be offset as well due to the folds in the row before too.

    " + ].join("\n")); + session.addFold('...', new Range(0, 8, 0, 42)); + session.addFold('...', new Range(1, 8, 1, 42)); + session.addFold('...', new Range(3, 7, 3, 51)); + session.setOption("wrap", 40); + session.remove(new Range(0,0, 2, 5)); + // needed because adjustWrapLimit is called async from renderer + session.adjustWrapLimit(80); + + assert.equal(session.$wrapData + "", [[], [], [40, 76]] + ""); + }, + + "test add fold": function() { + var session = createFoldTestSession(); + var fold; + + function tryAddFold(placeholder, range, shouldFail) { + var fail = false; + try { + fold = session.addFold(placeholder, range); + } catch (e) { + fail = true; + } + if (fail != shouldFail) { + throw new Error("Expected to get an exception"); + } + } + + tryAddFold("foo", new Range(0, 13, 0, 17), false); + tryAddFold("foo", new Range(0, 14, 0, 18), true); + tryAddFold("foo", new Range(0, 13, 0, 18), false); + assert.equal(session.$foldData[0].folds.length, 1); + + tryAddFold("f", new Range(0, 13, 0, 18), false); + tryAddFold("foo", new Range(0, 18, 0, 21), false); + assert.equal(session.$foldData[0].folds.length, 2); + session.removeFold(fold); + + tryAddFold("foo", new Range(0, 18, 0, 22), false); + tryAddFold("foo", new Range(0, 18, 0, 19), true); + tryAddFold("foo", new Range(0, 22, 1, 10), false); + }, + + "test add subfolds": function() { + var session = createFoldTestSession(); + var fold, oldFold; + var foldData = session.$foldData; + + oldFold = foldData[0].folds[0]; + + fold = session.addFold("fold0", new Range(0, 10, 0, 21)); + assert.equal(foldData[0].folds.length, 1); + assert.equal(fold.subFolds.length, 1); + assert.equal(fold.subFolds[0], oldFold); + + session.expandFold(fold); + assert.equal(foldData[0].folds.length, 1); + assert.equal(foldData[0].folds[0], oldFold); + assert.equal(fold.subFolds.length, 0); + + fold = session.addFold("fold0", new Range(0, 13, 2, 10)); + assert.equal(foldData.length, 1); + assert.equal(fold.subFolds.length, 2); + assert.equal(fold.subFolds[0], oldFold); + + session.expandFold(fold); + assert.equal(foldData.length, 2); + assert.equal(foldData[0].folds.length, 1); + assert.equal(foldData[0].folds[0], oldFold); + assert.equal(fold.subFolds.length, 0); + + session.unfold(null, true); + fold = session.addFold("fold0", new Range(0, 0, 0, 21)); + session.addFold("fold0", new Range(0, 1, 0, 5)); + session.addFold("fold0", new Range(0, 6, 0, 8)); + assert.equal(fold.subFolds.length, 2); + }, + + "test row cache": function() { + var session = createFoldTestSession(); + + session.screenToDocumentPosition(2,3); + assertArray(session.$docRowCache, [1,3]); + assertArray(session.$screenRowCache, [1,2]); + + session.screenToDocumentPosition(5,3); + assertArray(session.$docRowCache, [1,3,4]); + assertArray(session.$screenRowCache, [1,2,3]); + + session.screenToDocumentPosition(0,3); + assertArray(session.$docRowCache, [1,3,4]); + assertArray(session.$screenRowCache, [1,2,3]); + + var pos = session.screenToDocumentPosition(0,0); + assert.equal(pos.row, 0); + assertArray(session.$docRowCache, [1,3,4]); + assertArray(session.$screenRowCache, [1,2,3]); + + session.screenToDocumentPosition(1,0); + assertArray(session.$docRowCache, [1,3,4]); + assertArray(session.$screenRowCache, [1,2,3]); + + session.$resetRowCache(); + assertArray(session.$docRowCache, []); + assertArray(session.$screenRowCache, []); + + session.screenToDocumentPosition(1,3); + assertArray(session.$docRowCache, [1]); + assertArray(session.$screenRowCache, [1]); + + session.screenToDocumentPosition(5,3); + assertArray(session.$docRowCache, [1,3,4]); + assertArray(session.$screenRowCache, [1,2,3]); + + session = new EditSession(new Array(30).join("\n")); + session.documentToScreenPosition(2,0); + session.documentToScreenPosition(2,0); + assertArray(session.$docRowCache, [1,2]); + assertArray(session.$screenRowCache, [1,2]); + }, + + "test annotations": function() { + var session = new EditSession([]), + annotation = {row: 0, type: 'info', text: "This is a test."}; + + session.clearAnnotations(); + assertArray(session.getAnnotations(), []); + session.setAnnotations([annotation]); + assertArray(session.getAnnotations(), [annotation]); + }, + + "test: mode loading" : function(next) { + if (!require.undef) { + console.log("Skipping test: This test only runs in the browser"); + next(); + return; + } + var session = new EditSession([]); + session.setMode("ace/mode/javascript"); + assert.equal(session.$modeid, "ace/mode/javascript"); + session.on("changeMode", function() { + assert.equal(session.$modeid, "ace/mode/javascript"); + }); + session.setMode("ace/mode/sh", function(mode) { + assert.ok(!mode); + }); + setTimeout(function() { + session.setMode("ace/mode/javascript", function(mode) { + session.setMode("ace/mode/javascript"); + assert.equal(session.$modeid, "ace/mode/javascript"); + next(); + }); + }, 0); + } +}; +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec(); +} diff --git a/lib/ace/editor.js b/lib/ace/editor.js index aff0abfc..5da8a961 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -1,225 +1,506 @@ -/* vim:ts=4:sts=4:sw=4: - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Irakli Gozalishvili (http://jeditoolkit.com) - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -require("pilot/fixoldbrowsers"); +require("./lib/fixoldbrowsers"); -var oop = require("pilot/oop"); -var event = require("pilot/event"); -var lang = require("pilot/lang"); -var useragent = require("pilot/useragent"); -var TextInput = require("ace/keyboard/textinput").TextInput; -var MouseHandler = require("ace/mouse_handler").MouseHandler; -//var TouchHandler = require("ace/touch_handler").TouchHandler; -var KeyBinding = require("ace/keyboard/keybinding").KeyBinding; -var EditSession = require("ace/edit_session").EditSession; -var Search = require("ace/search").Search; -var BackgroundTokenizer = require("ace/background_tokenizer").BackgroundTokenizer; -var Range = require("ace/range").Range; -var EventEmitter = require("pilot/event_emitter").EventEmitter; +var oop = require("./lib/oop"); +var dom = require("./lib/dom"); +var lang = require("./lib/lang"); +var useragent = require("./lib/useragent"); +var TextInput = require("./keyboard/textinput").TextInput; +var MouseHandler = require("./mouse/mouse_handler").MouseHandler; +var FoldHandler = require("./mouse/fold_handler").FoldHandler; +var KeyBinding = require("./keyboard/keybinding").KeyBinding; +var EditSession = require("./edit_session").EditSession; +var Search = require("./search").Search; +var Range = require("./range").Range; +var EventEmitter = require("./lib/event_emitter").EventEmitter; +var CommandManager = require("./commands/command_manager").CommandManager; +var defaultCommands = require("./commands/default_commands").commands; +var config = require("./config"); +var TokenIterator = require("./token_iterator").TokenIterator; -var Editor =function(renderer, session) { +/** + * 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. + * @class Editor + **/ + +/** + * Creates a new `Editor` object. + * + * @param {VirtualRenderer} renderer Associated `VirtualRenderer` that draws everything + * @param {EditSession} session The `EditSession` to refer to + * + * + * @constructor + **/ +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 - if (useragent.isIPad) { - //this.$mouseHandler = new TouchHandler(this); - } else { - this.$mouseHandler = new MouseHandler(this); - } + this.$mouseHandler = new MouseHandler(this); + new FoldHandler(this); this.$blockScrolling = 0; this.$search = new Search().set({ wrap: true }); + this.$historyTracker = this.$historyTracker.bind(this); + this.commands.on("exec", this.$historyTracker); + + this.$initOperationListeners(); + + this._$emitInputEvent = lang.delayedCall(function() { + this._signal("input", {}); + if (this.session && this.session.bgTokenizer) + this.session.bgTokenizer.scheduleStart(); + }.bind(this)); + + this.on("change", function(_, _self) { + _self._$emitInputEvent.schedule(31); + }); + this.setSession(session || new EditSession("")); + config.resetOptions(this); + config._signal("editor", this); }; (function(){ oop.implement(this, EventEmitter); - this.$forwardEvents = { - gutterclick: 1, - gutterdblclick: 1 + this.$initOperationListeners = function() { + function last(a) {return a[a.length - 1]} + + this.selections = []; + this.commands.on("exec", this.startOperation.bind(this), true); + this.commands.on("afterExec", this.endOperation.bind(this), true); + + this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this)); + + this.on("change", function() { + this.curOp || this.startOperation(); + this.curOp.docChanged = true; + }.bind(this), true); + + this.on("changeSelection", function() { + this.curOp || this.startOperation(); + this.curOp.selectionChanged = true; + }.bind(this), true); }; - this.$originalAddEventListener = this.addEventListener; - this.$originalRemoveEventListener = this.removeEventListener; + this.curOp = null; + this.prevOp = {}; + this.startOperation = function(commadEvent) { + if (this.curOp) { + if (!commadEvent || this.curOp.command) + return; + this.prevOp = this.curOp; + } + if (!commadEvent) { + this.previousCommand = null; + commadEvent = {}; + } - this.addEventListener = function(eventName, callback) { - if (this.$forwardEvents[eventName]) { - return this.renderer.addEventListener(eventName, callback); - } else { - return this.$originalAddEventListener(eventName, callback); + this.$opResetTimer.schedule(); + this.curOp = { + command: commadEvent.command || {}, + args: commadEvent.args, + scrollTop: this.renderer.scrollTop + }; + if (this.curOp.command.name && this.curOp.command.scrollIntoView !== undefined) + this.$blockScrolling++; + }; + + this.endOperation = function(e) { + if (this.curOp) { + if (e && e.returnValue === false) + return this.curOp = null; + this._signal("beforeEndOperation"); + var command = this.curOp.command; + if (command.name && this.$blockScrolling > 0) + this.$blockScrolling--; + var scrollIntoView = command && command.scrollIntoView; + if (scrollIntoView) { + switch (scrollIntoView) { + case "center-animate": + scrollIntoView = "animate"; + /* fall through */ + case "center": + this.renderer.scrollCursorIntoView(null, 0.5); + break; + case "animate": + case "cursor": + this.renderer.scrollCursorIntoView(); + break; + case "selectionPart": + var range = this.selection.getRange(); + var config = this.renderer.layerConfig; + if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) { + this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead); + } + break; + default: + break; + } + if (scrollIntoView == "animate") + this.renderer.animateScrolling(this.curOp.scrollTop); + } + + this.prevOp = this.curOp; + this.curOp = null; } }; - this.removeEventListener = function(eventName, callback) { - if (this.$forwardEvents[eventName]) { - return this.renderer.removeEventListener(eventName, callback); + // TODO use property on commands instead of this + this.$mergeableCommands = ["backspace", "del", "insertstring"]; + this.$historyTracker = function(e) { + if (!this.$mergeUndoDeltas) + return; + + var prev = this.prevOp; + var mergeableCommands = this.$mergeableCommands; + // previous command was the same + var shouldMerge = prev.command && (e.command.name == prev.command.name); + if (e.command.name == "insertstring") { + var text = e.args; + if (this.mergeNextCommand === undefined) + this.mergeNextCommand = true; + + shouldMerge = shouldMerge + && this.mergeNextCommand // previous command allows to coalesce with + && (!/\s/.test(text) || /\s/.test(prev.args)); // previous insertion was of same type + + this.mergeNextCommand = true; } else { - return this.$originalRemoveEventListener(eventName, callback); + shouldMerge = shouldMerge + && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable + } + + if ( + this.$mergeUndoDeltas != "always" + && Date.now() - this.sequenceStartTime > 2000 + ) { + shouldMerge = false; // the sequence is too long + } + + if (shouldMerge) + this.session.mergeUndoDeltas = true; + else if (mergeableCommands.indexOf(e.command.name) !== -1) + this.sequenceStartTime = Date.now(); + }; + + /** + * Sets a new key handler, such as "vim" or "windows". + * @param {String} keyboardHandler The new key handler + * + **/ + this.setKeyboardHandler = function(keyboardHandler, cb) { + if (keyboardHandler && typeof keyboardHandler === "string") { + this.$keybindingId = keyboardHandler; + var _self = this; + config.loadModule(["keybinding", keyboardHandler], function(module) { + if (_self.$keybindingId == keyboardHandler) + _self.keyBinding.setKeyboardHandler(module && module.handler); + cb && cb(); + }); + } else { + this.$keybindingId = null; + this.keyBinding.setKeyboardHandler(keyboardHandler); + cb && cb(); } }; - this.setKeyboardHandler = function(keyboardHandler) { - this.keyBinding.setKeyboardHandler(keyboardHandler); - }; - + /** + * Returns the keyboard handler, such as "vim" or "windows". + * + * @returns {String} + * + **/ this.getKeyboardHandler = function() { return this.keyBinding.getKeyboardHandler(); - } + }; + + /** + * Emitted whenever the [[EditSession]] changes. + * @event changeSession + * @param {Object} e An object with two properties, `oldSession` and `session`, that represent the old and new [[EditSession]]s. + * + **/ + /** + * Sets a new editsession to use. This method also emits the `'changeSession'` event. + * @param {EditSession} session The new session to use + * + **/ this.setSession = function(session) { - if (this.session == session) return; + if (this.session == session) + return; + + // make sure operationEnd events are not emitted to wrong session + if (this.curOp) this.endOperation(); + this.curOp = {}; - if (this.session) { - var oldSession = this.session; + var oldSession = this.session; + if (oldSession) { 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("changeScrollLeft", this.$onScrollLeftChange); var selection = this.session.getSelection(); selection.removeEventListener("changeCursor", this.$onCursorChange); selection.removeEventListener("changeSelection", this.$onSelectionChange); - - this.session.setScrollTopRow(this.renderer.getScrollTopRow()); } this.session = session; + if (session) { + this.$onDocumentChange = this.onDocumentChange.bind(this); + session.addEventListener("change", this.$onDocumentChange); + this.renderer.setSession(session); + + this.$onChangeMode = this.onChangeMode.bind(this); + session.addEventListener("changeMode", this.$onChangeMode); + + this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this); + session.addEventListener("tokenizerUpdate", this.$onTokenizerUpdate); + + this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer); + session.addEventListener("changeTabSize", this.$onChangeTabSize); + + this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this); + session.addEventListener("changeWrapLimit", this.$onChangeWrapLimit); + + this.$onChangeWrapMode = this.onChangeWrapMode.bind(this); + session.addEventListener("changeWrapMode", this.$onChangeWrapMode); + + this.$onChangeFold = this.onChangeFold.bind(this); + session.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 = session.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(); + } else { + this.selection = null; + this.renderer.setSession(session); + } - this.$onDocumentChange = this.onDocumentChange.bind(this); - session.addEventListener("change", this.$onDocumentChange); - this.renderer.setSession(session); - - this.$onChangeMode = this.onChangeMode.bind(this); - session.addEventListener("changeMode", this.$onChangeMode); - - this.$onChangeTabSize = this.renderer.updateText.bind(this.renderer); - session.addEventListener("changeTabSize", this.$onChangeTabSize); - - this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this); - session.addEventListener("changeWrapLimit", this.$onChangeWrapLimit); - - this.$onChangeWrapMode = this.onChangeWrapMode.bind(this); - session.addEventListener("changeWrapMode", this.$onChangeWrapMode); - - 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.selection = session.getSelection(); - this.selection.addEventListener("changeCursor", this.$onCursorChange); - - this.$onSelectionChange = this.onSelectionChange.bind(this); - this.selection.addEventListener("changeSelection", this.$onSelectionChange); - - this.onChangeMode(); - this.bgTokenizer.setDocument(session.getDocument()); - this.bgTokenizer.start(0); - - this.onCursorChange(); - this.onSelectionChange(); - this.onChangeFrontMarker(); - this.onChangeBackMarker(); - this.onChangeBreakpoint(); - this.onChangeAnnotation(); - this.renderer.scrollToRow(session.getScrollTopRow()); - this.renderer.updateFull(); - - this._dispatchEvent("changeSession", { + this._signal("changeSession", { session: session, oldSession: oldSession }); + + this.curOp = null; + + oldSession && oldSession._signal("changeEditor", {oldEditor: this}); + session && session._signal("changeEditor", {editor: this}); }; + /** + * Returns the current session being used. + * @returns {EditSession} + **/ this.getSession = function() { return this.session; }; + /** + * Sets the current document to `val`. + * @param {String} val The new value to set for the document + * @param {Number} cursorPos Where to set the new value. `undefined` or 0 is selectAll, -1 is at the document start, and 1 is at the end + * + * @returns {String} The current document value + * @related Document.setValue + **/ + this.setValue = function(val, cursorPos) { + this.session.doc.setValue(val); + + if (!cursorPos) + this.selectAll(); + else if (cursorPos == 1) + this.navigateFileEnd(); + else if (cursorPos == -1) + this.navigateFileStart(); + + return val; + }; + + /** + * Returns the current session's content. + * + * @returns {String} + * @related EditSession.getValue + **/ + this.getValue = function() { + return this.session.getValue(); + }; + + /** + * + * Returns the currently highlighted selection. + * @returns {String} The highlighted selection + **/ this.getSelection = function() { return this.selection; }; - this.resize = function() { - this.renderer.onResize(); - this.renderer.$textLayer.$pollSizeChanges(); + /** + * {:VirtualRenderer.onResize} + * @param {Boolean} force If `true`, recomputes the size, even if the height and width haven't changed + * + * + * @related VirtualRenderer.onResize + **/ + this.resize = function(force) { + this.renderer.onResize(force); }; - this.setTheme = function(theme) { - this.renderer.setTheme(theme); + /** + * {:VirtualRenderer.setTheme} + * @param {String} theme The path to a theme + * @param {Function} cb optional callback called when theme is loaded + **/ + this.setTheme = function(theme, cb) { + this.renderer.setTheme(theme, cb); }; + /** + * {:VirtualRenderer.getTheme} + * + * @returns {String} The set theme + * @related VirtualRenderer.getTheme + **/ + this.getTheme = function() { + return this.renderer.getTheme(); + }; + + /** + * {:VirtualRenderer.setStyle} + * @param {String} style A class name + * + * + * @related VirtualRenderer.setStyle + **/ this.setStyle = function(style) { - this.renderer.setStyle(style) + this.renderer.setStyle(style); }; + /** + * {:VirtualRenderer.unsetStyle} + * @related VirtualRenderer.unsetStyle + **/ this.unsetStyle = function(style) { - this.renderer.unsetStyle(style) - } + this.renderer.unsetStyle(style); + }; + + /** + * Gets the current font size of the editor text. + */ + this.getFontSize = function () { + return this.getOption("fontSize") || + dom.computedStyle(this.container, "fontSize"); + }; + + /** + * Set a new font size (in pixels) for the editor text. + * @param {String} size A font size ( _e.g._ "12px") + * + * + **/ + this.setFontSize = function(size) { + this.setOption("fontSize", size); + }; this.$highlightBrackets = function() { if (this.session.$bracketHighlight) { @@ -236,17 +517,114 @@ var Editor =function(renderer, session) { this.$highlightPending = true; setTimeout(function() { self.$highlightPending = false; - - var pos = self.session.findMatchingBracket(self.getCursorPosition()); + var session = self.session; + if (!session || !session.bgTokenizer) return; + var pos = session.findMatchingBracket(self.getCursorPosition()); if (pos) { - var range = new Range(pos.row, pos.column, pos.row, pos.column+1); - self.session.$bracketHighlight = self.session.addMarker(range, "ace_bracket"); + var range = new Range(pos.row, pos.column, pos.row, pos.column + 1); + } else if (session.$mode.getMatching) { + var range = session.$mode.getMatching(self.session); } - }, 10); + if (range) + session.$bracketHighlight = session.addMarker(range, "ace_bracket", "text"); + }, 50); }; + // todo: move to mode.getMatching + this.$highlightTags = function() { + if (this.$highlightTagPending) + return; + + // perform highlight async to not block the browser during navigation + var self = this; + this.$highlightTagPending = true; + setTimeout(function() { + self.$highlightTagPending = false; + + var session = self.session; + if (!session || !session.bgTokenizer) return; + + var pos = self.getCursorPosition(); + var iterator = new TokenIterator(self.session, pos.row, pos.column); + var token = iterator.getCurrentToken(); + + if (!token || !/\b(?:tag-open|tag-name)/.test(token.type)) { + session.removeMarker(session.$tagHighlight); + session.$tagHighlight = null; + return; + } + + if (token.type.indexOf("tag-open") != -1) { + token = iterator.stepForward(); + if (!token) + return; + } + + var tag = token.value; + var depth = 0; + var prevToken = iterator.stepBackward(); + + if (prevToken.value == '<'){ + //find closing tag + do { + prevToken = token; + token = iterator.stepForward(); + + if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) { + if (prevToken.value === '<'){ + depth++; + } else if (prevToken.value === '= 0); + } else { + //find opening tag + do { + token = prevToken; + prevToken = iterator.stepBackward(); + + if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) { + if (prevToken.value === '<') { + depth++; + } else if (prevToken.value === ' 1)) + highlight = false; } - session.$highlightLineMarker = null; - if (this.getHighlightActiveLine() && (this.getSelectionStyle() != "line" || !this.selection.isMultiLine())) { - var cursor = this.getCursorPosition(); - var range = new Range(cursor.row, 0, cursor.row+1, 0); - session.$highlightLineMarker = session.addMarker(range, "ace_active_line", "line"); + if (session.$highlightLineMarker && !highlight) { + session.removeMarker(session.$highlightLineMarker.id); + session.$highlightLineMarker = null; + } else if (!session.$highlightLineMarker && highlight) { + var range = new Range(highlight.row, highlight.column, highlight.row, Infinity); + range.id = session.addMarker(range, "ace_active-line", "screenLine"); + session.$highlightLineMarker = range; + } else if (highlight) { + session.$highlightLineMarker.start.row = highlight.row; + session.$highlightLineMarker.end.row = highlight.row; + session.$highlightLineMarker.start.column = highlight.column; + session._signal("changeBackMarker"); } }; this.onSelectionChange = function(e) { - var session = this.getSession(); + var session = this.session; if (session.$selectionMarker) { session.removeMarker(session.$selectionMarker); @@ -334,14 +778,49 @@ var Editor =function(renderer, session) { var range = this.selection.getRange(); var style = this.getSelectionStyle(); session.$selectionMarker = session.addMarker(range, "ace_selection", style); + } else { + this.$updateHighlightActiveLine(); } - this.onCursorChange(e); + var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp(); + this.session.highlight(re); - if (this.$highlightSelectedWord) - this.mode.highlightSelection(this); + this._signal("changeSelection"); }; + this.$getSelectionHighLightRegexp = function() { + var session = this.session; + + var selection = this.getSelectionRange(); + if (selection.isEmpty() || selection.isMultiLine()) + return; + + var startOuter = selection.start.column - 1; + var endOuter = selection.end.column + 1; + var line = session.getLine(selection.start.row); + var lineCols = line.length; + var needle = line.substring(Math.max(startOuter, 0), + Math.min(endOuter, lineCols)); + + // Make sure the outer characters are not part of the word. + if ((startOuter >= 0 && /^[\w\d]/.test(needle)) || + (endOuter <= lineCols && /[\w\d]$/.test(needle))) + return; + + needle = line.substring(selection.start.column, selection.end.column); + if (!/^[\w\d]+$/.test(needle)) + return; + + var re = this.$search.$assembleRegExp({ + wholeWord: true, + caseSensitive: true, + needle: needle + }); + + return re; + }; + + this.onChangeFrontMarker = function() { this.renderer.updateFrontMarkers(); }; @@ -350,33 +829,22 @@ var Editor =function(renderer, session) { this.renderer.updateBackMarkers(); }; + this.onChangeBreakpoint = function() { - this.renderer.setBreakpoints(this.session.getBreakpoints()); + this.renderer.updateBreakpoints(); }; this.onChangeAnnotation = function() { this.renderer.setAnnotations(this.session.getAnnotations()); }; - this.onChangeMode = function() { - var mode = this.session.getMode(); - if (this.mode == mode) - return; - this.mode = mode; - var tokenizer = mode.getTokenizer(); - - if (!this.bgTokenizer) { - var onUpdate = this.onTokenizerUpdate.bind(this); - this.bgTokenizer = new BackgroundTokenizer(tokenizer, this); - this.bgTokenizer.addEventListener("update", onUpdate); - } else { - this.bgTokenizer.setTokenizer(tokenizer); - } - - this.renderer.setTokenizer(this.bgTokenizer); + this.onChangeMode = function(e) { + this.renderer.updateText(); + this._emit("changeMode", e); }; + this.onChangeWrapLimit = function() { this.renderer.updateFull(); }; @@ -385,35 +853,131 @@ var Editor =function(renderer, session) { this.renderer.onResize(true); }; + + this.onChangeFold = function() { + // Update the active line marker as due to folding changes the current + // line range on the screen might have changed. + this.$updateHighlightActiveLine(); + // TODO: This might be too much updating. Okay for now. + this.renderer.updateFull(); + }; + + + /** + * Returns the string of text currently highlighted. + * @returns {String} + **/ + this.getSelectedText = function() { + return this.session.getTextRange(this.getSelectionRange()); + }; + + /** + * Emitted when text is copied. + * @event copy + * @param {String} text The copied text + * + **/ + /** + * Returns the string of text currently highlighted. + * @returns {String} + * @deprecated Use getSelectedText instead. + **/ this.getCopyText = function() { - if (!this.selection.isEmpty()) { - return this.session.getTextRange(this.getSelectionRange()); - } - else { - return ""; - } + var text = this.getSelectedText(); + this._signal("copy", text); + return text; }; + /** + * Called whenever a text "copy" happens. + **/ + this.onCopy = function() { + this.commands.exec("copy", this); + }; + + /** + * Called whenever a text "cut" happens. + **/ this.onCut = function() { - if (this.$readOnly) - return; + this.commands.exec("cut", this); + }; - if (!this.selection.isEmpty()) { - this.session.remove(this.getSelectionRange()) - this.clearSelection(); + /** + * Emitted when text is pasted. + * @event paste + * @param {Object} an object which contains one property, `text`, that represents the text to be pasted. Editing this property will alter the text that is pasted. + * + * + **/ + /** + * Called whenever a text "paste" happens. + * @param {String} text The pasted text + * + * + **/ + this.onPaste = function(text, event) { + var e = {text: text, event: event}; + this.commands.exec("paste", this, e); + }; + + this.$handlePaste = function(e) { + if (typeof e == "string") + e = {text: e}; + this._signal("paste", e); + var text = e.text; + if (!this.inMultiSelectMode || this.inVirtualSelectionMode) { + this.insert(text); + } else { + var lines = text.split(/\r\n|\r|\n/); + var ranges = this.selection.rangeList.ranges; + + if (lines.length > ranges.length || lines.length < 2 || !lines[1]) + return this.commands.exec("insertstring", this, text); + + for (var i = ranges.length; i--;) { + var range = ranges[i]; + if (!range.isEmpty()) + this.session.remove(range); + + this.session.insert(range.start, lines[i]); + } } }; - this.insert = function(text) { - if (this.$readOnly) - return; + this.execCommand = function(command, args) { + return this.commands.exec(command, this, args); + }; + /** + * Inserts `text` into wherever the cursor is pointing. + * @param {String} text The new text to add + * + **/ + this.insert = function(text, pasted) { + var session = this.session; + var mode = session.getMode(); var cursor = this.getCursorPosition(); - text = text.replace("\t", this.session.getTabString()); + + if (this.getBehavioursEnabled() && !pasted) { + // Get a transform if the current mode wants one. + var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text); + if (transform) { + if (text !== transform.text) { + this.session.mergeUndoDeltas = false; + this.$mergeNextCommand = false; + } + text = transform.text; + + } + } + + if (text == "\t") + text = this.session.getTabString(); // remove selected text if (!this.selection.isEmpty()) { - var cursor = this.session.remove(this.getSelectionRange()); + var range = this.getSelectionRange(); + cursor = this.session.remove(range); this.clearSelection(); } else if (this.session.getOverwrite()) { @@ -422,59 +986,43 @@ var Editor =function(renderer, session) { this.session.remove(range); } + if (text == "\n" || text == "\r\n") { + var line = session.getLine(cursor.row); + if (cursor.column > line.search(/\S|$/)) { + var d = line.substr(cursor.column).search(/\S|$/); + session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d); + } + } this.clearSelection(); - var lineState = this.bgTokenizer.getState(cursor.row); - var shouldOutdent = this.mode.checkOutdent(lineState, this.session.getLine(cursor.row), text); - var line = this.session.getLine(cursor.row); - var lineIndent = this.mode.getNextLineIndent(lineState, line.slice(0, cursor.column), this.session.getTabString()); - var end = this.session.insert(cursor, text); + var start = cursor.column; + var lineState = session.getState(cursor.row); + var line = session.getLine(cursor.row); + var shouldOutdent = mode.checkOutdent(lineState, line, text); + var end = session.insert(cursor, text); - - var lineState = this.bgTokenizer.getState(cursor.row); - // TODO disabled multiline auto indent - // possibly doing the indent before inserting the text - // if (cursor.row !== end.row) { - if (this.session.getDocument().isNewLine(text)) { - this.moveCursorTo(cursor.row+1, 0); - - var size = this.session.getTabSize(), - minIndent = Number.MAX_VALUE; - - - for (var row = cursor.row + 1; row <= end.row; ++row) { - var indent = 0; - - line = this.session.getLine(row); - for (var i = 0; i < line.length; ++i) - if (line.charAt(i) == '\t') - indent += size; - else if (line.charAt(i) == ' ') - indent += 1; - else - break; - if (/[^\s]/.test(line)) - minIndent = Math.min(indent, minIndent); + if (transform && transform.selection) { + if (transform.selection.length == 2) { // Transform relative to the current column + this.selection.setSelectionRange( + new Range(cursor.row, start + transform.selection[0], + cursor.row, start + transform.selection[1])); + } else { // Transform relative to the current row. + this.selection.setSelectionRange( + new Range(cursor.row + transform.selection[0], + transform.selection[1], + cursor.row + transform.selection[2], + transform.selection[3])); } + } - for (var row = cursor.row + 1; row <= end.row; ++row) { - var outdent = minIndent; + if (session.getDocument().isNewLine(text)) { + var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString()); - line = this.session.getLine(row); - for (var i = 0; i < line.length && outdent > 0; ++i) - if (line.charAt(i) == '\t') - outdent -= size; - else if (line.charAt(i) == ' ') - outdent -= 1; - this.session.remove(new Range(row, 0, row, i)); - } - this.session.indentRows(cursor.row + 1, end.row, lineIndent); - } else { - if (shouldOutdent) { - this.mode.autoOutdent(lineState, this.session, cursor.row); - } - }; - } + session.insert({row: cursor.row+1, column: 0}, lineIndent); + } + if (shouldOutdent) + mode.autoOutdent(lineState, session, cursor.row); + }; this.onTextInput = function(text) { this.keyBinding.onTextInput(text); @@ -484,129 +1032,310 @@ var Editor =function(renderer, session) { this.keyBinding.onCommandKey(e, hashId, keyCode); }; + /** + * 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. + * @param {Boolean} overwrite Defines wheter or not to set overwrites + * + * + * @related EditSession.setOverwrite + **/ this.setOverwrite = function(overwrite) { - this.session.setOverwrite(); + this.session.setOverwrite(overwrite); }; + /** + * Returns `true` if overwrites are enabled; `false` otherwise. + * @returns {Boolean} + * @related EditSession.getOverwrite + **/ this.getOverwrite = function() { return this.session.getOverwrite(); }; + /** + * Sets the value of overwrite to the opposite of whatever it currently is. + * @related EditSession.toggleOverwrite + **/ this.toggleOverwrite = function() { this.session.toggleOverwrite(); }; + /** + * Sets how fast the mouse scrolling should do. + * @param {Number} speed A value indicating the new speed (in milliseconds) + **/ this.setScrollSpeed = function(speed) { - this.$mouseHandler.setScrollSpeed(speed); + this.setOption("scrollSpeed", speed); }; + /** + * Returns the value indicating how fast the mouse scroll speed is (in milliseconds). + * @returns {Number} + **/ this.getScrollSpeed = function() { - return this.$mouseHandler.getScrollSpeed() + return this.getOption("scrollSpeed"); }; - this.$selectionStyle = "line"; - this.setSelectionStyle = function(style) { - if (this.$selectionStyle == style) return; - - this.$selectionStyle = style; - this.onSelectionChange(); - this._dispatchEvent("changeSelectionStyle", {data: style}); + /** + * Sets the delay (in milliseconds) of the mouse drag. + * @param {Number} dragDelay A value indicating the new delay + **/ + this.setDragDelay = function(dragDelay) { + this.setOption("dragDelay", dragDelay); }; + /** + * Returns the current mouse drag delay. + * @returns {Number} + **/ + this.getDragDelay = function() { + return this.getOption("dragDelay"); + }; + + /** + * Emitted when the selection style changes, via [[Editor.setSelectionStyle]]. + * @event changeSelectionStyle + * @param {Object} data Contains one property, `data`, which indicates the new selection style + **/ + /** + * Draw selection markers spanning whole line, or only over selected text. Default value is "line" + * @param {String} style The new selection style "line"|"text" + * + **/ + this.setSelectionStyle = function(val) { + this.setOption("selectionStyle", val); + }; + + /** + * Returns the current selection style. + * @returns {String} + **/ this.getSelectionStyle = function() { - return this.$selectionStyle; + return this.getOption("selectionStyle"); }; - this.$highlightActiveLine = true; + /** + * Determines whether or not the current line should be highlighted. + * @param {Boolean} shouldHighlight Set to `true` to highlight the current line + **/ this.setHighlightActiveLine = function(shouldHighlight) { - if (this.$highlightActiveLine == shouldHighlight) return; - - this.$highlightActiveLine = shouldHighlight; - this.$updateHighlightActiveLine(); + this.setOption("highlightActiveLine", shouldHighlight); }; - + /** + * Returns `true` if current lines are always highlighted. + * @return {Boolean} + **/ this.getHighlightActiveLine = function() { - return this.$highlightActiveLine; + return this.getOption("highlightActiveLine"); + }; + this.setHighlightGutterLine = function(shouldHighlight) { + this.setOption("highlightGutterLine", shouldHighlight); }; - this.$highlightSelectedWord = false; + this.getHighlightGutterLine = function() { + return this.getOption("highlightGutterLine"); + }; + + /** + * Determines if the currently selected word should be highlighted. + * @param {Boolean} shouldHighlight Set to `true` to highlight the currently selected word + * + **/ this.setHighlightSelectedWord = function(shouldHighlight) { - if (this.$highlightSelectedWord == shouldHighlight) - return; - - this.$highlightSelectedWord = shouldHighlight; - if (shouldHighlight) - this.mode.highlightSelection(this); - else - this.mode.clearSelectionHighlight(this); + this.setOption("highlightSelectedWord", shouldHighlight); }; + /** + * Returns `true` if currently highlighted words are to be highlighted. + * @returns {Boolean} + **/ this.getHighlightSelectedWord = function() { return this.$highlightSelectedWord; }; - this.setShowInvisibles = function(showInvisibles) { - if (this.getShowInvisibles() == showInvisibles) - return; + this.setAnimatedScroll = function(shouldAnimate){ + this.renderer.setAnimatedScroll(shouldAnimate); + }; + this.getAnimatedScroll = function(){ + return this.renderer.getAnimatedScroll(); + }; + + /** + * If `showInvisibles` is set to `true`, invisible characters—like spaces or new lines—are show in the editor. + * @param {Boolean} showInvisibles Specifies whether or not to show invisible characters + * + **/ + this.setShowInvisibles = function(showInvisibles) { this.renderer.setShowInvisibles(showInvisibles); }; + /** + * Returns `true` if invisible characters are being shown. + * @returns {Boolean} + **/ this.getShowInvisibles = function() { return this.renderer.getShowInvisibles(); }; + this.setDisplayIndentGuides = function(display) { + this.renderer.setDisplayIndentGuides(display); + }; + + this.getDisplayIndentGuides = function() { + return this.renderer.getDisplayIndentGuides(); + }; + + /** + * If `showPrintMargin` is set to `true`, the print margin is shown in the editor. + * @param {Boolean} showPrintMargin Specifies whether or not to show the print margin + * + **/ this.setShowPrintMargin = function(showPrintMargin) { this.renderer.setShowPrintMargin(showPrintMargin); }; + /** + * Returns `true` if the print margin is being shown. + * @returns {Boolean} + **/ this.getShowPrintMargin = function() { return this.renderer.getShowPrintMargin(); }; + /** + * Sets the column defining where the print margin should be. + * @param {Number} showPrintMargin Specifies the new print margin + * + **/ this.setPrintMarginColumn = function(showPrintMargin) { this.renderer.setPrintMarginColumn(showPrintMargin); }; + /** + * Returns the column number of where the print margin is. + * @returns {Number} + **/ this.getPrintMarginColumn = function() { return this.renderer.getPrintMarginColumn(); }; - this.$readOnly = false; + /** + * If `readOnly` is true, then the editor is set to read-only mode, and none of the content can change. + * @param {Boolean} readOnly Specifies whether the editor can be modified or not + * + **/ this.setReadOnly = function(readOnly) { - this.$readOnly = readOnly; + this.setOption("readOnly", readOnly); }; + /** + * Returns `true` if the editor is set to read-only mode. + * @returns {Boolean} + **/ this.getReadOnly = function() { - return this.$readOnly; + return this.getOption("readOnly"); }; - this.removeRight = function() { - if (this.$readOnly) - return; + /** + * 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} + * @param {Boolean} enabled Enables or disables behaviors + * + **/ + this.setBehavioursEnabled = function (enabled) { + this.setOption("behavioursEnabled", enabled); + }; - if (this.selection.isEmpty()) { - this.selection.selectRight(); + /** + * Returns `true` if the behaviors are currently enabled. {:BehaviorsDef} + * + * @returns {Boolean} + **/ + this.getBehavioursEnabled = function () { + return this.getOption("behavioursEnabled"); + }; + + /** + * Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets + * when such a character is typed in. + * @param {Boolean} enabled Enables or disables wrapping behaviors + * + **/ + this.setWrapBehavioursEnabled = function (enabled) { + this.setOption("wrapBehavioursEnabled", enabled); + }; + + /** + * Returns `true` if the wrapping behaviors are currently enabled. + **/ + this.getWrapBehavioursEnabled = function () { + return this.getOption("wrapBehavioursEnabled"); + }; + + /** + * Indicates whether the fold widgets should be shown or not. + * @param {Boolean} show Specifies whether the fold widgets are shown + **/ + this.setShowFoldWidgets = function(show) { + this.setOption("showFoldWidgets", show); + + }; + /** + * Returns `true` if the fold widgets are shown. + * @return {Boolean} + **/ + this.getShowFoldWidgets = function() { + return this.getOption("showFoldWidgets"); + }; + + this.setFadeFoldWidgets = function(fade) { + this.setOption("fadeFoldWidgets", fade); + }; + + this.getFadeFoldWidgets = function() { + return this.getOption("fadeFoldWidgets"); + }; + + /** + * Removes the current selection or one character. + * @param {String} dir The direction of the deletion to occur, either "left" or "right" + * + **/ + this.remove = function(dir) { + if (this.selection.isEmpty()){ + if (dir == "left") + this.selection.selectLeft(); + else + this.selection.selectRight(); } - this.session.remove(this.getSelectionRange()) - this.clearSelection(); - }; - - this.removeLeft = function() { - if (this.$readOnly) - return; - - if (this.selection.isEmpty()) - this.selection.selectLeft(); - - this.session.remove(this.getSelectionRange()); + + var range = this.getSelectionRange(); + if (this.getBehavioursEnabled()) { + var session = this.session; + var state = session.getState(range.start.row); + var new_range = session.getMode().transformAction(state, 'deletion', this, session, range); + + if (range.end.column === 0) { + var text = session.getTextRange(range); + if (text[text.length - 1] == "\n") { + var line = session.getLine(range.end.row); + if (/^\s+$/.test(line)) { + range.end.column = line.length; + } + } + } + if (new_range) + range = new_range; + } + + this.session.remove(range); this.clearSelection(); }; + /** + * Removes the word directly to the right of the current selection. + **/ this.removeWordRight = function() { - if (this.$readOnly) - return; - if (this.selection.isEmpty()) this.selection.selectWordRight(); @@ -614,10 +1343,10 @@ var Editor =function(renderer, session) { this.clearSelection(); }; + /** + * Removes the word directly to the left of the current selection. + **/ this.removeWordLeft = function() { - if (this.$readOnly) - return; - if (this.selection.isEmpty()) this.selection.selectWordLeft(); @@ -625,10 +1354,10 @@ var Editor =function(renderer, session) { this.clearSelection(); }; + /** + * Removes all the words to the left of the current selection, until the start of the line. + **/ this.removeToLineStart = function() { - if (this.$readOnly) - return; - if (this.selection.isEmpty()) this.selection.selectLineStart(); @@ -636,21 +1365,27 @@ var Editor =function(renderer, session) { this.clearSelection(); }; + /** + * Removes all the words to the right of the current selection, until the end of the line. + **/ this.removeToLineEnd = function() { - if (this.$readOnly) - return; - if (this.selection.isEmpty()) this.selection.selectLineEnd(); - this.session.remove(this.getSelectionRange()); + var range = this.getSelectionRange(); + if (range.start.column == range.end.column && range.start.row == range.end.row) { + range.end.column = 0; + range.end.row++; + } + + this.session.remove(range); this.clearSelection(); }; + /** + * Splits the line at the current selection (by inserting an `'\n'`). + **/ this.splitLine = function() { - if (this.$readOnly) - return; - if (!this.selection.isEmpty()) { this.session.remove(this.getSelectionRange()); this.clearSelection(); @@ -661,146 +1396,384 @@ var Editor =function(renderer, session) { this.moveCursorToPosition(cursor); }; + /** + * Transposes current line. + **/ this.transposeLetters = function() { - if (this.$readOnly) - return; - if (!this.selection.isEmpty()) { return; } var cursor = this.getCursorPosition(); var column = cursor.column; - if (column == 0) + if (column === 0) return; var line = this.session.getLine(cursor.row); + var swap, range; if (column < line.length) { - var swap = line.charAt(column) + line.charAt(column-1); - var range = new Range(cursor.row, column-1, cursor.row, column+1) + swap = line.charAt(column) + line.charAt(column-1); + range = new Range(cursor.row, column-1, cursor.row, column+1); } else { - var swap = line.charAt(column-1) + line.charAt(column-2); - var range = new Range(cursor.row, column-2, cursor.row, column) + swap = line.charAt(column-1) + line.charAt(column-2); + range = new Range(cursor.row, column-2, cursor.row, column); } this.session.replace(range, swap); }; - this.indent = function() { - if (this.$readOnly) - return; + /** + * Converts the current selection entirely into lowercase. + **/ + this.toLowerCase = function() { + var originalRange = this.getSelectionRange(); + if (this.selection.isEmpty()) { + this.selection.selectWord(); + } + var range = this.getSelectionRange(); + var text = this.session.getTextRange(range); + this.session.replace(range, text.toLowerCase()); + this.selection.setSelectionRange(originalRange); + }; + + /** + * Converts the current selection entirely into uppercase. + **/ + this.toUpperCase = function() { + var originalRange = this.getSelectionRange(); + if (this.selection.isEmpty()) { + this.selection.selectWord(); + } + + var range = this.getSelectionRange(); + var text = this.session.getTextRange(range); + this.session.replace(range, text.toUpperCase()); + this.selection.setSelectionRange(originalRange); + }; + + /** + * Inserts an indentation into the current cursor position or indents the selected lines. + * + * @related EditSession.indentRows + **/ + this.indent = function() { var session = this.session; var range = this.getSelectionRange(); - if (range.start.row < range.end.row || range.start.column < range.end.column) { + if (range.start.row < range.end.row) { var rows = this.$getSelectedRows(); session.indentRows(rows.first, rows.last, "\t"); - } else { - var indentString; - - if (this.session.getUseSoftTabs()) { - var size = session.getTabSize(), - position = this.getCursorPosition(), - column = session.documentToScreenColumn(position.row, position.column), - count = (size - column % size); - - indentString = lang.stringRepeat(" ", count); - } else - indentString = "\t"; - return this.onTextInput(indentString); + return; + } else if (range.start.column < range.end.column) { + var text = session.getTextRange(range); + if (!/^\s+$/.test(text)) { + var rows = this.$getSelectedRows(); + session.indentRows(rows.first, rows.last, "\t"); + return; + } } + + var line = session.getLine(range.start.row); + var position = range.start; + var size = session.getTabSize(); + var column = session.documentToScreenColumn(position.row, position.column); + + if (this.session.getUseSoftTabs()) { + var count = (size - column % size); + var indentString = lang.stringRepeat(" ", count); + } else { + var count = column % size; + while (line[range.start.column] == " " && count) { + range.start.column--; + count--; + } + this.selection.setSelectionRange(range); + indentString = "\t"; + } + return this.insert(indentString); }; - this.blockOutdent = function() { - if (this.$readOnly) - return; + /** + * Indents the current line. + * @related EditSession.indentRows + **/ + this.blockIndent = function() { + var rows = this.$getSelectedRows(); + this.session.indentRows(rows.first, rows.last, "\t"); + }; + /** + * Outdents the current line. + * @related EditSession.outdentRows + **/ + this.blockOutdent = function() { var selection = this.session.getSelection(); this.session.outdentRows(selection.getRange()); }; - this.toggleCommentLines = function() { - if (this.$readOnly) - return; + // TODO: move out of core when we have good mechanism for managing extensions + this.sortLines = function() { + var rows = this.$getSelectedRows(); + var session = this.session; - var state = this.bgTokenizer.getState(this.getCursorPosition().row); - var rows = this.$getSelectedRows() - this.mode.toggleCommentLines(state, this.session, rows.first, rows.last); + var lines = []; + for (i = rows.first; i <= rows.last; i++) + lines.push(session.getLine(i)); + + lines.sort(function(a, b) { + if (a.toLowerCase() < b.toLowerCase()) return -1; + if (a.toLowerCase() > b.toLowerCase()) return 1; + return 0; + }); + + var deleteRange = new Range(0, 0, 0, 0); + for (var i = rows.first; i <= rows.last; i++) { + var line = session.getLine(i); + deleteRange.start.row = i; + deleteRange.end.row = i; + deleteRange.end.column = line.length; + session.replace(deleteRange, lines[i-rows.first]); + } }; - this.removeLines = function() { - if (this.$readOnly) - return; - + /** + * Given the currently selected range, this function either comments all the lines, or uncomments all of them. + **/ + this.toggleCommentLines = function() { + var state = this.session.getState(this.getCursorPosition().row); var rows = this.$getSelectedRows(); - this.session.remove(new Range(rows.first, 0, rows.last+1, 0)); + this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last); + }; + + this.toggleBlockComment = function() { + var cursor = this.getCursorPosition(); + var state = this.session.getState(cursor.row); + var range = this.getSelectionRange(); + this.session.getMode().toggleBlockComment(state, this.session, range, cursor); + }; + + /** + * Works like [[EditSession.getTokenAt]], except it returns a number. + * @returns {Number} + **/ + this.getNumberAt = function(row, column) { + var _numberRx = /[\-]?[0-9]+(?:\.[0-9]+)?/g; + _numberRx.lastIndex = 0; + + var s = this.session.getLine(row); + while (_numberRx.lastIndex < column) { + var m = _numberRx.exec(s); + if(m.index <= column && m.index+m[0].length >= column){ + var number = { + value: m[0], + start: m.index, + end: m.index+m[0].length + }; + return number; + } + } + return null; + }; + + /** + * If the character before the cursor is a number, this functions changes its value by `amount`. + * @param {Number} amount The value to change the numeral by (can be negative to decrease value) + * + **/ + this.modifyNumber = function(amount) { + var row = this.selection.getCursor().row; + var column = this.selection.getCursor().column; + + // get the char before the cursor + var charRange = new Range(row, column-1, row, column); + + var c = this.session.getTextRange(charRange); + // if the char is a digit + if (!isNaN(parseFloat(c)) && isFinite(c)) { + // get the whole number the digit is part of + var nr = this.getNumberAt(row, column); + // if number found + if (nr) { + var fp = nr.value.indexOf(".") >= 0 ? nr.start + nr.value.indexOf(".") + 1 : nr.end; + var decimals = nr.start + nr.value.length - fp; + + var t = parseFloat(nr.value); + t *= Math.pow(10, decimals); + + + if(fp !== nr.end && column < fp){ + amount *= Math.pow(10, nr.end - column - 1); + } else { + amount *= Math.pow(10, nr.end - column); + } + + t += amount; + t /= Math.pow(10, decimals); + var nnr = t.toFixed(decimals); + + //update number + var replaceRange = new Range(row, nr.start, row, nr.end); + this.session.replace(replaceRange, nnr); + + //reposition the cursor + this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length)); + + } + } + }; + + /** + * Removes all the lines in the current selection + * @related EditSession.remove + **/ + this.removeLines = function() { + var rows = this.$getSelectedRows(); + this.session.removeFullLines(rows.first, rows.last); this.clearSelection(); }; + this.duplicateSelection = function() { + var sel = this.selection; + var doc = this.session; + var range = sel.getRange(); + var reverse = sel.isBackwards(); + if (range.isEmpty()) { + var row = range.start.row; + doc.duplicateLines(row, row); + } else { + var point = reverse ? range.start : range.end; + var endPoint = doc.insert(point, doc.getTextRange(range), false); + range.start = point; + range.end = endPoint; + + sel.setSelectionRange(range, reverse); + } + }; + + /** + * Shifts all the selected lines down one row. + * + * @returns {Number} On success, it returns -1. + * @related EditSession.moveLinesUp + **/ this.moveLinesDown = function() { - if (this.$readOnly) - return; - - this.$moveLines(function(firstRow, lastRow) { - return this.session.moveLinesDown(firstRow, lastRow); - }); + this.$moveLines(1, false); }; + /** + * Shifts all the selected lines up one row. + * @returns {Number} On success, it returns -1. + * @related EditSession.moveLinesDown + **/ this.moveLinesUp = function() { - if (this.$readOnly) - return; - - this.$moveLines(function(firstRow, lastRow) { - return this.session.moveLinesUp(firstRow, lastRow); - }); + this.$moveLines(-1, false); }; - this.moveText = function(range, toPosition) { - if (this.$readOnly) - return null; - - return this.session.moveText(range, toPosition); + /** + * Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this: + * ```json + * { row: newRowLocation, column: newColumnLocation } + * ``` + * @param {Range} fromRange The range of text you want moved within the document + * @param {Object} toPosition The location (row and column) where you want to move the text to + * + * @returns {Range} The new range where the text was moved to. + * @related EditSession.moveText + **/ + this.moveText = function(range, toPosition, copy) { + return this.session.moveText(range, toPosition, copy); }; + /** + * Copies all the selected lines up one row. + * @returns {Number} On success, returns 0. + * + **/ this.copyLinesUp = function() { - if (this.$readOnly) - return; - - this.$moveLines(function(firstRow, lastRow) { - this.session.duplicateLines(firstRow, lastRow); - return 0; - }); + this.$moveLines(-1, true); }; + /** + * Copies all the selected lines down one row. + * @returns {Number} On success, returns the number of new rows added; in other words, `lastRow - firstRow + 1`. + * @related EditSession.duplicateLines + * + **/ this.copyLinesDown = function() { - if (this.$readOnly) - return; - - this.$moveLines(function(firstRow, lastRow) { - return this.session.duplicateLines(firstRow, lastRow); - }); + this.$moveLines(1, true); }; - - this.$moveLines = function(mover) { - var rows = this.$getSelectedRows(); - - var linesMoved = mover.call(this, rows.first, rows.last); - + /** + * for internal use + * @ignore + * + **/ + this.$moveLines = function(dir, copy) { + var rows, moved; var selection = this.selection; - selection.setSelectionAnchor(rows.last+linesMoved+1, 0); - selection.$moveSelection(function() { - selection.moveCursorTo(rows.first+linesMoved, 0); - }); + if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) { + var range = selection.toOrientedRange(); + rows = this.$getSelectedRows(range); + moved = this.session.$moveLines(rows.first, rows.last, copy ? 0 : dir); + if (copy && dir == -1) moved = 0; + range.moveBy(moved, 0); + selection.fromOrientedRange(range); + } else { + var ranges = selection.rangeList.ranges; + selection.rangeList.detach(this.session); + this.inVirtualSelectionMode = true; + + var diff = 0; + var totalDiff = 0; + var l = ranges.length; + for (var i = 0; i < l; i++) { + var rangeIndex = i; + ranges[i].moveBy(diff, 0); + rows = this.$getSelectedRows(ranges[i]); + var first = rows.first; + var last = rows.last; + while (++i < l) { + if (totalDiff) ranges[i].moveBy(totalDiff, 0); + var subRows = this.$getSelectedRows(ranges[i]); + if (copy && subRows.first != last) + break; + else if (!copy && subRows.first > last + 1) + break; + last = subRows.last; + } + i--; + diff = this.session.$moveLines(first, last, copy ? 0 : dir); + if (copy && dir == -1) rangeIndex = i + 1; + while (rangeIndex <= i) { + ranges[rangeIndex].moveBy(diff, 0); + rangeIndex++; + } + if (!copy) diff = 0; + totalDiff += diff; + } + + selection.fromOrientedRange(selection.ranges[0]); + selection.rangeList.attach(this.session); + this.inVirtualSelectionMode = false; + } }; - this.$getSelectedRows = function() { - var range = this.getSelectionRange().collapseRows(); + /** + * Returns an object indicating the currently selected rows. The object looks like this: + * + * ```json + * { first: range.start.row, last: range.end.row } + * ``` + * + * @returns {Object} + **/ + this.$getSelectedRows = function(range) { + range = (range || this.getSelectionRange()).collapseRows(); return { - first: range.start.row, - last: range.end.row + first: this.session.getRowFoldStart(range.start.row), + last: this.session.getRowFoldEnd(range.end.row) }; }; @@ -816,156 +1789,466 @@ var Editor =function(renderer, session) { this.renderer.hideComposition(); }; - + /** + * {:VirtualRenderer.getFirstVisibleRow} + * + * @returns {Number} + * @related VirtualRenderer.getFirstVisibleRow + **/ this.getFirstVisibleRow = function() { return this.renderer.getFirstVisibleRow(); }; + /** + * {:VirtualRenderer.getLastVisibleRow} + * + * @returns {Number} + * @related VirtualRenderer.getLastVisibleRow + **/ this.getLastVisibleRow = function() { return this.renderer.getLastVisibleRow(); }; + /** + * Indicates if the row is currently visible on the screen. + * @param {Number} row The row to check + * + * @returns {Boolean} + **/ this.isRowVisible = function(row) { return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow()); }; + /** + * Indicates if the entire row is currently visible on the screen. + * @param {Number} row The row to check + * + * + * @returns {Boolean} + **/ + this.isRowFullyVisible = function(row) { + return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow()); + }; + + /** + * Returns the number of currently visibile rows. + * @returns {Number} + **/ 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); }; + /** + * 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); }; + /** + * 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); }; + /** + * 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); }; + /** + * 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); }; + /** + * Scrolls the document to wherever "page down" is, without changing the cursor position. + **/ this.scrollPageDown = function() { - this.scrollToRow(this.$getPageDownRow()); + this.$moveByPage(1); }; + /** + * Scrolls the document to wherever "page up" is, without changing the cursor position. + **/ this.scrollPageUp = function() { - this.renderer.scrollToRow(this.$getPageUpRow()); + this.$moveByPage(-1); }; + /** + * Moves the editor to the specified row. + * @related VirtualRenderer.scrollToRow + **/ this.scrollToRow = function(row) { this.renderer.scrollToRow(row); }; - this.scrollToLine = function(line, center) { - this.renderer.scrollToLine(line, center); + /** + * Scrolls to a line. If `center` is `true`, it puts the line in middle of screen (or attempts to). + * @param {Number} line The line to scroll to + * @param {Boolean} center If `true` + * @param {Boolean} animate If `true` animates scrolling + * @param {Function} callback Function to be called when the animation has finished + * + * + * @related VirtualRenderer.scrollToLine + **/ + this.scrollToLine = function(line, center, animate, callback) { + this.renderer.scrollToLine(line, center, animate, callback); }; + /** + * 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); + var pos = { + row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2), + column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2) + }; + this.renderer.alignCursor(pos, 0.5); }; + /** + * Gets the current position of the cursor. + * @returns {Object} An object that looks something like this: + * + * ```json + * { row: currRow, column: currCol } + * ``` + * + * @related Selection.getCursor + **/ this.getCursorPosition = function() { return this.selection.getCursor(); }; + /** + * Returns the screen position of the cursor. + * @returns {Number} + * @related EditSession.documentToScreenPosition + **/ this.getCursorPositionScreen = function() { return this.session.documentToScreenPosition(this.getCursorPosition()); - } + }; + /** + * {:Selection.getRange} + * @returns {Range} + * @related Selection.getRange + **/ this.getSelectionRange = function() { return this.selection.getRange(); }; + /** + * Selects all the text in editor. + * @related Selection.selectAll + **/ this.selectAll = function() { this.$blockScrolling += 1; this.selection.selectAll(); this.$blockScrolling -= 1; }; + /** + * {:Selection.clearSelection} + * @related Selection.clearSelection + **/ this.clearSelection = function() { this.selection.clearSelection(); }; + /** + * Moves the cursor to the specified row and column. Note that this does not de-select the current selection. + * @param {Number} row The new row number + * @param {Number} column The new column number + * + * + * @related Selection.moveCursorTo + **/ this.moveCursorTo = function(row, column) { this.selection.moveCursorTo(row, column); }; + /** + * Moves the cursor to the position indicated by `pos.row` and `pos.column`. + * @param {Object} pos An object with two properties, row and column + * + * + * @related Selection.moveCursorToPosition + **/ this.moveCursorToPosition = function(pos) { this.selection.moveCursorToPosition(pos); }; + /** + * Moves the cursor's row and column to the next matching bracket or HTML tag. + * + **/ + this.jumpToMatching = function(select, expand) { + var cursor = this.getCursorPosition(); + var iterator = new TokenIterator(this.session, cursor.row, cursor.column); + var prevToken = iterator.getCurrentToken(); + var token = prevToken || iterator.stepForward(); - this.gotoLine = function(lineNumber, row) { + if (!token) return; + + //get next closing tag or bracket + var matchType; + var found = false; + var depth = {}; + var i = cursor.column - token.start; + var bracketType; + var brackets = { + ")": "(", + "(": "(", + "]": "[", + "[": "[", + "{": "{", + "}": "{" + }; + + do { + if (token.value.match(/[{}()\[\]]/g)) { + for (; i < token.value.length && !found; i++) { + if (!brackets[token.value[i]]) { + continue; + } + + bracketType = brackets[token.value[i]] + '.' + token.type.replace("rparen", "lparen"); + + if (isNaN(depth[bracketType])) { + depth[bracketType] = 0; + } + + switch (token.value[i]) { + case '(': + case '[': + case '{': + depth[bracketType]++; + break; + case ')': + case ']': + case '}': + depth[bracketType]--; + + if (depth[bracketType] === -1) { + matchType = 'bracket'; + found = true; + } + break; + } + } + } + else if (token && token.type.indexOf('tag-name') !== -1) { + if (isNaN(depth[token.value])) { + depth[token.value] = 0; + } + + if (prevToken.value === '<') { + depth[token.value]++; + } + else if (prevToken.value === '= 0; --i) - this.$tryReplace(ranges[i], replacement); + + var selection = this.getSelectionRange(); + this.selection.moveTo(0, 0); + + for (var i = ranges.length - 1; i >= 0; --i) { + if(this.$tryReplace(ranges[i], replacement)) { + replaced++; + } + } this.selection.setSelectionRange(selection); this.$blockScrolling -= 1; - }, + + return replaced; + }; this.$tryReplace = function(range, replacement) { var input = this.session.getTextRange(range); - var replacement = this.$search.replace(input, replacement); + replacement = this.$search.replace(input, replacement); if (replacement !== null) { range.end = this.session.replace(range, replacement); return range; @@ -1066,59 +2409,283 @@ var Editor =function(renderer, session) { } }; + /** + * {:Search.getOptions} For more information on `options`, see [[Search `Search`]]. + * @related Search.getOptions + * @returns {Object} + **/ this.getLastSearchOptions = function() { return this.$search.getOptions(); }; - this.find = function(needle, options) { - this.clearSelection(); - options = options || {}; - options.needle = needle; - this.$search.set(options); - this.$find(); - }, + /** + * Attempts to find `needle` within the document. For more information on `options`, see [[Search `Search`]]. + * @param {String} needle The text to search for (optional) + * @param {Object} options An object defining various search properties + * @param {Boolean} animate If `true` animate scrolling + * + * + * @related Search.find + **/ + this.find = function(needle, options, animate) { + if (!options) + options = {}; - this.findNext = function(options) { - options = options || {}; - if (typeof options.backwards == "undefined") - options.backwards = false; - this.$search.set(options); - this.$find(); - }; + if (typeof needle == "string" || needle instanceof RegExp) + options.needle = needle; + else if (typeof needle == "object") + oop.mixin(options, needle); - this.findPrevious = function(options) { - options = options || {}; - if (typeof options.backwards == "undefined") - options.backwards = true; - this.$search.set(options); - this.$find(); - }; - - this.$find = function(backwards) { - if (!this.selection.isEmpty()) { - this.$search.set({needle: this.session.getTextRange(this.getSelectionRange())}); + var range = this.selection.getRange(); + if (options.needle == null) { + needle = this.session.getTextRange(range) + || this.$search.$options.needle; + if (!needle) { + range = this.session.getWordRange(range.start.row, range.start.column); + needle = this.session.getTextRange(range); + } + this.$search.set({needle: needle}); } - if (typeof backwards != "undefined") - this.$search.set({backwards: backwards}); + this.$search.set(options); + if (!options.start) + this.$search.set({start: range}); - var range = this.$search.find(this.session); - if (range) { - this.gotoLine(range.end.row+1, range.end.column); - this.selection.setSelectionRange(range); + var newRange = this.$search.find(this.session); + if (options.preventScroll) + return newRange; + if (newRange) { + this.revealRange(newRange, animate); + return newRange; } + // clear selection if nothing is found + if (options.backwards) + range.start = range.end; + else + range.end = range.start; + this.selection.setRange(range); }; + /** + * Performs another search for `needle` in the document. For more information on `options`, see [[Search `Search`]]. + * @param {Object} options search options + * @param {Boolean} animate If `true` animate scrolling + * + * + * @related Editor.find + **/ + this.findNext = function(options, animate) { + this.find({skipCurrent: true, backwards: false}, options, animate); + }; + + /** + * Performs a search for `needle` backwards. For more information on `options`, see [[Search `Search`]]. + * @param {Object} options search options + * @param {Boolean} animate If `true` animate scrolling + * + * + * @related Editor.find + **/ + this.findPrevious = function(options, animate) { + this.find(options, {skipCurrent: true, backwards: true}, animate); + }; + + this.revealRange = function(range, animate) { + this.$blockScrolling += 1; + this.session.unfold(range); + this.selection.setSelectionRange(range); + this.$blockScrolling -= 1; + + var scrollTop = this.renderer.scrollTop; + this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5); + if (animate !== false) + this.renderer.animateScrolling(scrollTop); + }; + + /** + * {:UndoManager.undo} + * @related UndoManager.undo + **/ this.undo = function() { + this.$blockScrolling++; this.session.getUndoManager().undo(); + this.$blockScrolling--; + this.renderer.scrollCursorIntoView(null, 0.5); }; + /** + * {:UndoManager.redo} + * @related UndoManager.redo + **/ this.redo = function() { + this.$blockScrolling++; this.session.getUndoManager().redo(); + this.$blockScrolling--; + this.renderer.scrollCursorIntoView(null, 0.5); + }; + + /** + * + * Cleans up the entire editor. + **/ + this.destroy = function() { + this.renderer.destroy(); + this._signal("destroy", this); + if (this.session) { + this.session.destroy(); + } + }; + + /** + * Enables automatic scrolling of the cursor into view when editor itself is inside scrollable element + * @param {Boolean} enable default true + **/ + this.setAutoScrollEditorIntoView = function(enable) { + if (!enable) + return; + var rect; + var self = this; + var shouldScroll = false; + if (!this.$scrollAnchor) + this.$scrollAnchor = document.createElement("div"); + var scrollAnchor = this.$scrollAnchor; + scrollAnchor.style.cssText = "position:absolute"; + this.container.insertBefore(scrollAnchor, this.container.firstChild); + var onChangeSelection = this.on("changeSelection", function() { + shouldScroll = true; + }); + // needed to not trigger sync reflow + var onBeforeRender = this.renderer.on("beforeRender", function() { + if (shouldScroll) + rect = self.renderer.container.getBoundingClientRect(); + }); + var onAfterRender = this.renderer.on("afterRender", function() { + if (shouldScroll && rect && (self.isFocused() + || self.searchBox && self.searchBox.isFocused()) + ) { + var renderer = self.renderer; + var pos = renderer.$cursorLayer.$pixelPos; + var config = renderer.layerConfig; + var top = pos.top - config.offset; + if (pos.top >= 0 && top + rect.top < 0) { + shouldScroll = true; + } else if (pos.top < config.height && + pos.top + rect.top + config.lineHeight > window.innerHeight) { + shouldScroll = false; + } else { + shouldScroll = null; + } + if (shouldScroll != null) { + scrollAnchor.style.top = top + "px"; + scrollAnchor.style.left = pos.left + "px"; + scrollAnchor.style.height = config.lineHeight + "px"; + scrollAnchor.scrollIntoView(shouldScroll); + } + shouldScroll = rect = null; + } + }); + this.setAutoScrollEditorIntoView = function(enable) { + if (enable) + return; + delete this.setAutoScrollEditorIntoView; + this.removeEventListener("changeSelection", onChangeSelection); + this.renderer.removeEventListener("afterRender", onAfterRender); + this.renderer.removeEventListener("beforeRender", onBeforeRender); + }; + }; + + + this.$resetCursorStyle = function() { + var style = this.$cursorStyle || "ace"; + var cursorLayer = this.renderer.$cursorLayer; + if (!cursorLayer) + return; + cursorLayer.setSmoothBlinking(/smooth/.test(style)); + cursorLayer.isBlinking = !this.$readOnly && style != "wide"; + dom.setCssClass(cursorLayer.element, "ace_slim-cursors", /slim/.test(style)); }; }).call(Editor.prototype); + +config.defineOptions(Editor.prototype, "editor", { + selectionStyle: { + set: function(style) { + this.onSelectionChange(); + this._signal("changeSelectionStyle", {data: style}); + }, + initialValue: "line" + }, + highlightActiveLine: { + set: function() {this.$updateHighlightActiveLine();}, + initialValue: true + }, + highlightSelectedWord: { + set: function(shouldHighlight) {this.$onSelectionChange();}, + initialValue: true + }, + readOnly: { + set: function(readOnly) { + // disabled to not break vim mode! + // this.textInput.setReadOnly(readOnly); + this.$resetCursorStyle(); + }, + initialValue: false + }, + cursorStyle: { + set: function(val) { this.$resetCursorStyle(); }, + values: ["ace", "slim", "smooth", "wide"], + initialValue: "ace" + }, + mergeUndoDeltas: { + values: [false, true, "always"], + initialValue: true + }, + behavioursEnabled: {initialValue: true}, + wrapBehavioursEnabled: {initialValue: true}, + autoScrollEditorIntoView: { + set: function(val) {this.setAutoScrollEditorIntoView(val)} + }, + + hScrollBarAlwaysVisible: "renderer", + vScrollBarAlwaysVisible: "renderer", + highlightGutterLine: "renderer", + animatedScroll: "renderer", + showInvisibles: "renderer", + showPrintMargin: "renderer", + printMarginColumn: "renderer", + printMargin: "renderer", + fadeFoldWidgets: "renderer", + showFoldWidgets: "renderer", + showLineNumbers: "renderer", + showGutter: "renderer", + displayIndentGuides: "renderer", + fontSize: "renderer", + fontFamily: "renderer", + maxLines: "renderer", + minLines: "renderer", + scrollPastEnd: "renderer", + fixedWidthGutter: "renderer", + theme: "renderer", + + scrollSpeed: "$mouseHandler", + dragDelay: "$mouseHandler", + dragEnabled: "$mouseHandler", + focusTimout: "$mouseHandler", + tooltipFollowsMouse: "$mouseHandler", + + firstLineNumber: "session", + overwrite: "session", + newLineMode: "session", + useWorker: "session", + useSoftTabs: "session", + tabSize: "session", + wrap: "session", + indentedSoftWrap: "session", + foldStyle: "session", + mode: "session" +}); + exports.Editor = Editor; }); diff --git a/lib/ace/test/change_document_test.js b/lib/ace/editor_change_document_test.js similarity index 55% rename from lib/ace/test/change_document_test.js rename to lib/ace/editor_change_document_test.js index 79f989d3..a1fdaad9 100644 --- a/lib/ace/test/change_document_test.js +++ b/lib/ace/editor_change_document_test.js @@ -1,54 +1,57 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ +if (typeof process !== "undefined") { + require("amd-loader"); + require("./test/mockdom"); +} + define(function(require, exports, module) { +"use strict"; -var EditSession = require("../edit_session").EditSession, - Editor = require("../editor").Editor, - Text = require("../mode/text").Mode, - JavaScriptMode = require("../mode/javascript").Mode, - MockRenderer = require("./mockrenderer"), - assert = require("./assertions"); +var EditSession = require("./edit_session").EditSession; +var Editor = require("./editor").Editor; +var Text = require("./mode/text").Mode; +var JavaScriptMode = require("./mode/javascript").Mode; +var CssMode = require("./mode/css").Mode; +var HtmlMode = require("./mode/html").Mode; +var MockRenderer = require("./test/mockrenderer").MockRenderer; +var assert = require("./test/assertions"); -var Test = { +module.exports = { setUp : function(next) { this.session1 = new EditSession(["abc", "def"]); this.session2 = new EditSession(["ghi", "jkl"]); + + this.editor = new Editor(new MockRenderer()); next(); }, @@ -150,13 +153,36 @@ var Test = { this.session2.setMode(new JavaScriptMode()); assert.ok(called); + }, + + "test: should use stop worker of old document" : function(next) { + var self = this; + + // 1. Open an editor and set the session to CssMode + self.editor.setSession(self.session1); + self.session1.setMode(new CssMode()); + + // 2. Add a line or two of valid CSS. + self.session1.setValue("DIV { color: red; }"); + + // 3. Clear the session value. + self.session1.setValue(""); + + // 4. Set the session to HtmlMode + self.session1.setMode(new HtmlMode()); + + // 5. Try to type valid HTML + self.session1.insert({row: 0, column: 0}, ""); + + setTimeout(function() { + assert.equal(Object.keys(self.session1.getAnnotations()).length, 0); + next(); + }, 600); } }; -module.exports = require("asyncjs/test").testcase(Test); }); if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec() + require("asyncjs").test.testcase(module.exports).exec() } diff --git a/lib/ace/test/highlight_selected_word_test.js b/lib/ace/editor_highlight_selected_word_test.js similarity index 62% rename from lib/ace/test/highlight_selected_word_test.js rename to lib/ace/editor_highlight_selected_word_test.js index 8dcd39d1..13e19c23 100644 --- a/lib/ace/test/highlight_selected_word_test.js +++ b/lib/ace/editor_highlight_selected_word_test.js @@ -1,49 +1,45 @@ -/* vim:ts=4:sts=4:sw=4: - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Mihai Sucan. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Mihai Sucan - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ -define(function(require, exports, module) { +if (typeof process !== "undefined") { + require("amd-loader"); + require("./test/mockdom"); +} -var EditSession = require("ace/edit_session").EditSession, - Editor = require("../editor").Editor, - MockRenderer = require("./mockrenderer"), - TextMode = require("ace/mode/text").Mode, - assert = require("./assertions"), - async = require("asyncjs"); +define(function(require, exports, module) { +"use strict"; + +var EditSession = require("./edit_session").EditSession; +var Editor = require("./editor").Editor; +var MockRenderer = require("./test/mockrenderer").MockRenderer; +var assert = require("./test/assertions"); var lipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + "Mauris at arcu mi, eu lobortis mauris. Quisque ut libero eget " + @@ -66,7 +62,17 @@ var lipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + "libero vehicula odio, eget bibendum mauris velit eu lorem.\n" + "consectetur"; -var Test = { +function callHighlighterUpdate(session, firstRow, lastRow) { + var rangeCount = 0; + var mockMarkerLayer = { drawSingleLineMarker: function() {rangeCount++;} } + session.$searchHighlight.update([], mockMarkerLayer, session, { + firstRow: firstRow, + lastRow: lastRow + }); + return rangeCount; +} + +module.exports = { setUp: function(next) { this.session = new EditSession(lipsum); this.editor = new Editor(new MockRenderer(), this.session); @@ -83,9 +89,13 @@ var Test = { this.editor.moveCursorTo(0, 9); this.selection.selectWord(); + var highlighter = this.editor.session.$searchHighlight; + assert.ok(highlighter != null); + var range = this.selection.getRange(); assert.equal(this.session.getTextRange(range), "ipsum"); - assert.equal(this.session.$selectionOccurrences.length, 1); + assert.equal(highlighter.cache.length, 0); + assert.equal(callHighlighterUpdate(this.session, 0, 0), 2); }, "test: highlight a word and clear highlight": function() { @@ -94,10 +104,11 @@ var Test = { var range = this.selection.getRange(); assert.equal(this.session.getTextRange(range), "ipsum"); - assert.equal(this.session.$selectionOccurrences.length, 1); + assert.equal(callHighlighterUpdate(this.session, 0, 0), 2); - this.session.getMode().clearSelectionHighlight(this.editor); - assert.equal(this.session.$selectionOccurrences.length, 0); + this.session.highlight(""); + assert.equal(this.session.$searchHighlight.cache.length, 0); + assert.equal(callHighlighterUpdate(this.session, 0, 0), 0); }, "test: highlight another word": function() { @@ -106,22 +117,23 @@ var Test = { var range = this.selection.getRange(); assert.equal(this.session.getTextRange(range), "dolor"); - assert.equal(this.session.$selectionOccurrences.length, 3); + assert.equal(callHighlighterUpdate(this.session, 0, 0), 4); }, "test: no selection, no highlight": function() { this.selection.clearSelection(); - assert.equal(this.session.$selectionOccurrences.length, 0); + assert.equal(callHighlighterUpdate(this.session, 0, 0), 0); }, "test: select a word, no highlight": function() { - this.editor.setHighlightSelectedWord(false); this.selection.moveCursorTo(0, 14); this.selection.selectWord(); + this.editor.setHighlightSelectedWord(false); + var range = this.selection.getRange(); assert.equal(this.session.getTextRange(range), "dolor"); - assert.equal(this.session.$selectionOccurrences.length, 0); + assert.equal(callHighlighterUpdate(this.session, 0, 0), 0); }, "test: select a word with no matches": function() { @@ -144,7 +156,7 @@ var Test = { this.selection.setSelectionRange(match); assert.equal(this.session.getTextRange(match), "Mauris"); - assert.equal(this.session.$selectionOccurrences.length, 0); + assert.equal(callHighlighterUpdate(this.session, 0, 0), 1); }, "test: partial word selection 1": function() { @@ -154,7 +166,7 @@ var Test = { var range = this.selection.getRange(); assert.equal(this.session.getTextRange(range), "dolo"); - assert.equal(this.session.$selectionOccurrences.length, 0); + assert.equal(callHighlighterUpdate(this.session, 0, 0), 0); }, "test: partial word selection 2": function() { @@ -164,7 +176,7 @@ var Test = { var range = this.selection.getRange(); assert.equal(this.session.getTextRange(range), "dolor "); - assert.equal(this.session.$selectionOccurrences.length, 0); + assert.equal(callHighlighterUpdate(this.session, 0, 0), 0); }, "test: partial word selection 3": function() { @@ -175,7 +187,7 @@ var Test = { var range = this.selection.getRange(); assert.equal(this.session.getTextRange(range), "olor"); - assert.equal(this.session.$selectionOccurrences.length, 0); + assert.equal(callHighlighterUpdate(this.session, 0, 0), 0); }, "test: select last word": function() { @@ -200,14 +212,12 @@ var Test = { this.selection.setSelectionRange(match); assert.equal(this.session.getTextRange(match), "consectetur"); - assert.equal(this.session.$selectionOccurrences.length, 2); - }, + assert.equal(callHighlighterUpdate(this.session, 0, 1), 3); + } }; -module.exports = require("asyncjs/test").testcase(Test); }); if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec() + require("asyncjs").test.testcase(module.exports).exec(); } diff --git a/lib/ace/test/navigation_test.js b/lib/ace/editor_navigation_test.js similarity index 61% rename from lib/ace/test/navigation_test.js rename to lib/ace/editor_navigation_test.js index 3174baaa..ab348241 100644 --- a/lib/ace/test/navigation_test.js +++ b/lib/ace/editor_navigation_test.js @@ -1,48 +1,47 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ +if (typeof process !== "undefined") { + require("amd-loader"); + require("./test/mockdom"); +} + define(function(require, exports, module) { +"use strict"; -var EditSession = require("ace/edit_session").EditSession, - Editor = require("../editor").Editor, - MockRenderer = require("./mockrenderer"), - assert = require("./assertions"); +var EditSession = require("./edit_session").EditSession; +var Editor = require("./editor").Editor; +var MockRenderer = require("./test/mockrenderer").MockRenderer; +var assert = require("./test/assertions"); -var Test = { +module.exports = { createEditSession : function(rows, cols) { var line = new Array(cols + 1).join("a"); var text = new Array(rows).join(line + "\n") + line; @@ -76,7 +75,7 @@ var Test = { 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); @@ -96,7 +95,7 @@ var Test = { 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); @@ -145,13 +144,21 @@ var Test = { editor.navigateUp(); assert.position(editor.getCursorPosition(), 0, 1); + }, + + "test: typing text should update the desired column": function() { + var editor = new Editor(new MockRenderer(), new EditSession(["1234", "1234567890"])); + + editor.navigateTo(0, 3); + editor.insert("juhu"); + + editor.navigateDown(); + assert.position(editor.getCursorPosition(), 1, 7); } }; -module.exports = require("asyncjs/test").testcase(Test) }); if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec(); + require("asyncjs").test.testcase(module.exports).exec() } diff --git a/lib/ace/test/text_edit_test.js b/lib/ace/editor_text_edit_test.js similarity index 67% rename from lib/ace/test/text_edit_test.js rename to lib/ace/editor_text_edit_test.js index 5bdb49ce..77ec34ed 100644 --- a/lib/ace/test/text_edit_test.js +++ b/lib/ace/editor_text_edit_test.js @@ -1,50 +1,50 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ +if (typeof process !== "undefined") { + require("amd-loader"); + require("./test/mockdom"); +} + define(function(require, exports, module) { +"use strict"; -var EditSession = require("ace/edit_session").EditSession, - Editor = require("../editor").Editor, - JavaScriptMode = require("../mode/javascript").Mode, - UndoManager = require("../undomanager").UndoManager, - MockRenderer = require("./mockrenderer"), - assert = require("./assertions"); +var EditSession = require("./edit_session").EditSession; +var Editor = require("./editor").Editor; +var JavaScriptMode = require("./mode/javascript").Mode; +var UndoManager = require("./undomanager").UndoManager; +var MockRenderer = require("./test/mockrenderer").MockRenderer; +var assert = require("./test/assertions"); +var whitespace = require("./ext/whitespace"); -var Test = { +module.exports = { "test: delete line from the middle" : function() { var session = new EditSession(["a", "b", "c", "d"].join("\n")); var editor = new Editor(new MockRenderer(), session); @@ -62,13 +62,13 @@ var Test = { editor.removeLines(); - assert.equal(session.toString(), "a\n"); - assert.position(editor.getCursorPosition(), 1, 0); + assert.equal(session.toString(), "a"); + assert.position(editor.getCursorPosition(), 0, 1); editor.removeLines(); - assert.equal(session.toString(), "a\n"); - assert.position(editor.getCursorPosition(), 1, 0); + assert.equal(session.toString(), ""); + assert.position(editor.getCursorPosition(), 0, 0); }, "test: delete multiple selected lines" : function() { @@ -93,15 +93,19 @@ var Test = { assert.position(editor.getCursorPosition(), 0, 0); }, - "test: delete last" : function() { - var session = new EditSession(["a", "b", "c"].join("\n")); + "test: delete last should also delete the new line of the previous line" : function() { + var session = new EditSession(["a", "b", "c", ""].join("\n")); var editor = new Editor(new MockRenderer(), session); - editor.moveCursorTo(2, 1); - editor.removeLines(); + editor.moveCursorTo(3, 0); - assert.equal(session.toString(), "a\nb\n"); - assert.position(editor.getCursorPosition(), 2, 0); + editor.removeLines(); + assert.equal(session.toString(), "a\nb\nc"); + assert.position(editor.getCursorPosition(), 2, 1); + + editor.removeLines(); + assert.equal(session.toString(), "a\nb"); + assert.position(editor.getCursorPosition(), 1, 1); }, "test: indent block" : function() { @@ -141,7 +145,7 @@ var Test = { 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); @@ -181,21 +185,23 @@ var Test = { "test: comment lines should perserve selection" : function() { var session = new EditSession([" abc", "cde"].join("\n"), new JavaScriptMode()); var editor = new Editor(new MockRenderer(), session); - + whitespace.detectIndentation(session); + editor.moveCursorTo(0, 2); editor.getSelection().selectDown(); editor.toggleCommentLines(); - assert.equal(["// abc", "//cde"].join("\n"), session.toString()); + assert.equal(["// abc", "// cde"].join("\n"), session.toString()); var selection = editor.getSelectionRange(); - assert.position(selection.start, 0, 4); - assert.position(selection.end, 1, 4); + assert.position(selection.start, 0, 5); + assert.position(selection.end, 1, 5); }, "test: uncomment lines should perserve selection" : function() { - var session = new EditSession(["// abc", "//cde"].join("\n"), new JavaScriptMode()); + var session = new EditSession(["// abc", "//cde"].join("\n"), new JavaScriptMode()); var editor = new Editor(new MockRenderer(), session); + session.setTabSize(2); editor.moveCursorTo(0, 1); editor.getSelection().selectDown(); @@ -232,7 +238,7 @@ var Test = { editor.getSelection().selectDown(); editor.toggleCommentLines(); - assert.range(editor.getSelectionRange(), 0, 2, 1, 0); + assert.range(editor.getSelectionRange(), 0, 3, 1, 0); // select up var session = new EditSession(["abc", "cde"].join("\n"), new JavaScriptMode()); @@ -242,10 +248,10 @@ var Test = { editor.getSelection().selectUp(); editor.toggleCommentLines(); - assert.range(editor.getSelectionRange(), 0, 2, 1, 0); + assert.range(editor.getSelectionRange(), 0, 3, 1, 0); }, - "test: move lines down should select moved lines" : function() { + "test: move lines down should keep selection on moved lines" : function() { var session = new EditSession(["11", "22", "33", "44"].join("\n")); var editor = new Editor(new MockRenderer(), session); @@ -254,25 +260,25 @@ var Test = { editor.moveLinesDown(); assert.equal(["33", "11", "22", "44"].join("\n"), session.toString()); - assert.position(editor.getCursorPosition(), 1, 0); - assert.position(editor.getSelection().getSelectionAnchor(), 3, 0); - assert.position(editor.getSelection().getSelectionLead(), 1, 0); + assert.position(editor.getCursorPosition(), 2, 1); + assert.position(editor.getSelection().getSelectionAnchor(), 1, 1); + assert.position(editor.getSelection().getSelectionLead(), 2, 1); editor.moveLinesDown(); assert.equal(["33", "44", "11", "22"].join("\n"), session.toString()); - assert.position(editor.getCursorPosition(), 2, 0); - assert.position(editor.getSelection().getSelectionAnchor(), 3, 2); - assert.position(editor.getSelection().getSelectionLead(), 2, 0); + assert.position(editor.getCursorPosition(), 3, 1); + assert.position(editor.getSelection().getSelectionAnchor(), 2, 1); + assert.position(editor.getSelection().getSelectionLead(), 3, 1); // moving again should have no effect editor.moveLinesDown(); assert.equal(["33", "44", "11", "22"].join("\n"), session.toString()); - assert.position(editor.getCursorPosition(), 2, 0); - assert.position(editor.getSelection().getSelectionAnchor(), 3, 2); - assert.position(editor.getSelection().getSelectionLead(), 2, 0); + assert.position(editor.getCursorPosition(), 3, 1); + assert.position(editor.getSelection().getSelectionAnchor(), 2, 1); + assert.position(editor.getSelection().getSelectionLead(), 3, 1); }, - "test: move lines up should select moved lines" : function() { + "test: move lines up should keep selection on moved lines" : function() { var session = new EditSession(["11", "22", "33", "44"].join("\n")); var editor = new Editor(new MockRenderer(), session); @@ -281,19 +287,18 @@ var Test = { editor.moveLinesUp(); assert.equal(session.toString(), ["11", "33", "44", "22"].join("\n")); - assert.position(editor.getCursorPosition(), 1, 0); - assert.position(editor.getSelection().getSelectionAnchor(), 3, 0); - assert.position(editor.getSelection().getSelectionLead(), 1, 0); + assert.position(editor.getCursorPosition(), 2, 1); + assert.position(editor.getSelection().getSelectionAnchor(), 1, 1); + assert.position(editor.getSelection().getSelectionLead(), 2, 1); editor.moveLinesUp(); assert.equal(session.toString(), ["33", "44", "11", "22"].join("\n")); - assert.position(editor.getCursorPosition(), 0, 0); - assert.position(editor.getSelection().getSelectionAnchor(), 2, 0); - assert.position(editor.getSelection().getSelectionLead(), 0, 0); + assert.position(editor.getCursorPosition(), 1, 1); + assert.position(editor.getSelection().getSelectionAnchor(), 0, 1); + assert.position(editor.getSelection().getSelectionLead(), 1, 1); }, - "test: move line without active selection should move cursor to start of the moved line" : function() - { + "test: move line without active selection should not move cursor relative to the moved line" : function() { var session = new EditSession(["11", "22", "33", "44"].join("\n")); var editor = new Editor(new MockRenderer(), session); @@ -302,16 +307,16 @@ var Test = { editor.moveLinesDown(); assert.equal(["11", "33", "22", "44"].join("\n"), session.toString()); - assert.position(editor.getCursorPosition(), 2, 0); + assert.position(editor.getCursorPosition(), 2, 1); editor.clearSelection(); editor.moveLinesUp(); assert.equal(["11", "22", "33", "44"].join("\n"), session.toString()); - assert.position(editor.getCursorPosition(), 1, 0); + assert.position(editor.getCursorPosition(), 1, 1); }, - "test: copy lines down should select lines and place cursor at the selection start" : function() { + "test: copy lines down should keep selection" : function() { var session = new EditSession(["11", "22", "33", "44"].join("\n")); var editor = new Editor(new MockRenderer(), session); @@ -321,12 +326,12 @@ var Test = { editor.copyLinesDown(); assert.equal(["11", "22", "33", "22", "33", "44"].join("\n"), session.toString()); - assert.position(editor.getCursorPosition(), 3, 0); - assert.position(editor.getSelection().getSelectionAnchor(), 5, 0); - assert.position(editor.getSelection().getSelectionLead(), 3, 0); + assert.position(editor.getCursorPosition(), 4, 1); + assert.position(editor.getSelection().getSelectionAnchor(), 3, 1); + assert.position(editor.getSelection().getSelectionLead(), 4, 1); }, - "test: copy lines up should select lines and place cursor at the selection start" : function() { + "test: copy lines up should keep selection" : function() { var session = new EditSession(["11", "22", "33", "44"].join("\n")); var editor = new Editor(new MockRenderer(), session); @@ -336,9 +341,9 @@ var Test = { editor.copyLinesUp(); assert.equal(["11", "22", "33", "22", "33", "44"].join("\n"), session.toString()); - assert.position(editor.getCursorPosition(), 1, 0); - assert.position(editor.getSelection().getSelectionAnchor(), 3, 0); - assert.position(editor.getSelection().getSelectionLead(), 1, 0); + assert.position(editor.getCursorPosition(), 2, 1); + assert.position(editor.getSelection().getSelectionAnchor(), 1, 1); + assert.position(editor.getSelection().getSelectionLead(), 2, 1); }, "test: input a tab with soft tab should convert it to spaces" : function() { @@ -377,33 +382,32 @@ var Test = { editor.removeLines(); var step1 = session.toString(); assert.equal(step1, "222\n333"); - session.$informUndoManager.call(); + session.$syncInformUndoManager(); editor.removeLines(); var step2 = session.toString(); assert.equal(step2, "333"); - session.$informUndoManager.call(); + session.$syncInformUndoManager(); editor.removeLines(); var step3 = session.toString(); assert.equal(step3, ""); - session.$informUndoManager.call(); - + session.$syncInformUndoManager(); undoManager.undo(); - session.$informUndoManager.call(); + session.$syncInformUndoManager(); assert.equal(session.toString(), step2); undoManager.undo(); - session.$informUndoManager.call(); + session.$syncInformUndoManager(); assert.equal(session.toString(), step1); undoManager.undo(); - session.$informUndoManager.call(); + session.$syncInformUndoManager(); assert.equal(session.toString(), initialText); undoManager.undo(); - session.$informUndoManager.call(); + session.$syncInformUndoManager(); assert.equal(session.toString(), initialText); }, @@ -412,7 +416,7 @@ var Test = { var editor = new Editor(new MockRenderer(), session); editor.moveCursorTo(1, 1); - editor.removeLeft(); + editor.remove("left"); assert.equal(session.toString(), "123\n56"); }, @@ -421,7 +425,7 @@ var Test = { var editor = new Editor(new MockRenderer(), session); editor.moveCursorTo(1, 0); - editor.removeLeft(); + editor.remove("left"); assert.equal(session.toString(), "123456"); }, @@ -432,7 +436,7 @@ var Test = { var editor = new Editor(new MockRenderer(), session); editor.moveCursorTo(1, 8); - editor.removeLeft(); + editor.remove("left"); assert.equal(session.toString(), "123\n 456"); }, @@ -483,14 +487,71 @@ var Test = { var editor = new Editor(new MockRenderer(), session); editor.moveCursorTo(1, 2); editor.transposeLetters(); - assert.position(editor.getCursorPosition(), 1, 3); + assert.position(editor.getCursorPosition(), 1, 3); + }, + + "test: remove to line end": function() { + var session = new EditSession(["123", "4567", "89"]); + + var editor = new Editor(new MockRenderer(), session); + editor.moveCursorTo(1, 2); + editor.removeToLineEnd(); + assert.equal(session.getValue(), ["123", "45", "89"].join("\n")); + }, + + "test: remove to line end at line end should remove the new line": function() { + var session = new EditSession(["123", "4567", "89"]); + + var editor = new Editor(new MockRenderer(), session); + editor.moveCursorTo(1, 4); + editor.removeToLineEnd(); + assert.position(editor.getCursorPosition(), 1, 4); + assert.equal(session.getValue(), ["123", "456789"].join("\n")); + }, + + "test: transform selection to uppercase": function() { + var session = new EditSession(["ajax", "dot", "org"]); + + var editor = new Editor(new MockRenderer(), session); + editor.moveCursorTo(1, 0); + editor.getSelection().selectLineEnd(); + editor.toUpperCase() + assert.equal(session.getValue(), ["ajax", "DOT", "org"].join("\n")); + }, + + "test: transform word to uppercase": function() { + var session = new EditSession(["ajax", "dot", "org"]); + + var editor = new Editor(new MockRenderer(), session); + editor.moveCursorTo(1, 0); + editor.toUpperCase() + assert.equal(session.getValue(), ["ajax", "DOT", "org"].join("\n")); + assert.position(editor.getCursorPosition(), 1, 0); + }, + + "test: transform selection to lowercase": function() { + var session = new EditSession(["AJAX", "DOT", "ORG"]); + + var editor = new Editor(new MockRenderer(), session); + editor.moveCursorTo(1, 0); + editor.getSelection().selectLineEnd(); + editor.toLowerCase() + assert.equal(session.getValue(), ["AJAX", "dot", "ORG"].join("\n")); + }, + + "test: transform word to lowercase": function() { + var session = new EditSession(["AJAX", "DOT", "ORG"]); + + var editor = new Editor(new MockRenderer(), session); + editor.moveCursorTo(1, 0); + editor.toLowerCase() + assert.equal(session.getValue(), ["AJAX", "dot", "ORG"].join("\n")); + assert.position(editor.getCursorPosition(), 1, 0); } }; -module.exports = require("asyncjs/test").testcase(Test); }); if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec(); + require("asyncjs").test.testcase(module.exports).exec() } diff --git a/lib/ace/ext/beautify.js b/lib/ace/ext/beautify.js new file mode 100644 index 00000000..d0fa1799 --- /dev/null +++ b/lib/ace/ext/beautify.js @@ -0,0 +1,57 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +// [WIP] + +define(function(require, exports, module) { +"use strict"; +var TokenIterator = require("ace/token_iterator").TokenIterator; + +var phpTransform = require("./beautify/php_rules").transform; + +exports.beautify = function(session) { + var iterator = new TokenIterator(session, 0, 0); + var token = iterator.getCurrentToken(); + + var context = session.$modeId.split("/").pop(); + + var code = phpTransform(iterator, context); + session.doc.setValue(code); +}; + +exports.commands = [{ + name: "beautify", + exec: function(editor) { + exports.beautify(editor.session); + }, + bindKey: "Ctrl-Shift-B" +}] + +}); \ No newline at end of file diff --git a/lib/ace/ext/beautify/php_rules.js b/lib/ace/ext/beautify/php_rules.js new file mode 100644 index 00000000..9a5bed36 --- /dev/null +++ b/lib/ace/ext/beautify/php_rules.js @@ -0,0 +1,366 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; +var TokenIterator = require("ace/token_iterator").TokenIterator; +exports.newLines = [{ + type: 'support.php_tag', + value: '' +}, { + type: 'paren.lparen', + value: '{', + indent: true +}, { + type: 'paren.rparen', + breakBefore: true, + value: '}', + indent: false +}, { + type: 'paren.rparen', + breakBefore: true, + value: '})', + indent: false, + dontBreak: true +}, { + type: 'comment' +}, { + type: 'text', + value: ';' +}, { + type: 'text', + value: ':', + context: 'php' +}, { + type: 'keyword', + value: 'case', + indent: true, + dontBreak: true +}, { + type: 'keyword', + value: 'default', + indent: true, + dontBreak: true +}, { + type: 'keyword', + value: 'break', + indent: false, + dontBreak: true +}, { + type: 'punctuation.doctype.end', + value: '>' +}, { + type: 'meta.tag.punctuation.end', + value: '>' +}, { + type: 'meta.tag.punctuation.begin', + value: '<', + blockTag: true, + indent: true, + dontBreak: true +}, { + type: 'meta.tag.punctuation.begin', + value: '' ){ + context = 'php'; + } + else if( token.type == 'support.php_tag' && token.value == '?>' ){ + context = 'html'; + } + //css + else if( token.type == 'meta.tag.name.style' && context != 'css' ){ + context = 'css'; + } + else if( token.type == 'meta.tag.name.style' && context == 'css' ){ + context = 'html'; + } + //js + else if( token.type == 'meta.tag.name.script' && context != 'js' ){ + context = 'js'; + } + else if( token.type == 'meta.tag.name.script' && context == 'js' ){ + context = 'html'; + } + + nextToken = iterator.stepForward(); + + //tag name + if (nextToken && nextToken.type.indexOf('meta.tag.name') == 0) { + nextTag = nextToken.value; + } + + //don't linebreak + if ( lastToken.type == 'support.php_tag' && lastToken.value == '' ) { + dontBreak = false; + } + + //next token + lastTag = tag; + + lastToken = token; + + token = nextToken; + + if (token===null) { + break; + } + } + + return code; +}; + + + +}); \ No newline at end of file diff --git a/lib/ace/ext/chromevox.js b/lib/ace/ext/chromevox.js new file mode 100644 index 00000000..52a180d4 --- /dev/null +++ b/lib/ace/ext/chromevox.js @@ -0,0 +1,979 @@ +define(function(require, exports, module) { + +/* ChromeVox Ace namespace. */ +var cvoxAce = {}; + +/* Typedefs for Closure compiler. */ +/** + * @typedef {{ + rate: number, + pitch: number, + volume: number, + relativePitch: number, + punctuationEcho: string + }} + */ +/* TODO(peterxiao): Export this typedef through cvox.Api. */ +cvoxAce.SpeechProperty; + +/** + * @typedef {{ + * row: number, + * column: number + * }} + */ +cvoxAce.Cursor; + +/** + * @typedef {{ + type: string, + value: string + }} + } + */ +cvoxAce.Token; + +/** + * These are errors and information that Ace will display in the gutter. + * @typedef {{ + row: number, + column: number, + value: string + }} + } + */ +cvoxAce.Annotation; + +/* Speech Properties. */ +/** + * Speech property for speaking constant tokens. + * @type {cvoxAce.SpeechProperty} + */ +var CONSTANT_PROP = { + 'rate': 0.8, + 'pitch': 0.4, + 'volume': 0.9 +}; + +/** + * Default speech property for speaking tokens. + * @type {cvoxAce.SpeechProperty} + */ +var DEFAULT_PROP = { + 'rate': 1, + 'pitch': 0.5, + 'volume': 0.9 +}; + +/** + * Speech property for speaking entity tokens. + * @type {cvoxAce.SpeechProperty} + */ +var ENTITY_PROP = { + 'rate': 0.8, + 'pitch': 0.8, + 'volume': 0.9 +}; + +/** + * Speech property for speaking keywords. + * @type {cvoxAce.SpeechProperty} + */ +var KEYWORD_PROP = { + 'rate': 0.8, + 'pitch': 0.3, + 'volume': 0.9 +}; + +/** + * Speech property for speaking storage tokens. + * @type {cvoxAce.SpeechProperty} + */ +var STORAGE_PROP = { + 'rate': 0.8, + 'pitch': 0.7, + 'volume': 0.9 +}; + +/** + * Speech property for speaking variable tokens. + * @type {cvoxAce.SpeechProperty} + */ +var VARIABLE_PROP = { + 'rate': 0.8, + 'pitch': 0.8, + 'volume': 0.9 +}; + +/** + * Speech property for speaking deleted text. + * @type {cvoxAce.SpeechProperty} + */ +var DELETED_PROP = { + 'punctuationEcho': 'none', + 'relativePitch': -0.6 +}; + +/* Constants for Earcons. */ +var ERROR_EARCON = 'ALERT_NONMODAL'; +var MODE_SWITCH_EARCON = 'ALERT_MODAL'; +var NO_MATCH_EARCON = 'INVALID_KEYPRESS'; + +/* Constants for vim state. */ +var INSERT_MODE_STATE = 'insertMode'; +var COMMAND_MODE_STATE = 'start'; + +var REPLACE_LIST = [ + { + substr: ';', + newSubstr: ' semicolon ' + }, + { + substr: ':', + newSubstr: ' colon ' + } +]; + +/** + * Context menu commands. + */ +var Command = { + SPEAK_ANNOT: 'annots', + SPEAK_ALL_ANNOTS: 'all_annots', + TOGGLE_LOCATION: 'toggle_location', + SPEAK_MODE: 'mode', + SPEAK_ROW_COL: 'row_col', + TOGGLE_DISPLACEMENT: 'toggle_displacement', + FOCUS_TEXT: 'focus_text' +}; + +/** + * Key prefix for each shortcut. + */ +var KEY_PREFIX = 'CONTROL + SHIFT '; + +/* Globals. */ +cvoxAce.editor = null; +/** + * Last cursor position. + * @type {cvoxAce.Cursor} + */ +var lastCursor = null; + +/** + * Table of annotations. + * @typedef {!Object.>} + */ +var annotTable = {}; + +/** + * Whether to speak character, word, and then line. This allows blind users + * to know the location of the cursor when they change lines. + * @typedef {boolean} + */ +var shouldSpeakRowLocation = false; + +/** + * Whether to speak displacement. + * @typedef {boolean} + */ +var shouldSpeakDisplacement = false; + +/** + * Whether text was changed to cause a cursor change event. + * @typedef {boolean} + */ +var changed = false; + +/** + * Current state vim is in. + */ +var vimState = null; + +/** + * Mapping from key code to shortcut. + */ +var keyCodeToShortcutMap = {}; + +/** + * Mapping from command to shortcut. + */ +var cmdToShortcutMap = {}; + +/** + * Get shortcut string from keyCode. + * @param {number} keyCode Key code of shortcut. + * @return {string} String representation of shortcut. + */ +var getKeyShortcutString = function(keyCode) { + return KEY_PREFIX + String.fromCharCode(keyCode); +}; + +/** + * Return if in vim mode. + * @return {boolean} True if in Vim mode. + */ +var isVimMode = function() { + var keyboardHandler = cvoxAce.editor.keyBinding.getKeyboardHandler(); + return keyboardHandler.$id === 'ace/keyboard/vim'; +}; + +/** + * Gets the current token. + * @param {!cvoxAce.Cursor} cursor Current position of the cursor. + * @return {!cvoxAce.Token} Token at the current position. + */ +var getCurrentToken = function(cursor) { + return cvoxAce.editor.getSession().getTokenAt(cursor.row, cursor.column + 1); +}; + +/** + * Gets the current line the cursor is under. + * @param {!cvoxAce.Cursor} cursor Current cursor position. + */ +var getCurrentLine = function(cursor) { + return cvoxAce.editor.getSession().getLine(cursor.row); +}; + +/** + * Event handler for row changes. When the user changes rows we want to speak + * the line so the user can work on this line. If shouldSpeakRowLocation is on + * then we speak the character, then the row, then the line so the user knows + * where the cursor is. + * @param {!cvoxAce.Cursor} currCursor Current cursor position. + */ +var onRowChange = function(currCursor) { + /* Notify that this line has an annotation. */ + if (annotTable[currCursor.row]) { + cvox.Api.playEarcon(ERROR_EARCON); + } + if (shouldSpeakRowLocation) { + cvox.Api.stop(); + speakChar(currCursor); + speakTokenQueue(getCurrentToken(currCursor)); + speakLine(currCursor.row, 1); + } else { + speakLine(currCursor.row, 0); + } +}; + +/** + * Returns whether the cursor is at the beginning of a word. A word is + * a grouping of alphanumeric characters including underscores. + * @param {!cvoxAce.Cursor} cursor Current cursor position. + * @return {boolean} Whether there is word. + */ +var isWord = function(cursor) { + var line = getCurrentLine(cursor); + var lineSuffix = line.substr(cursor.column - 1); + if (cursor.column === 0) { + lineSuffix = ' ' + line; + } + /* Use regex to tell if the suffix is at the start of a new word. */ + var firstWordRegExp = /^\W(\w+)/; + var words = firstWordRegExp.exec(lineSuffix); + return words !== null; +}; + +/** + * A mapping of syntax type to speech properties / expanding rules. + */ +var rules = { + 'constant': { + prop: CONSTANT_PROP + }, + 'entity': { + prop: ENTITY_PROP + }, + 'keyword': { + prop: KEYWORD_PROP + }, + 'storage': { + prop: STORAGE_PROP + }, + 'variable': { + prop: VARIABLE_PROP + }, + 'meta': { + prop: DEFAULT_PROP, + replace: [ + { + substr: '', + newSubstr: ' close tag ' + }, + { + substr: '<', + newSubstr: ' tag start ' + }, + { + substr: '>', + newSubstr: ' tag end ' + } + ] + } +}; + +/** + * Default rule to be used. + */ +var DEFAULT_RULE = { + prop: DEFAULT_RULE +}; + +/** + * Expands substrings to how they are read based on the given rules. + * @param {string} value Text to be expanded. + * @param {Array.} replaceRules Rules to determine expansion. + * @return {string} New expanded value. + */ +var expand = function(value, replaceRules) { + var newValue = value; + for (var i = 0; i < replaceRules.length; i++) { + var replaceRule = replaceRules[i]; + var regexp = new RegExp(replaceRule.substr, 'g'); + newValue = newValue.replace(regexp, replaceRule.newSubstr); + } + return newValue; +}; + +/** + * Merges tokens from start inclusive to end exclusive. + * @param {Array.} Tokens to be merged. + * @param {number} start Start index inclusive. + * @param {number} end End index exclusive. + * @return {cvoxAce.Token} Merged token. + */ +var mergeTokens = function(tokens, start, end) { + /* Different type of token found! Merge all previous like tokens. */ + var newToken = {}; + newToken.value = ''; + newToken.type = tokens[start].type; + for (var j = start; j < end; j++) { + newToken.value += tokens[j].value; + } + return newToken; +}; + +/** + * Merges tokens that use the same speech properties. + * @param {Array.} tokens Tokens to be merged. + * @return {Array.} Merged tokens. + */ +var mergeLikeTokens = function(tokens) { + if (tokens.length <= 1) { + return tokens; + } + var newTokens = []; + var lastLikeIndex = 0; + for (var i = 1; i < tokens.length; i++) { + var lastLikeToken = tokens[lastLikeIndex]; + var currToken = tokens[i]; + if (getTokenRule(lastLikeToken) !== getTokenRule(currToken)) { + newTokens.push(mergeTokens(tokens, lastLikeIndex, i)); + lastLikeIndex = i; + } + } + newTokens.push(mergeTokens(tokens, lastLikeIndex, tokens.length)); + return newTokens; +}; + +/** + * Returns if given row is a whitespace row. + * @param {number} row Row. + * @return {boolean} True if row is whitespaces. + */ +var isRowWhiteSpace = function(row) { + var line = cvoxAce.editor.getSession().getLine(row); + var whiteSpaceRegexp = /^\s*$/; + return whiteSpaceRegexp.exec(line) !== null; +}; + +/** + * Speak the line with syntax properties. + * @param {number} row Row to speak. + * @param {number} queue Queue mode to speak. + */ +var speakLine = function(row, queue) { + var tokens = cvoxAce.editor.getSession().getTokens(row); + if (tokens.length === 0 || isRowWhiteSpace(row)) { + cvox.Api.playEarcon('EDITABLE_TEXT'); + return; + } + tokens = mergeLikeTokens(tokens); + var firstToken = tokens[0]; + /* Filter out first token. */ + tokens = tokens.filter(function(token) { + return token !== firstToken; + }); + /* Speak first token separately to flush if queue. */ + speakToken_(firstToken, queue); + /* Speak rest of tokens. */ + tokens.forEach(speakTokenQueue); +}; + +/** + * Speak the token based on the syntax of the token, flushing. + * @param {!cvoxAce.Token} token Token to speak. + * @param {number} queue Queue mode. + */ +var speakTokenFlush = function(token) { + speakToken_(token, 0); +}; + +/** + * Speak the token based on the syntax of the token, queueing. + * @param {!cvoxAce.Token} token Token to speak. + * @param {number} queue Queue mode. + */ +var speakTokenQueue = function(token) { + speakToken_(token, 1); +}; + +/** + * @param {!cvoxAce.Token} token Token to speak. + * Get the token speech property. + */ +var getTokenRule = function(token) { + /* Types are period delimited. In this case, we only syntax speak the outer + * most type of token. */ + if (!token || !token.type) { + return; + } + var split = token.type.split('.'); + if (split.length === 0) { + return; + } + var type = split[0]; + var rule = rules[type]; + if (!rule) { + return DEFAULT_RULE; + } + return rule; +}; + +/** + * Speak the token based on the syntax of the token. + * @private + * @param {!cvoxAce.Token} token Token to speak. + * @param {number} queue Queue mode. + */ +var speakToken_ = function(token, queue) { + var rule = getTokenRule(token); + var value = expand(token.value, REPLACE_LIST); + if (rule.replace) { + value = expand(value, rule.replace); + } + cvox.Api.speak(value, queue, rule.prop); +}; + +/** + * Speaks the character under the cursor. This is queued. + * @param {!cvoxAce.Cursor} cursor Current cursor position. + * @return {string} Character. + */ +var speakChar = function(cursor) { + var line = getCurrentLine(cursor); + cvox.Api.speak(line[cursor.column], 1); +}; + +/** + * Speaks the jump from lastCursor to currCursor. This function assumes the + * jump takes place on the current line. + * @param {!cvoxAce.Cursor} lastCursor Previous cursor position. + * @param {!cvoxAce.Cursor} currCursor Current cursor position. + */ +var speakDisplacement = function(lastCursor, currCursor) { + var line = getCurrentLine(currCursor); + + /* Get the text that we jumped past. */ + var displace = line.substring(lastCursor.column, currCursor.column); + + /* Speak out loud spaces. */ + displace = displace.replace(/ /g, ' space '); + cvox.Api.speak(displace); +}; + +/** + * Speaks the word if the cursor jumped to a new word or to the beginning + * of the line. Otherwise speak the charactor. + * @param {!cvoxAce.Cursor} lastCursor Previous cursor position. + * @param {!cvoxAce.Cursor} currCursor Current cursor position. + */ +var speakCharOrWordOrLine = function(lastCursor, currCursor) { + /* Say word only if jump. */ + if (Math.abs(lastCursor.column - currCursor.column) !== 1) { + var currLineLength = getCurrentLine(currCursor).length; + /* Speak line if jumping to beginning or end of line. */ + if (currCursor.column === 0 || currCursor.column === currLineLength) { + speakLine(currCursor.row, 0); + return; + } + if (isWord(currCursor)) { + cvox.Api.stop(); + speakTokenQueue(getCurrentToken(currCursor)); + return; + } + } + speakChar(currCursor); +}; + +/** + * Event handler for column changes. If shouldSpeakDisplacement is on, then + * we just speak displacements in row changes. Otherwise, we either speak + * the character for single character movements, the word when jumping to the + * next word, or the entire line if jumping to beginning or end of the line. + * @param {!cvoxAce.Cursor} lastCursor Previous cursor position. + * @param {!cvoxAce.Cursor} currCursor Current cursor position. + */ +var onColumnChange = function(lastCursor, currCursor) { + if (!cvoxAce.editor.selection.isEmpty()) { + speakDisplacement(lastCursor, currCursor); + cvox.Api.speak('selected', 1); + } + else if (shouldSpeakDisplacement) { + speakDisplacement(lastCursor, currCursor); + } else { + speakCharOrWordOrLine(lastCursor, currCursor); + } +}; + +/** + * Event handler for cursor changes. Classify cursor changes as either row or + * column changes, then delegate accordingly. + * @param {!Event} evt The event. + */ +var onCursorChange = function(evt) { + /* Do not speak if cursor change was a result of text insertion. We want to + * speak the text that was inserted and not where the cursor lands. */ + if (changed) { + changed = false; + return; + } + var currCursor = cvoxAce.editor.selection.getCursor(); + if (currCursor.row !== lastCursor.row) { + onRowChange(currCursor); + } else { + onColumnChange(lastCursor, currCursor); + } + lastCursor = currCursor; +}; + +/** + * Event handler for selection changes. + * @param {!Event} evt The event. + */ +var onSelectionChange = function(evt) { + /* Assumes that when selection changes to empty, the user has unselected. */ + if (cvoxAce.editor.selection.isEmpty()) { + cvox.Api.speak('unselected'); + } +}; + +/** + * Event handler for source changes. We want auditory feedback for inserting + * and deleting text. + * @param {!Event} evt The event. + */ +var onChange = function(delta) { + switch (data.action) { + case 'remove': + cvox.Api.speak(data.text, 0, DELETED_PROP); + /* Let the future cursor change event know it's from text change. */ + changed = true; + break; + case 'insert': + cvox.Api.speak(data.text, 0); + /* Let the future cursor change event know it's from text change. */ + changed = true; + break; + } +}; + +/** + * Returns whether or not the annotation is new. + * @param {!cvoxAce.Annotation} annot Annotation in question. + * @return {boolean} Whether annot is new. + */ +var isNewAnnotation = function(annot) { + var row = annot.row; + var col = annot.column; + return !annotTable[row] || !annotTable[row][col]; +}; + +/** + * Populates the annotation table. + * @param {!Array.} annotations Array of annotations. + */ +var populateAnnotations = function(annotations) { + annotTable = {}; + for (var i = 0; i < annotations.length; i++) { + var annotation = annotations[i]; + var row = annotation.row; + var col = annotation.column; + if (!annotTable[row]) { + annotTable[row] = {}; + } + annotTable[row][col] = annotation; + } +}; + +/** + * Event handler for annotation changes. We want to notify the user when an + * a new annotation appears. + * @param {!Event} evt Event. + */ +var onAnnotationChange = function(evt) { + var annotations = cvoxAce.editor.getSession().getAnnotations(); + var newAnnotations = annotations.filter(isNewAnnotation); + if (newAnnotations.length > 0) { + cvox.Api.playEarcon(ERROR_EARCON); + } + populateAnnotations(annotations); +}; + +/** + * Speak annotation. + * @param {!cvoxAce.Annotation} annot Annotation to speak. + */ +var speakAnnot = function(annot) { + var annotText = annot.type + ' ' + annot.text + ' on ' + + rowColToString(annot.row, annot.column); + annotText = annotText.replace(';', 'semicolon'); + cvox.Api.speak(annotText, 1); +}; + +/** + * Speak annotations in a row. + * @param {number} row Row of annotations to speak. + */ +var speakAnnotsByRow = function(row) { + var annots = annotTable[row]; + for (var col in annots) { + speakAnnot(annots[col]); + } +}; + +/** + * Get a string representation of a row and column. + * @param {boolean} row Zero indexed row. + * @param {boolean} col Zero indexed column. + * @return {string} Row and column to be spoken. + */ +var rowColToString = function(row, col) { + return 'row ' + (row + 1) + ' column ' + (col + 1); +}; + +/** + * Speaks the row and column. + */ +var speakCurrRowAndCol = function() { + cvox.Api.speak(rowColToString(lastCursor.row, lastCursor.column)); +}; + +/** + * Speaks all annotations. + */ +var speakAllAnnots = function() { + for (var row in annotTable) { + speakAnnotsByRow(row); + } +}; + +/** + * Speak the vim mode. If no vim mode, this function does nothing. + */ +var speakMode = function() { + if (!isVimMode()) { + return; + } + switch (cvoxAce.editor.keyBinding.$data.state) { + case INSERT_MODE_STATE: + cvox.Api.speak('Insert mode'); + break; + case COMMAND_MODE_STATE: + cvox.Api.speak('Command mode'); + break; + } +}; + +/** + * Toggle speak location. + */ +var toggleSpeakRowLocation = function() { + shouldSpeakRowLocation = !shouldSpeakRowLocation; + /* Auditory feedback of the change. */ + if (shouldSpeakRowLocation) { + cvox.Api.speak('Speak location on row change enabled.'); + } else { + cvox.Api.speak('Speak location on row change disabled.'); + } +}; + +/** + * Toggle speak displacement. + */ +var toggleSpeakDisplacement = function() { + shouldSpeakDisplacement = !shouldSpeakDisplacement; + /* Auditory feedback of the change. */ + if (shouldSpeakDisplacement) { + cvox.Api.speak('Speak displacement on column changes.'); + } else { + cvox.Api.speak('Speak current character or word on column changes.'); + } +}; + +/** + * Event handler for key down events. Gets the right shortcut from the map, + * and calls the associated function. + * @param {!Event} evt Keyboard event. + */ +var onKeyDown = function(evt) { + if (evt.ctrlKey && evt.shiftKey) { + var shortcut = keyCodeToShortcutMap[evt.keyCode]; + if (shortcut) { + shortcut.func(); + } + } +}; + +/** + * Event handler for status change events. Auditory feedback of changing + * between vim states. + * @param {!Event} evt Change status event. + * @param {!Object} editor Editor state. + */ +var onChangeStatus = function(evt, editor) { + if (!isVimMode()) { + return; + } + var state = editor.keyBinding.$data.state; + if (state === vimState) { + /* State hasn't changed, do nothing. */ + return; + } + switch (state) { + case INSERT_MODE_STATE: + cvox.Api.playEarcon(MODE_SWITCH_EARCON); + /* When in insert mode, we want to speak out keys as feedback. */ + cvox.Api.setKeyEcho(true); + break; + case COMMAND_MODE_STATE: + cvox.Api.playEarcon(MODE_SWITCH_EARCON); + /* When in command mode, we want don't speak out keys because those keys + * are not being inserted in the document. */ + cvox.Api.setKeyEcho(false); + break; + } + vimState = state; +}; + +/** + * Handles context menu events. This is a ChromeVox feature where hitting + * the shortcut ChromeVox + comma will open up a search bar where you can + * type in various commands. All keyboard shortcuts are also commands that + * can be invoked. This handles the event that ChromeVox sends to the page. + * @param {Event} evt Event received. + */ +var contextMenuHandler = function(evt) { + var cmd = evt.detail['customCommand']; + var shortcut = cmdToShortcutMap[cmd]; + if (shortcut) { + shortcut.func(); + /* ChromeVox will bring focus to an element near the cursor instead of the + * text input. */ + cvoxAce.editor.focus(); + } +}; + +/** + * Initialize the ChromeVox context menu. + */ +var initContextMenu = function() { + var ACTIONS = SHORTCUTS.map(function(shortcut) { + return { + desc: shortcut.desc + getKeyShortcutString(shortcut.keyCode), + cmd: shortcut.cmd + }; + }); + + /* Attach ContextMenuActions. */ + var body = document.querySelector('body'); + body.setAttribute('contextMenuActions', JSON.stringify(ACTIONS)); + + /* Listen for ContextMenu events. */ + body.addEventListener('ATCustomEvent', contextMenuHandler, true); +}; + +/** + * Event handler for find events. When there is a match, we want to speak the + * line we are now at. Otherwise, we want to notify the user there was no + * match + * @param {!Event} evt The event. + */ +var onFindSearchbox = function(evt) { + if (evt.match) { + /* There is still a match! Speak the line. */ + speakLine(lastCursor.row, 0); + } else { + /* No match, give auditory feedback! */ + cvox.Api.playEarcon(NO_MATCH_EARCON); + } +}; + +/** + * Focus to text input. + */ +var focus = function() { + cvoxAce.editor.focus(); +}; + +/** + * Shortcut definitions. + */ +var SHORTCUTS = [ + { + /* 1 key. */ + keyCode: 49, + func: function() { + speakAnnotsByRow(lastCursor.row); + }, + cmd: Command.SPEAK_ANNOT, + desc: 'Speak annotations on line' + }, + { + /* 2 key. */ + keyCode: 50, + func: speakAllAnnots, + cmd: Command.SPEAK_ALL_ANNOTS, + desc: 'Speak all annotations' + }, + { + /* 3 key. */ + keyCode: 51, + func: speakMode, + cmd: Command.SPEAK_MODE, + desc: 'Speak Vim mode' + }, + { + /* 4 key. */ + keyCode: 52, + func: toggleSpeakRowLocation, + cmd: Command.TOGGLE_LOCATION, + desc: 'Toggle speak row location' + }, + { + /* 5 key. */ + keyCode: 53, + func: speakCurrRowAndCol, + cmd: Command.SPEAK_ROW_COL, + desc: 'Speak row and column' + }, + { + /* 6 key. */ + keyCode: 54, + func: toggleSpeakDisplacement, + cmd: Command.TOGGLE_DISPLACEMENT, + desc: 'Toggle speak displacement' + }, + { + /* 7 key. */ + keyCode: 55, + func: focus, + cmd: Command.FOCUS_TEXT, + desc: 'Focus text' + } +]; + +/** + * Event handler for focus events. + */ +var onFocus = function() { + cvoxAce.editor = editor; + + /* Set up listeners. */ + editor.getSession().selection.on('changeCursor', onCursorChange); + editor.getSession().selection.on('changeSelection', onSelectionChange); + editor.getSession().on('change', onChange); + editor.getSession().on('changeAnnotation', onAnnotationChange); + editor.on('changeStatus', onChangeStatus); + editor.on('findSearchBox', onFindSearchbox); + editor.container.addEventListener('keydown', onKeyDown); + + lastCursor = editor.selection.getCursor(); +}; + +/** + * Initialize the theme. + * @param {Object} editor Editor to use. + */ +var init = function(editor) { + onFocus(); + + /* Construct maps. */ + SHORTCUTS.forEach(function(shortcut) { + keyCodeToShortcutMap[shortcut.keyCode] = shortcut; + cmdToShortcutMap[shortcut.cmd] = shortcut; + }); + + editor.on('focus', onFocus); + + /* Assume we start in command mode if vim. */ + if (isVimMode()) { + cvox.Api.setKeyEcho(false); + } + initContextMenu(); +}; + +/** + * Returns if cvox exists, and the api exists. + * @return {boolean} Whether not Cvox Api exists. + */ +function cvoxApiExists() { + return (typeof(cvox) !== 'undefined') && cvox && cvox.Api; +} + +/** + * Number of tries for Cvox loading. + * @type {number} + */ +var tries = 0; + +/** + * Max number of tries to watch for Cvox loading. + * @type {number} + */ +var MAX_TRIES = 15; + +/** + * Check for ChromeVox load. + * @param {Object} editor Editor to use. + */ +function watchForCvoxLoad(editor) { + if (cvoxApiExists()) { + init(editor); + } else { + tries++; + if (tries >= MAX_TRIES) { + return; + } + window.setTimeout(watchForCvoxLoad, 500, editor); + } +} + +var Editor = require('../editor').Editor; +require('../config').defineOptions(Editor.prototype, 'editor', { + enableChromevoxEnhancements: { + set: function(val) { + if (val) { + watchForCvoxLoad(this); + } + }, + value: true // turn it on by default or check for window.cvox + } +}); + +}); diff --git a/lib/ace/ext/elastic_tabstops_lite.js b/lib/ace/ext/elastic_tabstops_lite.js new file mode 100644 index 00000000..0f89423a --- /dev/null +++ b/lib/ace/ext/elastic_tabstops_lite.js @@ -0,0 +1,318 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var ElasticTabstopsLite = function(editor) { + this.$editor = editor; + var self = this; + var changedRows = []; + var recordChanges = false; + this.onAfterExec = function() { + recordChanges = false; + self.processRows(changedRows); + changedRows = []; + }; + this.onExec = function() { + recordChanges = true; + }; + this.onChange = function(delta) { + if (recordChanges) { + if (changedRows.indexOf(delta.start.row) == -1) + changedRows.push(delta.start.row); + if (delta.end.row != delta.start.row) + changedRows.push(delta.end.row); + } + }; +}; + +(function() { + this.processRows = function(rows) { + this.$inChange = true; + var checkedRows = []; + + for (var r = 0, rowCount = rows.length; r < rowCount; r++) { + var row = rows[r]; + + if (checkedRows.indexOf(row) > -1) + continue; + + var cellWidthObj = this.$findCellWidthsForBlock(row); + var cellWidths = this.$setBlockCellWidthsToMax(cellWidthObj.cellWidths); + var rowIndex = cellWidthObj.firstRow; + + for (var w = 0, l = cellWidths.length; w < l; w++) { + var widths = cellWidths[w]; + checkedRows.push(rowIndex); + this.$adjustRow(rowIndex, widths); + rowIndex++; + } + } + this.$inChange = false; + }; + + this.$findCellWidthsForBlock = function(row) { + var cellWidths = [], widths; + + // starting row and backward + var rowIter = row; + while (rowIter >= 0) { + widths = this.$cellWidthsForRow(rowIter); + if (widths.length == 0) + break; + + cellWidths.unshift(widths); + rowIter--; + } + var firstRow = rowIter + 1; + + // forward (not including starting row) + rowIter = row; + var numRows = this.$editor.session.getLength(); + + while (rowIter < numRows - 1) { + rowIter++; + + widths = this.$cellWidthsForRow(rowIter); + if (widths.length == 0) + break; + + cellWidths.push(widths); + } + + return { cellWidths: cellWidths, firstRow: firstRow }; + }; + + this.$cellWidthsForRow = function(row) { + var selectionColumns = this.$selectionColumnsForRow(row); + // todo: support multicursor + + var tabs = [-1].concat(this.$tabsForRow(row)); + var widths = tabs.map(function(el) { return 0; } ).slice(1); + var line = this.$editor.session.getLine(row); + + for (var i = 0, len = tabs.length - 1; i < len; i++) { + var leftEdge = tabs[i]+1; + var rightEdge = tabs[i+1]; + + var rightmostSelection = this.$rightmostSelectionInCell(selectionColumns, rightEdge); + var cell = line.substring(leftEdge, rightEdge); + widths[i] = Math.max(cell.replace(/\s+$/g,'').length, rightmostSelection - leftEdge); + } + + return widths; + }; + + this.$selectionColumnsForRow = function(row) { + var selections = [], cursor = this.$editor.getCursorPosition(); + if (this.$editor.session.getSelection().isEmpty()) { + // todo: support multicursor + if (row == cursor.row) + selections.push(cursor.column); + } + + return selections; + }; + + this.$setBlockCellWidthsToMax = function(cellWidths) { + var startingNewBlock = true, blockStartRow, blockEndRow, maxWidth; + var columnInfo = this.$izip_longest(cellWidths); + + for (var c = 0, l = columnInfo.length; c < l; c++) { + var column = columnInfo[c]; + if (!column.push) { + console.error(column); + continue; + } + // add an extra None to the end so that the end of the column automatically + // finishes a block + column.push(NaN); + + for (var r = 0, s = column.length; r < s; r++) { + var width = column[r]; + if (startingNewBlock) { + blockStartRow = r; + maxWidth = 0; + startingNewBlock = false; + } + if (isNaN(width)) { + // block ended + blockEndRow = r; + + for (var j = blockStartRow; j < blockEndRow; j++) { + cellWidths[j][c] = maxWidth; + } + startingNewBlock = true; + } + + maxWidth = Math.max(maxWidth, width); + } + } + + return cellWidths; + }; + + this.$rightmostSelectionInCell = function(selectionColumns, cellRightEdge) { + var rightmost = 0; + + if (selectionColumns.length) { + var lengths = []; + for (var s = 0, length = selectionColumns.length; s < length; s++) { + if (selectionColumns[s] <= cellRightEdge) + lengths.push(s); + else + lengths.push(0); + } + rightmost = Math.max.apply(Math, lengths); + } + + return rightmost; + }; + + this.$tabsForRow = function(row) { + var rowTabs = [], line = this.$editor.session.getLine(row), + re = /\t/g, match; + + while ((match = re.exec(line)) != null) { + rowTabs.push(match.index); + } + + return rowTabs; + }; + + this.$adjustRow = function(row, widths) { + var rowTabs = this.$tabsForRow(row); + + if (rowTabs.length == 0) + return; + + var bias = 0, location = -1; + + // this always only contains two elements, so we're safe in the loop below + var expandedSet = this.$izip(widths, rowTabs); + + for (var i = 0, l = expandedSet.length; i < l; i++) { + var w = expandedSet[i][0], it = expandedSet[i][1]; + location += 1 + w; + it += bias; + var difference = location - it; + + if (difference == 0) + continue; + + var partialLine = this.$editor.session.getLine(row).substr(0, it ); + var strippedPartialLine = partialLine.replace(/\s*$/g, ""); + var ispaces = partialLine.length - strippedPartialLine.length; + + if (difference > 0) { + // put the spaces after the tab and then delete the tab, so any insertion + // points behave as expected + this.$editor.session.getDocument().insertInLine({row: row, column: it + 1}, Array(difference + 1).join(" ") + "\t"); + this.$editor.session.getDocument().removeInLine(row, it, it + 1); + + bias += difference; + } + + if (difference < 0 && ispaces >= -difference) { + this.$editor.session.getDocument().removeInLine(row, it + difference, it); + bias += difference; + } + } + }; + + // the is a (naive) Python port--but works for these purposes + this.$izip_longest = function(iterables) { + if (!iterables[0]) + return []; + var longest = iterables[0].length; + var iterablesLength = iterables.length; + + for (var i = 1; i < iterablesLength; i++) { + var iLength = iterables[i].length; + if (iLength > longest) + longest = iLength; + } + + var expandedSet = []; + + for (var l = 0; l < longest; l++) { + var set = []; + for (var i = 0; i < iterablesLength; i++) { + if (iterables[i][l] === "") + set.push(NaN); + else + set.push(iterables[i][l]); + } + + expandedSet.push(set); + } + + + return expandedSet; + }; + + // an even more (naive) Python port + this.$izip = function(widths, tabs) { + // grab the shorter size + var size = widths.length >= tabs.length ? tabs.length : widths.length; + + var expandedSet = []; + for (var i = 0; i < size; i++) { + var set = [ widths[i], tabs[i] ]; + expandedSet.push(set); + } + return expandedSet; + }; + +}).call(ElasticTabstopsLite.prototype); + +exports.ElasticTabstopsLite = ElasticTabstopsLite; + +var Editor = require("../editor").Editor; +require("../config").defineOptions(Editor.prototype, "editor", { + useElasticTabstops: { + set: function(val) { + if (val) { + if (!this.elasticTabstops) + this.elasticTabstops = new ElasticTabstopsLite(this); + this.commands.on("afterExec", this.elasticTabstops.onAfterExec); + this.commands.on("exec", this.elasticTabstops.onExec); + this.on("change", this.elasticTabstops.onChange); + } else if (this.elasticTabstops) { + this.commands.removeListener("afterExec", this.elasticTabstops.onAfterExec); + this.commands.removeListener("exec", this.elasticTabstops.onExec); + this.removeListener("change", this.elasticTabstops.onChange); + } + } + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/ext/emmet.js b/lib/ace/ext/emmet.js new file mode 100644 index 00000000..4faacef2 --- /dev/null +++ b/lib/ace/ext/emmet.js @@ -0,0 +1,434 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; +var HashHandler = require("ace/keyboard/hash_handler").HashHandler; +var Editor = require("ace/editor").Editor; +var snippetManager = require("ace/snippets").snippetManager; +var Range = require("ace/range").Range; +var emmet, emmetPath; + +/** + * Implementation of {@link IEmmetEditor} interface for Ace + */ +function AceEmmetEditor() {} + +AceEmmetEditor.prototype = { + setupContext: function(editor) { + this.ace = editor; + this.indentation = editor.session.getTabString(); + if (!emmet) + emmet = window.emmet; + emmet.require("resources").setVariable("indentation", this.indentation); + this.$syntax = null; + this.$syntax = this.getSyntax(); + }, + /** + * Returns character indexes of selected text: object with start + * and end properties. If there's no selection, should return + * object with start and end properties referring + * to current caret position + * @return {Object} + * @example + * var selection = editor.getSelectionRange(); + * alert(selection.start + ', ' + selection.end); + */ + getSelectionRange: function() { + // TODO should start be caret position instead? + var range = this.ace.getSelectionRange(); + var doc = this.ace.session.doc; + return { + start: doc.positionToIndex(range.start), + end: doc.positionToIndex(range.end) + }; + }, + + /** + * Creates selection from start to end character + * indexes. If end is ommited, this method should place caret + * and start index + * @param {Number} start + * @param {Number} [end] + * @example + * editor.createSelection(10, 40); + * + * //move caret to 15th character + * editor.createSelection(15); + */ + createSelection: function(start, end) { + var doc = this.ace.session.doc; + this.ace.selection.setRange({ + start: doc.indexToPosition(start), + end: doc.indexToPosition(end) + }); + }, + + /** + * Returns current line's start and end indexes as object with start + * and end properties + * @return {Object} + * @example + * var range = editor.getCurrentLineRange(); + * alert(range.start + ', ' + range.end); + */ + getCurrentLineRange: function() { + var ace = this.ace; + var row = ace.getCursorPosition().row; + var lineLength = ace.session.getLine(row).length; + var index = ace.session.doc.positionToIndex({row: row, column: 0}); + return { + start: index, + end: index + lineLength + }; + }, + + /** + * Returns current caret position + * @return {Number|null} + */ + getCaretPos: function(){ + var pos = this.ace.getCursorPosition(); + return this.ace.session.doc.positionToIndex(pos); + }, + + /** + * Set new caret position + * @param {Number} index Caret position + */ + setCaretPos: function(index){ + var pos = this.ace.session.doc.indexToPosition(index); + this.ace.selection.moveToPosition(pos); + }, + + /** + * Returns content of current line + * @return {String} + */ + getCurrentLine: function() { + var row = this.ace.getCursorPosition().row; + return this.ace.session.getLine(row); + }, + + /** + * Replace editor's content or it's part (from start to + * end index). If value contains + * caret_placeholder, the editor will put caret into + * this position. If you skip start and end + * arguments, the whole target's content will be replaced with + * value. + * + * If you pass start argument only, + * the value will be placed at start string + * index of current content. + * + * If you pass start and end arguments, + * the corresponding substring of current target's content will be + * replaced with value. + * @param {String} value Content you want to paste + * @param {Number} [start] Start index of editor's content + * @param {Number} [end] End index of editor's content + * @param {Boolean} [noIndent] Do not auto indent value + */ + replaceContent: function(value, start, end, noIndent) { + if (end == null) + end = start == null ? this.getContent().length : start; + if (start == null) + start = 0; + + var editor = this.ace; + var doc = editor.session.doc; + var range = Range.fromPoints(doc.indexToPosition(start), doc.indexToPosition(end)); + editor.session.remove(range); + + range.end = range.start; + //editor.selection.setRange(range); + + value = this.$updateTabstops(value); + snippetManager.insertSnippet(editor, value); + }, + + /** + * Returns editor's content + * @return {String} + */ + getContent: function(){ + return this.ace.getValue(); + }, + + /** + * Returns current editor's syntax mode + * @return {String} + */ + getSyntax: function() { + if (this.$syntax) + return this.$syntax; + var syntax = this.ace.session.$modeId.split("/").pop(); + if (syntax == "html" || syntax == "php") { + var cursor = this.ace.getCursorPosition(); + var state = this.ace.session.getState(cursor.row); + if (typeof state != "string") + state = state[0]; + if (state) { + state = state.split("-"); + if (state.length > 1) + syntax = state[0]; + else if (syntax == "php") + syntax = "html"; + } + } + return syntax; + }, + + /** + * Returns current output profile name (@see emmet#setupProfile) + * @return {String} + */ + getProfileName: function() { + switch(this.getSyntax()) { + case "css": return "css"; + case "xml": + case "xsl": + return "xml"; + case "html": + var profile = emmet.require("resources").getVariable("profile"); + // no forced profile, guess from content html or xhtml? + if (!profile) + profile = this.ace.session.getLines(0,2).join("").search(/]+XHTML/i) != -1 ? "xhtml": "html"; + return profile; + } + return "xhtml"; + }, + + /** + * Ask user to enter something + * @param {String} title Dialog title + * @return {String} Entered data + * @since 0.65 + */ + prompt: function(title) { + return prompt(title); + }, + + /** + * Returns current selection + * @return {String} + * @since 0.65 + */ + getSelection: function() { + return this.ace.session.getTextRange(); + }, + + /** + * Returns current editor's file path + * @return {String} + * @since 0.65 + */ + getFilePath: function() { + return ""; + }, + + // update tabstops: make sure all caret placeholders are unique + // by default, abbreviation parser generates all unlinked (un-mirrored) + // tabstops as ${0}, so we have upgrade all caret tabstops with unique + // positions but make sure that all other tabstops are not linked accidentally + // based on https://github.com/sergeche/emmet-sublime/blob/master/editor.js#L119-L171 + $updateTabstops: function(value) { + var base = 1000; + var zeroBase = 0; + var lastZero = null; + var range = emmet.require('range'); + var ts = emmet.require('tabStops'); + var settings = emmet.require('resources').getVocabulary("user"); + var tabstopOptions = { + tabstop: function(data) { + var group = parseInt(data.group, 10); + var isZero = group === 0; + if (isZero) + group = ++zeroBase; + else + group += base; + + var placeholder = data.placeholder; + if (placeholder) { + // recursively update nested tabstops + placeholder = ts.processText(placeholder, tabstopOptions); + } + + var result = '${' + group + (placeholder ? ':' + placeholder : '') + '}'; + + if (isZero) { + lastZero = range.create(data.start, result); + } + + return result; + }, + escape: function(ch) { + if (ch == '$') return '\\$'; + if (ch == '\\') return '\\\\'; + return ch; + } + }; + + value = ts.processText(value, tabstopOptions); + + if (settings.variables['insert_final_tabstop'] && !/\$\{0\}$/.test(value)) { + value += '${0}'; + } else if (lastZero) { + value = emmet.require('utils').replaceSubstring(value, '${0}', lastZero); + } + + return value; + } +}; + + +var keymap = { + expand_abbreviation: {"mac": "ctrl+alt+e", "win": "alt+e"}, + match_pair_outward: {"mac": "ctrl+d", "win": "ctrl+,"}, + match_pair_inward: {"mac": "ctrl+j", "win": "ctrl+shift+0"}, + matching_pair: {"mac": "ctrl+alt+j", "win": "alt+j"}, + next_edit_point: "alt+right", + prev_edit_point: "alt+left", + toggle_comment: {"mac": "command+/", "win": "ctrl+/"}, + split_join_tag: {"mac": "shift+command+'", "win": "shift+ctrl+`"}, + remove_tag: {"mac": "command+'", "win": "shift+ctrl+;"}, + evaluate_math_expression: {"mac": "shift+command+y", "win": "shift+ctrl+y"}, + increment_number_by_1: "ctrl+up", + decrement_number_by_1: "ctrl+down", + increment_number_by_01: "alt+up", + decrement_number_by_01: "alt+down", + increment_number_by_10: {"mac": "alt+command+up", "win": "shift+alt+up"}, + decrement_number_by_10: {"mac": "alt+command+down", "win": "shift+alt+down"}, + select_next_item: {"mac": "shift+command+.", "win": "shift+ctrl+."}, + select_previous_item: {"mac": "shift+command+,", "win": "shift+ctrl+,"}, + reflect_css_value: {"mac": "shift+command+r", "win": "shift+ctrl+r"}, + + encode_decode_data_url: {"mac": "shift+ctrl+d", "win": "ctrl+'"}, + // update_image_size: {"mac": "shift+ctrl+i", "win": "ctrl+u"}, + // expand_as_you_type: "ctrl+alt+enter", + // wrap_as_you_type: {"mac": "shift+ctrl+g", "win": "shift+ctrl+g"}, + expand_abbreviation_with_tab: "Tab", + wrap_with_abbreviation: {"mac": "shift+ctrl+a", "win": "shift+ctrl+a"} +}; + +var editorProxy = new AceEmmetEditor(); +exports.commands = new HashHandler(); +exports.runEmmetCommand = function(editor) { + try { + editorProxy.setupContext(editor); + if (editorProxy.getSyntax() == "php") + return false; + var actions = emmet.require("actions"); + + if (this.action == "expand_abbreviation_with_tab") { + if (!editor.selection.isEmpty()) + return false; + } + + if (this.action == "wrap_with_abbreviation") { + // without setTimeout prompt doesn't work on firefox + return setTimeout(function() { + actions.run("wrap_with_abbreviation", editorProxy); + }, 0); + } + + var pos = editor.selection.lead; + var token = editor.session.getTokenAt(pos.row, pos.column); + if (token && /\btag\b/.test(token.type)) + return false; + + var result = actions.run(this.action, editorProxy); + } catch(e) { + editor._signal("changeStatus", typeof e == "string" ? e : e.message); + console.log(e); + result = false; + } + return result; +}; + +for (var command in keymap) { + exports.commands.addCommand({ + name: "emmet:" + command, + action: command, + bindKey: keymap[command], + exec: exports.runEmmetCommand, + multiSelectAction: "forEach" + }); +} + +exports.updateCommands = function(editor, enabled) { + if (enabled) { + editor.keyBinding.addKeyboardHandler(exports.commands); + } else { + editor.keyBinding.removeKeyboardHandler(exports.commands); + } +}; + +exports.isSupportedMode = function(modeId) { + return modeId && /css|less|scss|sass|stylus|html|php|twig|ejs|handlebars/.test(modeId); +}; + +var onChangeMode = function(e, target) { + var editor = target; + if (!editor) + return; + var enabled = exports.isSupportedMode(editor.session.$modeId); + if (e.enableEmmet === false) + enabled = false; + if (enabled) { + if (typeof emmetPath == "string") { + require("ace/config").loadModule(emmetPath, function() { + emmetPath = null; + }); + } + } + exports.updateCommands(editor, enabled); +}; + +exports.AceEmmetEditor = AceEmmetEditor; +require("ace/config").defineOptions(Editor.prototype, "editor", { + enableEmmet: { + set: function(val) { + this[val ? "on" : "removeListener"]("changeMode", onChangeMode); + onChangeMode({enableEmmet: !!val}, this); + }, + value: true + } +}); + +exports.setCore = function(e) { + if (typeof e == "string") + emmetPath = e; + else + emmet = e; +}; +}); + diff --git a/lib/ace/ext/error_marker.js b/lib/ace/ext/error_marker.js new file mode 100644 index 00000000..5dbe3d2e --- /dev/null +++ b/lib/ace/ext/error_marker.js @@ -0,0 +1,214 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; +var LineWidgets = require("../line_widgets").LineWidgets; +var dom = require("../lib/dom"); +var Range = require("../range").Range; + +function binarySearch(array, needle, comparator) { + var first = 0; + var last = array.length - 1; + + while (first <= last) { + var mid = (first + last) >> 1; + var c = comparator(needle, array[mid]); + if (c > 0) + first = mid + 1; + else if (c < 0) + last = mid - 1; + else + return mid; + } + + // Return the nearest lesser index, "-1" means "0, "-2" means "1", etc. + return -(first + 1); +} + +function findAnnotations(session, row, dir) { + var annotations = session.getAnnotations().sort(Range.comparePoints); + if (!annotations.length) + return; + + var i = binarySearch(annotations, {row: row, column: -1}, Range.comparePoints); + if (i < 0) + i = -i - 1; + + if (i >= annotations.length) + i = dir > 0 ? 0 : annotations.length - 1; + else if (i === 0 && dir < 0) + i = annotations.length - 1; + + var annotation = annotations[i]; + if (!annotation || !dir) + return; + + if (annotation.row === row) { + do { + annotation = annotations[i += dir]; + } while (annotation && annotation.row === row); + if (!annotation) + return annotations.slice(); + } + + + var matched = []; + row = annotation.row; + do { + matched[dir < 0 ? "unshift" : "push"](annotation); + annotation = annotations[i += dir]; + } while (annotation && annotation.row == row); + return matched.length && matched; +} + +exports.showErrorMarker = function(editor, dir) { + var session = editor.session; + if (!session.widgetManager) { + session.widgetManager = new LineWidgets(session); + session.widgetManager.attach(editor); + } + + var pos = editor.getCursorPosition(); + var row = pos.row; + var oldWidget = session.lineWidgets && session.lineWidgets[row]; + if (oldWidget) { + oldWidget.destroy(); + } else { + row -= dir; + } + var annotations = findAnnotations(session, row, dir); + var gutterAnno; + if (annotations) { + var annotation = annotations[0]; + pos.column = (annotation.pos && typeof annotation.column != "number" + ? annotation.pos.sc + : annotation.column) || 0; + pos.row = annotation.row; + gutterAnno = editor.renderer.$gutterLayer.$annotations[pos.row]; + } else if (oldWidget) { + return; + } else { + gutterAnno = { + text: ["Looks good!"], + className: "ace_ok" + }; + } + editor.session.unfold(pos.row); + editor.selection.moveToPosition(pos); + + var w = { + row: pos.row, + fixedWidth: true, + coverGutter: true, + el: dom.createElement("div") + }; + var el = w.el.appendChild(dom.createElement("div")); + var arrow = w.el.appendChild(dom.createElement("div")); + arrow.className = "error_widget_arrow " + gutterAnno.className; + + var left = editor.renderer.$cursorLayer + .getPixelPosition(pos).left; + arrow.style.left = left + editor.renderer.gutterWidth - 5 + "px"; + + w.el.className = "error_widget_wrapper"; + el.className = "error_widget " + gutterAnno.className; + el.innerHTML = gutterAnno.text.join("
    "); + + el.appendChild(dom.createElement("div")); + + var kb = function(_, hashId, keyString) { + if (hashId === 0 && (keyString === "esc" || keyString === "return")) { + w.destroy(); + return {command: "null"}; + } + }; + + w.destroy = function() { + if (editor.$mouseHandler.isMousePressed) + return; + editor.keyBinding.removeKeyboardHandler(kb); + session.widgetManager.removeLineWidget(w); + editor.off("changeSelection", w.destroy); + editor.off("changeSession", w.destroy); + editor.off("mouseup", w.destroy); + editor.off("change", w.destroy); + }; + + editor.keyBinding.addKeyboardHandler(kb); + editor.on("changeSelection", w.destroy); + editor.on("changeSession", w.destroy); + editor.on("mouseup", w.destroy); + editor.on("change", w.destroy); + + editor.session.widgetManager.addLineWidget(w); + + w.el.onmousedown = editor.focus.bind(editor); + + editor.renderer.scrollCursorIntoView(null, 0.5, {bottom: w.el.offsetHeight}); +}; + + +dom.importCssString("\ + .error_widget_wrapper {\ + background: inherit;\ + color: inherit;\ + border:none\ + }\ + .error_widget {\ + border-top: solid 2px;\ + border-bottom: solid 2px;\ + margin: 5px 0;\ + padding: 10px 40px;\ + white-space: pre-wrap;\ + }\ + .error_widget.ace_error, .error_widget_arrow.ace_error{\ + border-color: #ff5a5a\ + }\ + .error_widget.ace_warning, .error_widget_arrow.ace_warning{\ + border-color: #F1D817\ + }\ + .error_widget.ace_info, .error_widget_arrow.ace_info{\ + border-color: #5a5a5a\ + }\ + .error_widget.ace_ok, .error_widget_arrow.ace_ok{\ + border-color: #5aaa5a\ + }\ + .error_widget_arrow {\ + position: absolute;\ + border: solid 5px;\ + border-top-color: transparent!important;\ + border-right-color: transparent!important;\ + border-left-color: transparent!important;\ + top: -5px;\ + }\ +", ""); + +}); \ No newline at end of file diff --git a/lib/ace/ext/keybinding_menu.js b/lib/ace/ext/keybinding_menu.js new file mode 100644 index 00000000..bf8189a5 --- /dev/null +++ b/lib/ace/ext/keybinding_menu.js @@ -0,0 +1,86 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/ +/*global define, require */ + +/** + * Show Keyboard Shortcuts + * @fileOverview Show Keyboard Shortcuts
    + * Generates a menu which displays the keyboard shortcuts. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { + "use strict"; + var Editor = require("ace/editor").Editor; + /** + * Generates a menu which displays the keyboard shortcuts. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {ace.Editor} editor An instance of the ace editor. + */ + function showKeyboardShortcuts (editor) { + // make sure the menu isn't open already. + if(!document.getElementById('kbshortcutmenu')) { + var overlayPage = require('./menu_tools/overlay_page').overlayPage; + var getEditorKeybordShortcuts = require('./menu_tools/get_editor_keyboard_shortcuts').getEditorKeybordShortcuts; + var kb = getEditorKeybordShortcuts(editor); + var el = document.createElement('div'); + var commands = kb.reduce(function(previous, current) { + return previous + '
    ' + + current.command + ' : ' + + '' + current.key + '
    '; + }, ''); + + el.id = 'kbshortcutmenu'; + el.innerHTML = '

    Keyboard Shortcuts

    ' + commands + ''; + overlayPage(editor, el, '0', '0', '0', null); + } + }; + module.exports.init = function(editor) { + Editor.prototype.showKeyboardShortcuts = function() { + showKeyboardShortcuts(this); + }; + editor.commands.addCommands([{ + name: "showKeyboardShortcuts", + bindKey: {win: "Ctrl-Alt-h", mac: "Command-Alt-h"}, + exec: function(editor, line) { + editor.showKeyboardShortcuts(); + } + }]); + }; + +}); \ No newline at end of file diff --git a/lib/ace/ext/language_tools.js b/lib/ace/ext/language_tools.js new file mode 100644 index 00000000..563fe58a --- /dev/null +++ b/lib/ace/ext/language_tools.js @@ -0,0 +1,225 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var snippetManager = require("../snippets").snippetManager; +var Autocomplete = require("../autocomplete").Autocomplete; +var config = require("../config"); +var lang = require("../lib/lang"); +var util = require("../autocomplete/util"); + +var textCompleter = require("../autocomplete/text_completer"); +var keyWordCompleter = { + getCompletions: function(editor, session, pos, prefix, callback) { + if (session.$mode.completer) { + return session.$mode.completer.getCompletions(editor, session, pos, prefix, callback); + } + var state = editor.session.getState(pos.row); + var completions = session.$mode.getCompletions(state, session, pos, prefix); + callback(null, completions); + } +}; + +var snippetCompleter = { + getCompletions: function(editor, session, pos, prefix, callback) { + var snippetMap = snippetManager.snippetMap; + var completions = []; + snippetManager.getActiveScopes(editor).forEach(function(scope) { + var snippets = snippetMap[scope] || []; + for (var i = snippets.length; i--;) { + var s = snippets[i]; + var caption = s.name || s.tabTrigger; + if (!caption) + continue; + completions.push({ + caption: caption, + snippet: s.content, + meta: s.tabTrigger && !s.name ? s.tabTrigger + "\u21E5 " : "snippet", + type: "snippet" + }); + } + }, this); + callback(null, completions); + }, + getDocTooltip: function(item) { + if (item.type == "snippet" && !item.docHTML) { + item.docHTML = [ + "", lang.escapeHTML(item.caption), "", "
    ", + lang.escapeHTML(item.snippet) + ].join(""); + } + } +}; + +var completers = [snippetCompleter, textCompleter, keyWordCompleter]; +// Allows default completers to be removed or replaced with a explict set of completers +// A null argument here will result in an empty completer array, not a null attribute +exports.setCompleters = function(val) { + completers = val || []; +}; +exports.addCompleter = function(completer) { + completers.push(completer); +}; + +// Exports existing completer so that user can construct his own set of completers. +exports.textCompleter = textCompleter; +exports.keyWordCompleter = keyWordCompleter; +exports.snippetCompleter = snippetCompleter; + +var expandSnippet = { + name: "expandSnippet", + exec: function(editor) { + return snippetManager.expandWithTab(editor); + }, + bindKey: "Tab" +}; + +var onChangeMode = function(e, editor) { + loadSnippetsForMode(editor.session.$mode); +}; + +var loadSnippetsForMode = function(mode) { + var id = mode.$id; + if (!snippetManager.files) + snippetManager.files = {}; + loadSnippetFile(id); + if (mode.modes) + mode.modes.forEach(loadSnippetsForMode); +}; + +var loadSnippetFile = function(id) { + if (!id || snippetManager.files[id]) + return; + var snippetFilePath = id.replace("mode", "snippets"); + snippetManager.files[id] = {}; + config.loadModule(snippetFilePath, function(m) { + if (m) { + snippetManager.files[id] = m; + if (!m.snippets && m.snippetText) + m.snippets = snippetManager.parseSnippetFile(m.snippetText); + snippetManager.register(m.snippets || [], m.scope); + if (m.includeScopes) { + snippetManager.snippetMap[m.scope].includeScopes = m.includeScopes; + m.includeScopes.forEach(function(x) { + loadSnippetFile("ace/mode/" + x); + }); + } + } + }); +}; + +function getCompletionPrefix(editor) { + var pos = editor.getCursorPosition(); + var line = editor.session.getLine(pos.row); + var prefix; + // Try to find custom prefixes on the completers + editor.completers.forEach(function(completer) { + if (completer.identifierRegexps) { + completer.identifierRegexps.forEach(function(identifierRegex) { + if (!prefix && identifierRegex) + prefix = util.retrievePrecedingIdentifier(line, pos.column, identifierRegex); + }); + } + }); + return prefix || util.retrievePrecedingIdentifier(line, pos.column); +} + +var doLiveAutocomplete = function(e) { + var editor = e.editor; + var hasCompleter = editor.completer && editor.completer.activated; + + // We don't want to autocomplete with no prefix + if (e.command.name === "backspace") { + if (hasCompleter && !getCompletionPrefix(editor)) + editor.completer.detach(); + } + else if (e.command.name === "insertstring") { + var prefix = getCompletionPrefix(editor); + // Only autocomplete if there's a prefix that can be matched + if (prefix && !hasCompleter) { + if (!editor.completer) { + // Create new autocompleter + editor.completer = new Autocomplete(); + } + // Disable autoInsert + editor.completer.autoInsert = false; + editor.completer.showPopup(editor); + } + } +}; + +var Editor = require("../editor").Editor; +require("../config").defineOptions(Editor.prototype, "editor", { + enableBasicAutocompletion: { + set: function(val) { + if (val) { + if (!this.completers) + this.completers = Array.isArray(val)? val: completers; + this.commands.addCommand(Autocomplete.startCommand); + } else { + this.commands.removeCommand(Autocomplete.startCommand); + } + }, + value: false + }, + /** + * Enable live autocomplete. If the value is an array, it is assumed to be an array of completers + * and will use them instead of the default completers. + */ + enableLiveAutocompletion: { + set: function(val) { + if (val) { + if (!this.completers) + this.completers = Array.isArray(val)? val: completers; + // On each change automatically trigger the autocomplete + this.commands.on('afterExec', doLiveAutocomplete); + } else { + this.commands.removeListener('afterExec', doLiveAutocomplete); + } + }, + value: false + }, + enableSnippets: { + set: function(val) { + if (val) { + this.commands.addCommand(expandSnippet); + this.on("changeMode", onChangeMode); + onChangeMode(null, this); + } else { + this.commands.removeCommand(expandSnippet); + this.off("changeMode", onChangeMode); + } + }, + value: false + } +}); +}); diff --git a/lib/ace/ext/linking.js b/lib/ace/ext/linking.js new file mode 100644 index 00000000..cfd333b2 --- /dev/null +++ b/lib/ace/ext/linking.js @@ -0,0 +1,78 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var Editor = require("ace/editor").Editor; + +require("../config").defineOptions(Editor.prototype, "editor", { + enableLinking: { + set: function(val) { + if (val) { + this.on("click", onClick); + this.on("mousemove", onMouseMove); + } else { + this.off("click", onClick); + this.off("mousemove", onMouseMove); + } + }, + value: false + } +}) + +function onMouseMove(e) { + var editor = e.editor; + var ctrl = e.getAccelKey(); + + if (ctrl) { + var editor = e.editor; + var docPos = e.getDocumentPosition(); + var session = editor.session; + var token = session.getTokenAt(docPos.row, docPos.column); + + editor._emit("linkHover", {position: docPos, token: token}); + } +} + +function onClick(e) { + var ctrl = e.getAccelKey(); + var button = e.getButton(); + + if (button == 0 && ctrl) { + var editor = e.editor; + var docPos = e.getDocumentPosition(); + var session = editor.session; + var token = session.getTokenAt(docPos.row, docPos.column); + + editor._emit("linkClick", {position: docPos, token: token}); + } +} + +}); diff --git a/lib/ace/ext/menu_tools/add_editor_menu_options.js b/lib/ace/ext/menu_tools/add_editor_menu_options.js new file mode 100644 index 00000000..eb90e31d --- /dev/null +++ b/lib/ace/ext/menu_tools/add_editor_menu_options.js @@ -0,0 +1,109 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/ +/*global define, require */ + +/** + * Add Editor Menu Options + * @fileOverview Add Editor Menu Options
    + * The menu options property needs to be added to the editor + * so that the settings menu can know about options for + * selection elements and track which option is selected. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +'use strict'; + +/** + * The menu options property needs to be added to the editor + * so that the settings menu can know about options for + * selection elements and track which option is selected. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {ace.Editor} editor An instance of the ace editor. + */ +module.exports.addEditorMenuOptions = function addEditorMenuOptions (editor) { + var modelist = require('../modelist'); + var themelist = require('../themelist'); + editor.menuOptions = { + setNewLineMode: [{ + textContent: "unix", + value: "unix" + }, { + textContent: "windows", + value: "windows" + }, { + textContent: "auto", + value: "auto" + }], + setTheme: [], + setMode: [], + setKeyboardHandler: [{ + textContent: "ace", + value: "" + }, { + textContent: "vim", + value: "ace/keyboard/vim" + }, { + textContent: "emacs", + value: "ace/keyboard/emacs" + }, { + textContent: "textarea", + value: "ace/keyboard/textarea" + }, { + textContent: "sublime", + value: "ace/keyboard/sublime" + }] + }; + + editor.menuOptions.setTheme = themelist.themes.map(function(theme) { + return { + textContent: theme.caption, + value: theme.theme + }; + }); + + editor.menuOptions.setMode = modelist.modes.map(function(mode) { + return { + textContent: mode.name, + value: mode.mode + }; + }); +}; + + +}); diff --git a/lib/ace/ext/menu_tools/element_generator.js b/lib/ace/ext/menu_tools/element_generator.js new file mode 100644 index 00000000..ec6ba93b --- /dev/null +++ b/lib/ace/ext/menu_tools/element_generator.js @@ -0,0 +1,148 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/ +/*global define, require */ + +/** + * Element Generator + * @fileOverview Element Generator
    + * Contains methods for generating elements. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +'use strict'; +/** + * Creates a DOM option element + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {object} obj An object containing properties to add to the dom + * element. If one of those properties is named `selected` then it will be + * added as an attribute on the element instead. + */ +module.exports.createOption = function createOption (obj) { + var attribute; + var el = document.createElement('option'); + for(attribute in obj) { + if(obj.hasOwnProperty(attribute)) { + if(attribute === 'selected') { + el.setAttribute(attribute, obj[attribute]); + } else { + el[attribute] = obj[attribute]; + } + } + } + return el; +}; +/** + * Creates a DOM checkbox element. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {string} id The id of the element. + * @param {boolean} checked Whether or not the element is checked. + * @param {string} clss The class of the element. + * @returns {DOMElement} Returns a checkbox element reference. + */ +module.exports.createCheckbox = function createCheckbox (id, checked, clss) { + var el = document.createElement('input'); + el.setAttribute('type', 'checkbox'); + el.setAttribute('id', id); + el.setAttribute('name', id); + el.setAttribute('value', checked); + el.setAttribute('class', clss); + if(checked) { + el.setAttribute('checked', 'checked'); + } + return el; +}; +/** + * Creates a DOM text input element. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {string} id The id of the element. + * @param {string} value The default value of the input element. + * @param {string} clss The class of the element. + * @returns {DOMElement} Returns an input element reference. + */ +module.exports.createInput = function createInput (id, value, clss) { + var el = document.createElement('input'); + el.setAttribute('type', 'text'); + el.setAttribute('id', id); + el.setAttribute('name', id); + el.setAttribute('value', value); + el.setAttribute('class', clss); + return el; +}; +/** + * Creates a DOM label element. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {string} text The label text. + * @param {string} labelFor The id of the element being labeled. + * @returns {DOMElement} Returns a label element reference. + */ +module.exports.createLabel = function createLabel (text, labelFor) { + var el = document.createElement('label'); + el.setAttribute('for', labelFor); + el.textContent = text; + return el; +}; +/** + * Creates a DOM selection element. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {string} id The id of the element. + * @param {string} values An array of objects suitable for `createOption` + * @param {string} clss The class of the element. + * @returns {DOMElement} Returns a selection element reference. + * @see ace/ext/element_generator.createOption + */ +module.exports.createSelection = function createSelection (id, values, clss) { + var el = document.createElement('select'); + el.setAttribute('id', id); + el.setAttribute('name', id); + el.setAttribute('class', clss); + values.forEach(function(item) { + el.appendChild(module.exports.createOption(item)); + }); + return el; +}; + +}); \ No newline at end of file diff --git a/lib/ace/ext/menu_tools/generate_settings_menu.js b/lib/ace/ext/menu_tools/generate_settings_menu.js new file mode 100644 index 00000000..2ee1ae09 --- /dev/null +++ b/lib/ace/ext/menu_tools/generate_settings_menu.js @@ -0,0 +1,264 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/ +/*global define*/ + +/** + * Generates the settings menu + * @fileOverview Generates the settings menu. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +'use strict'; +var egen = require('./element_generator'); +var addEditorMenuOptions = require('./add_editor_menu_options').addEditorMenuOptions; +var getSetFunctions = require('./get_set_functions').getSetFunctions; + +/** + * Generates an interactive menu with settings useful to end users. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {ace.Editor} editor An instance of the ace editor. + */ +module.exports.generateSettingsMenu = function generateSettingsMenu (editor) { + /** + * container for dom elements that will go in the menu. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + var elements = []; + /** + * Sorts the menu entries (elements var) so they'll appear in alphabetical order + * the sort is performed based on the value of the contains property + * of each element. Since this is an `array.sort` the array is sorted + * in place. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + function cleanupElementsList() { + elements.sort(function(a, b) { + var x = a.getAttribute('contains'); + var y = b.getAttribute('contains'); + return x.localeCompare(y); + }); + } + /** + * Wraps all dom elements contained in the elements var with a single + * div. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + function wrapElements() { + var topmenu = document.createElement('div'); + topmenu.setAttribute('id', 'ace_settingsmenu'); + elements.forEach(function(element) { + topmenu.appendChild(element); + }); + + var el = topmenu.appendChild(document.createElement('div')); + var version = "1.1.9"; + el.style.padding = "1em"; + el.textContent = "Ace version " + version; + + return topmenu; + } + /** + * Creates a new menu entry. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {object} obj This is a reference to the object containing the + * set function. It is used to set up event listeners for when the + * menu options change. + * @param {string} clss Maps to the class of the dom element. This is + * the name of the object containing the set function e.g. `editor`, + * `session`, `renderer`. + * @param {string} item This is the set function name. It maps to the + * id of the dom element (check, select, input) and to the "contains" + * attribute of the div holding both the element and its label. + * @param {mixed} val This is the value of the setting. It is mapped to + * the dom element's value, checked, or selected option accordingly. + */ + function createNewEntry(obj, clss, item, val) { + var el; + var div = document.createElement('div'); + div.setAttribute('contains', item); + div.setAttribute('class', 'ace_optionsMenuEntry'); + div.setAttribute('style', 'clear: both;'); + + div.appendChild(egen.createLabel( + item.replace(/^set/, '').replace(/([A-Z])/g, ' $1').trim(), + item + )); + + if (Array.isArray(val)) { + el = egen.createSelection(item, val, clss); + el.addEventListener('change', function(e) { + try{ + editor.menuOptions[e.target.id].forEach(function(x) { + if(x.textContent !== e.target.textContent) { + delete x.selected; + } + }); + obj[e.target.id](e.target.value); + } catch (err) { + throw new Error(err); + } + }); + } else if(typeof val === 'boolean') { + el = egen.createCheckbox(item, val, clss); + el.addEventListener('change', function(e) { + try{ + // renderer['setHighlightGutterLine'](true); + obj[e.target.id](!!e.target.checked); + } catch (err) { + throw new Error(err); + } + }); + } else { + // this aids in giving the ability to specify settings through + // post and get requests. + // /ace_editor.html?setMode=ace/mode/html&setOverwrite=true + el = egen.createInput(item, val, clss); + el.addEventListener('change', function(e) { + try{ + if(e.target.value === 'true') { + obj[e.target.id](true); + } else if(e.target.value === 'false') { + obj[e.target.id](false); + } else { + obj[e.target.id](e.target.value); + } + } catch (err) { + throw new Error(err); + } + }); + } + el.style.cssText = 'float:right;'; + div.appendChild(el); + return div; + } + /** + * Generates selection fields for the menu and populates their options + * using information from `editor.menuOptions` + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {string} item The set function name. + * @param {object} esr A reference to the object having the set function. + * @param {string} clss The name of the object containing the set function. + * @param {string} fn The matching get function's function name. + * @returns {DOMElement} Returns a dom element containing a selection + * element populated with options. The option whose value matches that + * returned from `esr[fn]()` will be selected. + */ + function makeDropdown(item, esr, clss, fn) { + var val = editor.menuOptions[item]; + var currentVal = esr[fn](); + if (typeof currentVal == 'object') + currentVal = currentVal.$id; + val.forEach(function(valuex) { + if (valuex.value === currentVal) + valuex.selected = 'selected'; + }); + return createNewEntry(esr, clss, item, val); + } + /** + * Processes the set functions returned from `getSetFunctions`. First it + * checks for menu options defined in `editor.menuOptions`. If no + * options are specified then it checks whether there is a get function + * (replace set with get) for the setting. When either of those + * conditions are met it will attempt to create a new entry for the + * settings menu and push it into the elements array defined above. + * It can only do so for get functions which return + * strings, numbers, and booleans. A special case is written in for + * `getMode` where it looks at the returned objects `$id` property and + * forwards that through instead. Other special cases could be written + * in but that would get a bit ridiculous. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {object} setObj An item from the array returned by + * `getSetFunctions`. + */ + function handleSet(setObj) { + var item = setObj.functionName; + var esr = setObj.parentObj; + var clss = setObj.parentName; + var val; + var fn = item.replace(/^set/, 'get'); + if(editor.menuOptions[item] !== undefined) { + // has options for select element + elements.push(makeDropdown(item, esr, clss, fn)); + } else if(typeof esr[fn] === 'function') { + // has get function + try { + val = esr[fn](); + if(typeof val === 'object') { + // setMode takes a string, getMode returns an object + // the $id property of that object is the string + // which may be given to setMode... + val = val.$id; + } + // the rest of the get functions return strings, + // booleans, or numbers. + elements.push( + createNewEntry(esr, clss, item, val) + ); + } catch (e) { + // if there are errors it is because the element + // does not belong in the settings menu + } + } + } + addEditorMenuOptions(editor); + // gather the set functions + getSetFunctions(editor).forEach(function(setObj) { + // populate the elements array with good stuff. + handleSet(setObj); + }); + // sort the menu entries in the elements list so people can find + // the settings in alphabetical order. + cleanupElementsList(); + // dump the entries from the elements list and wrap them up in a div + return wrapElements(); +}; + +}); \ No newline at end of file diff --git a/lib/ace/ext/menu_tools/get_editor_keyboard_shortcuts.js b/lib/ace/ext/menu_tools/get_editor_keyboard_shortcuts.js new file mode 100644 index 00000000..99e006b0 --- /dev/null +++ b/lib/ace/ext/menu_tools/get_editor_keyboard_shortcuts.js @@ -0,0 +1,91 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/ +/*global define, require */ + +/** + * Get Editor Keyboard Shortcuts + * @fileOverview Get Editor Keyboard Shortcuts
    + * Gets a map of keyboard shortcuts to command names for the current platform. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +"use strict"; +var keys = require("../../lib/keys"); + +/** + * Gets a map of keyboard shortcuts to command names for the current platform. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {ace.Editor} editor An editor instance. + * @returns {Array} Returns an array of objects representing the keyboard + * shortcuts for the given editor. + * @example + * var getKbShortcuts = require('./get_keyboard_shortcuts'); + * console.log(getKbShortcuts(editor)); + * // [ + * // {'command' : aCommand, 'key' : 'Control-d'}, + * // {'command' : aCommand, 'key' : 'Control-d'} + * // ] + */ +module.exports.getEditorKeybordShortcuts = function(editor) { + var KEY_MODS = keys.KEY_MODS; + var keybindings = []; + var commandMap = {}; + editor.keyBinding.$handlers.forEach(function(handler) { + var ckb = handler.commandKeyBinding; + for (var i in ckb) { + var key = i.replace(/(^|-)\w/g, function(x) { return x.toUpperCase(); }); + var commands = ckb[i]; + if (!Array.isArray(commands)) + commands = [commands]; + commands.forEach(function(command) { + if (typeof command != "string") + command = command.name + if (commandMap[command]) { + commandMap[command].key += "|" + key; + } else { + commandMap[command] = {key: key, command: command}; + keybindings.push(commandMap[command]); + } + }); + } + }); + return keybindings; +}; + +}); \ No newline at end of file diff --git a/lib/ace/ext/menu_tools/get_set_functions.js b/lib/ace/ext/menu_tools/get_set_functions.js new file mode 100644 index 00000000..4cd65508 --- /dev/null +++ b/lib/ace/ext/menu_tools/get_set_functions.js @@ -0,0 +1,141 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true */ +/*global define*/ + +/** + * Get Set Functions + * @fileOverview Get Set Functions
    + * Gets various functions for setting settings. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +'use strict'; +/** + * Generates a list of set functions for the settings menu. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {object} editor The editor instance + * @return {array} Returns an array of objects. Each object contains the + * following properties: functionName, parentObj, and parentName. The + * function name will be the name of a method beginning with the string + * `set` which was found. The parent object will be a reference to the + * object having the method matching the function name. The parent name + * will be a string representing the identifier of the parent object e.g. + * `editor`, `session`, or `renderer`. + */ +module.exports.getSetFunctions = function getSetFunctions (editor) { + /** + * Output array. Will hold the objects described above. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + var out = []; + /** + * This object provides a map between the objects which will be + * traversed and the parent name which will appear in the output. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + var my = { + 'editor' : editor, + 'session' : editor.session, + 'renderer' : editor.renderer + }; + /** + * This array will hold the set function names which have already been + * found so that they are not added to the output multiple times. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + var opts = []; + /** + * This is a list of set functions which will not appear in the settings + * menu. I don't know what to do with setKeyboardHandler. When I tried + * to use it, it didn't appear to be working. Someone who knows better + * could remove it from this list and add it's options to + * add_editor_menu_options.js + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + var skip = [ + 'setOption', + 'setUndoManager', + 'setDocument', + 'setValue', + 'setBreakpoints', + 'setScrollTop', + 'setScrollLeft', + 'setSelectionStyle', + 'setWrapLimitRange' + ]; + + + /** + * This will search the objects mapped to the `my` variable above. When + * it finds a set function in the object that is not listed in the + * `skip` list or the `opts` list it will push a new object to the + * output array. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + ['renderer', 'session', 'editor'].forEach(function(esra) { + var esr = my[esra]; + var clss = esra; + for(var fn in esr) { + if(skip.indexOf(fn) === -1) { + if(/^set/.test(fn) && opts.indexOf(fn) === -1) { + // found set function + opts.push(fn); + out.push({ + 'functionName' : fn, + 'parentObj' : esr, + 'parentName' : clss + }); + } + } + } + }); + return out; +}; + +}); \ No newline at end of file diff --git a/lib/ace/ext/menu_tools/overlay_page.js b/lib/ace/ext/menu_tools/overlay_page.js new file mode 100644 index 00000000..bf985e29 --- /dev/null +++ b/lib/ace/ext/menu_tools/overlay_page.js @@ -0,0 +1,116 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/ +/*global define, require */ + +/** + * Overlay Page + * @fileOverview Overlay Page
    + * Generates an overlay for displaying menus. The overlay is an absolutely + * positioned div. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +'use strict'; +var dom = require("../../lib/dom"); +var cssText = require("../../requirejs/text!./settings_menu.css"); +dom.importCssString(cssText); + +/** + * Generates an overlay for displaying menus. The overlay is an absolutely + * positioned div. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {DOMElement} contentElement Any element which may be presented inside + * a div. + * @param {string|number} top absolute position value. + * @param {string|number} right absolute position value. + * @param {string|number} bottom absolute position value. + * @param {string|number} left absolute position value. + */ +module.exports.overlayPage = function overlayPage(editor, contentElement, top, right, bottom, left) { + top = top ? 'top: ' + top + ';' : ''; + bottom = bottom ? 'bottom: ' + bottom + ';' : ''; + right = right ? 'right: ' + right + ';' : ''; + left = left ? 'left: ' + left + ';' : ''; + + var closer = document.createElement('div'); + var contentContainer = document.createElement('div'); + + function documentEscListener(e) { + if (e.keyCode === 27) { + closer.click(); + } + } + + closer.style.cssText = 'margin: 0; padding: 0; ' + + 'position: fixed; top:0; bottom:0; left:0; right:0;' + + 'z-index: 9990; ' + + 'background-color: rgba(0, 0, 0, 0.3);'; + closer.addEventListener('click', function() { + document.removeEventListener('keydown', documentEscListener); + closer.parentNode.removeChild(closer); + editor.focus(); + closer = null; + }); + // click closer if esc key is pressed + document.addEventListener('keydown', documentEscListener); + + contentContainer.style.cssText = top + right + bottom + left; + contentContainer.addEventListener('click', function(e) { + e.stopPropagation(); + }); + + var wrapper = dom.createElement("div"); + wrapper.style.position = "relative"; + + var closeButton = dom.createElement("div"); + closeButton.className = "ace_closeButton"; + closeButton.addEventListener('click', function() { + closer.click(); + }); + + wrapper.appendChild(closeButton); + contentContainer.appendChild(wrapper); + + contentContainer.appendChild(contentElement); + closer.appendChild(contentContainer); + document.body.appendChild(closer); + editor.blur(); +}; + +}); \ No newline at end of file diff --git a/lib/ace/ext/menu_tools/settings_menu.css b/lib/ace/ext/menu_tools/settings_menu.css new file mode 100644 index 00000000..f8b761ce --- /dev/null +++ b/lib/ace/ext/menu_tools/settings_menu.css @@ -0,0 +1,48 @@ +#ace_settingsmenu, #kbshortcutmenu { + background-color: #F7F7F7; + color: black; + box-shadow: -5px 4px 5px rgba(126, 126, 126, 0.55); + padding: 1em 0.5em 2em 1em; + overflow: auto; + position: absolute; + margin: 0; + bottom: 0; + right: 0; + top: 0; + z-index: 9991; + cursor: default; +} + +.ace_dark #ace_settingsmenu, .ace_dark #kbshortcutmenu { + box-shadow: -20px 10px 25px rgba(126, 126, 126, 0.25); + background-color: rgba(255, 255, 255, 0.6); + color: black; +} + +.ace_optionsMenuEntry:hover { + background-color: rgba(100, 100, 100, 0.1); + -webkit-transition: all 0.5s; + transition: all 0.3s +} + +.ace_closeButton { + background: rgba(245, 146, 146, 0.5); + border: 1px solid #F48A8A; + border-radius: 50%; + padding: 7px; + position: absolute; + right: -8px; + top: -8px; + z-index: 1000; +} +.ace_closeButton{ + background: rgba(245, 146, 146, 0.9); +} +.ace_optionsMenuKey { + color: darkslateblue; + font-weight: bold; +} +.ace_optionsMenuCommand { + color: darkcyan; + font-weight: normal; +} \ No newline at end of file diff --git a/lib/ace/ext/modelist.js b/lib/ace/ext/modelist.js new file mode 100644 index 00000000..675a4b85 --- /dev/null +++ b/lib/ace/ext/modelist.js @@ -0,0 +1,197 @@ +define(function(require, exports, module) { +"use strict"; + +var modes = []; +/** + * Suggests a mode based on the file extension present in the given path + * @param {string} path The path to the file + * @returns {object} Returns an object containing information about the + * suggested mode. + */ +function getModeForPath(path) { + var mode = modesByName.text; + var fileName = path.split(/[\/\\]/).pop(); + for (var i = 0; i < modes.length; i++) { + if (modes[i].supportsFile(fileName)) { + mode = modes[i]; + break; + } + } + return mode; +} + +var Mode = function(name, caption, extensions) { + this.name = name; + this.caption = caption; + this.mode = "ace/mode/" + name; + this.extensions = extensions; + if (/\^/.test(extensions)) { + var re = extensions.replace(/\|(\^)?/g, function(a, b){ + return "$|" + (b ? "^" : "^.*\\."); + }) + "$"; + } else { + var re = "^.*\\.(" + extensions + ")$"; + } + + this.extRe = new RegExp(re, "gi"); +}; + +Mode.prototype.supportsFile = function(filename) { + return filename.match(this.extRe); +}; + +// todo firstlinematch +var supportedModes = { + ABAP: ["abap"], + ABC: ["abc"], + ActionScript:["as"], + ADA: ["ada|adb"], + Apache_Conf: ["^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd"], + AsciiDoc: ["asciidoc|adoc"], + Assembly_x86:["asm"], + AutoHotKey: ["ahk"], + BatchFile: ["bat|cmd"], + C9Search: ["c9search_results"], + C_Cpp: ["cpp|c|cc|cxx|h|hh|hpp"], + Cirru: ["cirru|cr"], + Clojure: ["clj|cljs"], + Cobol: ["CBL|COB"], + coffee: ["coffee|cf|cson|^Cakefile"], + ColdFusion: ["cfm"], + CSharp: ["cs"], + CSS: ["css"], + Curly: ["curly"], + D: ["d|di"], + Dart: ["dart"], + Diff: ["diff|patch"], + Dockerfile: ["^Dockerfile"], + Dot: ["dot"], + Dummy: ["dummy"], + DummySyntax: ["dummy"], + Eiffel: ["e"], + EJS: ["ejs"], + Elixir: ["ex|exs"], + Elm: ["elm"], + Erlang: ["erl|hrl"], + Forth: ["frt|fs|ldr"], + FTL: ["ftl"], + Gcode: ["gcode"], + Gherkin: ["feature"], + Gitignore: ["^.gitignore"], + Glsl: ["glsl|frag|vert"], + golang: ["go"], + Groovy: ["groovy"], + HAML: ["haml"], + Handlebars: ["hbs|handlebars|tpl|mustache"], + Haskell: ["hs"], + haXe: ["hx"], + HTML: ["html|htm|xhtml"], + HTML_Ruby: ["erb|rhtml|html.erb"], + INI: ["ini|conf|cfg|prefs"], + Io: ["io"], + Jack: ["jack"], + Jade: ["jade"], + Java: ["java"], + JavaScript: ["js|jsm"], + JSON: ["json"], + JSONiq: ["jq"], + JSP: ["jsp"], + JSX: ["jsx"], + Julia: ["jl"], + LaTeX: ["tex|latex|ltx|bib"], + Lean: ["lean|hlean"], + LESS: ["less"], + Liquid: ["liquid"], + Lisp: ["lisp"], + LiveScript: ["ls"], + LogiQL: ["logic|lql"], + LSL: ["lsl"], + Lua: ["lua"], + LuaPage: ["lp"], + Lucene: ["lucene"], + Makefile: ["^Makefile|^GNUmakefile|^makefile|^OCamlMakefile|make"], + Markdown: ["md|markdown"], + Mask: ["mask"], + MATLAB: ["matlab"], + MEL: ["mel"], + MUSHCode: ["mc|mush"], + MySQL: ["mysql"], + Nix: ["nix"], + Nim: ["nim"], + ObjectiveC: ["m|mm"], + OCaml: ["ml|mli"], + Pascal: ["pas|p"], + Perl: ["pl|pm"], + pgSQL: ["pgsql"], + PHP: ["php|phtml|shtml|php3|php4|php5|phps|phpt|aw|ctp"], + Powershell: ["ps1"], + Praat: ["praat|praatscript|psc|proc"], + Prolog: ["plg|prolog"], + Properties: ["properties"], + Protobuf: ["proto"], + Python: ["py"], + R: ["r"], + RDoc: ["Rd"], + RHTML: ["Rhtml"], + Ruby: ["rb|ru|gemspec|rake|^Guardfile|^Rakefile|^Gemfile"], + Rust: ["rs"], + SASS: ["sass"], + SCAD: ["scad"], + Scala: ["scala"], + Scheme: ["scm|rkt"], + SCSS: ["scss"], + SH: ["sh|bash|^.bashrc"], + SJS: ["sjs"], + Smarty: ["smarty|tpl"], + snippets: ["snippets"], + Soy_Template:["soy"], + Space: ["space"], + SQL: ["sql"], + SQLServer: ["sqlserver"], + Stylus: ["styl|stylus"], + SVG: ["svg"], + Tcl: ["tcl"], + Tex: ["tex"], + Text: ["txt"], + Textile: ["textile"], + Toml: ["toml"], + Twig: ["twig"], + Typescript: ["ts|typescript|str"], + Vala: ["vala"], + VBScript: ["vbs|vb"], + Velocity: ["vm"], + Verilog: ["v|vh|sv|svh"], + VHDL: ["vhd|vhdl"], + XML: ["xml|rdf|rss|wsdl|xslt|atom|mathml|mml|xul|xbl|xaml"], + XQuery: ["xq"], + YAML: ["yaml|yml"], + // Add the missing mode "Django" to ext-modelist + Django: ["html"] +}; + +var nameOverrides = { + ObjectiveC: "Objective-C", + CSharp: "C#", + golang: "Go", + C_Cpp: "C and C++", + coffee: "CoffeeScript", + HTML_Ruby: "HTML (Ruby)", + FTL: "FreeMarker" +}; +var modesByName = {}; +for (var name in supportedModes) { + var data = supportedModes[name]; + var displayName = (nameOverrides[name] || name).replace(/_/g, " "); + var filename = name.toLowerCase(); + var mode = new Mode(filename, displayName, data[0]); + modesByName[filename] = mode; + modes.push(mode); +} + +module.exports = { + getModeForPath: getModeForPath, + modes: modes, + modesByName: modesByName +}; + +}); diff --git a/lib/ace/ext/old_ie.js b/lib/ace/ext/old_ie.js new file mode 100644 index 00000000..8b8ce977 --- /dev/null +++ b/lib/ace/ext/old_ie.js @@ -0,0 +1,114 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; +var MAX_TOKEN_COUNT = 1000; +var useragent = require("../lib/useragent"); +var TokenizerModule = require("../tokenizer"); + +function patch(obj, name, regexp, replacement) { + eval("obj['" + name + "']=" + obj[name].toString().replace( + regexp, replacement + )); +} + +if (useragent.isIE && useragent.isIE < 10 && window.top.document.compatMode === "BackCompat") + useragent.isOldIE = true; + +if (typeof document != "undefined" && !document.documentElement.querySelector) { + useragent.isOldIE = true; + var qs = function(el, selector) { + if (selector.charAt(0) == ".") { + var classNeme = selector.slice(1); + } else { + var m = selector.match(/(\w+)=(\w+)/); + var attr = m && m[1]; + var attrVal = m && m[2]; + } + for (var i = 0; i < el.all.length; i++) { + var ch = el.all[i]; + if (classNeme) { + if (ch.className.indexOf(classNeme) != -1) + return ch; + } else if (attr) { + if (ch.getAttribute(attr) == attrVal) + return ch; + } + } + }; + var sb = require("./searchbox").SearchBox.prototype; + patch( + sb, "$initElements", + /([^\s=]*).querySelector\((".*?")\)/g, + "qs($1, $2)" + ); +} + +var compliantExecNpcg = /()??/.exec("")[1] === undefined; +if (compliantExecNpcg) + return; +var proto = TokenizerModule.Tokenizer.prototype; +TokenizerModule.Tokenizer_orig = TokenizerModule.Tokenizer; +proto.getLineTokens_orig = proto.getLineTokens; + +patch( + TokenizerModule, "Tokenizer", + "ruleRegExps.push(adjustedregex);\n", + function(m) { + return m + '\ + if (state[i].next && RegExp(adjustedregex).test(""))\n\ + rule._qre = RegExp(adjustedregex, "g");\n\ + '; + } +); +TokenizerModule.Tokenizer.prototype = proto; +patch( + proto, "getLineTokens", + /if \(match\[i \+ 1\] === undefined\)\s*continue;/, + "if (!match[i + 1]) {\n\ + if (value)continue;\n\ + var qre = state[mapping[i]]._qre;\n\ + if (!qre) continue;\n\ + qre.lastIndex = lastIndex;\n\ + if (!qre.exec(line) || qre.lastIndex != lastIndex)\n\ + continue;\n\ + }" +); + +patch( + require("../mode/text").Mode.prototype, "getTokenizer", + /Tokenizer/, + "TokenizerModule.Tokenizer" +); + +useragent.isOldIE = true; + +}); diff --git a/lib/ace/ext/old_ie_test.js b/lib/ace/ext/old_ie_test.js new file mode 100644 index 00000000..98652e14 --- /dev/null +++ b/lib/ace/ext/old_ie_test.js @@ -0,0 +1,77 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { +"use strict"; + +var assert = require("../test/assertions"); + +module.exports = { + "test: getTokenizer() (smoke test)" : function() { + var exec = RegExp.prototype.exec + var brokenExec = function(str) { + var result = exec.call(this, str); + if (result) { + for (var i = result.length; i--;) + if (!result[i]) + result[i] = ""; + } + return result; + } + + try { + // break this to emulate old ie + RegExp.prototype.exec = brokenExec; + require("./old_ie"); + var Tokenizer = require("../tokenizer").Tokenizer; + var JavaScriptHighlightRules = require("../mode/javascript_highlight_rules").JavaScriptHighlightRules; + var tokenizer = new Tokenizer((new JavaScriptHighlightRules).getRules()); + + var tokens = tokenizer.getLineTokens("'juhu'", "start").tokens; + assert.equal("string", tokens[0].type); + } finally { + // restore modified functions + RegExp.prototype.exec = exec; + var module = require("../tokenizer"); + module.Tokenizer = module.Tokenizer_orig; + module.Tokenizer.prototype.getLineTokens = module.Tokenizer.prototype.getLineTokens_orig; + } + } +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} diff --git a/lib/ace/ext/searchbox.css b/lib/ace/ext/searchbox.css new file mode 100644 index 00000000..5de8d847 --- /dev/null +++ b/lib/ace/ext/searchbox.css @@ -0,0 +1,153 @@ + + +/* ------------------------------------------------------------------------------------------ + * Editor Search Form + * --------------------------------------------------------------------------------------- */ + .ace_search { + background-color: #ddd; + border: 1px solid #cbcbcb; + border-top: 0 none; + max-width: 325px; + overflow: hidden; + margin: 0; + padding: 4px; + padding-right: 6px; + padding-bottom: 0; + position: absolute; + top: 0px; + z-index: 99; + white-space: normal; +} +.ace_search.left { + border-left: 0 none; + border-radius: 0px 0px 5px 0px; + left: 0; +} +.ace_search.right { + border-radius: 0px 0px 0px 5px; + border-right: 0 none; + right: 0; +} + +.ace_search_form, .ace_replace_form { + border-radius: 3px; + border: 1px solid #cbcbcb; + float: left; + margin-bottom: 4px; + overflow: hidden; +} +.ace_search_form.ace_nomatch { + outline: 1px solid red; +} + +.ace_search_field { + background-color: white; + border-right: 1px solid #cbcbcb; + border: 0 none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + height: 22px; + outline: 0; + padding: 0 7px; + width: 214px; + margin: 0; +} +.ace_searchbtn, +.ace_replacebtn { + background: #fff; + border: 0 none; + border-left: 1px solid #dcdcdc; + cursor: pointer; + float: left; + height: 22px; + margin: 0; + padding: 0; + position: relative; +} +.ace_searchbtn:last-child, +.ace_replacebtn:last-child { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.ace_searchbtn:disabled { + background: none; + cursor: default; +} +.ace_searchbtn { + background-position: 50% 50%; + background-repeat: no-repeat; + width: 27px; +} +.ace_searchbtn.prev { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADFJREFUeNpiSU1NZUAC/6E0I0yACYskCpsJiySKIiY0SUZk40FyTEgCjGgKwTRAgAEAQJUIPCE+qfkAAAAASUVORK5CYII=); +} +.ace_searchbtn.next { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNpiTE1NZQCC/0DMyIAKwGJMUAYDEo3M/s+EpvM/mkKwCQxYjIeLMaELoLMBAgwAU7UJObTKsvAAAAAASUVORK5CYII=); +} +.ace_searchbtn_close { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0; + border-radius: 50%; + border: 0 none; + color: #656565; + cursor: pointer; + float: right; + font: 16px/16px Arial; + height: 14px; + margin: 5px 1px 9px 5px; + padding: 0; + text-align: center; + width: 14px; +} +.ace_searchbtn_close:hover { + background-color: #656565; + background-position: 50% 100%; + color: white; +} +.ace_replacebtn.prev { + width: 54px +} +.ace_replacebtn.next { + width: 27px +} + +.ace_button { + margin-left: 2px; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -o-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: hidden; + opacity: 0.7; + border: 1px solid rgba(100,100,100,0.23); + padding: 1px; + -moz-box-sizing: border-box; + box-sizing: border-box; + color: black; +} + +.ace_button:hover { + background-color: #eee; + opacity:1; +} +.ace_button:active { + background-color: #ddd; +} + +.ace_button.checked { + border-color: #3399ff; + opacity:1; +} + +.ace_search_options{ + margin-bottom: 3px; + text-align: right; + -webkit-user-select: none; + -moz-user-select: none; + -o-user-select: none; + -ms-user-select: none; + user-select: none; +} \ No newline at end of file diff --git a/lib/ace/ext/searchbox.js b/lib/ace/ext/searchbox.js new file mode 100644 index 00000000..b316aa75 --- /dev/null +++ b/lib/ace/ext/searchbox.js @@ -0,0 +1,308 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var dom = require("../lib/dom"); +var lang = require("../lib/lang"); +var event = require("../lib/event"); +var searchboxCss = require("../requirejs/text!./searchbox.css"); +var HashHandler = require("../keyboard/hash_handler").HashHandler; +var keyUtil = require("../lib/keys"); + +dom.importCssString(searchboxCss, "ace_searchbox"); + +var html = ''.replace(/>\s+/g, ">"); + +var SearchBox = function(editor, range, showReplaceForm) { + var div = dom.createElement("div"); + div.innerHTML = html; + this.element = div.firstChild; + + this.$init(); + this.setEditor(editor); +}; + +(function() { + this.setEditor = function(editor) { + editor.searchBox = this; + editor.container.appendChild(this.element); + this.editor = editor; + }; + + this.$initElements = function(sb) { + this.searchBox = sb.querySelector(".ace_search_form"); + this.replaceBox = sb.querySelector(".ace_replace_form"); + this.searchOptions = sb.querySelector(".ace_search_options"); + this.regExpOption = sb.querySelector("[action=toggleRegexpMode]"); + this.caseSensitiveOption = sb.querySelector("[action=toggleCaseSensitive]"); + this.wholeWordOption = sb.querySelector("[action=toggleWholeWords]"); + this.searchInput = this.searchBox.querySelector(".ace_search_field"); + this.replaceInput = this.replaceBox.querySelector(".ace_search_field"); + }; + + this.$init = function() { + var sb = this.element; + + this.$initElements(sb); + + var _this = this; + event.addListener(sb, "mousedown", function(e) { + setTimeout(function(){ + _this.activeInput.focus(); + }, 0); + event.stopPropagation(e); + }); + event.addListener(sb, "click", function(e) { + var t = e.target || e.srcElement; + var action = t.getAttribute("action"); + if (action && _this[action]) + _this[action](); + else if (_this.$searchBarKb.commands[action]) + _this.$searchBarKb.commands[action].exec(_this); + event.stopPropagation(e); + }); + + event.addCommandKeyListener(sb, function(e, hashId, keyCode) { + var keyString = keyUtil.keyCodeToString(keyCode); + var command = _this.$searchBarKb.findKeyCommand(hashId, keyString); + if (command && command.exec) { + command.exec(_this); + event.stopEvent(e); + } + }); + + this.$onChange = lang.delayedCall(function() { + _this.find(false, false); + }); + + event.addListener(this.searchInput, "input", function() { + _this.$onChange.schedule(20); + }); + event.addListener(this.searchInput, "focus", function() { + _this.activeInput = _this.searchInput; + _this.searchInput.value && _this.highlight(); + }); + event.addListener(this.replaceInput, "focus", function() { + _this.activeInput = _this.replaceInput; + _this.searchInput.value && _this.highlight(); + }); + }; + + //keybinging outsite of the searchbox + this.$closeSearchBarKb = new HashHandler([{ + bindKey: "Esc", + name: "closeSearchBar", + exec: function(editor) { + editor.searchBox.hide(); + } + }]); + + //keybinging outsite of the searchbox + this.$searchBarKb = new HashHandler(); + this.$searchBarKb.bindKeys({ + "Ctrl-f|Command-f|Ctrl-H|Command-Option-F": function(sb) { + var isReplace = sb.isReplace = !sb.isReplace; + sb.replaceBox.style.display = isReplace ? "" : "none"; + sb[isReplace ? "replaceInput" : "searchInput"].focus(); + }, + "Ctrl-G|Command-G": function(sb) { + sb.findNext(); + }, + "Ctrl-Shift-G|Command-Shift-G": function(sb) { + sb.findPrev(); + }, + "esc": function(sb) { + setTimeout(function() { sb.hide();}); + }, + "Return": function(sb) { + if (sb.activeInput == sb.replaceInput) + sb.replace(); + sb.findNext(); + }, + "Shift-Return": function(sb) { + if (sb.activeInput == sb.replaceInput) + sb.replace(); + sb.findPrev(); + }, + "Alt-Return": function(sb) { + if (sb.activeInput == sb.replaceInput) + sb.replaceAll(); + sb.findAll(); + }, + "Tab": function(sb) { + (sb.activeInput == sb.replaceInput ? sb.searchInput : sb.replaceInput).focus(); + } + }); + + this.$searchBarKb.addCommands([{ + name: "toggleRegexpMode", + bindKey: {win: "Alt-R|Alt-/", mac: "Ctrl-Alt-R|Ctrl-Alt-/"}, + exec: function(sb) { + sb.regExpOption.checked = !sb.regExpOption.checked; + sb.$syncOptions(); + } + }, { + name: "toggleCaseSensitive", + bindKey: {win: "Alt-C|Alt-I", mac: "Ctrl-Alt-R|Ctrl-Alt-I"}, + exec: function(sb) { + sb.caseSensitiveOption.checked = !sb.caseSensitiveOption.checked; + sb.$syncOptions(); + } + }, { + name: "toggleWholeWords", + bindKey: {win: "Alt-B|Alt-W", mac: "Ctrl-Alt-B|Ctrl-Alt-W"}, + exec: function(sb) { + sb.wholeWordOption.checked = !sb.wholeWordOption.checked; + sb.$syncOptions(); + } + }]); + + this.$syncOptions = function() { + dom.setCssClass(this.regExpOption, "checked", this.regExpOption.checked); + dom.setCssClass(this.wholeWordOption, "checked", this.wholeWordOption.checked); + dom.setCssClass(this.caseSensitiveOption, "checked", this.caseSensitiveOption.checked); + this.find(false, false); + }; + + this.highlight = function(re) { + this.editor.session.highlight(re || this.editor.$search.$options.re); + this.editor.renderer.updateBackMarkers() + }; + this.find = function(skipCurrent, backwards) { + var range = this.editor.find(this.searchInput.value, { + skipCurrent: skipCurrent, + backwards: backwards, + wrap: true, + regExp: this.regExpOption.checked, + caseSensitive: this.caseSensitiveOption.checked, + wholeWord: this.wholeWordOption.checked + }); + var noMatch = !range && this.searchInput.value; + dom.setCssClass(this.searchBox, "ace_nomatch", noMatch); + this.editor._emit("findSearchBox", { match: !noMatch }); + this.highlight(); + }; + this.findNext = function() { + this.find(true, false); + }; + this.findPrev = function() { + this.find(true, true); + }; + this.findAll = function(){ + var range = this.editor.findAll(this.searchInput.value, { + regExp: this.regExpOption.checked, + caseSensitive: this.caseSensitiveOption.checked, + wholeWord: this.wholeWordOption.checked + }); + var noMatch = !range && this.searchInput.value; + dom.setCssClass(this.searchBox, "ace_nomatch", noMatch); + this.editor._emit("findSearchBox", { match: !noMatch }); + this.highlight(); + this.hide(); + }; + this.replace = function() { + if (!this.editor.getReadOnly()) + this.editor.replace(this.replaceInput.value); + }; + this.replaceAndFindNext = function() { + if (!this.editor.getReadOnly()) { + this.editor.replace(this.replaceInput.value); + this.findNext() + } + }; + this.replaceAll = function() { + if (!this.editor.getReadOnly()) + this.editor.replaceAll(this.replaceInput.value); + }; + + this.hide = function() { + this.element.style.display = "none"; + this.editor.keyBinding.removeKeyboardHandler(this.$closeSearchBarKb); + this.editor.focus(); + }; + this.show = function(value, isReplace) { + this.element.style.display = ""; + this.replaceBox.style.display = isReplace ? "" : "none"; + + this.isReplace = isReplace; + + if (value) + this.searchInput.value = value; + this.searchInput.focus(); + this.searchInput.select(); + + this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb); + }; + + this.isFocused = function() { + var el = document.activeElement; + return el == this.searchInput || el == this.replaceInput; + } +}).call(SearchBox.prototype); + +exports.SearchBox = SearchBox; + +exports.Search = function(editor, isReplace) { + var sb = editor.searchBox || new SearchBox(editor); + sb.show(editor.session.getTextRange(), isReplace); +}; + +}); + + +/* ------------------------------------------------------------------------------------------ + * TODO + * --------------------------------------------------------------------------------------- */ +/* +- move search form to the left if it masks current word +- includ all options that search has. ex: regex +- searchbox.searchbox is not that pretty. we should have just searchbox +- disable prev button if it makes sence +*/ diff --git a/lib/ace/ext/settings_menu.js b/lib/ace/ext/settings_menu.js new file mode 100644 index 00000000..44f6d6ad --- /dev/null +++ b/lib/ace/ext/settings_menu.js @@ -0,0 +1,76 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/*jslint indent: 4, maxerr: 50, white: true, browser: true, vars: true*/ +/*global define, require */ + +/** + * Show Settings Menu + * @fileOverview Show Settings Menu
    + * Displays an interactive settings menu mostly generated on the fly based on + * the current state of the editor. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +"use strict"; +var generateSettingsMenu = require('./menu_tools/generate_settings_menu').generateSettingsMenu; +var overlayPage = require('./menu_tools/overlay_page').overlayPage; +/** + * This displays the settings menu if it is not already being shown. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + * @param {ace.Editor} editor An instance of the ace editor. + */ +function showSettingsMenu(editor) { + // make sure the menu isn't open already. + var sm = document.getElementById('ace_settingsmenu'); + if (!sm) + overlayPage(editor, generateSettingsMenu(editor), '0', '0', '0'); +} + +/** + * Initializes the settings menu extension. It adds the showSettingsMenu + * method to the given editor object and adds the showSettingsMenu command + * to the editor with appropriate keyboard shortcuts. + * @param {ace.Editor} editor An instance of the Editor. + */ +module.exports.init = function(editor) { + var Editor = require("ace/editor").Editor; + Editor.prototype.showSettingsMenu = function() { + showSettingsMenu(this); + }; +}; +}); \ No newline at end of file diff --git a/lib/ace/ext/spellcheck.js b/lib/ace/ext/spellcheck.js new file mode 100644 index 00000000..08bf2189 --- /dev/null +++ b/lib/ace/ext/spellcheck.js @@ -0,0 +1,69 @@ +define(function(require, exports, module) { +"use strict"; +var event = require("../lib/event"); + +exports.contextMenuHandler = function(e){ + var host = e.target; + var text = host.textInput.getElement(); + if (!host.selection.isEmpty()) + return; + var c = host.getCursorPosition(); + var r = host.session.getWordRange(c.row, c.column); + var w = host.session.getTextRange(r); + + host.session.tokenRe.lastIndex = 0; + if (!host.session.tokenRe.test(w)) + return; + var PLACEHOLDER = "\x01\x01"; + var value = w + " " + PLACEHOLDER; + text.value = value; + text.setSelectionRange(w.length, w.length + 1); + text.setSelectionRange(0, 0); + text.setSelectionRange(0, w.length); + + var afterKeydown = false; + event.addListener(text, "keydown", function onKeydown() { + event.removeListener(text, "keydown", onKeydown); + afterKeydown = true; + }); + + host.textInput.setInputHandler(function(newVal) { + console.log(newVal , value, text.selectionStart, text.selectionEnd) + if (newVal == value) + return ''; + if (newVal.lastIndexOf(value, 0) === 0) + return newVal.slice(value.length); + if (newVal.substr(text.selectionEnd) == value) + return newVal.slice(0, -value.length); + if (newVal.slice(-2) == PLACEHOLDER) { + var val = newVal.slice(0, -2); + if (val.slice(-1) == " ") { + if (afterKeydown) + return val.substring(0, text.selectionEnd); + val = val.slice(0, -1); + host.session.replace(r, val); + return ""; + } + } + + return newVal; + }); +}; +// todo support highlighting with typo.js +var Editor = require("../editor").Editor; +require("../config").defineOptions(Editor.prototype, "editor", { + spellcheck: { + set: function(val) { + var text = this.textInput.getElement(); + text.spellcheck = !!val; + if (!val) + this.removeListener("nativecontextmenu", exports.contextMenuHandler); + else + this.on("nativecontextmenu", exports.contextMenuHandler); + }, + value: true + } +}); + +}); + diff --git a/lib/ace/ext/split.js b/lib/ace/ext/split.js new file mode 100644 index 00000000..8316562f --- /dev/null +++ b/lib/ace/ext/split.js @@ -0,0 +1,40 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +/** + * this is experimental, and subject to change, use at your own risk! + */ +module.exports = require("../split"); + +}); + diff --git a/lib/ace/ext/static.css b/lib/ace/ext/static.css new file mode 100644 index 00000000..51986c3f --- /dev/null +++ b/lib/ace/ext/static.css @@ -0,0 +1,38 @@ +.ace_static_highlight { + font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', 'Droid Sans Mono', monospace; + font-size: 12px; + white-space: pre-wrap +} + +.ace_static_highlight .ace_gutter { + width: 2em; + text-align: right; + padding: 0 3px 0 0; + margin-right: 3px; +} + +.ace_static_highlight.ace_show_gutter .ace_line { + padding-left: 2.6em; +} + +.ace_static_highlight .ace_line { position: relative; } + +.ace_static_highlight .ace_gutter-cell { + -moz-user-select: -moz-none; + -khtml-user-select: none; + -webkit-user-select: none; + user-select: none; + top: 0; + bottom: 0; + left: 0; + position: absolute; +} + + +.ace_static_highlight .ace_gutter-cell:before { + content: counter(ace_line, decimal); + counter-increment: ace_line; +} +.ace_static_highlight { + counter-reset: ace_line; +} diff --git a/lib/ace/ext/static_highlight.js b/lib/ace/ext/static_highlight.js new file mode 100644 index 00000000..2acb3ac5 --- /dev/null +++ b/lib/ace/ext/static_highlight.js @@ -0,0 +1,191 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var EditSession = require("../edit_session").EditSession; +var TextLayer = require("../layer/text").Text; +var baseStyles = require("../requirejs/text!./static.css"); +var config = require("../config"); +var dom = require("../lib/dom"); + +var SimpleTextLayer = function() { + this.config = {}; +}; +SimpleTextLayer.prototype = TextLayer.prototype; + +var highlight = function(el, opts, callback) { + var m = el.className.match(/lang-(\w+)/); + var mode = opts.mode || m && ("ace/mode/" + m[1]); + if (!mode) + return false; + var theme = opts.theme || "ace/theme/textmate"; + + var data = ""; + var nodes = []; + + if (el.firstElementChild) { + var textLen = 0; + for (var i = 0; i < el.childNodes.length; i++) { + var ch = el.childNodes[i]; + if (ch.nodeType == 3) { + textLen += ch.data.length; + data += ch.data; + } else { + nodes.push(textLen, ch); + } + } + } else { + data = dom.getInnerText(el); + if (opts.trim) + data = data.trim(); + } + + highlight.render(data, mode, theme, opts.firstLineNumber, !opts.showGutter, function (highlighted) { + dom.importCssString(highlighted.css, "ace_highlight"); + el.innerHTML = highlighted.html; + var container = el.firstChild.firstChild; + for (var i = 0; i < nodes.length; i += 2) { + var pos = highlighted.session.doc.indexToPosition(nodes[i]); + var node = nodes[i + 1]; + var lineEl = container.children[pos.row]; + lineEl && lineEl.appendChild(node); + } + callback && callback(); + }); +}; + +/** + * Transforms a given input code snippet into HTML using the given mode + * + * @param {string} input Code snippet + * @param {string|mode} mode String specifying the mode to load such as + * `ace/mode/javascript` or, a mode loaded from `/ace/mode` + * (use 'ServerSideHiglighter.getMode'). + * @param {string|theme} theme String specifying the theme to load such as + * `ace/theme/twilight` or, a theme loaded from `/ace/theme`. + * @param {number} lineStart A number indicating the first line number. Defaults + * to 1. + * @param {boolean} disableGutter Specifies whether or not to disable the gutter. + * `true` disables the gutter, `false` enables the gutter. Defaults to `false`. + * @param {function} callback When specifying the mode or theme as a string, + * this method has no return value and you must specify a callback function. The + * callback will receive the rendered object containing the properties `html` + * and `css`. + * @returns {object} An object containing the properties `html` and `css`. + */ +highlight.render = function(input, mode, theme, lineStart, disableGutter, callback) { + var waiting = 1; + var modeCache = EditSession.prototype.$modes; + + // if either the theme or the mode were specified as objects + // then we need to lazily load them. + if (typeof theme == "string") { + waiting++; + config.loadModule(['theme', theme], function(m) { + theme = m; + --waiting || done(); + }); + } + // allow setting mode options e.h {path: "ace/mode/php", inline:true} + var modeOptions; + if (mode && typeof mode === "object" && !mode.getTokenizer) { + modeOptions = mode; + mode = modeOptions.path; + } + if (typeof mode == "string") { + waiting++; + config.loadModule(['mode', mode], function(m) { + if (!modeCache[mode] || modeOptions) + modeCache[mode] = new m.Mode(modeOptions); + mode = modeCache[mode]; + --waiting || done(); + }); + } + + // loads or passes the specified mode module then calls renderer + function done() { + var result = highlight.renderSync(input, mode, theme, lineStart, disableGutter); + return callback ? callback(result) : result; + } + return --waiting || done(); +}; + +/** + * 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') + * @param {string} r Code snippet + * @returns {object} An object containing: html, css + */ +highlight.renderSync = function(input, mode, theme, lineStart, disableGutter) { + lineStart = parseInt(lineStart || 1, 10); + + var session = new EditSession(""); + session.setUseWorker(false); + session.setMode(mode); + + var textLayer = new SimpleTextLayer(); + textLayer.setSession(session); + + session.setValue(input); + + var stringBuilder = []; + var length = session.getLength(); + + for(var ix = 0; ix < length; ix++) { + stringBuilder.push("
    "); + if (!disableGutter) + stringBuilder.push("" + /*(ix + lineStart) + */ ""); + textLayer.$renderLine(stringBuilder, ix, true, false); + stringBuilder.push("\n
    "); + } + + // let's prepare the whole html + var html = "
    " + + "
    " + + stringBuilder.join("") + + "
    " + + "
    "; + + textLayer.destroy(); + + return { + css: baseStyles + theme.cssText, + html: html, + session: session + }; +}; + +module.exports = highlight; +module.exports.highlight =highlight; +}); diff --git a/lib/ace/ext/static_highlight_test.js b/lib/ace/ext/static_highlight_test.js new file mode 100644 index 00000000..6271666d --- /dev/null +++ b/lib/ace/ext/static_highlight_test.js @@ -0,0 +1,96 @@ +if (typeof process !== "undefined") { + require("amd-loader"); + require("../test/mockdom"); +} + +define(function(require, exports, module) { +"use strict"; + +var assert = require("assert"); +var highlighter = require("./static_highlight"); +var JavaScriptMode = require("../mode/javascript").Mode; +var TextMode = require("../mode/text").Mode; + +// Execution ORDER: test.setUpSuite, setUp, testFn, tearDown, test.tearDownSuite +module.exports = { + timeout: 10000, + + "test simple snippet": function(next) { + var theme = require("../theme/tomorrow"); + var snippet = [ + "/** this is a function", + "*", + "*/", + "function hello (a, b, c) {", + " console.log(a * b + c + 'sup$');", + "}" + ].join("\n"); + var mode = new JavaScriptMode(); + + var result = highlighter.render(snippet, mode, theme); + assert.equal(result.html, "
    " + + "
    /** this is a function\n
    " + + "
    *\n
    " + + "
    */\n
    " + + "
    function hello (a, b, c) {\n
    " + + "
    console.log(a * b + c + 'sup$');\n
    " + + "
    }\n
    " + + "
    "); + assert.ok(!!result.css); + next(); + }, + + "test css from theme is used": function(next) { + var theme = require("../theme/tomorrow"); + var snippet = [ + "/** this is a function", + "*", + "*/", + "function hello (a, b, c) {", + " console.log(a * b + c + 'sup?');", + "}" + ].join("\n"); + var mode = new JavaScriptMode(); + + var result = highlighter.render(snippet, mode, theme); + + assert.ok(result.css.indexOf(theme.cssText) !== -1); + + next(); + }, + + "test theme classname should be in output html": function(next) { + var theme = require("../theme/tomorrow"); + var snippet = [ + "/** this is a function", + "*", + "*/", + "function hello (a, b, c) {", + " console.log(a * b + c + 'sup?');", + "}" + ].join("\n"); + var mode = new JavaScriptMode(); + + var result = highlighter.render(snippet, mode, theme); + assert.equal(!!result.html.match(/
    /), true); + + next(); + }, + + "test js string replace specials": function(next) { + var theme = require("../theme/tomorrow"); + var snippet = "$'$1$2$$$&"; + var mode = new TextMode(); + + var result = highlighter.render(snippet, mode, theme); + assert.ok(result.html.indexOf(snippet) != -1); + + next(); + } +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec(); +} diff --git a/lib/ace/ext/statusbar.js b/lib/ace/ext/statusbar.js new file mode 100644 index 00000000..5e5b0572 --- /dev/null +++ b/lib/ace/ext/statusbar.js @@ -0,0 +1,48 @@ +define(function(require, exports, module) { +"use strict"; +/** simple statusbar **/ +var dom = require("ace/lib/dom"); +var lang = require("ace/lib/lang"); + +var StatusBar = function(editor, parentNode) { + this.element = dom.createElement("div"); + this.element.className = "ace_status-indicator"; + this.element.style.cssText = "display: inline-block;"; + parentNode.appendChild(this.element); + + var statusUpdate = lang.delayedCall(function(){ + this.updateStatus(editor) + }.bind(this)); + editor.on("changeStatus", function() { + statusUpdate.schedule(100); + }); + editor.on("changeSelection", function() { + statusUpdate.schedule(100); + }); +}; + +(function(){ + this.updateStatus = function(editor) { + var status = []; + function add(str, separator) { + str && status.push(str, separator || "|"); + } + + add(editor.keyBinding.getStatusText(editor)); + if (editor.commands.recording) + add("REC"); + + var c = editor.selection.lead; + add(c.row + ":" + c.column, " "); + if (!editor.selection.isEmpty()) { + var r = editor.getSelectionRange(); + add("(" + (r.end.row - r.start.row) + ":" +(r.end.column - r.start.column) + ")"); + } + status.pop(); + this.element.textContent = status.join(""); + }; +}).call(StatusBar.prototype); + +exports.StatusBar = StatusBar; + +}); \ No newline at end of file diff --git a/lib/ace/ext/textarea.js b/lib/ace/ext/textarea.js new file mode 100644 index 00000000..c9972488 --- /dev/null +++ b/lib/ace/ext/textarea.js @@ -0,0 +1,521 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var event = require("../lib/event"); +var UA = require("../lib/useragent"); +var net = require("../lib/net"); +var ace = require("../ace"); + +require("../theme/textmate"); + +module.exports = exports = ace; + +/* + * 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 + * + * If the property can't get computed, is 'auto' or 'intrinsic', the former + * calculated property is used (this can happen in cases where the textarea + * is hidden and has no dimension styles). + */ +var getCSSProperty = function(element, container, property) { + var ret = element.style[property]; + + if (!ret) { + if (window.getComputedStyle) { + ret = window.getComputedStyle(element, '').getPropertyValue(property); + } else { + ret = element.currentStyle[property]; + } + } + + if (!ret || ret == 'auto' || ret == 'intrinsic') { + ret = container.style[property]; + } + return ret; +}; + +function applyStyles(elm, styles) { + for (var style in styles) { + elm.style[style] = styles[style]; + } +} + +function setupContainer(element, getValue) { + if (element.type != 'textarea') { + throw new Error("Textarea required!"); + } + + var parentNode = element.parentNode; + + // This will hold the editor. + var container = document.createElement('div'); + + // To put Ace in the place of the textarea, we have to copy a few of the + // textarea's style attributes to the div container. + // + // The problem is that the properties have to get computed (they might be + // defined by a CSS file on the page - you can't access such rules that + // apply to an element via elm.style). Computed properties are converted to + // pixels although the dimension might be given as percentage. When the + // window resizes, the dimensions defined by percentages changes, so the + // properties have to get recomputed to get the new/true pixels. + var resizeEvent = function() { + var style = 'position:relative;'; + [ + 'margin-top', 'margin-left', 'margin-right', 'margin-bottom' + ].forEach(function(item) { + style += item + ':' + + getCSSProperty(element, container, item) + ';'; + }); + + // Calculating the width/height of the textarea is somewhat tricky. To + // do it right, you have to include the paddings to the sides as well + // (eg. width = width + padding-left, -right). This works well, as + // long as the width of the element is not set or given in pixels. In + // this case and after the textarea is hidden, getCSSProperty(element, + // container, 'width') will still return pixel value. If the element + // has realtiv dimensions (e.g. width='95') + // getCSSProperty(...) will return pixel values only as long as the + // textarea is visible. After it is hidden getCSSProperty will return + // the relative dimensions as they are set on the element (in the case + // of width, 95). + // Making the sum of pixel vaules (e.g. padding) and realtive values + // (e.g. ) is not possible. As such the padding styles are + // ignored. + + // The complete width is the width of the textarea + the padding + // to the left and right. + var width = getCSSProperty(element, container, 'width') || (element.clientWidth + "px"); + var height = getCSSProperty(element, container, 'height') || (element.clientHeight + "px"); + style += 'height:' + height + ';width:' + width + ';'; + + // Set the display property to 'inline-block'. + style += 'display:inline-block;'; + container.setAttribute('style', style); + }; + event.addListener(window, 'resize', resizeEvent); + + // Call the resizeEvent once, so that the size of the container is + // calculated. + resizeEvent(); + + // Insert the div container after the element. + parentNode.insertBefore(container, element.nextSibling); + + // Override the forms onsubmit function. Set the innerHTML and value + // of the textarea before submitting. + while (parentNode !== document) { + if (parentNode.tagName.toUpperCase() === 'FORM') { + var oldSumit = parentNode.onsubmit; + // Override the onsubmit function of the form. + parentNode.onsubmit = function(evt) { + element.value = getValue(); + // If there is a onsubmit function already, then call + // it with the current context and pass the event. + if (oldSumit) { + oldSumit.call(this, evt); + } + }; + break; + } + parentNode = parentNode.parentNode; + } + return container; +} + +exports.transformTextarea = function(element, options) { + var session; + var container = setupContainer(element, function() { + return session.getValue(); + }); + + // Hide the element. + element.style.display = 'none'; + container.style.background = 'white'; + + // + var editorDiv = document.createElement("div"); + applyStyles(editorDiv, { + top: "0px", + left: "0px", + right: "0px", + bottom: "0px", + border: "1px solid gray", + position: "absolute" + }); + container.appendChild(editorDiv); + + var settingOpener = document.createElement("div"); + applyStyles(settingOpener, { + position: "absolute", + right: "0px", + bottom: "0px", + background: "red", + cursor: "nw-resize", + borderStyle: "solid", + borderWidth: "9px 8px 10px 9px", + width: "2px", + borderColor: "lightblue gray gray lightblue", + zIndex: 101 + }); + + var settingDiv = document.createElement("div"); + var settingDivStyles = { + top: "0px", + left: "20%", + right: "0px", + bottom: "0px", + position: "absolute", + padding: "5px", + zIndex: 100, + color: "white", + display: "none", + overflow: "auto", + fontSize: "14px", + boxShadow: "-5px 2px 3px gray" + }; + if (!UA.isOldIE) { + settingDivStyles.backgroundColor = "rgba(0, 0, 0, 0.6)"; + } else { + settingDivStyles.backgroundColor = "#333"; + } + + applyStyles(settingDiv, settingDivStyles); + container.appendChild(settingDiv); + + options = options || exports.defaultOptions; + // Power up ace on the textarea: + var editor = ace.edit(editorDiv); + session = editor.getSession(); + + session.setValue(element.value || element.innerHTML); + editor.focus(); + + // Add the settingPanel opener to the editor's div. + container.appendChild(settingOpener); + + // Create the API. + setupApi(editor, editorDiv, settingDiv, ace, options, load); + + // Create the setting's panel. + setupSettingPanel(settingDiv, settingOpener, editor); + + var state = ""; + event.addListener(settingOpener, "mousemove", function(e) { + var rect = this.getBoundingClientRect(); + var x = e.clientX - rect.left, y = e.clientY - rect.top; + if (x + y < (rect.width + rect.height)/2) { + this.style.cursor = "pointer"; + state = "toggle"; + } else { + state = "resize"; + this.style.cursor = "nw-resize"; + } + }); + + event.addListener(settingOpener, "mousedown", function(e) { + if (state == "toggle") { + editor.setDisplaySettings(); + return; + } + container.style.zIndex = 100000; + var rect = container.getBoundingClientRect(); + var startX = rect.width + rect.left - e.clientX; + var startY = rect.height + rect.top - e.clientY; + event.capture(settingOpener, function(e) { + container.style.width = e.clientX - rect.left + startX + "px"; + container.style.height = e.clientY - rect.top + startY + "px"; + editor.resize(); + }, function() {}); + }); + + return editor; +}; + +function load(url, module, callback) { + net.loadScript(url, function() { + require([module], callback); + }); +} + +function setupApi(editor, editorDiv, settingDiv, ace, options, loader) { + var session = editor.getSession(); + var renderer = editor.renderer; + loader = loader || load; + + function toBool(value) { + return value === "true" || value == true; + } + + editor.setDisplaySettings = function(display) { + if (display == null) + display = settingDiv.style.display == "none"; + if (display) { + settingDiv.style.display = "block"; + settingDiv.hideButton.focus(); + editor.on("focus", function onFocus() { + editor.removeListener("focus", onFocus); + settingDiv.style.display = "none"; + }); + } else { + editor.focus(); + } + }; + + editor.$setOption = editor.setOption; + editor.$getOption = editor.getOption; + editor.setOption = function(key, value) { + switch (key) { + case "mode": + editor.$setOption("mode", "ace/mode/" + value) + break; + case "theme": + editor.$setOption("theme", "ace/theme/" + value) + break; + case "keybindings": + switch (value) { + case "vim": + editor.setKeyboardHandler("ace/keyboard/vim"); + break; + case "emacs": + editor.setKeyboardHandler("ace/keyboard/emacs"); + break; + default: + editor.setKeyboardHandler(null); + } + break; + + case "softWrap": + case "fontSize": + editor.$setOption(key, value); + break; + + default: + editor.$setOption(key, toBool(value)); + } + }; + + editor.getOption = function(key) { + switch (key) { + case "mode": + return editor.$getOption("mode").substr("ace/mode/".length) + break; + + case "theme": + return editor.$getOption("theme").substr("ace/theme/".length) + break; + + case "keybindings": + var value = editor.getKeyboardHandler() + switch (value && value.$id) { + case "ace/keyboard/vim": + return "vim"; + case "ace/keyboard/emacs": + return "emacs"; + default: + return "ace"; + } + break; + + default: + return editor.$getOption(key); + } + }; + + editor.setOptions(options); + return editor; +} + +function setupSettingPanel(settingDiv, settingOpener, editor) { + var BOOL = null; + + var desc = { + mode: "Mode:", + wrap: "Soft Wrap:", + theme: "Theme:", + fontSize: "Font Size:", + showGutter: "Display Gutter:", + keybindings: "Keyboard", + showPrintMargin: "Show Print Margin:", + useSoftTabs: "Use Soft Tabs:", + showInvisibles: "Show Invisibles" + }; + + var optionValues = { + mode: { + text: "Plain", + javascript: "JavaScript", + xml: "XML", + html: "HTML", + css: "CSS", + scss: "SCSS", + python: "Python", + php: "PHP", + java: "Java", + ruby: "Ruby", + c_cpp: "C/C++", + coffee: "CoffeeScript", + json: "json", + perl: "Perl", + clojure: "Clojure", + ocaml: "OCaml", + csharp: "C#", + haxe: "haXe", + svg: "SVG", + textile: "Textile", + groovy: "Groovy", + liquid: "Liquid", + Scala: "Scala" + }, + theme: { + clouds: "Clouds", + clouds_midnight: "Clouds Midnight", + cobalt: "Cobalt", + crimson_editor: "Crimson Editor", + dawn: "Dawn", + eclipse: "Eclipse", + idle_fingers: "Idle Fingers", + kr_theme: "Kr Theme", + merbivore: "Merbivore", + merbivore_soft: "Merbivore Soft", + mono_industrial: "Mono Industrial", + monokai: "Monokai", + pastel_on_dark: "Pastel On Dark", + solarized_dark: "Solarized Dark", + solarized_light: "Solarized Light", + textmate: "Textmate", + twilight: "Twilight", + vibrant_ink: "Vibrant Ink" + }, + showGutter: BOOL, + fontSize: { + "10px": "10px", + "11px": "11px", + "12px": "12px", + "14px": "14px", + "16px": "16px" + }, + wrap: { + off: "Off", + 40: "40", + 80: "80", + free: "Free" + }, + keybindings: { + ace: "ace", + vim: "vim", + emacs: "emacs" + }, + showPrintMargin: BOOL, + useSoftTabs: BOOL, + showInvisibles: BOOL + }; + + var table = []; + table.push(""); + + function renderOption(builder, option, obj, cValue) { + if (!obj) { + builder.push( + "" + ); + return; + } + builder.push(""); + } + + for (var option in exports.defaultOptions) { + table.push(""); + table.push(""); + } + table.push("
    SettingValue
    ", desc[option], ""); + renderOption(table, option, optionValues[option], editor.getOption(option)); + table.push("
    "); + settingDiv.innerHTML = table.join(""); + + var onChange = function(e) { + var select = e.currentTarget; + editor.setOption(select.title, select.value); + }; + var onClick = function(e) { + var cb = e.currentTarget; + editor.setOption(cb.title, cb.checked); + }; + var selects = settingDiv.getElementsByTagName("select"); + for (var i = 0; i < selects.length; i++) + selects[i].onchange = onChange; + var cbs = settingDiv.getElementsByTagName("input"); + for (var i = 0; i < cbs.length; i++) + cbs[i].onclick = onClick; + + + var button = document.createElement("input"); + button.type = "button"; + button.value = "Hide"; + event.addListener(button, "click", function() { + editor.setDisplaySettings(false); + }); + settingDiv.appendChild(button); + settingDiv.hideButton = button; +} + +// Default startup options. +exports.defaultOptions = { + mode: "javascript", + theme: "textmate", + wrap: "off", + fontSize: "12px", + showGutter: "false", + keybindings: "ace", + showPrintMargin: "false", + useSoftTabs: "true", + showInvisibles: "false" +}; + +}); diff --git a/lib/ace/ext/themelist.js b/lib/ace/ext/themelist.js new file mode 100644 index 00000000..0df76b02 --- /dev/null +++ b/lib/ace/ext/themelist.js @@ -0,0 +1,103 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + + +/** + * Generates a list of themes available when ace was built. + * @fileOverview Generates a list of themes available when ace was built. + * @author + * Matthew Christopher Kastor-Inare III
    + * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +"use strict"; +require("ace/lib/fixoldbrowsers"); + +var themeData = [ + ["Chrome" ], + ["Clouds" ], + ["Crimson Editor" ], + ["Dawn" ], + ["Dreamweaver" ], + ["Eclipse" ], + ["GitHub" ], + ["IPlastic" ], + ["Solarized Light"], + ["TextMate" ], + ["Tomorrow" ], + ["XCode" ], + ["Kuroir"], + ["KatzenMilch"], + ["SQL Server" ,"sqlserver" , "light"], + ["Ambiance" ,"ambiance" , "dark"], + ["Chaos" ,"chaos" , "dark"], + ["Clouds Midnight" ,"clouds_midnight" , "dark"], + ["Cobalt" ,"cobalt" , "dark"], + ["idle Fingers" ,"idle_fingers" , "dark"], + ["krTheme" ,"kr_theme" , "dark"], + ["Merbivore" ,"merbivore" , "dark"], + ["Merbivore Soft" ,"merbivore_soft" , "dark"], + ["Mono Industrial" ,"mono_industrial" , "dark"], + ["Monokai" ,"monokai" , "dark"], + ["Pastel on dark" ,"pastel_on_dark" , "dark"], + ["Solarized Dark" ,"solarized_dark" , "dark"], + ["Terminal" ,"terminal" , "dark"], + ["Tomorrow Night" ,"tomorrow_night" , "dark"], + ["The Night After Tomorrow" ,"the_night_after_tomorrow" , "dark"], + ["Tomorrow Night Blue" ,"tomorrow_night_blue" , "dark"], + ["Tomorrow Night Bright","tomorrow_night_bright" , "dark"], + ["Tomorrow Night 80s" ,"tomorrow_night_eighties" , "dark"], + ["Twilight" ,"twilight" , "dark"], + ["Vibrant Ink" ,"vibrant_ink" , "dark"] +]; + + +exports.themesByName = {}; + +/** + * An array containing information about available themes. + */ +exports.themes = themeData.map(function(data) { + var name = data[1] || data[0].replace(/ /g, "_").toLowerCase(); + var theme = { + caption: data[0], + theme: "ace/theme/" + name, + isDark: data[2] == "dark", + name: name + }; + exports.themesByName[name] = theme; + return theme; +}); + +}); + diff --git a/lib/ace/ext/whitespace.js b/lib/ace/ext/whitespace.js new file mode 100644 index 00000000..27ee223e --- /dev/null +++ b/lib/ace/ext/whitespace.js @@ -0,0 +1,213 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var lang = require("../lib/lang"); + +// based on http://www.freehackers.org/Indent_Finder +exports.$detectIndentation = function(lines, fallback) { + var stats = []; + var changes = []; + var tabIndents = 0; + var prevSpaces = 0; + var max = Math.min(lines.length, 1000); + for (var i = 0; i < max; i++) { + var line = lines[i]; + // ignore empty and comment lines + if (!/^\s*[^*+\-\s]/.test(line)) + continue; + + if (line[0] == "\t") + tabIndents++; + + var spaces = line.match(/^ */)[0].length; + if (spaces && line[spaces] != "\t") { + var diff = spaces - prevSpaces; + if (diff > 0 && !(prevSpaces%diff) && !(spaces%diff)) + changes[diff] = (changes[diff] || 0) + 1; + + stats[spaces] = (stats[spaces] || 0) + 1; + } + prevSpaces = spaces; + + // ignore lines ending with backslash + while (i < max && line[line.length - 1] == "\\") + line = lines[i++]; + } + + function getScore(indent) { + var score = 0; + for (var i = indent; i < stats.length; i += indent) + score += stats[i] || 0; + return score; + } + + var changesTotal = changes.reduce(function(a,b){return a+b}, 0); + + var first = {score: 0, length: 0}; + var spaceIndents = 0; + for (var i = 1; i < 12; i++) { + var score = getScore(i); + if (i == 1) { + spaceIndents = score; + score = stats[1] ? 0.9 : 0.8; + if (!stats.length) + score = 0 + } else + score /= spaceIndents; + + if (changes[i]) + score += changes[i] / changesTotal; + + if (score > first.score) + first = {score: score, length: i}; + } + + if (first.score && first.score > 1.4) + var tabLength = first.length; + + if (tabIndents > spaceIndents + 1) + return {ch: "\t", length: tabLength}; + + if (spaceIndents > tabIndents + 1) + return {ch: " ", length: tabLength}; +}; + +exports.detectIndentation = function(session) { + var lines = session.getLines(0, 1000); + var indent = exports.$detectIndentation(lines) || {}; + + if (indent.ch) + session.setUseSoftTabs(indent.ch == " "); + + if (indent.length) + session.setTabSize(indent.length); + return indent; +}; + +exports.trimTrailingSpace = function(session, trimEmpty) { + var doc = session.getDocument(); + var lines = doc.getAllLines(); + + var min = trimEmpty ? -1 : 0; + + for (var i = 0, l=lines.length; i < l; i++) { + var line = lines[i]; + var index = line.search(/\s+$/); + + if (index > min) + doc.removeInLine(i, index, line.length); + } +}; + +exports.convertIndentation = function(session, ch, len) { + var oldCh = session.getTabString()[0]; + var oldLen = session.getTabSize(); + if (!len) len = oldLen; + if (!ch) ch = oldCh; + + var tab = ch == "\t" ? ch: lang.stringRepeat(ch, len); + + var doc = session.doc; + var lines = doc.getAllLines(); + + var cache = {}; + var spaceCache = {}; + for (var i = 0, l=lines.length; i < l; i++) { + var line = lines[i]; + var match = line.match(/^\s*/)[0]; + if (match) { + var w = session.$getStringScreenWidth(match)[0]; + var tabCount = Math.floor(w/oldLen); + var reminder = w%oldLen; + var toInsert = cache[tabCount] || (cache[tabCount] = lang.stringRepeat(tab, tabCount)); + toInsert += spaceCache[reminder] || (spaceCache[reminder] = lang.stringRepeat(" ", reminder)); + + if (toInsert != match) { + doc.removeInLine(i, 0, match.length); + doc.insertInLine({row: i, column: 0}, toInsert); + } + } + } + session.setTabSize(len); + session.setUseSoftTabs(ch == " "); +}; + +exports.$parseStringArg = function(text) { + var indent = {}; + if (/t/.test(text)) + indent.ch = "\t"; + else if (/s/.test(text)) + indent.ch = " "; + var m = text.match(/\d+/); + if (m) + indent.length = parseInt(m[0], 10); + return indent; +}; + +exports.$parseArg = function(arg) { + if (!arg) + return {}; + if (typeof arg == "string") + return exports.$parseStringArg(arg); + if (typeof arg.text == "string") + return exports.$parseStringArg(arg.text); + return arg; +}; + +exports.commands = [{ + name: "detectIndentation", + exec: function(editor) { + exports.detectIndentation(editor.session); + // todo show message? + } +}, { + name: "trimTrailingSpace", + exec: function(editor) { + exports.trimTrailingSpace(editor.session); + } +}, { + name: "convertIndentation", + exec: function(editor, arg) { + var indent = exports.$parseArg(arg); + exports.convertIndentation(editor.session, indent.ch, indent.length); + } +}, { + name: "setIndentation", + exec: function(editor, arg) { + var indent = exports.$parseArg(arg); + indent.length && editor.session.setTabSize(indent.length); + indent.ch && editor.session.setUseSoftTabs(indent.ch == " "); + } +}]; + +}); diff --git a/lib/ace/ext/whitespace_test.js b/lib/ace/ext/whitespace_test.js new file mode 100644 index 00000000..be4f360f --- /dev/null +++ b/lib/ace/ext/whitespace_test.js @@ -0,0 +1,116 @@ +if (typeof process !== "undefined") { + require("amd-loader"); + require("../test/mockdom"); +} + +define(function(require, exports, module) { +"use strict"; + +var assert = require("assert"); +var EditSession = require("../edit_session").EditSession; +var whitespace = require("./whitespace"); + +// Execution ORDER: test.setUpSuite, setUp, testFn, tearDown, test.tearDownSuite +module.exports = { + timeout: 10000, + + "test tab detection": function(next) { + var s = new EditSession([ + "define({", + "\tfoo:1,", + "\tbar:2,", + "\tbaz:{,", + "\t\tx:3", + "\t}", + "})" + ]); + + var indent = whitespace.$detectIndentation(s.doc.$lines); + assert.equal(indent.ch, "\t"); + assert.equal(indent.length, undefined); + + s.insert({row: 0, column: 0}, " "); + indent = whitespace.$detectIndentation(s.doc.$lines); + assert.equal(indent.ch, "\t"); + assert.equal(indent.length, 4); + + s.setValue(""); + indent = whitespace.$detectIndentation(s.doc.$lines); + assert.ok(!indent); + + next(); + }, + + "test empty session": function(next) { + var s = new EditSession([ + "define({", + "foo:1,", + "})" + ]); + var indent = whitespace.$detectIndentation(s.doc.$lines); + assert.ok(!indent); + s.insert({row: 1, column: 0}, " x\n "); + + indent = whitespace.$detectIndentation(s.doc.$lines); + assert.equal(indent.ch, " "); + assert.equal(indent.length, 4); + + next(); + }, + + "!test one line": function(next) { + var s = new EditSession([ + "define({", + " foo:1,", + "})" + ]); + var indent = whitespace.$detectIndentation(s.doc.$lines); + assert.equal(indent.ch, " "); + assert.equal(indent.length, 4); + + next(); + }, + + "test 1 width indents": function(next) { + var s = new EditSession([ + "define({", + " foo:1,", + "})", + "define({", + " bar:1,", + "})", + " t", + " t", + " t", + " t", + " t", + " t", + " t", + " t" + ]); + var indent = whitespace.$detectIndentation(s.doc.$lines); + // assert.equal(indent.ch, " "); + // assert.equal(indent.length, 4); + + s = new EditSession([ + "{", + " foo:1,", + " bar: {", + " baz:2", + " }", + "}" + ]); + indent = whitespace.$detectIndentation(s.doc.$lines); + assert.equal(indent.ch, " "); + assert.equal(indent.length, 1); + + next(); + }, + +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec(); +} diff --git a/lib/ace/incremental_search.js b/lib/ace/incremental_search.js new file mode 100644 index 00000000..e4c1bdf8 --- /dev/null +++ b/lib/ace/incremental_search.js @@ -0,0 +1,317 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var Range = require("./range").Range; +var Search = require("./search").Search; +var SearchHighlight = require("./search_highlight").SearchHighlight; +var iSearchCommandModule = require("./commands/incremental_search_commands"); +var ISearchKbd = iSearchCommandModule.IncrementalSearchKeyboardHandler; + +/** + * @class IncrementalSearch + * + * Implements immediate searching while the user is typing. When incremental + * search is activated, keystrokes into the editor will be used for composing + * a search term. Immediately after every keystroke the search is updated: + * - so-far-matching characters are highlighted + * - the cursor is moved to the next match + * + **/ + + +/** + * + * + * Creates a new `IncrementalSearch` object. + * + * @constructor + **/ +function IncrementalSearch() { + this.$options = {wrap: false, skipCurrent: false}; + this.$keyboardHandler = new ISearchKbd(this); +} + +oop.inherits(IncrementalSearch, Search); + +// regexp handling + +function isRegExp(obj) { + return obj instanceof RegExp; +} + +function regExpToObject(re) { + var string = String(re), + start = string.indexOf('/'), + flagStart = string.lastIndexOf('/'); + return { + expression: string.slice(start+1, flagStart), + flags: string.slice(flagStart+1) + } +} + +function stringToRegExp(string, flags) { + try { + return new RegExp(string, flags); + } catch (e) { return string; } +} + +function objectToRegExp(obj) { + return stringToRegExp(obj.expression, obj.flags); +} + +// iSearch class + +;(function() { + + this.activate = function(ed, backwards) { + this.$editor = ed; + this.$startPos = this.$currentPos = ed.getCursorPosition(); + this.$options.needle = ''; + this.$options.backwards = backwards; + ed.keyBinding.addKeyboardHandler(this.$keyboardHandler); + // we need to completely intercept paste, just registering an event handler does not work + this.$originalEditorOnPaste = ed.onPaste; ed.onPaste = this.onPaste.bind(this); + this.$mousedownHandler = ed.addEventListener('mousedown', this.onMouseDown.bind(this)); + this.selectionFix(ed); + this.statusMessage(true); + }; + + this.deactivate = function(reset) { + this.cancelSearch(reset); + var ed = this.$editor; + ed.keyBinding.removeKeyboardHandler(this.$keyboardHandler); + if (this.$mousedownHandler) { + ed.removeEventListener('mousedown', this.$mousedownHandler); + delete this.$mousedownHandler; + } + ed.onPaste = this.$originalEditorOnPaste; + this.message(''); + }; + + this.selectionFix = function(editor) { + // Fix selection bug: When clicked inside the editor + // editor.selection.$isEmpty is false even if the mouse click did not + // open a selection. This is interpreted by the move commands to + // extend the selection. To only extend the selection when there is + // one, we clear it here + if (editor.selection.isEmpty() && !editor.session.$emacsMark) { + editor.clearSelection(); + } + }; + + this.highlight = function(regexp) { + var sess = this.$editor.session, + hl = sess.$isearchHighlight = sess.$isearchHighlight || sess.addDynamicMarker( + new SearchHighlight(null, "ace_isearch-result", "text")); + hl.setRegexp(regexp); + sess._emit("changeBackMarker"); // force highlight layer redraw + }; + + this.cancelSearch = function(reset) { + var e = this.$editor; + this.$prevNeedle = this.$options.needle; + this.$options.needle = ''; + if (reset) { + e.moveCursorToPosition(this.$startPos); + this.$currentPos = this.$startPos; + } else { + e.pushEmacsMark && e.pushEmacsMark(this.$startPos, false); + } + this.highlight(null); + return Range.fromPoints(this.$currentPos, this.$currentPos); + }; + + this.highlightAndFindWithNeedle = function(moveToNext, needleUpdateFunc) { + if (!this.$editor) return null; + var options = this.$options; + + // get search term + if (needleUpdateFunc) { + options.needle = needleUpdateFunc.call(this, options.needle || '') || ''; + } + if (options.needle.length === 0) { + this.statusMessage(true); + return this.cancelSearch(true); + } + + // try to find the next occurence and enable highlighting marker + options.start = this.$currentPos; + var session = this.$editor.session, + found = this.find(session), + shouldSelect = this.$editor.emacsMark ? + !!this.$editor.emacsMark() : !this.$editor.selection.isEmpty(); + if (found) { + if (options.backwards) found = Range.fromPoints(found.end, found.start); + this.$editor.selection.setRange(Range.fromPoints(shouldSelect ? this.$startPos : found.end, found.end)); + if (moveToNext) this.$currentPos = found.end; + // highlight after cursor move, so selection works properly + this.highlight(options.re); + } + + this.statusMessage(found); + + return found; + }; + + this.addString = function(s) { + return this.highlightAndFindWithNeedle(false, function(needle) { + if (!isRegExp(needle)) + return needle + s; + var reObj = regExpToObject(needle); + reObj.expression += s; + return objectToRegExp(reObj); + }); + }; + + this.removeChar = function(c) { + return this.highlightAndFindWithNeedle(false, function(needle) { + if (!isRegExp(needle)) + return needle.substring(0, needle.length-1); + var reObj = regExpToObject(needle); + reObj.expression = reObj.expression.substring(0, reObj.expression.length-1); + return objectToRegExp(reObj); + }); + }; + + this.next = function(options) { + // try to find the next occurence of whatever we have searched for + // earlier. + // options = {[backwards: BOOL], [useCurrentOrPrevSearch: BOOL]} + options = options || {}; + this.$options.backwards = !!options.backwards; + this.$currentPos = this.$editor.getCursorPosition(); + return this.highlightAndFindWithNeedle(true, function(needle) { + return options.useCurrentOrPrevSearch && needle.length === 0 ? + this.$prevNeedle || '' : needle; + }); + }; + + this.onMouseDown = function(evt) { + // when mouse interaction happens then we quit incremental search + this.deactivate(); + return true; + }; + + this.onPaste = function(text) { + this.addString(text); + }; + + this.convertNeedleToRegExp = function() { + return this.highlightAndFindWithNeedle(false, function(needle) { + return isRegExp(needle) ? needle : stringToRegExp(needle, 'ig'); + }); + }; + + this.convertNeedleToString = function() { + return this.highlightAndFindWithNeedle(false, function(needle) { + return isRegExp(needle) ? regExpToObject(needle).expression : needle; + }); + }; + + this.statusMessage = function(found) { + var options = this.$options, msg = ''; + msg += options.backwards ? 'reverse-' : ''; + msg += 'isearch: ' + options.needle; + msg += found ? '' : ' (not found)'; + this.message(msg); + }; + + this.message = function(msg) { + if (this.$editor.showCommandLine) { + this.$editor.showCommandLine(msg); + this.$editor.focus(); + } else { + console.log(msg); + } + }; + +}).call(IncrementalSearch.prototype); + + +exports.IncrementalSearch = IncrementalSearch; + + +/** + * + * Config settings for enabling/disabling [[IncrementalSearch `IncrementalSearch`]]. + * + **/ + +var dom = require('./lib/dom'); +dom.importCssString && dom.importCssString("\ +.ace_marker-layer .ace_isearch-result {\ + position: absolute;\ + z-index: 6;\ + -moz-box-sizing: border-box;\ + -webkit-box-sizing: border-box;\ + box-sizing: border-box;\ +}\ +div.ace_isearch-result {\ + border-radius: 4px;\ + background-color: rgba(255, 200, 0, 0.5);\ + box-shadow: 0 0 4px rgb(255, 200, 0);\ +}\ +.ace_dark div.ace_isearch-result {\ + background-color: rgb(100, 110, 160);\ + box-shadow: 0 0 4px rgb(80, 90, 140);\ +}", "incremental-search-highlighting"); + +// support for default keyboard handler +var commands = require("./commands/command_manager"); +(function() { + this.setupIncrementalSearch = function(editor, val) { + if (this.usesIncrementalSearch == val) return; + this.usesIncrementalSearch = val; + var iSearchCommands = iSearchCommandModule.iSearchStartCommands; + var method = val ? 'addCommands' : 'removeCommands'; + this[method](iSearchCommands); + }; +}).call(commands.CommandManager.prototype); + +// incremental search config option +var Editor = require("./editor").Editor; +require("./config").defineOptions(Editor.prototype, "editor", { + useIncrementalSearch: { + set: function(val) { + this.keyBinding.$handlers.forEach(function(handler) { + if (handler.setupIncrementalSearch) { + handler.setupIncrementalSearch(this, val); + } + }); + this._emit('incrementalSearchSettingChanged', {isEnabled: val}); + } + } +}); + +}); diff --git a/lib/ace/incremental_search_test.js b/lib/ace/incremental_search_test.js new file mode 100644 index 00000000..d1303b42 --- /dev/null +++ b/lib/ace/incremental_search_test.js @@ -0,0 +1,213 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { +"use strict"; + +var emacs = require('./keyboard/emacs'); +var EditSession = require("./edit_session").EditSession; +var Editor = require("./editor").Editor; +var MockRenderer = require("./test/mockrenderer").MockRenderer; +var Range = require("./range").Range; +var MultiSelect = require("./multi_select").MultiSelect; +var assert = require("./test/assertions"); +var IncrementalSearch = require("./incremental_search").IncrementalSearch; + +require("./multi_select"); + +var editor, iSearch; +function testRanges(str, ranges) { + ranges = ranges || editor.selection.getAllRanges(); + assert.equal(ranges + "", str + ""); +} + +// force "rerender" +function callHighlighterUpdate() { + var session = editor.session, + ranges = [], + mockMarkerLayer = { + drawSingleLineMarker: function(_, markerRanges) { + ranges = ranges.concat(markerRanges); + } + } + session.$isearchHighlight.update([], mockMarkerLayer, session, { + firstRow: 0, lastRow: session.getRowLength()}); + return ranges; +} + +module.exports = { + + name: "ACE incremental_search.js", + + setUp: function() { + var session = new EditSession(["abc123", "xyz124"]); + editor = new Editor(new MockRenderer(), session); + new MultiSelect(editor); + iSearch = new IncrementalSearch(); + }, + + "test: keyboard handler setup" : function() { + iSearch.activate(editor); + assert.equal(editor.getKeyboardHandler(), iSearch.$keyboardHandler); + iSearch.deactivate(); + assert.notEqual(editor.getKeyboardHandler(), iSearch.$keyboardHandler); + }, + + "test: isearch highlight setup" : function() { + var sess = editor.session; + iSearch.activate(editor); + iSearch.highlight('foo'); + var highl = sess.$isearchHighlight.id; + assert.ok(sess.$isearchHighlight, 'session has no isearch highlighter'); + assert.equal(sess.getMarkers()[highl.id], highl.id, 'isearch highlight not in markers'); + iSearch.deactivate(); + iSearch.activate(editor); + iSearch.highlight('bar'); + var highl2 = sess.$isearchHighlight.id; + assert.equal(highl2, highl, 'multiple isearch highlights'); + }, + + "test: find simple text incrementally" : function() { + iSearch.activate(editor); + var range = iSearch.addString('1'), // "1" + highlightRanges = callHighlighterUpdate(editor.session); + testRanges("Range: [0/3] -> [0/4]", [range], "range"); + testRanges("Range: [0/3] -> [0/4],Range: [1/3] -> [1/4]", highlightRanges, "highlight"); + + range = iSearch.addString('2'); // "12" + highlightRanges = callHighlighterUpdate(editor.session); + testRanges("Range: [0/3] -> [0/5]", [range], "range"); + testRanges("Range: [0/3] -> [0/5],Range: [1/3] -> [1/5]", highlightRanges, "highlight"); + + range = iSearch.addString('3'); // "123" + highlightRanges = callHighlighterUpdate(editor.session); + testRanges("Range: [0/3] -> [0/6]", [range], "range"); + testRanges("Range: [0/3] -> [0/6]", highlightRanges, "highlight"); + + range = iSearch.removeChar(); // "12" + highlightRanges = callHighlighterUpdate(editor.session); + testRanges("Range: [0/3] -> [0/5]", [range], "range"); + testRanges("Range: [0/3] -> [0/5],Range: [1/3] -> [1/5]", highlightRanges, "highlight"); + }, + + "test: forward / backward" : function() { + iSearch.activate(editor); + iSearch.addString('1'); iSearch.addString('2'); + var range = iSearch.next(); + testRanges("Range: [1/3] -> [1/5]", [range], "range"); + + range = iSearch.next(); // nothing to find + testRanges("", [range], "range"); + + range = iSearch.next({backwards: true}); // backwards + testRanges("Range: [1/5] -> [1/3]", [range], "range"); + }, + + "test: cancelSearch" : function() { + iSearch.activate(editor); + iSearch.addString('1'); iSearch.addString('2'); + var range = iSearch.cancelSearch(true); + testRanges("Range: [0/0] -> [0/0]", [range], "range"); + + iSearch.addString('1'); range = iSearch.addString('2'); + testRanges("Range: [0/3] -> [0/5]", [range], "range"); + }, + + "test: failing search keeps pos" : function() { + iSearch.activate(editor); + iSearch.addString('1'); iSearch.addString('2'); + var range = iSearch.addString('x'); + testRanges("", [range], "range"); + assert.position(editor.getCursorPosition(), 0, 5); + }, + + "test: backwards search" : function() { + editor.moveCursorTo(1,0); + iSearch.activate(editor, true); + iSearch.addString('1'); var range = iSearch.addString('2');; + testRanges("Range: [0/5] -> [0/3]", [range], "range"); + assert.position(editor.getCursorPosition(), 0, 3); + }, + + "test: forwards then backwards, same result, reoriented range" : function() { + iSearch.activate(editor); + iSearch.addString('1'); var range = iSearch.addString('2');; + testRanges("Range: [0/3] -> [0/5]", [range], "range"); + assert.position(editor.getCursorPosition(), 0, 5); + + range = iSearch.next({backwards: true}); + testRanges("Range: [0/5] -> [0/3]", [range], "range"); + assert.position(editor.getCursorPosition(), 0, 3); + }, + + "test: reuse prev search via option" : function() { + iSearch.activate(editor); + iSearch.addString('1'); iSearch.addString('2');; + assert.position(editor.getCursorPosition(), 0, 5); + iSearch.deactivate(); + + iSearch.activate(editor); + iSearch.next({backwards: false, useCurrentOrPrevSearch: true}); + assert.position(editor.getCursorPosition(), 1, 5); + }, + + "test: don't extend selection range if selection is empty" : function() { + iSearch.activate(editor); + iSearch.addString('1'); iSearch.addString('2');; + testRanges("Range: [0/5] -> [0/5]", [editor.getSelectionRange()], "sel range"); + }, + + "test: extend selection range if selection exists" : function() { + iSearch.activate(editor); + editor.selection.selectTo(0, 1); + iSearch.addString('1'); iSearch.addString('2');; + testRanges("Range: [0/0] -> [0/5]", [editor.getSelectionRange()], "sel range"); + }, + + "test: extend selection in emacs mark mode" : function() { + var emacs = require('./keyboard/emacs'); + editor.keyBinding.addKeyboardHandler(emacs.handler); + emacs.handler.commands.setMark.exec(editor); + iSearch.activate(editor); + iSearch.addString('1'); iSearch.addString('2'); + testRanges("Range: [0/0] -> [0/5]", [editor.getSelectionRange()], "sel range"); + } + +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} diff --git a/lib/ace/keyboard/emacs.js b/lib/ace/keyboard/emacs.js new file mode 100644 index 00000000..8cecad1b --- /dev/null +++ b/lib/ace/keyboard/emacs.js @@ -0,0 +1,652 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var dom = require("../lib/dom"); +require("../incremental_search"); +var iSearchCommandModule = require("../commands/incremental_search_commands"); + + +var screenToTextBlockCoordinates = function(x, y) { + var canvasPos = this.scroller.getBoundingClientRect(); + + var col = Math.floor( + (x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth + ); + var row = Math.floor( + (y + this.scrollTop - canvasPos.top) / this.lineHeight + ); + + return this.session.screenToDocumentPosition(row, col); +}; + +var HashHandler = require("./hash_handler").HashHandler; +exports.handler = new HashHandler(); + +exports.handler.isEmacs = true; +exports.handler.$id = "ace/keyboard/emacs"; + +var initialized = false; +var $formerLongWords; +var $formerLineStart; + +exports.handler.attach = function(editor) { + if (!initialized) { + initialized = true; + dom.importCssString('\ + .emacs-mode .ace_cursor{\ + border: 1px rgba(50,250,50,0.8) solid!important;\ + -moz-box-sizing: border-box!important;\ + -webkit-box-sizing: border-box!important;\ + box-sizing: border-box!important;\ + background-color: rgba(0,250,0,0.9);\ + opacity: 0.5;\ + }\ + .emacs-mode .ace_hidden-cursors .ace_cursor{\ + opacity: 1;\ + background-color: transparent;\ + }\ + .emacs-mode .ace_overwrite-cursors .ace_cursor {\ + opacity: 1;\ + background-color: transparent;\ + border-width: 0 0 2px 2px !important;\ + }\ + .emacs-mode .ace_text-layer {\ + z-index: 4\ + }\ + .emacs-mode .ace_cursor-layer {\ + z-index: 2\ + }', 'emacsMode' + ); + } + // in emacs, gotowordleft/right should not count a space as a word.. + $formerLongWords = editor.session.$selectLongWords; + editor.session.$selectLongWords = true; + // CTRL-A should go to actual beginning of line + $formerLineStart = editor.session.$useEmacsStyleLineStart; + editor.session.$useEmacsStyleLineStart = true; + + editor.session.$emacsMark = null; // the active mark + editor.session.$emacsMarkRing = editor.session.$emacsMarkRing || []; + + editor.emacsMark = function() { + return this.session.$emacsMark; + }; + + editor.setEmacsMark = function(p) { + // to deactivate pass in a falsy value + this.session.$emacsMark = p; + }; + + editor.pushEmacsMark = function(p, activate) { + var prevMark = this.session.$emacsMark; + if (prevMark) + this.session.$emacsMarkRing.push(prevMark); + if (!p || activate) this.setEmacsMark(p); + else this.session.$emacsMarkRing.push(p); + }; + + editor.popEmacsMark = function() { + var mark = this.emacsMark(); + if (mark) { this.setEmacsMark(null); return mark; } + return this.session.$emacsMarkRing.pop(); + }; + + editor.getLastEmacsMark = function(p) { + return this.session.$emacsMark || this.session.$emacsMarkRing.slice(-1)[0]; + }; + + editor.emacsMarkForSelection = function(replacement) { + // find the mark in $emacsMarkRing corresponding to the current + // selection + var sel = this.selection, + multiRangeLength = this.multiSelect ? + this.multiSelect.getAllRanges().length : 1, + selIndex = sel.index || 0, + markRing = this.session.$emacsMarkRing, + markIndex = markRing.length - (multiRangeLength - selIndex), + lastMark = markRing[markIndex] || sel.anchor; + if (replacement) { + markRing.splice(markIndex, 1, + "row" in replacement && "column" in replacement ? + replacement : undefined); + } + return lastMark; + } + + editor.on("click", $resetMarkMode); + editor.on("changeSession", $kbSessionChange); + editor.renderer.screenToTextCoordinates = screenToTextBlockCoordinates; + editor.setStyle("emacs-mode"); + editor.commands.addCommands(commands); + exports.handler.platform = editor.commands.platform; + editor.$emacsModeHandler = this; + editor.addEventListener('copy', this.onCopy); + editor.addEventListener('paste', this.onPaste); +}; + +exports.handler.detach = function(editor) { + delete editor.renderer.screenToTextCoordinates; + editor.session.$selectLongWords = $formerLongWords; + editor.session.$useEmacsStyleLineStart = $formerLineStart; + editor.removeEventListener("click", $resetMarkMode); + editor.removeEventListener("changeSession", $kbSessionChange); + editor.unsetStyle("emacs-mode"); + editor.commands.removeCommands(commands); + editor.removeEventListener('copy', this.onCopy); + editor.removeEventListener('paste', this.onPaste); + editor.$emacsModeHandler = null; +}; + +var $kbSessionChange = function(e) { + if (e.oldSession) { + e.oldSession.$selectLongWords = $formerLongWords; + e.oldSession.$useEmacsStyleLineStart = $formerLineStart; + } + + $formerLongWords = e.session.$selectLongWords; + e.session.$selectLongWords = true; + $formerLineStart = e.session.$useEmacsStyleLineStart; + e.session.$useEmacsStyleLineStart = true; + + if (!e.session.hasOwnProperty('$emacsMark')) + e.session.$emacsMark = null; + if (!e.session.hasOwnProperty('$emacsMarkRing')) + e.session.$emacsMarkRing = []; +}; + +var $resetMarkMode = function(e) { + e.editor.session.$emacsMark = null; +}; + +var keys = require("../lib/keys").KEY_MODS; +var eMods = {C: "ctrl", S: "shift", M: "alt", CMD: "command"}; +var combinations = ["C-S-M-CMD", + "S-M-CMD", "C-M-CMD", "C-S-CMD", "C-S-M", + "M-CMD", "S-CMD", "S-M", "C-CMD", "C-M", "C-S", + "CMD", "M", "S", "C"]; +combinations.forEach(function(c) { + var hashId = 0; + c.split("-").forEach(function(c) { + hashId = hashId | keys[eMods[c]]; + }); + eMods[hashId] = c.toLowerCase() + "-"; +}); + +exports.handler.onCopy = function(e, editor) { + if (editor.$handlesEmacsOnCopy) return; + editor.$handlesEmacsOnCopy = true; + exports.handler.commands.killRingSave.exec(editor); + editor.$handlesEmacsOnCopy = false; +}; + +exports.handler.onPaste = function(e, editor) { + editor.pushEmacsMark(editor.getCursorPosition()); +}; + +exports.handler.bindKey = function(key, command) { + if (typeof key == "object") + key = key[this.platform]; + if (!key) + return; + + var ckb = this.commandKeyBinding; + key.split("|").forEach(function(keyPart) { + keyPart = keyPart.toLowerCase(); + ckb[keyPart] = command; + // register all partial key combos as null commands + // to be able to activate key combos with arbitrary length + // Example: if keyPart is "C-c C-l t" then "C-c C-l t" will + // get command assigned and "C-c" and "C-c C-l" will get + // a null command assigned in this.commandKeyBinding. For + // the lookup logic see handleKeyboard() + var keyParts = keyPart.split(" ").slice(0,-1); + keyParts.reduce(function(keyMapKeys, keyPart, i) { + var prefix = keyMapKeys[i-1] ? keyMapKeys[i-1] + ' ' : ''; + return keyMapKeys.concat([prefix + keyPart]); + }, []).forEach(function(keyPart) { + if (!ckb[keyPart]) ckb[keyPart] = "null"; + }); + }, this); +}; + +exports.handler.getStatusText = function(editor, data) { + var str = ""; + if (data.count) + str += data.count; + if (data.keyChain) + str += " " + data.keyChain + return str; +}; + +exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { + // if keyCode == -1 a non-printable key was pressed, such as just + // control. Handling those is currently not supported in this handler + if (keyCode === -1) return undefined; + + var editor = data.editor; + editor._signal("changeStatus"); + // insertstring data.count times + if (hashId == -1) { + editor.pushEmacsMark(); + if (data.count) { + var str = new Array(data.count + 1).join(key); + data.count = null; + return {command: "insertstring", args: str}; + } + } + + var modifier = eMods[hashId]; + + // CTRL + number / universalArgument for setting data.count + if (modifier == "c-" || data.count) { + var count = parseInt(key[key.length - 1]); + if (typeof count === 'number' && !isNaN(count)) { + data.count = Math.max(data.count, 0) || 0; + data.count = 10 * data.count + count; + return {command: "null"}; + } + } + + // this.commandKeyBinding maps key specs like "c-p" (for CTRL + P) to + // command objects, for lookup key needs to include the modifier + if (modifier) key = modifier + key; + + // Key combos like CTRL+X H build up the data.keyChain + if (data.keyChain) key = data.keyChain += " " + key; + + // Key combo prefixes get stored as "null" (String!) in this + // this.commandKeyBinding. When encountered no command is invoked but we + // buld up data.keyChain + var command = this.commandKeyBinding[key]; + data.keyChain = command == "null" ? key : ""; + + // there really is no command + if (!command) return undefined; + + // we pass b/c of key combo or universalArgument + if (command === "null") return {command: "null"}; + + if (command === "universalArgument") { + // if no number pressed emacs repeats action 4 times. + // minus sign is needed to allow next keypress to replace it + data.count = -4; + return {command: "null"}; + } + + // lookup command + // TODO extract special handling of markmode + // TODO special case command.command is really unnecessary, remove + var args; + if (typeof command !== "string") { + args = command.args; + if (command.command) command = command.command; + if (command === "goorselect") { + command = editor.emacsMark() ? args[1] : args[0]; + args = null; + } + } + + if (typeof command === "string") { + if (command === "insertstring" || + command === "splitline" || + command === "togglecomment") { + editor.pushEmacsMark(); + } + command = this.commands[command] || editor.commands.commands[command]; + if (!command) return undefined; + } + + if (!command.readOnly && !command.isYank) + data.lastCommand = null; + + if (!command.readOnly && editor.emacsMark()) + editor.setEmacsMark(null) + + if (data.count) { + var count = data.count; + data.count = 0; + if (!command || !command.handlesCount) { + return { + args: args, + command: { + exec: function(editor, args) { + for (var i = 0; i < count; i++) + command.exec(editor, args); + }, + multiSelectAction: command.multiSelectAction + } + }; + } else { + if (!args) args = {}; + if (typeof args === 'object') args.count = count; + } + } + + return {command: command, args: args}; +}; + +exports.emacsKeys = { + // movement + "Up|C-p" : {command: "goorselect", args: ["golineup","selectup"]}, + "Down|C-n" : {command: "goorselect", args: ["golinedown","selectdown"]}, + "Left|C-b" : {command: "goorselect", args: ["gotoleft","selectleft"]}, + "Right|C-f" : {command: "goorselect", args: ["gotoright","selectright"]}, + "C-Left|M-b" : {command: "goorselect", args: ["gotowordleft","selectwordleft"]}, + "C-Right|M-f" : {command: "goorselect", args: ["gotowordright","selectwordright"]}, + "Home|C-a" : {command: "goorselect", args: ["gotolinestart","selecttolinestart"]}, + "End|C-e" : {command: "goorselect", args: ["gotolineend","selecttolineend"]}, + "C-Home|S-M-,": {command: "goorselect", args: ["gotostart","selecttostart"]}, + "C-End|S-M-." : {command: "goorselect", args: ["gotoend","selecttoend"]}, + + // selection + "S-Up|S-C-p" : "selectup", + "S-Down|S-C-n" : "selectdown", + "S-Left|S-C-b" : "selectleft", + "S-Right|S-C-f" : "selectright", + "S-C-Left|S-M-b" : "selectwordleft", + "S-C-Right|S-M-f" : "selectwordright", + "S-Home|S-C-a" : "selecttolinestart", + "S-End|S-C-e" : "selecttolineend", + "S-C-Home" : "selecttostart", + "S-C-End" : "selecttoend", + + "C-l" : "recenterTopBottom", + "M-s" : "centerselection", + "M-g": "gotoline", + "C-x C-p": "selectall", + + // todo fix these + "C-Down": {command: "goorselect", args: ["gotopagedown","selectpagedown"]}, + "C-Up": {command: "goorselect", args: ["gotopageup","selectpageup"]}, + "PageDown|C-v": {command: "goorselect", args: ["gotopagedown","selectpagedown"]}, + "PageUp|M-v": {command: "goorselect", args: ["gotopageup","selectpageup"]}, + "S-C-Down": "selectpagedown", + "S-C-Up": "selectpageup", + + "C-s": "iSearch", + "C-r": "iSearchBackwards", + + "M-C-s": "findnext", + "M-C-r": "findprevious", + "S-M-5": "replace", + + // basic editing + "Backspace": "backspace", + "Delete|C-d": "del", + "Return|C-m": {command: "insertstring", args: "\n"}, // "newline" + "C-o": "splitline", + + "M-d|C-Delete": {command: "killWord", args: "right"}, + "C-Backspace|M-Backspace|M-Delete": {command: "killWord", args: "left"}, + "C-k": "killLine", + + "C-y|S-Delete": "yank", + "M-y": "yankRotate", + "C-g": "keyboardQuit", + + "C-w|C-S-W": "killRegion", + "M-w": "killRingSave", + "C-Space": "setMark", + "C-x C-x": "exchangePointAndMark", + + "C-t": "transposeletters", + "M-u": "touppercase", // Doesn't work + "M-l": "tolowercase", + "M-/": "autocomplete", // Doesn't work + "C-u": "universalArgument", + + "M-;": "togglecomment", + + "C-/|C-x u|S-C--|C-z": "undo", + "S-C-/|S-C-x u|C--|S-C-z": "redo", // infinite undo? + // vertical editing + "C-x r": "selectRectangularRegion", + "M-x": {command: "focusCommandLine", args: "M-x "} + // todo + // "C-x C-t" "M-t" "M-c" "F11" "C-M- "M-q" +}; + + +exports.handler.bindKeys(exports.emacsKeys); + +exports.handler.addCommands({ + recenterTopBottom: function(editor) { + var renderer = editor.renderer; + var pos = renderer.$cursorLayer.getPixelPosition(); + var h = renderer.$size.scrollerHeight - renderer.lineHeight; + var scrollTop = renderer.scrollTop; + if (Math.abs(pos.top - scrollTop) < 2) { + scrollTop = pos.top - h; + } else if (Math.abs(pos.top - scrollTop - h * 0.5) < 2) { + scrollTop = pos.top; + } else { + scrollTop = pos.top - h * 0.5; + } + editor.session.setScrollTop(scrollTop); + }, + selectRectangularRegion: function(editor) { + editor.multiSelect.toggleBlockSelection(); + }, + setMark: { + exec: function(editor, args) { + // Sets mark-mode and clears current selection. + // When mark is set, keyboard cursor movement commands become + // selection modification commands. That is, + // "goto" commands become "select" commands. + // Any insertion or mouse click resets mark-mode. + // setMark twice in a row at the same place resets markmode. + // in multi select mode, ea selection is handled individually + + if (args && args.count) { + if (editor.inMultiSelectMode) editor.forEachSelection(moveToMark); + else moveToMark(); + moveToMark(); + return; + } + + var mark = editor.emacsMark(), + ranges = editor.selection.getAllRanges(), + rangePositions = ranges.map(function(r) { return {row: r.start.row, column: r.start.column}; }), + transientMarkModeActive = true, + hasNoSelection = ranges.every(function(range) { return range.isEmpty(); }); + // if transientMarkModeActive then mark behavior is a little + // different. Deactivate the mark when setMark is run with active + // mark + if (transientMarkModeActive && (mark || !hasNoSelection)) { + if (editor.inMultiSelectMode) editor.forEachSelection({exec: editor.clearSelection.bind(editor)}); + else editor.clearSelection(); + if (mark) editor.pushEmacsMark(null); + return; + } + + if (!mark) { + rangePositions.forEach(function(pos) { editor.pushEmacsMark(pos); }); + editor.setEmacsMark(rangePositions[rangePositions.length-1]); + return; + } + + // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + function moveToMark() { + var mark = editor.popEmacsMark(); + mark && editor.moveCursorToPosition(mark); + } + + }, + readOnly: true, + handlesCount: true + }, + exchangePointAndMark: { + exec: function exchangePointAndMark$exec(editor, args) { + var sel = editor.selection; + if (!args.count && !sel.isEmpty()) { // just invert selection + sel.setSelectionRange(sel.getRange(), !sel.isBackwards()); + return; + } + + if (args.count) { // replace mark and point + var pos = {row: sel.lead.row, column: sel.lead.column}; + sel.clearSelection(); + sel.moveCursorToPosition(editor.emacsMarkForSelection(pos)); + } else { // create selection to last mark + sel.selectToPosition(editor.emacsMarkForSelection()); + } + }, + readOnly: true, + handlesCount: true, + multiSelectAction: "forEach" + }, + killWord: { + exec: function(editor, dir) { + editor.clearSelection(); + if (dir == "left") + editor.selection.selectWordLeft(); + else + editor.selection.selectWordRight(); + + var range = editor.getSelectionRange(); + var text = editor.session.getTextRange(range); + exports.killRing.add(text); + + editor.session.remove(range); + editor.clearSelection(); + }, + multiSelectAction: "forEach" + }, + killLine: function(editor) { + editor.pushEmacsMark(null); + var pos = editor.getCursorPosition(); + if (pos.column === 0 && + editor.session.doc.getLine(pos.row).length === 0) { + // If an already empty line is killed, remove + // the line entirely + editor.selection.selectLine(); + } else { + // otherwise just remove from the current cursor position + // to the end (but don't delete the selection if it's before + // the cursor) + editor.clearSelection(); + editor.selection.selectLineEnd(); + } + var range = editor.getSelectionRange(); + var text = editor.session.getTextRange(range); + exports.killRing.add(text); + + editor.session.remove(range); + editor.clearSelection(); + }, + yank: function(editor) { + editor.onPaste(exports.killRing.get() || ''); + editor.keyBinding.$data.lastCommand = "yank"; + }, + yankRotate: function(editor) { + if (editor.keyBinding.$data.lastCommand != "yank") + return; + editor.undo(); + editor.session.$emacsMarkRing.pop(); // also undo recording mark + editor.onPaste(exports.killRing.rotate()); + editor.keyBinding.$data.lastCommand = "yank"; + }, + killRegion: { + exec: function(editor) { + exports.killRing.add(editor.getCopyText()); + editor.commands.byName.cut.exec(editor); + }, + readOnly: true, + multiSelectAction: "forEach" + }, + killRingSave: { + exec: function(editor) { + // copy text and deselect. will save marks for starts of the + // selection(s) + + editor.$handlesEmacsOnCopy = true; + var marks = editor.session.$emacsMarkRing.slice(), + deselectedMarks = []; + exports.killRing.add(editor.getCopyText()); + + setTimeout(function() { + function deselect() { + var sel = editor.selection, range = sel.getRange(), + pos = sel.isBackwards() ? range.end : range.start; + deselectedMarks.push({row: pos.row, column: pos.column}); + sel.clearSelection(); + } + editor.$handlesEmacsOnCopy = false; + if (editor.inMultiSelectMode) editor.forEachSelection({exec: deselect}); + else deselect(); + editor.session.$emacsMarkRing = marks.concat(deselectedMarks.reverse()); + }, 0); + }, + readOnly: true + }, + keyboardQuit: function(editor) { + editor.selection.clearSelection(); + editor.setEmacsMark(null); + editor.keyBinding.$data.count = null; + }, + focusCommandLine: function(editor, arg) { + if (editor.showCommandLine) + editor.showCommandLine(arg); + } +}); + +exports.handler.addCommands(iSearchCommandModule.iSearchStartCommands); + +var commands = exports.handler.commands; +commands.yank.isYank = true; +commands.yankRotate.isYank = true; + +exports.killRing = { + $data: [], + add: function(str) { + str && this.$data.push(str); + if (this.$data.length > 30) + this.$data.shift(); + }, + get: function(n) { + n = n || 1; + return this.$data.slice(this.$data.length-n, this.$data.length).reverse().join('\n'); + }, + pop: function() { + if (this.$data.length > 1) + this.$data.pop(); + return this.get(); + }, + rotate: function() { + this.$data.unshift(this.$data.pop()); + return this.get(); + } +}; + +}); diff --git a/lib/ace/keyboard/emacs_test.js b/lib/ace/keyboard/emacs_test.js new file mode 100644 index 00000000..3ba5efaa --- /dev/null +++ b/lib/ace/keyboard/emacs_test.js @@ -0,0 +1,151 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { +"use strict"; + +require("../multi_select"); + +var EditSession = require("./../edit_session").EditSession, + Editor = require("./../editor").Editor, + Range = require("./../range").Range, + MockRenderer = require("./../test/mockrenderer").MockRenderer, + emacs = require('./emacs'), + assert = require("./../test/assertions"), + editor, sel; + +function initEditor(docString) { + var doc = new EditSession(docString.split("\n")); + editor = new Editor(new MockRenderer(), doc); + editor.setKeyboardHandler(emacs.handler); + sel = editor.selection; +} + +function print(obj) { + return JSON.stringify(obj, null, 2); +} + +function pluck(arr, what) { + return arr.map(function(ea) { return ea[what]; }); +} + +module.exports = { + + "test: detach removes emacs commands from command manager": function() { + initEditor(''); + assert.ok(!!editor.commands.byName["keyboardQuit"], 'setup error: emacs commands not installed'); + editor.keyBinding.removeKeyboardHandler(editor.getKeyboardHandler()); + assert.ok(!editor.commands.byName["keyboardQuit"], 'emacs commands not removed'); + }, + + "test: keyboardQuit clears selection": function() { + initEditor('foo'); + editor.selectAll(); + editor.execCommand('keyboardQuit'); + assert.ok(editor.selection.isEmpty(), 'selection non-empty'); + }, + + "test: exchangePointAndMark without mark set": function() { + initEditor('foo'); + sel.setRange(Range.fromPoints({row: 0, column: 1}, {row: 0, column: 3})); + editor.execCommand('exchangePointAndMark'); + assert.deepEqual({row: 0, column: 1}, editor.getCursorPosition(), print(editor.getCursorPosition())); + }, + + "test: exchangePointAndMark with mark set": function() { + initEditor('foo'); + editor.pushEmacsMark({row: 0, column: 1}); + editor.pushEmacsMark({row: 0, column: 2}); + editor.execCommand('exchangePointAndMark', {count: 4}); + assert.deepEqual({row: 0, column: 2}, editor.getCursorPosition(), print(editor.getCursorPosition())); + assert.deepEqual([{row: 0, column: 1}, {row: 0, column: 0}], editor.session.$emacsMarkRing, print(editor.session.$emacsMarkRing)); + }, + + "test: exchangePointAndMark with selection": function() { + initEditor('foo'); + editor.pushEmacsMark({row: 0, column: 1}); + editor.pushEmacsMark({row: 0, column: 2}); + sel.setRange(Range.fromPoints({row: 0, column: 0}, {row: 0, column: 1}), true); + editor.execCommand('exchangePointAndMark'); + assert.deepEqual({row: 0, column: 1}, editor.getCursorPosition(), print(editor.getCursorPosition())); + assert.deepEqual([{row: 0, column: 1}, {row: 0, column: 2}], editor.session.$emacsMarkRing, print(editor.session.$emacsMarkRing)); + }, + + "test: exchangePointAndMark with multi selection": function() { + initEditor('foo\nhello world\n123'); + var ranges = [[{row: 0, column: 0}, {row: 0, column: 3}], + [{row: 1, column: 0}, {row: 1, column: 5}], + [{row: 1, column: 6}, {row: 1, column: 11}]] + ranges.forEach(function(r) { + sel.addRange(Range.fromPoints(r[0], r[1])); + }); + assert.equal("foo\nhello\nworld", editor.getSelectedText()); + editor.execCommand('exchangePointAndMark'); + assert.equal("foo\nhello\nworld", editor.getSelectedText()); + assert.deepEqual(pluck(ranges, 0), pluck(sel.getAllRanges(), 'cursor'), "selections dir not inverted"); + }, + + "test: exchangePointAndMark with multi cursors": function() { + initEditor('foo\nhello world\n123'); + var ranges = [[{row: 0, column: 0}, {row: 0, column: 3}], + [{row: 1, column: 0}, {row: 1, column: 5}], + [{row: 1, column: 6}, {row: 1, column: 11}]]; + // move cursors to the start of each range and set a mark to its end + // without selecting anything + ranges.forEach(function(r) { + editor.pushEmacsMark(r[1]); + sel.addRange(Range.fromPoints(r[0], r[0])); + }); + assert.deepEqual(pluck(ranges, 0), pluck(sel.getAllRanges(), 'cursor'), print(sel.getAllRanges())); + editor.execCommand('exchangePointAndMark'); + assert.deepEqual(pluck(ranges, 1), pluck(sel.getAllRanges(), 'cursor'), "not inverted: " + print(sel.getAllRanges())); + }, + + "test: setMark with multi cursors": function() { + initEditor('foo\nhello world\n123'); + var positions = [{row: 0, column: 0}, + {row: 1, column: 0}, + {row: 1, column: 6}]; + positions.forEach(function(p) { sel.addRange(Range.fromPoints(p,p)); }); + editor.execCommand('setMark'); + assert.deepEqual(positions, editor.session.$emacsMarkRing, print(editor.session.$emacsMarkRing)); + } + +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} diff --git a/lib/ace/keyboard/hash_handler.js b/lib/ace/keyboard/hash_handler.js index f968b39b..a7dc1a93 100644 --- a/lib/ace/keyboard/hash_handler.js +++ b/lib/ace/keyboard/hash_handler.js @@ -1,116 +1,256 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck (julian.viereck@gmail.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var keyUtil = require("pilot/keys"); +var keyUtil = require("../lib/keys"); +var useragent = require("../lib/useragent"); +var KEY_MODS = keyUtil.KEY_MODS; -function HashHandler(config) { - this.setConfig(config); +function HashHandler(config, platform) { + this.platform = platform || (useragent.isMac ? "mac" : "win"); + this.commands = {}; + this.commandKeyBinding = {}; + this.addCommands(config); + this.$singleCommand = true; } +function MultiHashHandler(config, platform) { + HashHandler.call(this, config, platform); + this.$singleCommand = false; +} + +MultiHashHandler.prototype = HashHandler.prototype; + (function() { - function splitSafe(s, separator, limit, bLowerCase) { - return (bLowerCase && s.toLowerCase() || s) - .replace(/(?:^\s+|\n|\s+$)/g, "") - .split(new RegExp("[\\s ]*" + separator + "[\\s ]*", "g"), limit || 999); - } + - function parseKeys(keys, val, ret) { - var key, - hashId = 0, - parts = splitSafe(keys, "\\-", null, true), - i = 0, - l = parts.length; + this.addCommand = function(command) { + if (this.commands[command.name]) + this.removeCommand(command); - for (; i < l; ++i) { - if (keyUtil.KEY_MODS[parts[i]]) - hashId = hashId | keyUtil.KEY_MODS[parts[i]]; - else - key = parts[i] || "-"; //when empty, the splitSafe removed a '-' - } + this.commands[command.name] = command; - (ret[hashId] || (ret[hashId] = {}))[key] = val; - return ret; - } - - function objectReverse(obj, keySplit) { - var i, j, l, key, - ret = {}; - for (i in obj) { - key = obj[i]; - if (keySplit && typeof key == "string") { - key = key.split(keySplit); - for (j = 0, l = key.length; j < l; ++j) - parseKeys.call(this, key[j], i, ret); - } - else { - parseKeys.call(this, key, i, ret); - } - } - return ret; - } - - this.setConfig = function(config) { - this.$config = config; - if (typeof this.$config.reverse == "undefined") - this.$config.reverse = objectReverse.call(this, this.$config, "|"); + if (command.bindKey) + this._buildKeyHash(command); }; - /** - * This function is called by keyBinding. - */ - this.handleKeyboard = function(data, hashId, textOrKey, keyCode) { - // Figure out if a commandKey was pressed or just some text was insert. - if (hashId != 0 || keyCode != 0) { - return { - command: (this.$config.reverse[hashId] || {})[textOrKey] - } - } else { - return { - command: "inserttext", - args: { - text: textOrKey + this.removeCommand = function(command, keepCommand) { + var name = command && (typeof command === 'string' ? command : command.name); + command = this.commands[name]; + if (!keepCommand) + delete this.commands[name]; + + // exhaustive search is brute force but since removeCommand is + // not a performance critical operation this should be OK + var ckb = this.commandKeyBinding; + for (var keyId in ckb) { + var cmdGroup = ckb[keyId]; + if (cmdGroup == command) { + delete ckb[keyId]; + } else if (Array.isArray(cmdGroup)) { + var i = cmdGroup.indexOf(command); + if (i != -1) { + cmdGroup.splice(i, 1); + if (cmdGroup.length == 1) + ckb[keyId] = cmdGroup[0]; } } } + }; + + this.bindKey = function(key, command, position) { + if (typeof key == "object") { + if (position == undefined) + position = key.position; + key = key[this.platform]; + } + if (!key) + return; + if (typeof command == "function") + return this.addCommand({exec: command, bindKey: key, name: command.name || key}); + + key.split("|").forEach(function(keyPart) { + var chain = ""; + if (keyPart.indexOf(" ") != -1) { + var parts = keyPart.split(/\s+/); + keyPart = parts.pop(); + parts.forEach(function(keyPart) { + var binding = this.parseKeys(keyPart); + var id = KEY_MODS[binding.hashId] + binding.key; + chain += (chain ? " " : "") + id; + this._addCommandToBinding(chain, "chainKeys"); + }, this); + chain += " "; + } + var binding = this.parseKeys(keyPart); + var id = KEY_MODS[binding.hashId] + binding.key; + this._addCommandToBinding(chain + id, command, position); + }, this); + }; + + function getPosition(command) { + return typeof command == "object" && command.bindKey + && command.bindKey.position || 0; } -}).call(HashHandler.prototype) + this._addCommandToBinding = function(keyId, command, position) { + var ckb = this.commandKeyBinding, i; + if (!command) { + delete ckb[keyId]; + } else if (!ckb[keyId] || this.$singleCommand) { + ckb[keyId] = command; + } else { + if (!Array.isArray(ckb[keyId])) { + ckb[keyId] = [ckb[keyId]]; + } else if ((i = ckb[keyId].indexOf(command)) != -1) { + ckb[keyId].splice(i, 1); + } + + if (typeof position != "number") { + if (position || command.isDefault) + position = -100; + else + position = getPosition(command); + } + var commands = ckb[keyId]; + for (i = 0; i < commands.length; i++) { + var other = commands[i]; + var otherPos = getPosition(other); + if (otherPos > position) + break; + } + commands.splice(i, 0, command); + } + }; + + this.addCommands = function(commands) { + commands && Object.keys(commands).forEach(function(name) { + var command = commands[name]; + if (!command) + return; + + if (typeof command === "string") + return this.bindKey(command, name); + + if (typeof command === "function") + command = { exec: command }; + + if (typeof command !== "object") + return; + + if (!command.name) + command.name = name; + + this.addCommand(command); + }, this); + }; + + this.removeCommands = function(commands) { + Object.keys(commands).forEach(function(name) { + this.removeCommand(commands[name]); + }, this); + }; + + this.bindKeys = function(keyList) { + Object.keys(keyList).forEach(function(key) { + this.bindKey(key, keyList[key]); + }, this); + }; + + this._buildKeyHash = function(command) { + this.bindKey(command.bindKey, command); + }; + + // accepts keys in the form ctrl+Enter or ctrl-Enter + // keys without modifiers or shift only + this.parseKeys = function(keys) { + var parts = keys.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(x){return x}); + var key = parts.pop(); + + var keyCode = keyUtil[key]; + if (keyUtil.FUNCTION_KEYS[keyCode]) + key = keyUtil.FUNCTION_KEYS[keyCode].toLowerCase(); + else if (!parts.length) + return {key: key, hashId: -1}; + else if (parts.length == 1 && parts[0] == "shift") + return {key: key.toUpperCase(), hashId: -1}; + + var hashId = 0; + for (var i = parts.length; i--;) { + var modifier = keyUtil.KEY_MODS[parts[i]]; + if (modifier == null) { + if (typeof console != "undefined") + console.error("invalid modifier " + parts[i] + " in " + keys); + return false; + } + hashId |= modifier; + } + return {key: key, hashId: hashId}; + }; + + this.findKeyCommand = function findKeyCommand(hashId, keyString) { + var key = KEY_MODS[hashId] + keyString; + return this.commandKeyBinding[key]; + }; + + this.handleKeyboard = function(data, hashId, keyString, keyCode) { + var key = KEY_MODS[hashId] + keyString; + var command = this.commandKeyBinding[key]; + if (data.$keyChain) { + data.$keyChain += " " + key; + command = this.commandKeyBinding[data.$keyChain] || command; + } + + if (command) { + if (command == "chainKeys" || command[command.length - 1] == "chainKeys") { + data.$keyChain = data.$keyChain || key; + return {command: "null"}; + } + } + + if (data.$keyChain) { + if ((!hashId || hashId == 4) && keyString.length == 1) + data.$keyChain = data.$keyChain.slice(0, -key.length - 1); // wait for input + else if (hashId == -1 || keyCode > 0) + data.$keyChain = ""; // reset keyChain + } + return {command: command}; + }; + + this.getStatusText = function(editor, data) { + return data.$keyChain || ""; + }; + +}).call(HashHandler.prototype); exports.HashHandler = HashHandler; +exports.MultiHashHandler = MultiHashHandler; }); diff --git a/lib/ace/keyboard/keybinding.js b/lib/ace/keyboard/keybinding.js index b098e2ce..cddf0666 100644 --- a/lib/ace/keyboard/keybinding.js +++ b/lib/ace/keyboard/keybinding.js @@ -1,106 +1,143 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var useragent = require("pilot/useragent"); -var keyUtil = require("pilot/keys"); -var event = require("pilot/event"); -var settings = require("pilot/settings").settings; -var HashHandler = require("ace/keyboard/hash_handler").HashHandler; -var default_mac = require("ace/keyboard/keybinding/default_mac").bindings; -var default_win = require("ace/keyboard/keybinding/default_win").bindings; -var canon = require("pilot/canon"); -require("ace/commands/default_commands"); +var keyUtil = require("../lib/keys"); +var event = require("../lib/event"); -var KeyBinding = function(editor, config) { +var KeyBinding = function(editor) { this.$editor = editor; - this.$data = { }; - this.$keyboardHandler = null; - this.$defaulKeyboardHandler = new HashHandler(config || (useragent.isMac - ? default_mac - : default_win)); + this.$data = {editor: editor}; + this.$handlers = []; + this.setDefaultHandler(editor.commands); }; (function() { - this.setKeyboardHandler = function(keyboardHandler) { - if (this.$keyboardHandler != keyboardHandler) { - this.$data = { }; - this.$keyboardHandler = keyboardHandler; - } + this.setDefaultHandler = function(kb) { + this.removeKeyboardHandler(this.$defaultHandler); + this.$defaultHandler = kb; + this.addKeyboardHandler(kb, 0); + }; + + this.setKeyboardHandler = function(kb) { + var h = this.$handlers; + if (h[h.length - 1] == kb) + return; + + while (h[h.length - 1] && h[h.length - 1] != this.$defaultHandler) + this.removeKeyboardHandler(h[h.length - 1]); + + this.addKeyboardHandler(kb, 1); + }; + + this.addKeyboardHandler = function(kb, pos) { + if (!kb) + return; + if (typeof kb == "function" && !kb.handleKeyboard) + kb.handleKeyboard = kb; + var i = this.$handlers.indexOf(kb); + if (i != -1) + this.$handlers.splice(i, 1); + + if (pos == undefined) + this.$handlers.push(kb); + else + this.$handlers.splice(pos, 0, kb); + + if (i == -1 && kb.attach) + kb.attach(this.$editor); + }; + + this.removeKeyboardHandler = function(kb) { + var i = this.$handlers.indexOf(kb); + if (i == -1) + return false; + this.$handlers.splice(i, 1); + kb.detach && kb.detach(this.$editor); + return true; }; this.getKeyboardHandler = function() { - return this.$keyboardHandler; + return this.$handlers[this.$handlers.length - 1]; + }; + + this.getStatusText = function() { + var data = this.$data; + var editor = data.editor; + return this.$handlers.map(function(h) { + return h.getStatusText && h.getStatusText(editor, data) || ""; + }).filter(Boolean).join(" "); }; - this.$callKeyboardHandler = function (e, hashId, keyOrText, keyCode) { + this.$callKeyboardHandlers = function(hashId, keyString, keyCode, e) { var toExecute; - if (this.$keyboardHandler) { - toExecute = - this.$keyboardHandler.handleKeyboard(this.$data, hashId, keyOrText, keyCode, e); - } + var success = false; + var commands = this.$editor.commands; - // If there is nothing to execute yet, then use the default keymapping. - if (!toExecute || !toExecute.command) { - toExecute = this.$defaulKeyboardHandler. - handleKeyboard(this.$data, hashId, keyOrText, keyCode, e); - } - - if (toExecute) { - var success = canon.exec(toExecute.command, - {editor: this.$editor}, toExecute.args); - if (success) { - return event.stopEvent(e); + for (var i = this.$handlers.length; i--;) { + toExecute = this.$handlers[i].handleKeyboard( + this.$data, hashId, keyString, keyCode, e + ); + if (!toExecute || !toExecute.command) + continue; + + // allow keyboardHandler to consume keys + if (toExecute.command == "null") { + success = true; + } else { + success = commands.exec(toExecute.command, this.$editor, toExecute.args, e); } + // do not stop input events to not break repeating + if (success && e && hashId != -1 && + toExecute.passEvent != true && toExecute.command.passEvent != true + ) { + event.stopEvent(e); + } + if (success) + break; } + return success; }; this.onCommandKey = function(e, hashId, keyCode) { - key = (keyUtil[keyCode] || - String.fromCharCode(keyCode)).toLowerCase(); - - this.$callKeyboardHandler(e, hashId, key, keyCode); + var keyString = keyUtil.keyCodeToString(keyCode); + this.$callKeyboardHandlers(hashId, keyString, keyCode, e); }; this.onTextInput = function(text) { - this.$callKeyboardHandler({}, 0, text, 0); - } + var success = this.$callKeyboardHandlers(-1, text); + if (!success) + this.$editor.commands.exec("insertstring", this.$editor, text); + }; }).call(KeyBinding.prototype); diff --git a/lib/ace/keyboard/keybinding/default_mac.js b/lib/ace/keyboard/keybinding/default_mac.js deleted file mode 100644 index c13e3865..00000000 --- a/lib/ace/keyboard/keybinding/default_mac.js +++ /dev/null @@ -1,97 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -exports.bindings = { - "selectall": "Command-A", - "removeline": "Command-D", - "gotoline": "Command-L", - "togglecomment": "Command-7", - "findnext": "Command-G", - "findprevious": "Command-Shift-G", - "find": "Command-F", - "replace": "Alt-Command-R", - "undo": "Command-Z", - "redo": "Command-Shift-Z|Command-Y", - "overwrite": "Insert", - "copylinesup": "Command-Option-Up", - "movelinesup": "Option-Up", - "selecttostart": "Command-Shift-Up", - "gotostart": "Command-Home|Command-Up", - "selectup": "Shift-Up", - "golineup": "Up|Ctrl-P", - "copylinesdown": "Command-Option-Down", - "movelinesdown": "Option-Down", - "selecttoend": "Command-Shift-Down", - "gotoend": "Command-End|Command-Down", - "selectdown": "Shift-Down", - "golinedown": "Down|Ctrl-N", - "selectwordleft": "Option-Shift-Left", - "gotowordleft": "Option-Left", - "selecttolinestart": "Command-Shift-Left", - "gotolinestart": "Command-Left|Home|Ctrl-A", - "selectleft": "Shift-Left", - "gotoleft": "Left|Ctrl-B", - "selectwordright": "Option-Shift-Right", - "gotowordright": "Option-Right", - "selecttolineend": "Command-Shift-Right", - "gotolineend": "Command-Right|End|Ctrl-E", - "selectright": "Shift-Right", - "gotoright": "Right|Ctrl-F", - "selectpagedown": "Shift-PageDown", - "pagedown": "PageDown", - "gotopagedown": "Option-PageDown|Ctrl-V", - "selectpageup": "Shift-PageUp", - "pageup": "PageUp", - "gotopageup": "Option-PageUp", - "selectlinestart": "Shift-Home", - "selectlineend": "Shift-End", - "del": "Delete|Ctrl-D", - "backspace": "Ctrl-Backspace|Command-Backspace|Shift-Backspace|Backspace|Ctrl-H", - "removetolineend": "Ctrl-K", - "removetolinestart": "Option-Backspace", - "removewordleft": "Alt-Backspace|Ctrl-Alt-Backspace", - "removewordright": "Alt-Delete", - "outdent": "Shift-Tab", - "indent": "Tab", - "transposeletters": "Ctrl-T", - "splitline": "Ctrl-O", - "centerselection": "Ctrl-L" -}; - -}); \ No newline at end of file diff --git a/lib/ace/keyboard/keybinding/default_win.js b/lib/ace/keyboard/keybinding/default_win.js deleted file mode 100644 index b0d68f48..00000000 --- a/lib/ace/keyboard/keybinding/default_win.js +++ /dev/null @@ -1,88 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -exports.bindings = { - "selectall": "Ctrl-A", - "removeline": "Ctrl-D", - "gotoline": "Ctrl-L", - "togglecomment": "Ctrl-7", - "findnext": "Ctrl-K", - "findprevious": "Ctrl-Shift-K", - "find": "Ctrl-F", - "replace": "Alt-Ctrl-R", - "undo": "Ctrl-Z", - "redo": "Ctrl-Shift-Z|Ctrl-Y", - "overwrite": "Insert", - "copylinesup": "Ctrl-Alt-Up", - "movelinesup": "Alt-Up", - "selecttostart": "Alt-Shift-Up", - "gotostart": "Ctrl-Home|Ctrl-Up", - "selectup": "Shift-Up", - "golineup": "Up", - "copylinesdown": "Ctrl-Alt-Down", - "movelinesdown": "Alt-Down", - "selecttoend": "Alt-Shift-Down", - "gotoend": "Ctrl-End|Ctrl-Down", - "selectdown": "Shift-Down", - "golinedown": "Down", - "selectwordleft": "Ctrl-Shift-Left", - "gotowordleft": "Ctrl-Left", - "selecttolinestart": "Alt-Shift-Left", - "gotolinestart": "Alt-Left|Home", - "selectleft": "Shift-Left", - "gotoleft": "Left", - "selectwordright": "Ctrl-Shift-Right", - "gotowordright": "Ctrl-Right", - "selecttolineend": "Alt-Shift-Right", - "gotolineend": "Alt-Right|End", - "selectright": "Shift-Right", - "gotoright": "Right", - "selectpagedown": "Shift-PageDown", - "gotopagedown": "PageDown", - "selectpageup": "Shift-PageUp", - "gotopageup": "PageUp", - "selectlinestart": "Shift-Home", - "selectlineend": "Shift-End", - "del": "Delete", - "backspace": "Ctrl-Backspace|Command-Backspace|Option-Backspace|Shift-Backspace|Backspace", - "outdent": "Shift-Tab", - "indent": "Tab" -}; - -}); diff --git a/lib/ace/keyboard/keybinding/emacs.js b/lib/ace/keyboard/keybinding/emacs.js deleted file mode 100644 index ce0cbc06..00000000 --- a/lib/ace/keyboard/keybinding/emacs.js +++ /dev/null @@ -1,149 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Julian Viereck (julian.viereck@gmail.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var StateHandler = require("ace/keyboard/state_handler").StateHandler; -var matchCharacterOnly = require("ace/keyboard/state_handler").matchCharacterOnly; - -var emacsState = { - start: [ - { - key: "ctrl-x", - then: "c-x" - }, - { - regex: [ "(?:command-([0-9]*))*", "(down|ctrl-n)" ], - exec: "golinedown", - params: [ - { - name: "times", - match: 1, - type: "number", - defaultValue: 1 - } - ] - }, - { - regex: [ "(?:command-([0-9]*))*", "(right|ctrl-f)" ], - exec: "gotoright", - params: [ - { - name: "times", - match: 1, - type: "number", - defaultValue: 1 - } - ] - }, - { - regex: [ "(?:command-([0-9]*))*", "(up|ctrl-p)" ], - exec: "golineup", - params: [ - { - name: "times", - match: 1, - type: "number", - defaultValue: 1 - } - ] - }, - { - regex: [ "(?:command-([0-9]*))*", "(left|ctrl-b)" ], - exec: "gotoleft", - params: [ - { - name: "times", - match: 1, - type: "number", - defaultValue: 1 - } - ] - }, - { - comment: "This binding matches all printable characters except numbers as long as they are no numbers and print them n times.", - regex: [ "(?:command-([0-9]*))", "([^0-9]+)*" ], - match: matchCharacterOnly, - exec: "inserttext", - params: [ - { - name: "times", - match: 1, - type: "number", - defaultValue: "1" - }, - { - name: "text", - match: 2 - } - ] - }, - { - comment: "This binding matches numbers as long as there is no meta_number in the buffer.", - regex: [ "(command-[0-9]*)*", "([0-9]+)" ], - match: matchCharacterOnly, - disallowMatches: [ 1 ], - exec: "inserttext", - params: [ - { - name: "text", - match: 2, - type: "text" - } - ] - }, - { - regex: [ "command-([0-9]*)", "(command-[0-9]|[0-9])" ], - comment: "Stops execution if the regex /meta_[0-9]+/ matches to avoid resetting the buffer." - } - ], - "c-x": [ - { - key: "ctrl-g", - then: "start" - }, - { - key: "ctrl-s", - exec: "save", - then: "start" - } - ] -}; - -exports.Emacs = new StateHandler(emacsState); - -}); diff --git a/lib/ace/keyboard/keybinding/vim.js b/lib/ace/keyboard/keybinding/vim.js deleted file mode 100644 index abe537f7..00000000 --- a/lib/ace/keyboard/keybinding/vim.js +++ /dev/null @@ -1,112 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Julian Viereck (julian.viereck@gmail.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var StateHandler = require("ace/keyboard/state_handler").StateHandler; -var matchCharacterOnly = require("ace/keyboard/state_handler").matchCharacterOnly; - -var vimStates = { - start: [ - { - key: "i", - then: "insertMode" - }, - { - regex: [ "([0-9]*)", "(k|up)" ], - exec: "golineup", - params: [ - { - name: "times", - match: 1, - type: "number", - defaultValue: 1 - } - ] - }, - { - regex: [ "([0-9]*)", "(j|down|enter)" ], - exec: "golinedown", - params: [ - { - name: "times", - match: 1, - type: "number", - defaultValue: 1 - } - ] - }, - { - regex: [ "([0-9]*)", "(l|right)" ], - exec: "gotoright", - params: [ - { - name: "times", - match: 1, - type: "number", - defaultValue: 1 - } - ] - }, - { - regex: [ "([0-9]*)", "(h|left)" ], - exec: "gotoleft", - params: [ - { - name: "times", - match: 1, - type: "number", - defaultValue: 1 - } - ] - }, - { - comment: "Catch some keyboard input to stop it here", - match: matchCharacterOnly - } - ], - insertMode: [ - { - key: "esc", - then: "start" - } - ] -}; - -exports.Vim = new StateHandler(vimStates); - -}); diff --git a/lib/ace/keyboard/keybinding_test.js b/lib/ace/keyboard/keybinding_test.js new file mode 100644 index 00000000..617d99c4 --- /dev/null +++ b/lib/ace/keyboard/keybinding_test.js @@ -0,0 +1,69 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { +"use strict"; + +var EditSession = require("./../edit_session").EditSession, + Editor = require("./../editor").Editor, + MockRenderer = require("./../test/mockrenderer").MockRenderer, + assert = require("./../test/assertions"), + HashHandler = require('./hash_handler').HashHandler, + keys = require('../lib/keys'), + editor; + +function initEditor(docString) { + var doc = new EditSession(docString.split("\n")); + editor = new Editor(new MockRenderer(), doc); +} + +module.exports = { + + "test: adding a new keyboard handler does not remove the default handler": function() { + initEditor('abc'); + var handler = new HashHandler({'del': 'f1'}); + editor.keyBinding.setKeyboardHandler(handler); + editor.onCommandKey({}, 0, keys['f1']); + assert.equal('bc', editor.getValue(), "binding of new handler"); + editor.onCommandKey({}, 0, keys['delete']); + assert.equal('c', editor.getValue(), "bindings of the old handler should still work"); + } + +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} diff --git a/lib/ace/keyboard/state_handler.js b/lib/ace/keyboard/state_handler.js index 5861ad23..8265bbe1 100644 --- a/lib/ace/keyboard/state_handler.js +++ b/lib/ace/keyboard/state_handler.js @@ -1,41 +1,35 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Skywriter. - * - * The Initial Developer of the Original Code is - * Mozilla. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Julian Viereck (julian.viereck@gmail.com) - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; // If you're developing a new keymapping and want to get an idea what's going // on, then enable debugging. @@ -46,13 +40,13 @@ 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. */ $buildKeymappingRegex: function(keymapping) { - for (state in keymapping) { + for (var state in keymapping) { this.$buildBindingsRegex(keymapping[state]); } return keymapping; @@ -64,7 +58,8 @@ StateHandler.prototype = { if (binding.key) { binding.key = new RegExp('^' + binding.key + '$'); } else if (Array.isArray(binding.regex)) { - binding.key = new RegExp('^' + binding.regex[1] + '$'); + if (!('key' in binding)) + binding.key = new RegExp('^' + binding.regex[1] + '$'); binding.regex = new RegExp(binding.regex.join('') + '$'); } else if (binding.regex) { binding.regex = new RegExp(binding.regex + '$'); @@ -72,7 +67,7 @@ StateHandler.prototype = { }); }, - $composeBuffer: function(data, hashId, key) { + $composeBuffer: function(data, hashId, key, e) { // Initialize the data object. if (data.state == null || data.buffer == null) { data.state = "start"; @@ -101,17 +96,23 @@ StateHandler.prototype = { data.buffer = bufferToUse; } - return { - bufferToUse: bufferToUse, - symbolicName: symbolicName + var bufferObj = { + bufferToUse: bufferToUse, + symbolicName: symbolicName }; + + if (e) { + bufferObj.keyIdentifier = e.keyIdentifier; + } + + return bufferObj; }, - $find: function(data, buffer, symbolicName, hashId, key) { + $find: function(data, buffer, symbolicName, hashId, key, keyIdentifier) { // Holds the command to execute and the args if a command matched. var result = {}; - // Loop over all the bindings of the keymapp until a match is found. + // Loop over all the bindings of the keymap until a match is found. this.keymapping[data.state].some(function(binding) { var match; @@ -126,7 +127,7 @@ StateHandler.prototype = { } // Check if the match function matches. - if (binding.match && !binding.match(buffer, hashId, key, symbolicName)) { + if (binding.match && !binding.match(buffer, hashId, key, symbolicName, keyIdentifier)) { return false; } @@ -140,11 +141,11 @@ StateHandler.prototype = { } // If there is a command to execute, then figure out the - // comand and the arguments. + // command and the arguments. if (binding.exec) { result.command = binding.exec; - // Bulid the arguments. + // Build the arguments. if (binding.params) { var value; result.args = {}; @@ -190,23 +191,26 @@ StateHandler.prototype = { } }, - /** + /* * This function is called by keyBinding. */ - handleKeyboard: function(data, hashId, key) { + handleKeyboard: function(data, hashId, key, keyCode, e) { + if (hashId == -1) + hashId = 0 // If we pressed any command key but no other key, then ignore the input. // Otherwise "shift-" is added to the buffer, and later on "shift-g" - // which results in "shift-shift-g" which doesn't make senese. - if (hashId != 0 && (key == "" || String.fromCharCode(0))) { + // which results in "shift-shift-g" which doesn't make sense. + if (hashId != 0 && (key == "" || key == String.fromCharCode(0))) { return null; } // Compute the current value of the keyboard input buffer. - var r = this.$composeBuffer(data, hashId, key); + var r = this.$composeBuffer(data, hashId, key, e); var buffer = r.bufferToUse; var symbolicName = r.symbolicName; + var keyId = r.keyIdentifier; - r = this.$find(data, buffer, symbolicName, hashId, key); + r = this.$find(data, buffer, symbolicName, hashId, key, keyId); if (DEBUG) { console.log("KeyboardStateMapper#match", buffer, symbolicName, r); } @@ -215,12 +219,11 @@ StateHandler.prototype = { } } -/** +/* * This is a useful matching function and therefore is defined here so that * users of KeyboardStateMapper can use it. * - * @return boolean - * If no command key (Command|Option|Shift|Ctrl) is pressed, it + * @return {Boolean} If no command key (Command|Option|Shift|Ctrl) is pressed, it * returns true. If the only the Shift key is pressed + a character * true is returned as well. Otherwise, false is returned. * Summing up, the function returns true whenever the user typed diff --git a/lib/ace/keyboard/textarea.js b/lib/ace/keyboard/textarea.js new file mode 100644 index 00000000..470b2940 --- /dev/null +++ b/lib/ace/keyboard/textarea.js @@ -0,0 +1,82 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var HashHandler = require("./hash_handler").HashHandler; +exports.handler = new HashHandler(); + +[{ + bindKey: "Shift-Tab|Tab", + command: "passKeysToBrowser" +}, { + bindKey: {win: "Ctrl-L", mac: "Cmd-L"}, + command: "passKeysToBrowser" +}, { + bindKey: {win: "Ctrl-G", mac: "Cmd-G"}, + command: "gotoline" +}, { + bindKey: {win: "Ctrl-T|Ctrl-Shift-T", mac: "Cmd-T|Cmd-Shift-T"}, + command: "passKeysToBrowser" +}, { + bindKey: {win: "Ctrl-G", mac: "Cmd-G"}, + command: "passKeysToBrowser" +}, { + bindKey: {win: "Ctrl-G", mac: "Cmd-G"}, + command: "passKeysToBrowser" +}, { + name: "golineup", + bindKey: {win: null, mac: "Ctrl-P"}, +}, { + name: "golinedown", + bindKey: {win: null, mac: "Ctrl-N"}, +}, { + name: "gotoleft", + bindKey: {win: null, mac: "Ctrl-B"}, +}, { + name: "gotoright", + bindKey: {win: null, mac: "Ctrl-F"}, +}, { + name: "gotolineend", + bindKey: {win: null, mac: "Ctrl-E"}, +}, { + name: "gotolinestart", + bindKey: {win: null, mac: "Ctrl-A"}, +} +].forEach(function(k) { + var bindKey = k.bindKey; + if (typeof bindKey == "object") + bindKey = bindKey[exports.handler.platform]; + exports.handler.bindKey(bindKey, k.command); +}); +exports.handler.$id = "ace/keyboard/textarea"; + +}); diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index b793a280..4a2bb72c 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -1,252 +1,509 @@ -/* vim:ts=4:sts=4:sw=4: - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var event = require("pilot/event"); -var useragent = require("pilot/useragent"); -var dom = require("pilot/dom"); +var event = require("../lib/event"); +var useragent = require("../lib/useragent"); +var dom = require("../lib/dom"); +var lang = require("../lib/lang"); +var BROKEN_SETDATA = useragent.isChrome < 18; +var USE_IE_MIME_TYPE = useragent.isIE; var TextInput = function(parentNode, host) { - var text = dom.createElement("textarea"); - text.style.left = "-10000px"; - // We have too many moving parts in the iPad, so we set the text - // positioning to absolute to be able to calculate the precise position for - // cursor. Otherwise the cursor position would be relative to the screen - // coordinates (position: fixed). - if (useragent.isIPad) - text.style.position = "absolute"; + text.className = "ace_text-input"; - parentNode.appendChild(text); + if (useragent.isTouchPad) + text.setAttribute("x-palm-disable-auto-cap", true); - var PLACEHOLDER = String.fromCharCode(0); - sendText(); + text.setAttribute("wrap", "off"); + text.setAttribute("autocorrect", "off"); + text.setAttribute("autocapitalize", "off"); + text.setAttribute("spellcheck", false); + + text.style.opacity = "0"; + if (useragent.isOldIE) text.style.top = "-1000px"; + parentNode.insertBefore(text, parentNode.firstChild); + + var PLACEHOLDER = "\x01\x01"; - var inCompostion = false; var copied = false; + var pasted = false; + var inComposition = false; var tempStyle = ''; + var isSelectionEmpty = true; - function sendText(valueToSend) { - 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); - } else - host.onTextInput(value); - } + // FOCUS + // ie9 throws error if document.activeElement is accessed too soon + try { var isFocused = document.activeElement === text; } catch(e) {} + + event.addListener(text, "blur", function(e) { + host.onBlur(e); + isFocused = false; + }); + event.addListener(text, "focus", function(e) { + isFocused = true; + host.onFocus(e); + resetSelection(); + }); + this.focus = function() { + if (tempStyle) return text.focus(); + text.style.position = "fixed"; + text.style.top = "-1000px"; + text.focus(); + setTimeout(function() { + text.style.position = ""; + }, 0); + }; + this.blur = function() { text.blur(); }; + this.isFocused = function() { + return isFocused; + }; + + // modifying selection of blured textarea can focus it (chrome mac/linux) + var syncSelection = lang.delayedCall(function() { + isFocused && resetSelection(isSelectionEmpty); + }); + var syncValue = lang.delayedCall(function() { + if (!inComposition) { + text.value = PLACEHOLDER; + isFocused && resetSelection(); + } + }); + + function resetSelection(isEmpty) { + if (inComposition) + return; + + // this prevents infinite recursion on safari 8 + // see https://github.com/ajaxorg/ace/issues/2114 + inComposition = true; + + if (inputHandler) { + selectionStart = 0; + selectionEnd = isEmpty ? 0 : text.value.length - 1; + } else { + var selectionStart = isEmpty ? 2 : 1; + var selectionEnd = 2; } - copied = false; - - // Safari doesn't fire copy events if no text is selected - text.value = PLACEHOLDER; - text.select(); + // on firefox this throws if textarea is hidden + try { + text.setSelectionRange(selectionStart, selectionEnd); + } catch(e){} + + inComposition = false; } - var onTextInput = function(e) { - if (useragent.isIE && text.value.charCodeAt(0) > 128) return; - setTimeout(function() { - if (!inCompostion) - sendText(); - }, 0); - }; + function resetValue() { + if (inComposition) + return; + text.value = PLACEHOLDER; + //http://code.google.com/p/chromium/issues/detail?id=76516 + if (useragent.isWebKit) + syncValue.schedule(); + } - var onCompositionStart = function(e) { - inCompostion = true; - if (!useragent.isIE) { - sendText(); - text.value = ""; + useragent.isWebKit || host.addEventListener('changeSelection', function() { + if (host.selection.isEmpty() != isSelectionEmpty) { + isSelectionEmpty = !isSelectionEmpty; + syncSelection.schedule(); + } + }); + + resetValue(); + if (isFocused) + host.onFocus(); + + + var isAllSelected = function(text) { + return text.selectionStart === 0 && text.selectionEnd === text.value.length; + }; + // IE8 does not support setSelectionRange + if (!text.setSelectionRange && text.createTextRange) { + text.setSelectionRange = function(selectionStart, selectionEnd) { + var range = this.createTextRange(); + range.collapse(true); + range.moveStart('character', selectionStart); + range.moveEnd('character', selectionEnd); + range.select(); }; - host.onCompositionStart(); - if (!useragent.isGecko) setTimeout(onCompositionUpdate, 0); + isAllSelected = function(text) { + try { + var range = text.ownerDocument.selection.createRange(); + }catch(e) {} + if (!range || range.parentElement() != text) return false; + return range.text == text.value; + } + } + if (useragent.isOldIE) { + var inPropertyChange = false; + var onPropertyChange = function(e){ + if (inPropertyChange) + return; + var data = text.value; + if (inComposition || !data || data == PLACEHOLDER) + return; + // can happen either after delete or during insert operation + if (e && data == PLACEHOLDER[0]) + return syncProperty.schedule(); + + sendText(data); + // ie8 calls propertychange handlers synchronously! + inPropertyChange = true; + resetValue(); + inPropertyChange = false; + }; + var syncProperty = lang.delayedCall(onPropertyChange); + event.addListener(text, "propertychange", onPropertyChange); + + var keytable = { 13:1, 27:1 }; + event.addListener(text, "keyup", function (e) { + if (inComposition && (!text.value || keytable[e.keyCode])) + setTimeout(onCompositionEnd, 0); + if ((text.value.charCodeAt(0)||0) < 129) { + return syncProperty.call(); + } + inComposition ? onCompositionUpdate() : onCompositionStart(); + }); + // when user presses backspace after focusing the editor + // propertychange isn't called for the next character + event.addListener(text, "keydown", function (e) { + syncProperty.schedule(50); + }); + } + + var onSelect = function(e) { + if (copied) { + copied = false; + } else if (isAllSelected(text)) { + host.selectAll(); + resetSelection(); + } else if (inputHandler) { + resetSelection(host.selection.isEmpty()); + } }; - var onCompositionUpdate = function() { - if (!inCompostion) return; - host.onCompositionUpdate(text.value); + var inputHandler = null; + this.setInputHandler = function(cb) {inputHandler = cb}; + this.getInputHandler = function() {return inputHandler}; + var afterContextMenu = false; + + var sendText = function(data) { + if (inputHandler) { + data = inputHandler(data); + inputHandler = null; + } + if (pasted) { + resetSelection(); + if (data) + host.onPaste(data); + pasted = false; + } else if (data == PLACEHOLDER.charAt(0)) { + if (afterContextMenu) + host.execCommand("del", {source: "ace"}); + else // some versions of android do not fire keydown when pressing backspace + host.execCommand("backspace", {source: "ace"}); + } else { + if (data.substring(0, 2) == PLACEHOLDER) + data = data.substr(2); + else if (data.charAt(0) == PLACEHOLDER.charAt(0)) + data = data.substr(1); + else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) + data = data.slice(0, -1); + // can happen if undo in textarea isn't stopped + if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0)) + data = data.slice(0, -1); + + if (data) + host.onTextInput(data); + } + if (afterContextMenu) + afterContextMenu = false; + }; + var onInput = function(e) { + // console.log("onInput", inComposition) + if (inComposition) + return; + var data = text.value; + sendText(data); + resetValue(); + }; + + var handleClipboardData = function(e, data) { + var clipboardData = e.clipboardData || window.clipboardData; + if (!clipboardData || BROKEN_SETDATA) + return; + // using "Text" doesn't work on old webkit but ie needs it + // TODO are there other browsers that require "Text"? + var mime = USE_IE_MIME_TYPE ? "Text" : "text/plain"; + if (data) { + // Safari 5 has clipboardData object, but does not handle setData() + return clipboardData.setData(mime, data) !== false; + } else { + return clipboardData.getData(mime); + } }; - var onCompositionEnd = function() { - inCompostion = false; - host.onCompositionEnd(); - setTimeout(function () { - sendText(); - }, 0); - }; + var doCopy = function(e, isCut) { + var data = host.getCopyText(); + if (!data) + return event.preventDefault(e); - var onCopy = function(e) { - copied = true; - var copyText = host.getCopyText(); - if(copyText) - text.value = copyText; - else - e.preventDefault(); - text.select(); - setTimeout(function () { - sendText(); - }, 0); + if (handleClipboardData(e, data)) { + isCut ? host.onCut() : host.onCopy(); + event.preventDefault(e); + } else { + copied = true; + text.value = data; + text.select(); + setTimeout(function(){ + copied = false; + resetValue(); + resetSelection(); + isCut ? host.onCut() : host.onCopy(); + }); + } }; - + var onCut = function(e) { - copied = true; - var copyText = host.getCopyText(); - if(copyText) { - text.value = copyText; - host.onCut(); - } else - e.preventDefault(); - text.select(); - setTimeout(function () { - sendText(); - }, 0); + doCopy(e, true); + }; + + var onCopy = function(e) { + doCopy(e, false); + }; + + var onPaste = function(e) { + var data = handleClipboardData(e); + if (typeof data == "string") { + if (data) + host.onPaste(data, e); + if (useragent.isIE) + setTimeout(resetSelection); + event.preventDefault(e); + } + else { + text.value = ""; + pasted = true; + } }; event.addCommandKeyListener(text, host.onCommandKey.bind(host)); - event.addListener(text, "keypress", onTextInput); - if (useragent.isIE) { - var keytable = { 13:1, 27:1 }; - event.addListener(text, "keyup", function (e) { - if (inCompostion && (!text.value || keytable[e.keyCode])) - setTimeout(onCompositionEnd, 0); - if ((text.value.charCodeAt(0)|0) < 129) { - return; - }; - inCompostion ? onCompositionUpdate() : onCompositionStart(); - }); - }; - event.addListener(text, "textInput", onTextInput); - event.addListener(text, "paste", function(e) { - // Some browsers support the event.clipboardData API. Use this to get - // the pasted content which increases speed if pasting a lot of lines. - if (e.clipboardData && e.clipboardData.getData) { - sendText(e.clipboardData.getData("text/plain")); - e.preventDefault(); - } else - // If a browser doesn't support any of the things above, use the regular - // method to detect the pasted input. - { - onTextInput(); - } - }); - if (!useragent.isIE) { - event.addListener(text, "propertychange", onTextInput); - }; - if (useragent.isIE) { - event.addListener(text, "beforecopy", function(e) { - var copyText = host.getCopyText(); - if(copyText) - clipboardData.setData("Text", copyText); - else - e.preventDefault(); - }); + event.addListener(text, "select", onSelect); + + event.addListener(text, "input", onInput); + + event.addListener(text, "cut", onCut); + event.addListener(text, "copy", onCopy); + event.addListener(text, "paste", onPaste); + + + // Opera has no clipboard events + if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)){ event.addListener(parentNode, "keydown", function(e) { - if (e.ctrlKey && e.keyCode == 88) { - var copyText = host.getCopyText(); - if (copyText) { - clipboardData.setData("Text", copyText); - host.onCut(); - } - event.preventDefault(e) + if ((useragent.isMac && !e.metaKey) || !e.ctrlKey) + return; + + switch (e.keyCode) { + case 67: + onCopy(e); + break; + case 86: + onPaste(e); + break; + case 88: + onCut(e); + break; } }); } - else { - event.addListener(text, "copy", onCopy); - event.addListener(text, "cut", onCut); - } + + + // COMPOSITION + var onCompositionStart = function(e) { + if (inComposition || !host.onCompositionStart || host.$readOnly) + return; + // console.log("onCompositionStart", inComposition) + inComposition = {}; + host.onCompositionStart(); + setTimeout(onCompositionUpdate, 0); + host.on("mousedown", onCompositionEnd); + if (!host.selection.isEmpty()) { + host.insert(""); + host.session.markUndoGroup(); + host.selection.clearSelection(); + } + host.session.markUndoGroup(); + }; + + var onCompositionUpdate = function() { + // console.log("onCompositionUpdate", inComposition && JSON.stringify(text.value)) + if (!inComposition || !host.onCompositionUpdate || host.$readOnly) + return; + var val = text.value.replace(/\x01/g, ""); + if (inComposition.lastValue === val) return; + + host.onCompositionUpdate(val); + if (inComposition.lastValue) + host.undo(); + inComposition.lastValue = val; + if (inComposition.lastValue) { + var r = host.selection.getRange(); + host.insert(inComposition.lastValue); + host.session.markUndoGroup(); + inComposition.range = host.selection.getRange(); + host.selection.setRange(r); + host.selection.clearSelection(); + } + }; + + var onCompositionEnd = function(e) { + if (!host.onCompositionEnd || host.$readOnly) return; + // console.log("onCompositionEnd", inComposition &&inComposition.lastValue) + var c = inComposition; + inComposition = false; + var timer = setTimeout(function() { + timer = null; + var str = text.value.replace(/\x01/g, ""); + // console.log(str, c.lastValue) + if (inComposition) + return; + else if (str == c.lastValue) + resetValue(); + else if (!c.lastValue && str) { + resetValue(); + sendText(str); + } + }); + inputHandler = function compositionInputHandler(str) { + // console.log("onCompositionEnd", str, c.lastValue) + if (timer) + clearTimeout(timer); + str = str.replace(/\x01/g, ""); + if (str == c.lastValue) + return ""; + if (c.lastValue && timer) + host.undo(); + return str; + }; + host.onCompositionEnd(); + host.removeListener("mousedown", onCompositionEnd); + if (e.type == "compositionend" && c.range) { + host.selection.setRange(c.range); + } + }; + + + + var syncComposition = lang.delayedCall(onCompositionUpdate, 50); event.addListener(text, "compositionstart", onCompositionStart); if (useragent.isGecko) { - event.addListener(text, "text", onCompositionUpdate); - }; - if (useragent.isWebKit) { - event.addListener(text, "keyup", onCompositionUpdate); - }; + event.addListener(text, "text", function(){syncComposition.schedule()}); + } else { + event.addListener(text, "keyup", function(){syncComposition.schedule()}); + event.addListener(text, "keydown", function(){syncComposition.schedule()}); + } event.addListener(text, "compositionend", onCompositionEnd); - event.addListener(text, "blur", function() { - host.onBlur(); - }); - - event.addListener(text, "focus", function() { - host.onFocus(); - text.select(); - }); - - this.focus = function() { - host.onFocus(); - text.select(); - text.focus(); - }; - - this.blur = function() { - text.blur(); - }; - this.getElement = function() { return text; }; - this.onContextMenu = function(mousePos, isEmpty){ - if (mousePos) { - if(!tempStyle) - tempStyle = text.style.cssText; - text.style.cssText = 'position:fixed; z-index:1000;' + - 'left:' + (mousePos.x - 2) + 'px; top:' + (mousePos.y - 2) + 'px;' + this.setReadOnly = function(readOnly) { + text.readOnly = readOnly; + }; - } - if (isEmpty) - text.value=''; - } + this.onContextMenu = function(e) { + afterContextMenu = true; + resetSelection(host.selection.isEmpty()); + host._emit("nativecontextmenu", {target: host, domEvent: e}); + this.moveToMouse(e, true); + }; + + this.moveToMouse = function(e, bringToFront) { + if (!bringToFront && useragent.isOldIE) + return; + if (!tempStyle) + tempStyle = text.style.cssText; + text.style.cssText = (bringToFront ? "z-index:100000;" : "") + + "height:" + text.style.height + ";" + + (useragent.isIE ? "opacity:0.1;" : ""); - this.onContextMenuClose = function(){ - setTimeout(function () { + var rect = host.container.getBoundingClientRect(); + var style = dom.computedStyle(host.container); + var top = rect.top + (parseInt(style.borderTopWidth) || 0); + var left = rect.left + (parseInt(rect.borderLeftWidth) || 0); + var maxTop = rect.bottom - top - text.clientHeight -2; + var move = function(e) { + text.style.left = e.clientX - left - 2 + "px"; + text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px"; + }; + move(e); + + if (e.type != "mousedown") + return; + + if (host.renderer.$keepTextAreaAtCursor) + host.renderer.$keepTextAreaAtCursor = null; + + // on windows context menu is opened after mouseup + if (useragent.isWin && !useragent.isOldIE) + event.capture(host.container, move, onContextMenuClose); + }; + + this.onContextMenuClose = onContextMenuClose; + var closeTimeout; + function onContextMenuClose() { + clearTimeout(closeTimeout) + closeTimeout = setTimeout(function () { if (tempStyle) { text.style.cssText = tempStyle; tempStyle = ''; } - sendText(); - }, 0); + if (host.renderer.$keepTextAreaAtCursor == null) { + host.renderer.$keepTextAreaAtCursor = true; + host.renderer.$moveTextAreaToCursor(); + } + }, useragent.isOldIE ? 200 : 0); } + + var onContextMenu = function(e) { + host.textInput.onContextMenu(e); + onContextMenuClose(); + }; + event.addListener(host.renderer.scroller, "contextmenu", onContextMenu); + event.addListener(text, "contextmenu", onContextMenu); }; exports.TextInput = TextInput; diff --git a/lib/ace/keyboard/vim.js b/lib/ace/keyboard/vim.js new file mode 100644 index 00000000..17c26c16 --- /dev/null +++ b/lib/ace/keyboard/vim.js @@ -0,0 +1,6177 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/** + * Supported keybindings: + * + * Motion: + * h, j, k, l + * gj, gk + * e, E, w, W, b, B, ge, gE + * f, F, t, T + * $, ^, 0, -, +, _ + * gg, G + * % + * ', ` + * + * Operator: + * d, y, c + * dd, yy, cc + * g~, g~g~ + * >, <, >>, << + * + * Operator-Motion: + * x, X, D, Y, C, ~ + * + * Action: + * a, i, s, A, I, S, o, O + * zz, z., z, zt, zb, z- + * J + * u, Ctrl-r + * m + * r + * + * Modes: + * ESC - leave insert mode, visual mode, and clear input state. + * Ctrl-[, Ctrl-c - same as ESC. + * + * Registers: unnamed, -, a-z, A-Z, 0-9 + * (Does not respect the special case for number registers when delete + * operator is made with these commands: %, (, ), , /, ?, n, N, {, } ) + * TODO: Implement the remaining registers. + * Marks: a-z, A-Z, and 0-9 + * TODO: Implement the remaining special marks. They have more complex + * behavior. + * + * Events: + * 'vim-mode-change' - raised on the editor anytime the current mode changes, + * Event object: {mode: "visual", subMode: "linewise"} + * + * Code structure: + * 1. Default keymap + * 2. Variable declarations and short basic helpers + * 3. Instance (External API) implementation + * 4. Internal state tracking objects (input state, counter) implementation + * and instanstiation + * 5. Key handler (the main command dispatcher) implementation + * 6. Motion, operator, and action implementations + * 7. Helper functions for the key handler, motions, operators, and actions + * 8. Set up Vim to work as a keymap for CodeMirror. + */ + +define(function(require, exports, module) { + 'use strict'; + + function log() { + var d = ""; + function format(p) { + if (typeof p != "object") + return p + ""; + if ("line" in p) { + return p.line + ":" + p.ch; + } + if ("anchor" in p) { + return format(p.anchor) + "->" + format(p.head); + } + if (Array.isArray(p)) + return "[" + p.map(function(x) { + return format(x); + }) + "]"; + return JSON.stringify(p); + } + for (var i = 0; i < arguments.length; i++) { + var p = arguments[i]; + var f = format(p); + d += f + " "; + } + console.log(d); + } + var Range = require("../range").Range; + var EventEmitter = require("../lib/event_emitter").EventEmitter; + var dom = require("../lib/dom"); + var oop = require("../lib/oop"); + var KEYS = require("../lib/keys"); + var event = require("../lib/event"); + var Search = require("../search").Search; + var useragent = require("../lib/useragent"); + var SearchHighlight = require("../search_highlight").SearchHighlight; + var multiSelectCommands = require("../commands/multi_select_commands"); + var TextModeTokenRe = require("../mode/text").Mode.prototype.tokenRe; + require("../multi_select"); + + var CodeMirror = function(ace) { + this.ace = ace; + this.state = {}; + this.marks = {}; + this.$uid = 0; + this.onChange = this.onChange.bind(this); + this.onSelectionChange = this.onSelectionChange.bind(this); + this.onBeforeEndOperation = this.onBeforeEndOperation.bind(this); + this.ace.on('change', this.onChange); + this.ace.on('changeSelection', this.onSelectionChange); + this.ace.on('beforeEndOperation', this.onBeforeEndOperation); + }; + CodeMirror.Pos = function(line, ch) { + if (!(this instanceof Pos)) return new Pos(line, ch); + this.line = line; this.ch = ch; + }; + CodeMirror.defineOption = function(name, val, setter) {}; + CodeMirror.commands = { + redo: function(cm) { cm.ace.redo(); }, + undo: function(cm) { cm.ace.undo(); }, + newlineAndIndent: function(cm) { cm.ace.insert("\n"); }, + }; + CodeMirror.keyMap = {}; + CodeMirror.addClass = CodeMirror.rmClass = + CodeMirror.e_stop = function() {}; + CodeMirror.keyName = function(e) { + if (e.key) return e.key; + var key = (KEYS[e.keyCode] || ""); + if (key.length == 1) key = key.toUpperCase(); + key = event.getModifierString(e).replace(/(^|-)\w/g, function(m) { + return m.toUpperCase(); + }) + key; + return key; + }; + CodeMirror.keyMap['default'] = function(key) { + return function(cm) { + var cmd = cm.ace.commands.commandKeyBinding[key.toLowerCase()]; + return cmd && cm.ace.execCommand(cmd) !== false; + }; + }; + CodeMirror.lookupKey = function lookupKey(key, map, handle) { + if (typeof map == "string") + map = CodeMirror.keyMap[map]; + var found = typeof map == "function" ? map(key) : map[key]; + if (found === false) return "nothing"; + if (found === "...") return "multi"; + if (found != null && handle(found)) return "handled"; + + if (map.fallthrough) { + if (!Array.isArray(map.fallthrough)) + return lookupKey(key, map.fallthrough, handle); + for (var i = 0; i < map.fallthrough.length; i++) { + var result = lookupKey(key, map.fallthrough[i], handle); + if (result) return result; + } + } + }; + + CodeMirror.signal = function(o, name, e) { return o._signal(name, e) }; + CodeMirror.on = event.addListener; + CodeMirror.off = event.removeListener; + CodeMirror.isWordChar = function(ch) { + TextModeTokenRe.lastIndex = 0; + return TextModeTokenRe.test(ch); + }; + +(function() { + oop.implement(CodeMirror.prototype, EventEmitter); + + this.destroy = function() { + this.ace.off('change', this.onChange); + this.ace.off('changeSelection', this.onSelectionChange); + this.ace.off('beforeEndOperation', this.onBeforeEndOperation); + this.removeOverlay(); + }; + this.virtualSelectionMode = function() { + return this.ace.inVirtualSelectionMode && this.ace.selection.index; + }; + this.onChange = function(delta) { + if (delta.action[0] == 'i') { + var change = { text: delta.lines }; + var curOp = this.curOp = this.curOp || {}; + if (!curOp.changeHandlers) + curOp.changeHandlers = this._eventRegistry["change"] && this._eventRegistry["change"].slice(); + if (this.virtualSelectionMode()) return; + if (!curOp.lastChange) { + curOp.lastChange = curOp.change = change; + } else { + curOp.lastChange.next = curOp.lastChange = change; + } + } + this.$updateMarkers(delta); + }; + this.onSelectionChange = function() { + var curOp = this.curOp = this.curOp || {}; + if (!curOp.cursorActivityHandlers) + curOp.cursorActivityHandlers = this._eventRegistry["cursorActivity"] && this._eventRegistry["cursorActivity"].slice(); + this.curOp.cursorActivity = true; + if (this.ace.inMultiSelectMode) { + this.ace.keyBinding.removeKeyboardHandler(multiSelectCommands.keyboardHandler); + } + }; + this.operation = function(fn, force) { + if (!force && this.curOp || force && this.curOp && this.curOp.force) { + return fn(); + } + if (force || !this.ace.curOp) { + if (this.curOp) + this.onBeforeEndOperation(); + } + if (!this.ace.curOp) { + var prevOp = this.ace.prevOp; + this.ace.startOperation({ + command: { name: "vim", scrollIntoView: "cursor" } + }); + } + var curOp = this.curOp = this.curOp || {}; + this.curOp.force = force; + var result = fn(); + if (this.ace.curOp && this.ace.curOp.command.name == "vim") { + this.ace.endOperation(); + if (!curOp.cursorActivity && !curOp.lastChange && prevOp) + this.ace.prevOp = prevOp; + } + if (force || !this.ace.curOp) { + if (this.curOp) + this.onBeforeEndOperation(); + } + return result; + }; + this.onBeforeEndOperation = function() { + var op = this.curOp; + if (op) { + if (op.change) { this.signal("change", op.change, op); } + if (op && op.cursorActivity) { this.signal("cursorActivity", null, op); } + this.curOp = null; + } + }; + + this.signal = function(eventName, e, handlers) { + var listeners = handlers ? handlers[eventName + "Handlers"] + : (this._eventRegistry || {})[eventName]; + if (!listeners) + return; + listeners = listeners.slice(); + for (var i=0; i 0) { + point.row += rowShift; + point.column += point.row == end.row ? colShift : 0; + continue; + } + if (!isInsert && cmp2 <= 0) { + point.row = start.row; + point.column = start.column; + if (cmp2 === 0) + point.bias = 1; + } + } + }; + var Marker = function(cm, id, row, column) { + this.cm = cm; + this.id = id; + this.row = row; + this.column = column; + cm.marks[this.id] = this; + }; + Marker.prototype.clear = function() { delete this.cm.marks[this.id] }; + Marker.prototype.find = function() { return toCmPos(this) }; + this.setBookmark = function(cursor, options) { + var bm = new Marker(this, this.$uid++, cursor.line, cursor.ch); + if (!options || !options.insertLeft) + bm.$insertRight = true; + this.marks[bm.id] = bm; + return bm; + }; + this.moveH = function(increment, unit) { + if (unit == 'char') { + var sel = this.ace.selection; + sel.clearSelection(); + sel.moveCursorBy(0, increment); + } + }; + this.findPosV = function(start, amount, unit, goalColumn) { + if (unit == 'page') { + var renderer = this.ace.renderer; + var config = renderer.layerConfig; + amount = amount * Math.floor(config.height / config.lineHeight); + unit = 'line'; + } + if (unit == 'line') { + var screenPos = this.ace.session.documentToScreenPosition(start.line, start.ch); + if (goalColumn != null) + screenPos.column = goalColumn; + screenPos.row += amount; + // not what codemirror does but vim mode needs only this + screenPos.row = Math.min(Math.max(0, screenPos.row), this.ace.session.getScreenLength() - 1); + var pos = this.ace.session.screenToDocumentPosition(screenPos.row, screenPos.column); + return toCmPos(pos); + } else { + debugger; + } + }; + this.charCoords = function(pos, mode) { + if (mode == 'div' || !mode) { + var sc = this.ace.session.documentToScreenPosition(pos.line, pos.ch); + return {left: sc.column, top: sc.row}; + }if (mode == 'local') { + var renderer = this.ace.renderer; + var sc = this.ace.session.documentToScreenPosition(pos.line, pos.ch); + var lh = renderer.layerConfig.lineHeight; + var cw = renderer.layerConfig.characterWidth; + var top = lh * sc.row; + return {left: sc.column * cw, top: top, bottom: top + lh}; + } + }; + this.coordsChar = function(pos, mode) { + var renderer = this.ace.renderer; + if (mode == 'local') { + var row = Math.max(0, Math.floor(pos.top / renderer.lineHeight)); + var col = Math.max(0, Math.floor(pos.left / renderer.characterWidth)); + var ch = renderer.session.screenToDocumentPosition(row, col); + return toCmPos(ch); + } else if (mode == 'div') { + throw "not implemented"; + } + }; + this.getSearchCursor = function(query, pos, caseFold) { + var caseSensitive = false; + var isRegexp = false; + if (query instanceof RegExp && !query.global) { + caseSensitive = !query.ignoreCase; + query = query.source; + isRegexp = true; + } + var search = new Search(); + if (pos.ch == undefined) pos.ch = Number.MAX_VALUE; + var acePos = {row: pos.line, column: pos.ch}; + var cm = this; + var last = null; + return { + findNext: function() { return this.find(false) }, + findPrevious: function() {return this.find(true) }, + find: function(back) { + search.setOptions({ + needle: query, + caseSensitive: caseSensitive, + wrap: false, + backwards: back, + regExp: isRegexp, + start: last || acePos + }); + var range = search.find(cm.ace.session); + if (range && range.isEmpty()) { + if (cm.getLine(range.start.row).length == range.start.column) { + search.$options.start = range; + range = search.find(cm.ace.session); + } + } + last = range; + return last; + }, + from: function() { return last && toCmPos(last.start) }, + to: function() { return last && toCmPos(last.end) }, + replace: function(text) { + if (last) { + last.end = cm.ace.session.doc.replace(last, text); + } + } + }; + }; + this.scrollTo = function(x, y) { + var renderer = this.ace.renderer; + var config = renderer.layerConfig; + var maxHeight = config.maxHeight; + maxHeight -= (renderer.$size.scrollerHeight - renderer.lineHeight) * renderer.$scrollPastEnd; + if (y != null) this.ace.session.setScrollTop(Math.max(0, Math.min(y, maxHeight))); + if (x != null) this.ace.session.setScrollLeft(Math.max(0, Math.min(x, config.width))); + }; + this.scrollInfo = function() { return 0; }; + this.scrollIntoView = function(pos, margin) { + if (pos) { + var renderer = this.ace.renderer; + var viewMargin = { "top": 0, "bottom": margin }; + renderer.scrollCursorIntoView(toAcePos(pos), + (renderer.lineHeight * 2) / renderer.$size.scrollerHeight, viewMargin); + } + }; + this.getLine = function(row) { return this.ace.session.getLine(row) }; + this.getRange = function(s, e) { + return this.ace.session.getTextRange(new Range(s.line, s.ch, e.line, e.ch)); + }; + this.replaceRange = function(text, s, e) { + if (!e) e = s; + return this.ace.session.replace(new Range(s.line, s.ch, e.line, e.ch), text); + }; + this.replaceSelections = function(p) { + var sel = this.ace.selection; + if (this.ace.inVirtualSelectionMode) { + this.ace.session.replace(sel.getRange(), p[0] || ""); + return; + } + sel.inVirtualSelectionMode = true; + var ranges = sel.rangeList.ranges; + if (!ranges.length) ranges = [this.ace.multiSelect.getRange()]; + for (var i = ranges.length; i--;) + this.ace.session.replace(ranges[i], p[i] || ""); + sel.inVirtualSelectionMode = false; + }; + this.getSelection = function() { + return this.ace.getSelectedText(); + }; + this.getSelections = function() { + return this.listSelections().map(function(x) { + return this.getRange(x.anchor, x.head); + }, this); + }; + this.getInputField = function() { + return this.ace.textInput.getElement(); + }; + this.getWrapperElement = function() { + return this.ace.containter; + }; + var optMap = { + indentWithTabs: "useSoftTabs", + indentUnit: "tabSize", + firstLineNumber: "firstLineNumber" + }; + this.setOption = function(name, val) { + this.state[name] = val; + switch (name) { + case 'indentWithTabs': + name = optMap[name]; + val = !val; + break; + default: + name = optMap[name]; + } + if (name) + this.ace.setOption(name, val); + }; + this.getOption = function(name, val) { + var aceOpt = optMap[name]; + if (aceOpt) + val = this.ace.getOption(aceOpt); + switch (name) { + case 'indentWithTabs': + name = optMap[name]; + return !val; + } + return aceOpt ? val : this.state[name]; + }; + this.toggleOverwrite = function(on) { + this.state.overwrite = on; + return this.ace.setOverwrite(on); + }; + this.addOverlay = function(o) { + if (!this.$searchHighlight || !this.$searchHighlight.session) { + var highlight = new SearchHighlight(null, "ace_highlight-marker", "text"); + var marker = this.ace.session.addDynamicMarker(highlight); + highlight.id = marker.id; + highlight.session = this.ace.session; + highlight.destroy = function(o) { + highlight.session.off("change", highlight.updateOnChange); + highlight.session.off("changeEditor", highlight.destroy); + highlight.session.removeMarker(highlight.id); + highlight.session = null; + }; + highlight.updateOnChange = function(delta) { + var row = delta.start.row; + if (row == delta.end.row) highlight.cache[row] = undefined; + else highlight.cache.splice(row, highlight.cache.length); + }; + highlight.session.on("changeEditor", highlight.destroy); + highlight.session.on("change", highlight.updateOnChange); + } + var re = new RegExp(o.query.source, "gmi"); + this.$searchHighlight = o.highlight = highlight; + this.$searchHighlight.setRegexp(re); + this.ace.renderer.updateBackMarkers(); + }; + this.removeOverlay = function(o) { + if (this.$searchHighlight && this.$searchHighlight.session) { + this.$searchHighlight.destroy(); + } + }; + this.getScrollInfo = function() { + var renderer = this.ace.renderer; + var config = renderer.layerConfig; + return { + left: renderer.scrollLeft, + top: renderer.scrollTop, + height: config.maxHeight, + width: config.width, + clientHeight: config.height, + clientWidth: config.width + }; + }; + this.getValue = function() { + return this.ace.getValue(); + }; + this.setValue = function(v) { + return this.ace.setValue(v); + }; + this.getTokenTypeAt = function(pos) { + var token = this.ace.session.getTokenAt(pos.line, pos.ch); + return token && /comment|string/.test(token.type) ? "string" : ""; + }; + this.findMatchingBracket = function(pos) { + var m = this.ace.session.findMatchingBracket(toAcePos(pos)); + return {to: m && toCmPos(m)}; + }; + this.indentLine = function(line, method) { + if (method === true) + this.ace.session.indentRows(line, line, "\t"); + else if (method === false) + this.ace.session.outdentRows(new Range(line, 0, line, 0)); + }; + this.indexFromPos = function(pos) { + return this.ace.session.doc.positionToIndex(toAcePos(pos)); + }; + this.posFromIndex = function(index) { + return toCmPos(this.ace.session.doc.indexToPosition(index)); + }; + this.focus = function(index) { + return this.ace.focus(); + }; + this.blur = function(index) { + return this.ace.blur(); + }; + this.defaultTextHeight = function(index) { + return this.ace.renderer.layerConfig.lineHeight; + }; + this.scanForBracket = function(pos, dir, _, options) { + var re = options.bracketRegex.source; + if (dir == 1) { + var m = this.ace.session.$findClosingBracket(re.slice(1, 2), toAcePos(pos), /paren|text/); + } else { + var m = this.ace.session.$findOpeningBracket(re.slice(-2, -1), {row: pos.line, column: pos.ch + 1}, /paren|text/); + } + return m && {pos: toCmPos(m)}; + }; + this.refresh = function() { + return this.ace.resize(true); + }; + this.getMode = function() { + return { name : this.getOption("mode") }; + } +}).call(CodeMirror.prototype); + function toAcePos(cmPos) { + return {row: cmPos.line, column: cmPos.ch}; + } + function toCmPos(acePos) { + return new Pos(acePos.row, acePos.column); + } + + var StringStream = CodeMirror.StringStream = function(string, tabSize) { + this.pos = this.start = 0; + this.string = string; + this.tabSize = tabSize || 8; + this.lastColumnPos = this.lastColumnValue = 0; + this.lineStart = 0; + }; + + StringStream.prototype = { + eol: function() {return this.pos >= this.string.length;}, + sol: function() {return this.pos == this.lineStart;}, + peek: function() {return this.string.charAt(this.pos) || undefined;}, + next: function() { + if (this.pos < this.string.length) + return this.string.charAt(this.pos++); + }, + eat: function(match) { + var ch = this.string.charAt(this.pos); + if (typeof match == "string") var ok = ch == match; + else var ok = ch && (match.test ? match.test(ch) : match(ch)); + if (ok) {++this.pos; return ch;} + }, + eatWhile: function(match) { + var start = this.pos; + while (this.eat(match)){} + return this.pos > start; + }, + eatSpace: function() { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; + return this.pos > start; + }, + skipToEnd: function() {this.pos = this.string.length;}, + skipTo: function(ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) {this.pos = found; return true;} + }, + backUp: function(n) {this.pos -= n;}, + column: function() { + throw "not implemented"; + }, + indentation: function() { + throw "not implemented"; + }, + match: function(pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; + var substr = this.string.substr(this.pos, pattern.length); + if (cased(substr) == cased(pattern)) { + if (consume !== false) this.pos += pattern.length; + return true; + } + } else { + var match = this.string.slice(this.pos).match(pattern); + if (match && match.index > 0) return null; + if (match && consume !== false) this.pos += match[0].length; + return match; + } + }, + current: function(){return this.string.slice(this.start, this.pos);}, + hideFirstChars: function(n, inner) { + this.lineStart += n; + try { return inner(); } + finally { this.lineStart -= n; } + } + }; + +// todo replace with showCommandLine +CodeMirror.defineExtension = function(name, fn) { + CodeMirror.prototype[name] = fn; +}; +dom.importCssString(".normal-mode .ace_cursor{\ + border: 1px solid red;\ + background-color: red;\ + opacity: 0.5;\ +}\ +.normal-mode .ace_hidden-cursors .ace_cursor{\ + background-color: transparent;\ +}\ +.ace_dialog {\ + position: absolute;\ + left: 0; right: 0;\ + background: white;\ + z-index: 15;\ + padding: .1em .8em;\ + overflow: hidden;\ + color: #333;\ +}\ +.ace_dialog-top {\ + border-bottom: 1px solid #eee;\ + top: 0;\ +}\ +.ace_dialog-bottom {\ + border-top: 1px solid #eee;\ + bottom: 0;\ +}\ +.ace_dialog input {\ + border: none;\ + outline: none;\ + background: transparent;\ + width: 20em;\ + color: inherit;\ + font-family: monospace;\ +}", "vimMode"); +(function() { + function closeNotification(cm, newVal) { + if (cm.state.currentNotificationClose) + cm.state.currentNotificationClose(); + cm.state.currentNotificationClose = newVal; + } + + CodeMirror.defineExtension("openDialog", function(template, callback, options) { + if (this.virtualSelectionMode()) return; + if (!options) options = {}; + + closeNotification(this, null); + + var dialog = dialogDiv(this, template, options.bottom); + var closed = false, me = this; + function close(newVal) { + if (typeof newVal == 'string') { + inp.value = newVal; + } else { + if (closed) return; + closed = true; + dialog.parentNode.removeChild(dialog); + me.focus(); + + if (options.onClose) options.onClose(dialog); + } + } + + var inp = dialog.getElementsByTagName("input")[0], button; + if (inp) { + if (options.value) { + inp.value = options.value; + if (options.select !== false) inp.select(); + } + + if (options.onInput) + CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);}); + if (options.onKeyUp) + CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);}); + + CodeMirror.on(inp, "keydown", function(e) { + if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } + if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) { + inp.blur(); + CodeMirror.e_stop(e); + close(); + } + if (e.keyCode == 13) callback(inp.value); + }); + + if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close); + + inp.focus(); + } else if (button = dialog.getElementsByTagName("button")[0]) { + CodeMirror.on(button, "click", function() { + close(); + me.focus(); + }); + + if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close); + + button.focus(); + } + return close; + }); + + CodeMirror.defineExtension("openNotification", function(template, options) { + if (this.virtualSelectionMode()) return; + closeNotification(this, close); + var dialog = dialogDiv(this, template, options && options.bottom); + var closed = false, doneTimer; + var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000; + + function close() { + if (closed) return; + closed = true; + clearTimeout(doneTimer); + dialog.parentNode.removeChild(dialog); + } + + CodeMirror.on(dialog, 'click', function(e) { + CodeMirror.e_preventDefault(e); + close(); + }); + + if (duration) + doneTimer = setTimeout(close, duration); + + return close; + }); +})(); + + + var defaultKeymap = [ + // Key to key mapping. This goes first to make it possible to override + // existing mappings. + { keys: '', type: 'keyToKey', toKeys: 'h' }, + { keys: '', type: 'keyToKey', toKeys: 'l' }, + { keys: '', type: 'keyToKey', toKeys: 'k' }, + { keys: '', type: 'keyToKey', toKeys: 'j' }, + { keys: '', type: 'keyToKey', toKeys: 'l' }, + { keys: '', type: 'keyToKey', toKeys: 'h', context: 'normal'}, + { keys: '', type: 'keyToKey', toKeys: 'W' }, + { keys: '', type: 'keyToKey', toKeys: 'B', context: 'normal' }, + { keys: '', type: 'keyToKey', toKeys: 'w' }, + { keys: '', type: 'keyToKey', toKeys: 'b', context: 'normal' }, + { keys: '', type: 'keyToKey', toKeys: 'j' }, + { keys: '', type: 'keyToKey', toKeys: 'k' }, + { keys: '', type: 'keyToKey', toKeys: '' }, + { keys: '', type: 'keyToKey', toKeys: '' }, + { keys: '', type: 'keyToKey', toKeys: '', context: 'insert' }, + { keys: '', type: 'keyToKey', toKeys: '', context: 'insert' }, + { keys: 's', type: 'keyToKey', toKeys: 'cl', context: 'normal' }, + { keys: 's', type: 'keyToKey', toKeys: 'xi', context: 'visual'}, + { keys: 'S', type: 'keyToKey', toKeys: 'cc', context: 'normal' }, + { keys: 'S', type: 'keyToKey', toKeys: 'dcc', context: 'visual' }, + { keys: '', type: 'keyToKey', toKeys: '0' }, + { keys: '', type: 'keyToKey', toKeys: '$' }, + { keys: '', type: 'keyToKey', toKeys: '' }, + { keys: '', type: 'keyToKey', toKeys: '' }, + { keys: '', type: 'keyToKey', toKeys: 'j^', context: 'normal' }, + // Motions + { keys: 'H', type: 'motion', motion: 'moveToTopLine', motionArgs: { linewise: true, toJumplist: true }}, + { keys: 'M', type: 'motion', motion: 'moveToMiddleLine', motionArgs: { linewise: true, toJumplist: true }}, + { keys: 'L', type: 'motion', motion: 'moveToBottomLine', motionArgs: { linewise: true, toJumplist: true }}, + { keys: 'h', type: 'motion', motion: 'moveByCharacters', motionArgs: { forward: false }}, + { keys: 'l', type: 'motion', motion: 'moveByCharacters', motionArgs: { forward: true }}, + { keys: 'j', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, linewise: true }}, + { keys: 'k', type: 'motion', motion: 'moveByLines', motionArgs: { forward: false, linewise: true }}, + { keys: 'gj', type: 'motion', motion: 'moveByDisplayLines', motionArgs: { forward: true }}, + { keys: 'gk', type: 'motion', motion: 'moveByDisplayLines', motionArgs: { forward: false }}, + { keys: 'w', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: false }}, + { keys: 'W', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: false, bigWord: true }}, + { keys: 'e', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: true, inclusive: true }}, + { keys: 'E', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: true, bigWord: true, inclusive: true }}, + { keys: 'b', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false }}, + { keys: 'B', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false, bigWord: true }}, + { keys: 'ge', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: true, inclusive: true }}, + { keys: 'gE', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: true, bigWord: true, inclusive: true }}, + { keys: '{', type: 'motion', motion: 'moveByParagraph', motionArgs: { forward: false, toJumplist: true }}, + { keys: '}', type: 'motion', motion: 'moveByParagraph', motionArgs: { forward: true, toJumplist: true }}, + { keys: '', type: 'motion', motion: 'moveByPage', motionArgs: { forward: true }}, + { keys: '', type: 'motion', motion: 'moveByPage', motionArgs: { forward: false }}, + { keys: '', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: true, explicitRepeat: true }}, + { keys: '', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: false, explicitRepeat: true }}, + { keys: 'gg', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: false, explicitRepeat: true, linewise: true, toJumplist: true }}, + { keys: 'G', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: true, explicitRepeat: true, linewise: true, toJumplist: true }}, + { keys: '0', type: 'motion', motion: 'moveToStartOfLine' }, + { keys: '^', type: 'motion', motion: 'moveToFirstNonWhiteSpaceCharacter' }, + { keys: '+', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true }}, + { keys: '-', type: 'motion', motion: 'moveByLines', motionArgs: { forward: false, toFirstChar:true }}, + { keys: '_', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true, repeatOffset:-1 }}, + { keys: '$', type: 'motion', motion: 'moveToEol', motionArgs: { inclusive: true }}, + { keys: '%', type: 'motion', motion: 'moveToMatchedSymbol', motionArgs: { inclusive: true, toJumplist: true }}, + { keys: 'f', type: 'motion', motion: 'moveToCharacter', motionArgs: { forward: true , inclusive: true }}, + { keys: 'F', type: 'motion', motion: 'moveToCharacter', motionArgs: { forward: false }}, + { keys: 't', type: 'motion', motion: 'moveTillCharacter', motionArgs: { forward: true, inclusive: true }}, + { keys: 'T', type: 'motion', motion: 'moveTillCharacter', motionArgs: { forward: false }}, + { keys: ';', type: 'motion', motion: 'repeatLastCharacterSearch', motionArgs: { forward: true }}, + { keys: ',', type: 'motion', motion: 'repeatLastCharacterSearch', motionArgs: { forward: false }}, + { keys: '\'', type: 'motion', motion: 'goToMark', motionArgs: {toJumplist: true, linewise: true}}, + { keys: '`', type: 'motion', motion: 'goToMark', motionArgs: {toJumplist: true}}, + { keys: ']`', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: true } }, + { keys: '[`', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: false } }, + { keys: ']\'', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: true, linewise: true } }, + { keys: '[\'', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: false, linewise: true } }, + // the next two aren't motions but must come before more general motion declarations + { keys: ']p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true, matchIndent: true}}, + { keys: '[p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true, matchIndent: true}}, + { keys: ']', type: 'motion', motion: 'moveToSymbol', motionArgs: { forward: true, toJumplist: true}}, + { keys: '[', type: 'motion', motion: 'moveToSymbol', motionArgs: { forward: false, toJumplist: true}}, + { keys: '|', type: 'motion', motion: 'moveToColumn'}, + { keys: 'o', type: 'motion', motion: 'moveToOtherHighlightedEnd', context:'visual'}, + { keys: 'O', type: 'motion', motion: 'moveToOtherHighlightedEnd', motionArgs: {sameLine: true}, context:'visual'}, + // Operators + { keys: 'd', type: 'operator', operator: 'delete' }, + { keys: 'y', type: 'operator', operator: 'yank' }, + { keys: 'c', type: 'operator', operator: 'change' }, + { keys: '>', type: 'operator', operator: 'indent', operatorArgs: { indentRight: true }}, + { keys: '<', type: 'operator', operator: 'indent', operatorArgs: { indentRight: false }}, + { keys: 'g~', type: 'operator', operator: 'changeCase' }, + { keys: 'gu', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, isEdit: true }, + { keys: 'gU', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, isEdit: true }, + { keys: 'n', type: 'motion', motion: 'findNext', motionArgs: { forward: true, toJumplist: true }}, + { keys: 'N', type: 'motion', motion: 'findNext', motionArgs: { forward: false, toJumplist: true }}, + // Operator-Motion dual commands + { keys: 'x', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorMotionArgs: { visualLine: false }}, + { keys: 'X', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: false }, operatorMotionArgs: { visualLine: true }}, + { keys: 'D', type: 'operatorMotion', operator: 'delete', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'}, + { keys: 'D', type: 'operator', operator: 'delete', operatorArgs: { linewise: true }, context: 'visual'}, + { keys: 'Y', type: 'operatorMotion', operator: 'yank', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'}, + { keys: 'Y', type: 'operator', operator: 'yank', operatorArgs: { linewise: true }, context: 'visual'}, + { keys: 'C', type: 'operatorMotion', operator: 'change', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'}, + { keys: 'C', type: 'operator', operator: 'change', operatorArgs: { linewise: true }, context: 'visual'}, + { keys: '~', type: 'operatorMotion', operator: 'changeCase', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorArgs: { shouldMoveCursor: true }, context: 'normal'}, + { keys: '~', type: 'operator', operator: 'changeCase', context: 'visual'}, + { keys: '', type: 'operatorMotion', operator: 'delete', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false }, context: 'insert' }, + // Actions + { keys: '', type: 'action', action: 'jumpListWalk', actionArgs: { forward: true }}, + { keys: '', type: 'action', action: 'jumpListWalk', actionArgs: { forward: false }}, + { keys: '', type: 'action', action: 'scroll', actionArgs: { forward: true, linewise: true }}, + { keys: '', type: 'action', action: 'scroll', actionArgs: { forward: false, linewise: true }}, + { keys: 'a', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'charAfter' }, context: 'normal' }, + { keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'eol' }, context: 'normal' }, + { keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'endOfSelectedArea' }, context: 'visual' }, + { keys: 'i', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'inplace' }, context: 'normal' }, + { keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'firstNonBlank'}, context: 'normal' }, + { keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'startOfSelectedArea' }, context: 'visual' }, + { keys: 'o', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: true }, context: 'normal' }, + { keys: 'O', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: false }, context: 'normal' }, + { keys: 'v', type: 'action', action: 'toggleVisualMode' }, + { keys: 'V', type: 'action', action: 'toggleVisualMode', actionArgs: { linewise: true }}, + { keys: '', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }}, + { keys: 'gv', type: 'action', action: 'reselectLastSelection' }, + { keys: 'J', type: 'action', action: 'joinLines', isEdit: true }, + { keys: 'p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true }}, + { keys: 'P', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true }}, + { keys: 'r', type: 'action', action: 'replace', isEdit: true }, + { keys: '@', type: 'action', action: 'replayMacro' }, + { keys: 'q', type: 'action', action: 'enterMacroRecordMode' }, + // Handle Replace-mode as a special case of insert mode. + { keys: 'R', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { replace: true }}, + { keys: 'u', type: 'action', action: 'undo', context: 'normal' }, + { keys: 'u', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, context: 'visual', isEdit: true }, + { keys: 'U', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, context: 'visual', isEdit: true }, + { keys: '', type: 'action', action: 'redo' }, + { keys: 'm', type: 'action', action: 'setMark' }, + { keys: '"', type: 'action', action: 'setRegister' }, + { keys: 'zz', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'center' }}, + { keys: 'z.', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'center' }, motion: 'moveToFirstNonWhiteSpaceCharacter' }, + { keys: 'zt', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'top' }}, + { keys: 'z', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'top' }, motion: 'moveToFirstNonWhiteSpaceCharacter' }, + { keys: 'z-', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }}, + { keys: 'zb', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }, motion: 'moveToFirstNonWhiteSpaceCharacter' }, + { keys: '.', type: 'action', action: 'repeatLastEdit' }, + { keys: '', type: 'action', action: 'incrementNumberToken', isEdit: true, actionArgs: {increase: true, backtrack: false}}, + { keys: '', type: 'action', action: 'incrementNumberToken', isEdit: true, actionArgs: {increase: false, backtrack: false}}, + // Text object motions + { keys: 'a', type: 'motion', motion: 'textObjectManipulation' }, + { keys: 'i', type: 'motion', motion: 'textObjectManipulation', motionArgs: { textObjectInner: true }}, + // Search + { keys: '/', type: 'search', searchArgs: { forward: true, querySrc: 'prompt', toJumplist: true }}, + { keys: '?', type: 'search', searchArgs: { forward: false, querySrc: 'prompt', toJumplist: true }}, + { keys: '*', type: 'search', searchArgs: { forward: true, querySrc: 'wordUnderCursor', wholeWordOnly: true, toJumplist: true }}, + { keys: '#', type: 'search', searchArgs: { forward: false, querySrc: 'wordUnderCursor', wholeWordOnly: true, toJumplist: true }}, + { keys: 'g*', type: 'search', searchArgs: { forward: true, querySrc: 'wordUnderCursor', toJumplist: true }}, + { keys: 'g#', type: 'search', searchArgs: { forward: false, querySrc: 'wordUnderCursor', toJumplist: true }}, + // Ex command + { keys: ':', type: 'ex' } + ]; + + var Pos = CodeMirror.Pos; + + var Vim = function() { return vimApi; } //{ + function enterVimMode(cm) { + cm.setOption('disableInput', true); + cm.setOption('showCursorWhenSelecting', false); + CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"}); + cm.on('cursorActivity', onCursorActivity); + maybeInitVimState(cm); + CodeMirror.on(cm.getInputField(), 'paste', getOnPasteFn(cm)); + } + + function leaveVimMode(cm) { + cm.setOption('disableInput', false); + cm.off('cursorActivity', onCursorActivity); + CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm)); + cm.state.vim = null; + } + + function detachVimMap(cm, next) { + if (this == CodeMirror.keyMap.vim) + CodeMirror.rmClass(cm.getWrapperElement(), "cm-fat-cursor"); + + if (!next || next.attach != attachVimMap) + leaveVimMode(cm, false); + } + function attachVimMap(cm, prev) { + if (this == CodeMirror.keyMap.vim) + CodeMirror.addClass(cm.getWrapperElement(), "cm-fat-cursor"); + + if (!prev || prev.attach != attachVimMap) + enterVimMode(cm); + } + + // Deprecated, simply setting the keymap works again. + CodeMirror.defineOption('vimMode', false, function(cm, val, prev) { + if (val && cm.getOption("keyMap") != "vim") + cm.setOption("keyMap", "vim"); + else if (!val && prev != CodeMirror.Init && /^vim/.test(cm.getOption("keyMap"))) + cm.setOption("keyMap", "default"); + }); + + function cmKey(key, cm) { + if (!cm) { return undefined; } + var vimKey = cmKeyToVimKey(key); + if (!vimKey) { + return false; + } + var cmd = CodeMirror.Vim.findKey(cm, vimKey); + if (typeof cmd == 'function') { + CodeMirror.signal(cm, 'vim-keypress', vimKey); + } + return cmd; + } + + var modifiers = {'Shift': 'S', 'Ctrl': 'C', 'Alt': 'A', 'Cmd': 'D', 'Mod': 'A'}; + var specialKeys = {Enter:'CR',Backspace:'BS',Delete:'Del'}; + function cmKeyToVimKey(key) { + if (key.charAt(0) == '\'') { + // Keypress character binding of format "'a'" + return key.charAt(1); + } + var pieces = key.split('-'); + if (/-$/.test(key)) { + // If the - key was typed, split will result in 2 extra empty strings + // in the array. Replace them with 1 '-'. + pieces.splice(-2, 2, '-'); + } + var lastPiece = pieces[pieces.length - 1]; + if (pieces.length == 1 && pieces[0].length == 1) { + // No-modifier bindings use literal character bindings above. Skip. + return false; + } else if (pieces.length == 2 && pieces[0] == 'Shift' && lastPiece.length == 1) { + // Ignore Shift+char bindings as they should be handled by literal character. + return false; + } + var hasCharacter = false; + for (var i = 0; i < pieces.length; i++) { + var piece = pieces[i]; + if (piece in modifiers) { pieces[i] = modifiers[piece]; } + else { hasCharacter = true; } + if (piece in specialKeys) { pieces[i] = specialKeys[piece]; } + } + if (!hasCharacter) { + // Vim does not support modifier only keys. + return false; + } + // TODO: Current bindings expect the character to be lower case, but + // it looks like vim key notation uses upper case. + if (isUpperCase(lastPiece)) { + pieces[pieces.length - 1] = lastPiece.toLowerCase(); + } + return '<' + pieces.join('-') + '>'; + } + + function getOnPasteFn(cm) { + var vim = cm.state.vim; + if (!vim.onPasteFn) { + vim.onPasteFn = function() { + if (!vim.insertMode) { + cm.setCursor(offsetCursor(cm.getCursor(), 0, 1)); + actions.enterInsertMode(cm, {}, vim); + } + }; + } + return vim.onPasteFn; + } + + var numberRegex = /[\d]/; + var wordCharTest = [CodeMirror.isWordChar, function(ch) { + return ch && !CodeMirror.isWordChar(ch) && !/\s/.test(ch); + }], bigWordCharTest = [function(ch) { + return /\S/.test(ch); + }]; + function makeKeyRange(start, size) { + var keys = []; + for (var i = start; i < start + size; i++) { + keys.push(String.fromCharCode(i)); + } + return keys; + } + var upperCaseAlphabet = makeKeyRange(65, 26); + var lowerCaseAlphabet = makeKeyRange(97, 26); + var numbers = makeKeyRange(48, 10); + var validMarks = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['<', '>']); + var validRegisters = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['-', '"', '.', ':', '/']); + + function isLine(cm, line) { + return line >= cm.firstLine() && line <= cm.lastLine(); + } + function isLowerCase(k) { + return (/^[a-z]$/).test(k); + } + function isMatchableSymbol(k) { + return '()[]{}'.indexOf(k) != -1; + } + function isNumber(k) { + return numberRegex.test(k); + } + function isUpperCase(k) { + return (/^[A-Z]$/).test(k); + } + function isWhiteSpaceString(k) { + return (/^\s*$/).test(k); + } + function inArray(val, arr) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] == val) { + return true; + } + } + return false; + } + + var options = {}; + function defineOption(name, defaultValue, type, aliases, callback) { + if (defaultValue === undefined && !callback) { + throw Error('defaultValue is required unless callback is provided'); + } + if (!type) { type = 'string'; } + options[name] = { + type: type, + defaultValue: defaultValue, + callback: callback + }; + if (aliases) { + for (var i = 0; i < aliases.length; i++) { + options[aliases[i]] = options[name]; + } + } + if (defaultValue) { + setOption(name, defaultValue); + } + } + + function setOption(name, value, cm, cfg) { + var option = options[name]; + cfg = cfg || {}; + var scope = cfg.scope; + if (!option) { + throw Error('Unknown option: ' + name); + } + if (option.type == 'boolean') { + if (value && value !== true) { + throw Error('Invalid argument: ' + name + '=' + value); + } else if (value !== false) { + // Boolean options are set to true if value is not defined. + value = true; + } + } + if (option.callback) { + if (scope !== 'local') { + option.callback(value, undefined); + } + if (scope !== 'global' && cm) { + option.callback(value, cm); + } + } else { + if (scope !== 'local') { + option.value = option.type == 'boolean' ? !!value : value; + } + if (scope !== 'global' && cm) { + cm.state.vim.options[name] = {value: value}; + } + } + } + + function getOption(name, cm, cfg) { + var option = options[name]; + cfg = cfg || {}; + var scope = cfg.scope; + if (!option) { + throw Error('Unknown option: ' + name); + } + if (option.callback) { + var local = cm && option.callback(undefined, cm); + if (scope !== 'global' && local !== undefined) { + return local; + } + if (scope !== 'local') { + return option.callback(); + } + return; + } else { + var local = (scope !== 'global') && (cm && cm.state.vim.options[name]); + return (local || (scope !== 'local') && option || {}).value; + } + } + + defineOption('filetype', undefined, 'string', ['ft'], function(name, cm) { + // Option is local. Do nothing for global. + if (cm === undefined) { + return; + } + // The 'filetype' option proxies to the CodeMirror 'mode' option. + if (name === undefined) { + var mode = cm.getMode().name; + return mode == 'null' ? '' : mode; + } else { + var mode = name == '' ? 'null' : name; + cm.setOption('mode', mode); + } + }); + + var createCircularJumpList = function() { + var size = 100; + var pointer = -1; + var head = 0; + var tail = 0; + var buffer = new Array(size); + function add(cm, oldCur, newCur) { + var current = pointer % size; + var curMark = buffer[current]; + function useNextSlot(cursor) { + var next = ++pointer % size; + var trashMark = buffer[next]; + if (trashMark) { + trashMark.clear(); + } + buffer[next] = cm.setBookmark(cursor); + } + if (curMark) { + var markPos = curMark.find(); + // avoid recording redundant cursor position + if (markPos && !cursorEqual(markPos, oldCur)) { + useNextSlot(oldCur); + } + } else { + useNextSlot(oldCur); + } + useNextSlot(newCur); + head = pointer; + tail = pointer - size + 1; + if (tail < 0) { + tail = 0; + } + } + function move(cm, offset) { + pointer += offset; + if (pointer > head) { + pointer = head; + } else if (pointer < tail) { + pointer = tail; + } + var mark = buffer[(size + pointer) % size]; + // skip marks that are temporarily removed from text buffer + if (mark && !mark.find()) { + var inc = offset > 0 ? 1 : -1; + var newCur; + var oldCur = cm.getCursor(); + do { + pointer += inc; + mark = buffer[(size + pointer) % size]; + // skip marks that are the same as current position + if (mark && + (newCur = mark.find()) && + !cursorEqual(oldCur, newCur)) { + break; + } + } while (pointer < head && pointer > tail); + } + return mark; + } + return { + cachedCursor: undefined, //used for # and * jumps + add: add, + move: move + }; + }; + + // Returns an object to track the changes associated insert mode. It + // clones the object that is passed in, or creates an empty object one if + // none is provided. + var createInsertModeChanges = function(c) { + if (c) { + // Copy construction + return { + changes: c.changes, + expectCursorActivityForChange: c.expectCursorActivityForChange + }; + } + return { + // Change list + changes: [], + // Set to true on change, false on cursorActivity. + expectCursorActivityForChange: false + }; + }; + + function MacroModeState() { + this.latestRegister = undefined; + this.isPlaying = false; + this.isRecording = false; + this.replaySearchQueries = []; + this.onRecordingDone = undefined; + this.lastInsertModeChanges = createInsertModeChanges(); + } + MacroModeState.prototype = { + exitMacroRecordMode: function() { + var macroModeState = vimGlobalState.macroModeState; + if (macroModeState.onRecordingDone) { + macroModeState.onRecordingDone(); // close dialog + } + macroModeState.onRecordingDone = undefined; + macroModeState.isRecording = false; + }, + enterMacroRecordMode: function(cm, registerName) { + var register = + vimGlobalState.registerController.getRegister(registerName); + if (register) { + register.clear(); + this.latestRegister = registerName; + if (cm.openDialog) { + this.onRecordingDone = cm.openDialog( + '(recording)['+registerName+']', null, {bottom:true}); + } + this.isRecording = true; + } + } + }; + + function maybeInitVimState(cm) { + if (!cm.state.vim) { + // Store instance state in the CodeMirror object. + cm.state.vim = { + inputState: new InputState(), + // Vim's input state that triggered the last edit, used to repeat + // motions and operators with '.'. + lastEditInputState: undefined, + // Vim's action command before the last edit, used to repeat actions + // with '.' and insert mode repeat. + lastEditActionCommand: undefined, + // When using jk for navigation, if you move from a longer line to a + // shorter line, the cursor may clip to the end of the shorter line. + // If j is pressed again and cursor goes to the next line, the + // cursor should go back to its horizontal position on the longer + // line if it can. This is to keep track of the horizontal position. + lastHPos: -1, + // Doing the same with screen-position for gj/gk + lastHSPos: -1, + // The last motion command run. Cleared if a non-motion command gets + // executed in between. + lastMotion: null, + marks: {}, + // Mark for rendering fake cursor for visual mode. + fakeCursor: null, + insertMode: false, + // Repeat count for changes made in insert mode, triggered by key + // sequences like 3,i. Only exists when insertMode is true. + insertModeRepeat: undefined, + visualMode: false, + // If we are in visual line mode. No effect if visualMode is false. + visualLine: false, + visualBlock: false, + lastSelection: null, + lastPastedText: null, + sel: {}, + // Buffer-local/window-local values of vim options. + options: {} + }; + } + return cm.state.vim; + } + var vimGlobalState; + function resetVimGlobalState() { + vimGlobalState = { + // The current search query. + searchQuery: null, + // Whether we are searching backwards. + searchIsReversed: false, + // Replace part of the last substituted pattern + lastSubstituteReplacePart: undefined, + jumpList: createCircularJumpList(), + macroModeState: new MacroModeState, + // Recording latest f, t, F or T motion command. + lastChararacterSearch: {increment:0, forward:true, selectedCharacter:''}, + registerController: new RegisterController({}), + // search history buffer + searchHistoryController: new HistoryController({}), + // ex Command history buffer + exCommandHistoryController : new HistoryController({}) + }; + for (var optionName in options) { + var option = options[optionName]; + option.value = option.defaultValue; + } + } + + var lastInsertModeKeyTimer; + var vimApi= { + buildKeyMap: function() { + // TODO: Convert keymap into dictionary format for fast lookup. + }, + // Testing hook, though it might be useful to expose the register + // controller anyways. + getRegisterController: function() { + return vimGlobalState.registerController; + }, + // Testing hook. + resetVimGlobalState_: resetVimGlobalState, + + // Testing hook. + getVimGlobalState_: function() { + return vimGlobalState; + }, + + // Testing hook. + maybeInitVimState_: maybeInitVimState, + + suppressErrorLogging: false, + + InsertModeKey: InsertModeKey, + map: function(lhs, rhs, ctx) { + // Add user defined key bindings. + exCommandDispatcher.map(lhs, rhs, ctx); + }, + unmap: function(lhs, ctx) { + // remove user defined key bindings. + exCommandDispatcher.unmap(lhs, ctx); + }, + // TODO: Expose setOption and getOption as instance methods. Need to decide how to namespace + // them, or somehow make them work with the existing CodeMirror setOption/getOption API. + setOption: setOption, + getOption: getOption, + defineOption: defineOption, + defineEx: function(name, prefix, func){ + if (name.indexOf(prefix) !== 0) { + throw new Error('(Vim.defineEx) "'+prefix+'" is not a prefix of "'+name+'", command not registered'); + } + exCommands[name]=func; + exCommandDispatcher.commandMap_[prefix]={name:name, shortName:prefix, type:'api'}; + }, + handleKey: function (cm, key, origin) { + var command = this.findKey(cm, key, origin); + if (typeof command === 'function') { + return command(); + } + }, + /** + * This is the outermost function called by CodeMirror, after keys have + * been mapped to their Vim equivalents. + * + * Finds a command based on the key (and cached keys if there is a + * multi-key sequence). Returns `undefined` if no key is matched, a noop + * function if a partial match is found (multi-key), and a function to + * execute the bound command if a a key is matched. The function always + * returns true. + */ + findKey: function(cm, key, origin) { + var vim = maybeInitVimState(cm); + function handleMacroRecording() { + var macroModeState = vimGlobalState.macroModeState; + if (macroModeState.isRecording) { + if (key == 'q') { + macroModeState.exitMacroRecordMode(); + clearInputState(cm); + return true; + } + if (origin != 'mapping') { + logKey(macroModeState, key); + } + } + } + function handleEsc() { + if (key == '') { + // Clear input state and get back to normal mode. + clearInputState(cm); + if (vim.visualMode) { + exitVisualMode(cm); + } else if (vim.insertMode) { + exitInsertMode(cm); + } + return true; + } + } + function doKeyToKey(keys) { + // TODO: prevent infinite recursion. + var match; + while (keys) { + // Pull off one command key, which is either a single character + // or a special sequence wrapped in '<' and '>', e.g. ''. + match = (/<\w+-.+?>|<\w+>|./).exec(keys); + key = match[0]; + keys = keys.substring(match.index + key.length); + CodeMirror.Vim.handleKey(cm, key, 'mapping'); + } + } + + function handleKeyInsertMode() { + if (handleEsc()) { return true; } + var keys = vim.inputState.keyBuffer = vim.inputState.keyBuffer + key; + var keysAreChars = key.length == 1; + var match = commandDispatcher.matchCommand(keys, defaultKeymap, vim.inputState, 'insert'); + // Need to check all key substrings in insert mode. + while (keys.length > 1 && match.type != 'full') { + var keys = vim.inputState.keyBuffer = keys.slice(1); + var thisMatch = commandDispatcher.matchCommand(keys, defaultKeymap, vim.inputState, 'insert'); + if (thisMatch.type != 'none') { match = thisMatch; } + } + if (match.type == 'none') { clearInputState(cm); return false; } + else if (match.type == 'partial') { + if (lastInsertModeKeyTimer) { window.clearTimeout(lastInsertModeKeyTimer); } + lastInsertModeKeyTimer = window.setTimeout( + function() { if (vim.insertMode && vim.inputState.keyBuffer) { clearInputState(cm); } }, + getOption('insertModeEscKeysTimeout')); + return !keysAreChars; + } + + if (lastInsertModeKeyTimer) { window.clearTimeout(lastInsertModeKeyTimer); } + if (keysAreChars) { + var here = cm.getCursor(); + cm.replaceRange('', offsetCursor(here, 0, -(keys.length - 1)), here, '+input'); + } + clearInputState(cm); + return match.command; + } + + function handleKeyNonInsertMode() { + if (handleMacroRecording() || handleEsc()) { return true; }; + + var keys = vim.inputState.keyBuffer = vim.inputState.keyBuffer + key; + if (/^[1-9]\d*$/.test(keys)) { return true; } + + var keysMatcher = /^(\d*)(.*)$/.exec(keys); + if (!keysMatcher) { clearInputState(cm); return false; } + var context = vim.visualMode ? 'visual' : + 'normal'; + var match = commandDispatcher.matchCommand(keysMatcher[2] || keysMatcher[1], defaultKeymap, vim.inputState, context); + if (match.type == 'none') { clearInputState(cm); return false; } + else if (match.type == 'partial') { return true; } + + vim.inputState.keyBuffer = ''; + var keysMatcher = /^(\d*)(.*)$/.exec(keys); + if (keysMatcher[1] && keysMatcher[1] != '0') { + vim.inputState.pushRepeatDigit(keysMatcher[1]); + } + return match.command; + } + + var command; + if (vim.insertMode) { command = handleKeyInsertMode(); } + else { command = handleKeyNonInsertMode(); } + if (command === false) { + return undefined; + } else if (command === true) { + // TODO: Look into using CodeMirror's multi-key handling. + // Return no-op since we are caching the key. Counts as handled, but + // don't want act on it just yet. + return function() {}; + } else { + return function() { + return cm.operation(function() { + cm.curOp.isVimOp = true; + try { + if (command.type == 'keyToKey') { + doKeyToKey(command.toKeys); + } else { + commandDispatcher.processCommand(cm, vim, command); + } + } catch (e) { + // clear VIM state in case it's in a bad state. + cm.state.vim = undefined; + maybeInitVimState(cm); + if (!CodeMirror.Vim.suppressErrorLogging) { + console['log'](e); + } + throw e; + } + return true; + }); + }; + } + }, + handleEx: function(cm, input) { + exCommandDispatcher.processCommand(cm, input); + }, + + defineMotion: defineMotion, + defineAction: defineAction, + defineOperator: defineOperator, + mapCommand: mapCommand, + _mapCommand: _mapCommand, + + exitVisualMode: exitVisualMode, + exitInsertMode: exitInsertMode + }; + + // Represents the current input state. + function InputState() { + this.prefixRepeat = []; + this.motionRepeat = []; + + this.operator = null; + this.operatorArgs = null; + this.motion = null; + this.motionArgs = null; + this.keyBuffer = []; // For matching multi-key commands. + this.registerName = null; // Defaults to the unnamed register. + } + InputState.prototype.pushRepeatDigit = function(n) { + if (!this.operator) { + this.prefixRepeat = this.prefixRepeat.concat(n); + } else { + this.motionRepeat = this.motionRepeat.concat(n); + } + }; + InputState.prototype.getRepeat = function() { + var repeat = 0; + if (this.prefixRepeat.length > 0 || this.motionRepeat.length > 0) { + repeat = 1; + if (this.prefixRepeat.length > 0) { + repeat *= parseInt(this.prefixRepeat.join(''), 10); + } + if (this.motionRepeat.length > 0) { + repeat *= parseInt(this.motionRepeat.join(''), 10); + } + } + return repeat; + }; + + function clearInputState(cm, reason) { + cm.state.vim.inputState = new InputState(); + CodeMirror.signal(cm, 'vim-command-done', reason); + } + + /* + * Register stores information about copy and paste registers. Besides + * text, a register must store whether it is linewise (i.e., when it is + * pasted, should it insert itself into a new line, or should the text be + * inserted at the cursor position.) + */ + function Register(text, linewise, blockwise) { + this.clear(); + this.keyBuffer = [text || '']; + this.insertModeChanges = []; + this.searchQueries = []; + this.linewise = !!linewise; + this.blockwise = !!blockwise; + } + Register.prototype = { + setText: function(text, linewise, blockwise) { + this.keyBuffer = [text || '']; + this.linewise = !!linewise; + this.blockwise = !!blockwise; + }, + pushText: function(text, linewise) { + // if this register has ever been set to linewise, use linewise. + if (linewise) { + if (!this.linewise) { + this.keyBuffer.push('\n'); + } + this.linewise = true; + } + this.keyBuffer.push(text); + }, + pushInsertModeChanges: function(changes) { + this.insertModeChanges.push(createInsertModeChanges(changes)); + }, + pushSearchQuery: function(query) { + this.searchQueries.push(query); + }, + clear: function() { + this.keyBuffer = []; + this.insertModeChanges = []; + this.searchQueries = []; + this.linewise = false; + }, + toString: function() { + return this.keyBuffer.join(''); + } + }; + + /* + * vim registers allow you to keep many independent copy and paste buffers. + * See http://usevim.com/2012/04/13/registers/ for an introduction. + * + * RegisterController keeps the state of all the registers. An initial + * state may be passed in. The unnamed register '"' will always be + * overridden. + */ + function RegisterController(registers) { + this.registers = registers; + this.unnamedRegister = registers['"'] = new Register(); + registers['.'] = new Register(); + registers[':'] = new Register(); + registers['/'] = new Register(); + } + RegisterController.prototype = { + pushText: function(registerName, operator, text, linewise, blockwise) { + if (linewise && text.charAt(0) == '\n') { + text = text.slice(1) + '\n'; + } + if (linewise && text.charAt(text.length - 1) !== '\n'){ + text += '\n'; + } + // Lowercase and uppercase registers refer to the same register. + // Uppercase just means append. + var register = this.isValidRegister(registerName) ? + this.getRegister(registerName) : null; + // if no register/an invalid register was specified, things go to the + // default registers + if (!register) { + switch (operator) { + case 'yank': + // The 0 register contains the text from the most recent yank. + this.registers['0'] = new Register(text, linewise, blockwise); + break; + case 'delete': + case 'change': + if (text.indexOf('\n') == -1) { + // Delete less than 1 line. Update the small delete register. + this.registers['-'] = new Register(text, linewise); + } else { + // Shift down the contents of the numbered registers and put the + // deleted text into register 1. + this.shiftNumericRegisters_(); + this.registers['1'] = new Register(text, linewise); + } + break; + } + // Make sure the unnamed register is set to what just happened + this.unnamedRegister.setText(text, linewise, blockwise); + return; + } + + // If we've gotten to this point, we've actually specified a register + var append = isUpperCase(registerName); + if (append) { + register.pushText(text, linewise); + } else { + register.setText(text, linewise, blockwise); + } + // The unnamed register always has the same value as the last used + // register. + this.unnamedRegister.setText(register.toString(), linewise); + }, + // Gets the register named @name. If one of @name doesn't already exist, + // create it. If @name is invalid, return the unnamedRegister. + getRegister: function(name) { + if (!this.isValidRegister(name)) { + return this.unnamedRegister; + } + name = name.toLowerCase(); + if (!this.registers[name]) { + this.registers[name] = new Register(); + } + return this.registers[name]; + }, + isValidRegister: function(name) { + return name && inArray(name, validRegisters); + }, + shiftNumericRegisters_: function() { + for (var i = 9; i >= 2; i--) { + this.registers[i] = this.getRegister('' + (i - 1)); + } + } + }; + function HistoryController() { + this.historyBuffer = []; + this.iterator; + this.initialPrefix = null; + } + HistoryController.prototype = { + // the input argument here acts a user entered prefix for a small time + // until we start autocompletion in which case it is the autocompleted. + nextMatch: function (input, up) { + var historyBuffer = this.historyBuffer; + var dir = up ? -1 : 1; + if (this.initialPrefix === null) this.initialPrefix = input; + for (var i = this.iterator + dir; up ? i >= 0 : i < historyBuffer.length; i+= dir) { + var element = historyBuffer[i]; + for (var j = 0; j <= element.length; j++) { + if (this.initialPrefix == element.substring(0, j)) { + this.iterator = i; + return element; + } + } + } + // should return the user input in case we reach the end of buffer. + if (i >= historyBuffer.length) { + this.iterator = historyBuffer.length; + return this.initialPrefix; + } + // return the last autocompleted query or exCommand as it is. + if (i < 0 ) return input; + }, + pushInput: function(input) { + var index = this.historyBuffer.indexOf(input); + if (index > -1) this.historyBuffer.splice(index, 1); + if (input.length) this.historyBuffer.push(input); + }, + reset: function() { + this.initialPrefix = null; + this.iterator = this.historyBuffer.length; + } + }; + var commandDispatcher = { + matchCommand: function(keys, keyMap, inputState, context) { + var matches = commandMatches(keys, keyMap, context, inputState); + if (!matches.full && !matches.partial) { + return {type: 'none'}; + } else if (!matches.full && matches.partial) { + return {type: 'partial'}; + } + + var bestMatch; + for (var i = 0; i < matches.full.length; i++) { + var match = matches.full[i]; + if (!bestMatch) { + bestMatch = match; + } + } + if (bestMatch.keys.slice(-11) == '') { + inputState.selectedCharacter = lastChar(keys); + } + return {type: 'full', command: bestMatch}; + }, + processCommand: function(cm, vim, command) { + vim.inputState.repeatOverride = command.repeatOverride; + switch (command.type) { + case 'motion': + this.processMotion(cm, vim, command); + break; + case 'operator': + this.processOperator(cm, vim, command); + break; + case 'operatorMotion': + this.processOperatorMotion(cm, vim, command); + break; + case 'action': + this.processAction(cm, vim, command); + break; + case 'search': + this.processSearch(cm, vim, command); + break; + case 'ex': + case 'keyToEx': + this.processEx(cm, vim, command); + break; + default: + break; + } + }, + processMotion: function(cm, vim, command) { + vim.inputState.motion = command.motion; + vim.inputState.motionArgs = copyArgs(command.motionArgs); + this.evalInput(cm, vim); + }, + processOperator: function(cm, vim, command) { + var inputState = vim.inputState; + if (inputState.operator) { + if (inputState.operator == command.operator) { + // Typing an operator twice like 'dd' makes the operator operate + // linewise + inputState.motion = 'expandToLine'; + inputState.motionArgs = { linewise: true }; + this.evalInput(cm, vim); + return; + } else { + // 2 different operators in a row doesn't make sense. + clearInputState(cm); + } + } + inputState.operator = command.operator; + inputState.operatorArgs = copyArgs(command.operatorArgs); + if (vim.visualMode) { + // Operating on a selection in visual mode. We don't need a motion. + this.evalInput(cm, vim); + } + }, + processOperatorMotion: function(cm, vim, command) { + var visualMode = vim.visualMode; + var operatorMotionArgs = copyArgs(command.operatorMotionArgs); + if (operatorMotionArgs) { + // Operator motions may have special behavior in visual mode. + if (visualMode && operatorMotionArgs.visualLine) { + vim.visualLine = true; + } + } + this.processOperator(cm, vim, command); + if (!visualMode) { + this.processMotion(cm, vim, command); + } + }, + processAction: function(cm, vim, command) { + var inputState = vim.inputState; + var repeat = inputState.getRepeat(); + var repeatIsExplicit = !!repeat; + var actionArgs = copyArgs(command.actionArgs) || {}; + if (inputState.selectedCharacter) { + actionArgs.selectedCharacter = inputState.selectedCharacter; + } + // Actions may or may not have motions and operators. Do these first. + if (command.operator) { + this.processOperator(cm, vim, command); + } + if (command.motion) { + this.processMotion(cm, vim, command); + } + if (command.motion || command.operator) { + this.evalInput(cm, vim); + } + actionArgs.repeat = repeat || 1; + actionArgs.repeatIsExplicit = repeatIsExplicit; + actionArgs.registerName = inputState.registerName; + clearInputState(cm); + vim.lastMotion = null; + if (command.isEdit) { + this.recordLastEdit(vim, inputState, command); + } + actions[command.action](cm, actionArgs, vim); + }, + processSearch: function(cm, vim, command) { + if (!cm.getSearchCursor) { + // Search depends on SearchCursor. + return; + } + var forward = command.searchArgs.forward; + var wholeWordOnly = command.searchArgs.wholeWordOnly; + getSearchState(cm).setReversed(!forward); + var promptPrefix = (forward) ? '/' : '?'; + var originalQuery = getSearchState(cm).getQuery(); + var originalScrollPos = cm.getScrollInfo(); + function handleQuery(query, ignoreCase, smartCase) { + vimGlobalState.searchHistoryController.pushInput(query); + vimGlobalState.searchHistoryController.reset(); + try { + updateSearchQuery(cm, query, ignoreCase, smartCase); + } catch (e) { + showConfirm(cm, 'Invalid regex: ' + query); + clearInputState(cm); + return; + } + commandDispatcher.processMotion(cm, vim, { + type: 'motion', + motion: 'findNext', + motionArgs: { forward: true, toJumplist: command.searchArgs.toJumplist } + }); + } + function onPromptClose(query) { + cm.scrollTo(originalScrollPos.left, originalScrollPos.top); + handleQuery(query, true /** ignoreCase */, true /** smartCase */); + var macroModeState = vimGlobalState.macroModeState; + if (macroModeState.isRecording) { + logSearchQuery(macroModeState, query); + } + } + function onPromptKeyUp(e, query, close) { + var keyName = CodeMirror.keyName(e), up; + if (keyName == 'Up' || keyName == 'Down') { + up = keyName == 'Up' ? true : false; + query = vimGlobalState.searchHistoryController.nextMatch(query, up) || ''; + close(query); + } else { + if ( keyName != 'Left' && keyName != 'Right' && keyName != 'Ctrl' && keyName != 'Alt' && keyName != 'Shift') + vimGlobalState.searchHistoryController.reset(); + } + var parsedQuery; + try { + parsedQuery = updateSearchQuery(cm, query, + true /** ignoreCase */, true /** smartCase */); + } catch (e) { + // Swallow bad regexes for incremental search. + } + if (parsedQuery) { + cm.scrollIntoView(findNext(cm, !forward, parsedQuery), 30); + } else { + clearSearchHighlight(cm); + cm.scrollTo(originalScrollPos.left, originalScrollPos.top); + } + } + function onPromptKeyDown(e, query, close) { + var keyName = CodeMirror.keyName(e); + if (keyName == 'Esc' || keyName == 'Ctrl-C' || keyName == 'Ctrl-[' || + (keyName == 'Backspace' && query == '')) { + vimGlobalState.searchHistoryController.pushInput(query); + vimGlobalState.searchHistoryController.reset(); + updateSearchQuery(cm, originalQuery); + clearSearchHighlight(cm); + cm.scrollTo(originalScrollPos.left, originalScrollPos.top); + CodeMirror.e_stop(e); + clearInputState(cm); + close(); + cm.focus(); + } else if (keyName == 'Ctrl-U') { + // Ctrl-U clears input. + CodeMirror.e_stop(e); + close(''); + } + } + switch (command.searchArgs.querySrc) { + case 'prompt': + var macroModeState = vimGlobalState.macroModeState; + if (macroModeState.isPlaying) { + var query = macroModeState.replaySearchQueries.shift(); + handleQuery(query, true /** ignoreCase */, false /** smartCase */); + } else { + showPrompt(cm, { + onClose: onPromptClose, + prefix: promptPrefix, + desc: searchPromptDesc, + onKeyUp: onPromptKeyUp, + onKeyDown: onPromptKeyDown + }); + } + break; + case 'wordUnderCursor': + var word = expandWordUnderCursor(cm, false /** inclusive */, + true /** forward */, false /** bigWord */, + true /** noSymbol */); + var isKeyword = true; + if (!word) { + word = expandWordUnderCursor(cm, false /** inclusive */, + true /** forward */, false /** bigWord */, + false /** noSymbol */); + isKeyword = false; + } + if (!word) { + return; + } + var query = cm.getLine(word.start.line).substring(word.start.ch, + word.end.ch); + if (isKeyword && wholeWordOnly) { + query = '\\b' + query + '\\b'; + } else { + query = escapeRegex(query); + } + + // cachedCursor is used to save the old position of the cursor + // when * or # causes vim to seek for the nearest word and shift + // the cursor before entering the motion. + vimGlobalState.jumpList.cachedCursor = cm.getCursor(); + cm.setCursor(word.start); + + handleQuery(query, true /** ignoreCase */, false /** smartCase */); + break; + } + }, + processEx: function(cm, vim, command) { + function onPromptClose(input) { + // Give the prompt some time to close so that if processCommand shows + // an error, the elements don't overlap. + vimGlobalState.exCommandHistoryController.pushInput(input); + vimGlobalState.exCommandHistoryController.reset(); + exCommandDispatcher.processCommand(cm, input); + } + function onPromptKeyDown(e, input, close) { + var keyName = CodeMirror.keyName(e), up; + if (keyName == 'Esc' || keyName == 'Ctrl-C' || keyName == 'Ctrl-[' || + (keyName == 'Backspace' && input == '')) { + vimGlobalState.exCommandHistoryController.pushInput(input); + vimGlobalState.exCommandHistoryController.reset(); + CodeMirror.e_stop(e); + clearInputState(cm); + close(); + cm.focus(); + } + if (keyName == 'Up' || keyName == 'Down') { + up = keyName == 'Up' ? true : false; + input = vimGlobalState.exCommandHistoryController.nextMatch(input, up) || ''; + close(input); + } else if (keyName == 'Ctrl-U') { + // Ctrl-U clears input. + CodeMirror.e_stop(e); + close(''); + } else { + if ( keyName != 'Left' && keyName != 'Right' && keyName != 'Ctrl' && keyName != 'Alt' && keyName != 'Shift') + vimGlobalState.exCommandHistoryController.reset(); + } + } + if (command.type == 'keyToEx') { + // Handle user defined Ex to Ex mappings + exCommandDispatcher.processCommand(cm, command.exArgs.input); + } else { + if (vim.visualMode) { + showPrompt(cm, { onClose: onPromptClose, prefix: ':', value: '\'<,\'>', + onKeyDown: onPromptKeyDown, select: false}); + } else { + showPrompt(cm, { onClose: onPromptClose, prefix: ':', + onKeyDown: onPromptKeyDown}); + } + } + }, + evalInput: function(cm, vim) { + // If the motion comand is set, execute both the operator and motion. + // Otherwise return. + var inputState = vim.inputState; + var motion = inputState.motion; + var motionArgs = inputState.motionArgs || {}; + var operator = inputState.operator; + var operatorArgs = inputState.operatorArgs || {}; + var registerName = inputState.registerName; + var sel = vim.sel; + // TODO: Make sure cm and vim selections are identical outside visual mode. + var origHead = copyCursor(vim.visualMode ? clipCursorToContent(cm, sel.head): cm.getCursor('head')); + var origAnchor = copyCursor(vim.visualMode ? clipCursorToContent(cm, sel.anchor) : cm.getCursor('anchor')); + var oldHead = copyCursor(origHead); + var oldAnchor = copyCursor(origAnchor); + var newHead, newAnchor; + var repeat; + if (operator) { + this.recordLastEdit(vim, inputState); + } + if (inputState.repeatOverride !== undefined) { + // If repeatOverride is specified, that takes precedence over the + // input state's repeat. Used by Ex mode and can be user defined. + repeat = inputState.repeatOverride; + } else { + repeat = inputState.getRepeat(); + } + if (repeat > 0 && motionArgs.explicitRepeat) { + motionArgs.repeatIsExplicit = true; + } else if (motionArgs.noRepeat || + (!motionArgs.explicitRepeat && repeat === 0)) { + repeat = 1; + motionArgs.repeatIsExplicit = false; + } + if (inputState.selectedCharacter) { + // If there is a character input, stick it in all of the arg arrays. + motionArgs.selectedCharacter = operatorArgs.selectedCharacter = + inputState.selectedCharacter; + } + motionArgs.repeat = repeat; + clearInputState(cm); + if (motion) { + var motionResult = motions[motion](cm, origHead, motionArgs, vim); + vim.lastMotion = motions[motion]; + if (!motionResult) { + return; + } + if (motionArgs.toJumplist) { + if (!operator) + cm.ace.curOp.command.scrollIntoView = "center-animate"; // ace patch + var jumpList = vimGlobalState.jumpList; + // if the current motion is # or *, use cachedCursor + var cachedCursor = jumpList.cachedCursor; + if (cachedCursor) { + recordJumpPosition(cm, cachedCursor, motionResult); + delete jumpList.cachedCursor; + } else { + recordJumpPosition(cm, origHead, motionResult); + } + } + if (motionResult instanceof Array) { + newAnchor = motionResult[0]; + newHead = motionResult[1]; + } else { + newHead = motionResult; + } + // TODO: Handle null returns from motion commands better. + if (!newHead) { + newHead = copyCursor(origHead); + } + if (vim.visualMode) { + if (!(vim.visualBlock && newHead.ch === Infinity)) { + newHead = clipCursorToContent(cm, newHead, vim.visualBlock); + } + if (newAnchor) { + newAnchor = clipCursorToContent(cm, newAnchor, true); + } + newAnchor = newAnchor || oldAnchor; + sel.anchor = newAnchor; + sel.head = newHead; + updateCmSelection(cm); + updateMark(cm, vim, '<', + cursorIsBefore(newAnchor, newHead) ? newAnchor + : newHead); + updateMark(cm, vim, '>', + cursorIsBefore(newAnchor, newHead) ? newHead + : newAnchor); + } else if (!operator) { + newHead = clipCursorToContent(cm, newHead); + cm.setCursor(newHead.line, newHead.ch); + } + } + if (operator) { + if (operatorArgs.lastSel) { + // Replaying a visual mode operation + newAnchor = oldAnchor; + var lastSel = operatorArgs.lastSel; + var lineOffset = Math.abs(lastSel.head.line - lastSel.anchor.line); + var chOffset = Math.abs(lastSel.head.ch - lastSel.anchor.ch); + if (lastSel.visualLine) { + // Linewise Visual mode: The same number of lines. + newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch); + } else if (lastSel.visualBlock) { + // Blockwise Visual mode: The same number of lines and columns. + newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch + chOffset); + } else if (lastSel.head.line == lastSel.anchor.line) { + // Normal Visual mode within one line: The same number of characters. + newHead = Pos(oldAnchor.line, oldAnchor.ch + chOffset); + } else { + // Normal Visual mode with several lines: The same number of lines, in the + // last line the same number of characters as in the last line the last time. + newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch); + } + vim.visualMode = true; + vim.visualLine = lastSel.visualLine; + vim.visualBlock = lastSel.visualBlock; + sel = vim.sel = { + anchor: newAnchor, + head: newHead + }; + updateCmSelection(cm); + } else if (vim.visualMode) { + operatorArgs.lastSel = { + anchor: copyCursor(sel.anchor), + head: copyCursor(sel.head), + visualBlock: vim.visualBlock, + visualLine: vim.visualLine + }; + } + var curStart, curEnd, linewise, mode; + var cmSel; + if (vim.visualMode) { + // Init visual op + curStart = cursorMin(sel.head, sel.anchor); + curEnd = cursorMax(sel.head, sel.anchor); + linewise = vim.visualLine || operatorArgs.linewise; + mode = vim.visualBlock ? 'block' : + linewise ? 'line' : + 'char'; + cmSel = makeCmSelection(cm, { + anchor: curStart, + head: curEnd + }, mode); + if (linewise) { + var ranges = cmSel.ranges; + if (mode == 'block') { + // Linewise operators in visual block mode extend to end of line + for (var i = 0; i < ranges.length; i++) { + ranges[i].head.ch = lineLength(cm, ranges[i].head.line); + } + } else if (mode == 'line') { + ranges[0].head = Pos(ranges[0].head.line + 1, 0); + } + } + } else { + // Init motion op + curStart = copyCursor(newAnchor || oldAnchor); + curEnd = copyCursor(newHead || oldHead); + if (cursorIsBefore(curEnd, curStart)) { + var tmp = curStart; + curStart = curEnd; + curEnd = tmp; + } + linewise = motionArgs.linewise || operatorArgs.linewise; + if (linewise) { + // Expand selection to entire line. + expandSelectionToLine(cm, curStart, curEnd); + } else if (motionArgs.forward) { + // Clip to trailing newlines only if the motion goes forward. + clipToLine(cm, curStart, curEnd); + } + mode = 'char'; + var exclusive = !motionArgs.inclusive || linewise; + cmSel = makeCmSelection(cm, { + anchor: curStart, + head: curEnd + }, mode, exclusive); + } + cm.setSelections(cmSel.ranges, cmSel.primary); + vim.lastMotion = null; + operatorArgs.repeat = repeat; // For indent in visual mode. + operatorArgs.registerName = registerName; + // Keep track of linewise as it affects how paste and change behave. + operatorArgs.linewise = linewise; + var operatorMoveTo = operators[operator]( + cm, operatorArgs, cmSel.ranges, oldAnchor, newHead); + if (vim.visualMode) { + exitVisualMode(cm, operatorMoveTo != null); + } + if (operatorMoveTo) { + cm.setCursor(operatorMoveTo); + } + } + }, + recordLastEdit: function(vim, inputState, actionCommand) { + var macroModeState = vimGlobalState.macroModeState; + if (macroModeState.isPlaying) { return; } + vim.lastEditInputState = inputState; + vim.lastEditActionCommand = actionCommand; + macroModeState.lastInsertModeChanges.changes = []; + macroModeState.lastInsertModeChanges.expectCursorActivityForChange = false; + } + }; + + /** + * typedef {Object{line:number,ch:number}} Cursor An object containing the + * position of the cursor. + */ + // All of the functions below return Cursor objects. + var motions = { + moveToTopLine: function(cm, _head, motionArgs) { + var line = getUserVisibleLines(cm).top + motionArgs.repeat -1; + return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); + }, + moveToMiddleLine: function(cm) { + var range = getUserVisibleLines(cm); + var line = Math.floor((range.top + range.bottom) * 0.5); + return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); + }, + moveToBottomLine: function(cm, _head, motionArgs) { + var line = getUserVisibleLines(cm).bottom - motionArgs.repeat +1; + return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line))); + }, + expandToLine: function(_cm, head, motionArgs) { + // Expands forward to end of line, and then to next line if repeat is + // >1. Does not handle backward motion! + var cur = head; + return Pos(cur.line + motionArgs.repeat - 1, Infinity); + }, + findNext: function(cm, _head, motionArgs) { + var state = getSearchState(cm); + var query = state.getQuery(); + if (!query) { + return; + } + var prev = !motionArgs.forward; + // If search is initiated with ? instead of /, negate direction. + prev = (state.isReversed()) ? !prev : prev; + highlightSearchMatches(cm, query); + return findNext(cm, prev/** prev */, query, motionArgs.repeat); + }, + goToMark: function(cm, _head, motionArgs, vim) { + var mark = vim.marks[motionArgs.selectedCharacter]; + if (mark) { + var pos = mark.find(); + return motionArgs.linewise ? { line: pos.line, ch: findFirstNonWhiteSpaceCharacter(cm.getLine(pos.line)) } : pos; + } + return null; + }, + moveToOtherHighlightedEnd: function(cm, _head, motionArgs, vim) { + if (vim.visualBlock && motionArgs.sameLine) { + var sel = vim.sel; + return [ + clipCursorToContent(cm, Pos(sel.anchor.line, sel.head.ch)), + clipCursorToContent(cm, Pos(sel.head.line, sel.anchor.ch)) + ]; + } else { + return ([vim.sel.head, vim.sel.anchor]); + } + }, + jumpToMark: function(cm, head, motionArgs, vim) { + var best = head; + for (var i = 0; i < motionArgs.repeat; i++) { + var cursor = best; + for (var key in vim.marks) { + if (!isLowerCase(key)) { + continue; + } + var mark = vim.marks[key].find(); + var isWrongDirection = (motionArgs.forward) ? + cursorIsBefore(mark, cursor) : cursorIsBefore(cursor, mark); + + if (isWrongDirection) { + continue; + } + if (motionArgs.linewise && (mark.line == cursor.line)) { + continue; + } + + var equal = cursorEqual(cursor, best); + var between = (motionArgs.forward) ? + cursorIsBetween(cursor, mark, best) : + cursorIsBetween(best, mark, cursor); + + if (equal || between) { + best = mark; + } + } + } + + if (motionArgs.linewise) { + // Vim places the cursor on the first non-whitespace character of + // the line if there is one, else it places the cursor at the end + // of the line, regardless of whether a mark was found. + best = Pos(best.line, findFirstNonWhiteSpaceCharacter(cm.getLine(best.line))); + } + return best; + }, + moveByCharacters: function(_cm, head, motionArgs) { + var cur = head; + var repeat = motionArgs.repeat; + var ch = motionArgs.forward ? cur.ch + repeat : cur.ch - repeat; + return Pos(cur.line, ch); + }, + moveByLines: function(cm, head, motionArgs, vim) { + var cur = head; + var endCh = cur.ch; + // Depending what our last motion was, we may want to do different + // things. If our last motion was moving vertically, we want to + // preserve the HPos from our last horizontal move. If our last motion + // was going to the end of a line, moving vertically we should go to + // the end of the line, etc. + switch (vim.lastMotion) { + case this.moveByLines: + case this.moveByDisplayLines: + case this.moveByScroll: + case this.moveToColumn: + case this.moveToEol: + endCh = vim.lastHPos; + break; + default: + vim.lastHPos = endCh; + } + var repeat = motionArgs.repeat+(motionArgs.repeatOffset||0); + var line = motionArgs.forward ? cur.line + repeat : cur.line - repeat; + var first = cm.firstLine(); + var last = cm.lastLine(); + // Vim cancels linewise motions that start on an edge and move beyond + // that edge. It does not cancel motions that do not start on an edge. + if ((line < first && cur.line == first) || + (line > last && cur.line == last)) { + return; + } + // /ace patch + var fold = cm.ace.session.getFoldAt(line, endCh); + if (fold) { + if (motionArgs.forward) + line = fold.end.row + 1; + else + line = fold.start.row - 1; + } + // /ace patche + if (motionArgs.toFirstChar){ + endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line)); + vim.lastHPos = endCh; + } + vim.lastHSPos = cm.charCoords(Pos(line, endCh),'div').left; + return Pos(line, endCh); + }, + moveByDisplayLines: function(cm, head, motionArgs, vim) { + var cur = head; + switch (vim.lastMotion) { + case this.moveByDisplayLines: + case this.moveByScroll: + case this.moveByLines: + case this.moveToColumn: + case this.moveToEol: + break; + default: + vim.lastHSPos = cm.charCoords(cur,'div').left; + } + var repeat = motionArgs.repeat; + var res=cm.findPosV(cur,(motionArgs.forward ? repeat : -repeat),'line',vim.lastHSPos); + if (res.hitSide) { + if (motionArgs.forward) { + var lastCharCoords = cm.charCoords(res, 'div'); + var goalCoords = { top: lastCharCoords.top + 8, left: vim.lastHSPos }; + var res = cm.coordsChar(goalCoords, 'div'); + } else { + var resCoords = cm.charCoords(Pos(cm.firstLine(), 0), 'div'); + resCoords.left = vim.lastHSPos; + res = cm.coordsChar(resCoords, 'div'); + } + } + vim.lastHPos = res.ch; + return res; + }, + moveByPage: function(cm, head, motionArgs) { + // CodeMirror only exposes functions that move the cursor page down, so + // doing this bad hack to move the cursor and move it back. evalInput + // will move the cursor to where it should be in the end. + var curStart = head; + var repeat = motionArgs.repeat; + return cm.findPosV(curStart, (motionArgs.forward ? repeat : -repeat), 'page'); + }, + moveByParagraph: function(cm, head, motionArgs) { + var dir = motionArgs.forward ? 1 : -1; + return findParagraph(cm, head, motionArgs.repeat, dir); + }, + moveByScroll: function(cm, head, motionArgs, vim) { + var scrollbox = cm.getScrollInfo(); + var curEnd = null; + var repeat = motionArgs.repeat; + if (!repeat) { + repeat = scrollbox.clientHeight / (2 * cm.defaultTextHeight()); + } + var orig = cm.charCoords(head, 'local'); + motionArgs.repeat = repeat; + var curEnd = motions.moveByDisplayLines(cm, head, motionArgs, vim); + if (!curEnd) { + return null; + } + var dest = cm.charCoords(curEnd, 'local'); + cm.scrollTo(null, scrollbox.top + dest.top - orig.top); + return curEnd; + }, + moveByWords: function(cm, head, motionArgs) { + return moveToWord(cm, head, motionArgs.repeat, !!motionArgs.forward, + !!motionArgs.wordEnd, !!motionArgs.bigWord); + }, + moveTillCharacter: function(cm, _head, motionArgs) { + var repeat = motionArgs.repeat; + var curEnd = moveToCharacter(cm, repeat, motionArgs.forward, + motionArgs.selectedCharacter); + var increment = motionArgs.forward ? -1 : 1; + recordLastCharacterSearch(increment, motionArgs); + if (!curEnd) return null; + curEnd.ch += increment; + return curEnd; + }, + moveToCharacter: function(cm, head, motionArgs) { + var repeat = motionArgs.repeat; + recordLastCharacterSearch(0, motionArgs); + return moveToCharacter(cm, repeat, motionArgs.forward, + motionArgs.selectedCharacter) || head; + }, + moveToSymbol: function(cm, head, motionArgs) { + var repeat = motionArgs.repeat; + return findSymbol(cm, repeat, motionArgs.forward, + motionArgs.selectedCharacter) || head; + }, + moveToColumn: function(cm, head, motionArgs, vim) { + var repeat = motionArgs.repeat; + // repeat is equivalent to which column we want to move to! + vim.lastHPos = repeat - 1; + vim.lastHSPos = cm.charCoords(head,'div').left; + return moveToColumn(cm, repeat); + }, + moveToEol: function(cm, head, motionArgs, vim) { + var cur = head; + vim.lastHPos = Infinity; + var retval= Pos(cur.line + motionArgs.repeat - 1, Infinity); + var end=cm.clipPos(retval); + end.ch--; + vim.lastHSPos = cm.charCoords(end,'div').left; + return retval; + }, + moveToFirstNonWhiteSpaceCharacter: function(cm, head) { + // Go to the start of the line where the text begins, or the end for + // whitespace-only lines + var cursor = head; + return Pos(cursor.line, + findFirstNonWhiteSpaceCharacter(cm.getLine(cursor.line))); + }, + moveToMatchedSymbol: function(cm, head) { + var cursor = head; + var line = cursor.line; + var ch = cursor.ch; + var lineText = cm.getLine(line); + var symbol; + do { + symbol = lineText.charAt(ch++); + if (symbol && isMatchableSymbol(symbol)) { + var style = cm.getTokenTypeAt(Pos(line, ch)); + if (style !== "string" && style !== "comment") { + break; + } + } + } while (symbol); + if (symbol) { + var matched = cm.findMatchingBracket(Pos(line, ch)); + return matched.to; + } else { + return cursor; + } + }, + moveToStartOfLine: function(_cm, head) { + return Pos(head.line, 0); + }, + moveToLineOrEdgeOfDocument: function(cm, _head, motionArgs) { + var lineNum = motionArgs.forward ? cm.lastLine() : cm.firstLine(); + if (motionArgs.repeatIsExplicit) { + lineNum = motionArgs.repeat - cm.getOption('firstLineNumber'); + } + return Pos(lineNum, + findFirstNonWhiteSpaceCharacter(cm.getLine(lineNum))); + }, + textObjectManipulation: function(cm, head, motionArgs, vim) { + // TODO: lots of possible exceptions that can be thrown here. Try da( + // outside of a () block. + + // TODO: adding <> >< to this map doesn't work, presumably because + // they're operators + var mirroredPairs = {'(': ')', ')': '(', + '{': '}', '}': '{', + '[': ']', ']': '['}; + var selfPaired = {'\'': true, '"': true}; + + var character = motionArgs.selectedCharacter; + // 'b' refers to '()' block. + // 'B' refers to '{}' block. + if (character == 'b') { + character = '('; + } else if (character == 'B') { + character = '{'; + } + + // Inclusive is the difference between a and i + // TODO: Instead of using the additional text object map to perform text + // object operations, merge the map into the defaultKeyMap and use + // motionArgs to define behavior. Define separate entries for 'aw', + // 'iw', 'a[', 'i[', etc. + var inclusive = !motionArgs.textObjectInner; + + var tmp; + if (mirroredPairs[character]) { + tmp = selectCompanionObject(cm, head, character, inclusive); + } else if (selfPaired[character]) { + tmp = findBeginningAndEnd(cm, head, character, inclusive); + } else if (character === 'W') { + tmp = expandWordUnderCursor(cm, inclusive, true /** forward */, + true /** bigWord */); + } else if (character === 'w') { + tmp = expandWordUnderCursor(cm, inclusive, true /** forward */, + false /** bigWord */); + } else if (character === 'p') { + tmp = findParagraph(cm, head, motionArgs.repeat, 0, inclusive); + motionArgs.linewise = true; + if (vim.visualMode) { + if (!vim.visualLine) { vim.visualLine = true; } + } else { + var operatorArgs = vim.inputState.operatorArgs; + if (operatorArgs) { operatorArgs.linewise = true; } + tmp.end.line--; + } + } else { + // No text object defined for this, don't move. + return null; + } + + if (!cm.state.vim.visualMode) { + return [tmp.start, tmp.end]; + } else { + return expandSelection(cm, tmp.start, tmp.end); + } + }, + + repeatLastCharacterSearch: function(cm, head, motionArgs) { + var lastSearch = vimGlobalState.lastChararacterSearch; + var repeat = motionArgs.repeat; + var forward = motionArgs.forward === lastSearch.forward; + var increment = (lastSearch.increment ? 1 : 0) * (forward ? -1 : 1); + cm.moveH(-increment, 'char'); + motionArgs.inclusive = forward ? true : false; + var curEnd = moveToCharacter(cm, repeat, forward, lastSearch.selectedCharacter); + if (!curEnd) { + cm.moveH(increment, 'char'); + return head; + } + curEnd.ch += increment; + return curEnd; + } + }; + + function defineMotion(name, fn) { + motions[name] = fn; + } + + function fillArray(val, times) { + var arr = []; + for (var i = 0; i < times; i++) { + arr.push(val); + } + return arr; + } + /** + * An operator acts on a text selection. It receives the list of selections + * as input. The corresponding CodeMirror selection is guaranteed to + * match the input selection. + */ + var operators = { + change: function(cm, args, ranges) { + var finalHead, text; + var vim = cm.state.vim; + vimGlobalState.macroModeState.lastInsertModeChanges.inVisualBlock = vim.visualBlock; + if (!vim.visualMode) { + var anchor = ranges[0].anchor, + head = ranges[0].head; + text = cm.getRange(anchor, head); + var lastState = vim.lastEditInputState || {}; + if (lastState.motion == "moveByWords" && !isWhiteSpaceString(text)) { + // Exclude trailing whitespace if the range is not all whitespace. + var match = (/\s+$/).exec(text); + if (match && lastState.motionArgs && lastState.motionArgs.forward) { + head = offsetCursor(head, 0, - match[0].length); + text = text.slice(0, - match[0].length); + } + } + var wasLastLine = head.line - 1 == cm.lastLine(); + cm.replaceRange('', anchor, head); + if (args.linewise && !wasLastLine) { + // Push the next line back down, if there is a next line. + CodeMirror.commands.newlineAndIndent(cm); + // null ch so setCursor moves to end of line. + anchor.ch = null; + } + finalHead = anchor; + } else { + text = cm.getSelection(); + var replacement = fillArray('', ranges.length); + cm.replaceSelections(replacement); + finalHead = cursorMin(ranges[0].head, ranges[0].anchor); + } + vimGlobalState.registerController.pushText( + args.registerName, 'change', text, + args.linewise, ranges.length > 1); + actions.enterInsertMode(cm, {head: finalHead}, cm.state.vim); + }, + // delete is a javascript keyword. + 'delete': function(cm, args, ranges) { + var finalHead, text; + var vim = cm.state.vim; + if (!vim.visualBlock) { + var anchor = ranges[0].anchor, + head = ranges[0].head; + if (args.linewise && + head.line != cm.firstLine() && + anchor.line == cm.lastLine() && + anchor.line == head.line - 1) { + // Special case for dd on last line (and first line). + if (anchor.line == cm.firstLine()) { + anchor.ch = 0; + } else { + anchor = Pos(anchor.line - 1, lineLength(cm, anchor.line - 1)); + } + } + text = cm.getRange(anchor, head); + cm.replaceRange('', anchor, head); + finalHead = anchor; + if (args.linewise) { + finalHead = motions.moveToFirstNonWhiteSpaceCharacter(cm, anchor); + } + } else { + text = cm.getSelection(); + var replacement = fillArray('', ranges.length); + cm.replaceSelections(replacement); + finalHead = ranges[0].anchor; + } + vimGlobalState.registerController.pushText( + args.registerName, 'delete', text, + args.linewise, vim.visualBlock); + return clipCursorToContent(cm, finalHead); + }, + indent: function(cm, args, ranges) { + var vim = cm.state.vim; + var startLine = ranges[0].anchor.line; + var endLine = vim.visualBlock ? + ranges[ranges.length - 1].anchor.line : + ranges[0].head.line; + // In visual mode, n> shifts the selection right n times, instead of + // shifting n lines right once. + var repeat = (vim.visualMode) ? args.repeat : 1; + if (args.linewise) { + // The only way to delete a newline is to delete until the start of + // the next line, so in linewise mode evalInput will include the next + // line. We don't want this in indent, so we go back a line. + endLine--; + } + for (var i = startLine; i <= endLine; i++) { + for (var j = 0; j < repeat; j++) { + cm.indentLine(i, args.indentRight); + } + } + return motions.moveToFirstNonWhiteSpaceCharacter(cm, ranges[0].anchor); + }, + changeCase: function(cm, args, ranges, oldAnchor, newHead) { + var selections = cm.getSelections(); + var swapped = []; + var toLower = args.toLower; + for (var j = 0; j < selections.length; j++) { + var toSwap = selections[j]; + var text = ''; + if (toLower === true) { + text = toSwap.toLowerCase(); + } else if (toLower === false) { + text = toSwap.toUpperCase(); + } else { + for (var i = 0; i < toSwap.length; i++) { + var character = toSwap.charAt(i); + text += isUpperCase(character) ? character.toLowerCase() : + character.toUpperCase(); + } + } + swapped.push(text); + } + cm.replaceSelections(swapped); + if (args.shouldMoveCursor){ + return newHead; + } else if (!cm.state.vim.visualMode && args.linewise && ranges[0].anchor.line + 1 == ranges[0].head.line) { + return motions.moveToFirstNonWhiteSpaceCharacter(cm, oldAnchor); + } else if (args.linewise){ + return oldAnchor; + } else { + return cursorMin(ranges[0].anchor, ranges[0].head); + } + }, + yank: function(cm, args, ranges, oldAnchor) { + var vim = cm.state.vim; + var text = cm.getSelection(); + var endPos = vim.visualMode + ? cursorMin(vim.sel.anchor, vim.sel.head, ranges[0].head, ranges[0].anchor) + : oldAnchor; + vimGlobalState.registerController.pushText( + args.registerName, 'yank', + text, args.linewise, vim.visualBlock); + return endPos; + } + }; + + function defineOperator(name, fn) { + operators[name] = fn; + } + + var actions = { + jumpListWalk: function(cm, actionArgs, vim) { + if (vim.visualMode) { + return; + } + var repeat = actionArgs.repeat; + var forward = actionArgs.forward; + var jumpList = vimGlobalState.jumpList; + + var mark = jumpList.move(cm, forward ? repeat : -repeat); + var markPos = mark ? mark.find() : undefined; + markPos = markPos ? markPos : cm.getCursor(); + cm.setCursor(markPos); + cm.ace.curOp.command.scrollIntoView = "center-animate"; // ace patch + }, + scroll: function(cm, actionArgs, vim) { + if (vim.visualMode) { + return; + } + var repeat = actionArgs.repeat || 1; + var lineHeight = cm.defaultTextHeight(); + var top = cm.getScrollInfo().top; + var delta = lineHeight * repeat; + var newPos = actionArgs.forward ? top + delta : top - delta; + var cursor = copyCursor(cm.getCursor()); + var cursorCoords = cm.charCoords(cursor, 'local'); + if (actionArgs.forward) { + if (newPos > cursorCoords.top) { + cursor.line += (newPos - cursorCoords.top) / lineHeight; + cursor.line = Math.ceil(cursor.line); + cm.setCursor(cursor); + cursorCoords = cm.charCoords(cursor, 'local'); + cm.scrollTo(null, cursorCoords.top); + } else { + // Cursor stays within bounds. Just reposition the scroll window. + cm.scrollTo(null, newPos); + } + } else { + var newBottom = newPos + cm.getScrollInfo().clientHeight; + if (newBottom < cursorCoords.bottom) { + cursor.line -= (cursorCoords.bottom - newBottom) / lineHeight; + cursor.line = Math.floor(cursor.line); + cm.setCursor(cursor); + cursorCoords = cm.charCoords(cursor, 'local'); + cm.scrollTo( + null, cursorCoords.bottom - cm.getScrollInfo().clientHeight); + } else { + // Cursor stays within bounds. Just reposition the scroll window. + cm.scrollTo(null, newPos); + } + } + }, + scrollToCursor: function(cm, actionArgs) { + var lineNum = cm.getCursor().line; + var charCoords = cm.charCoords(Pos(lineNum, 0), 'local'); + var height = cm.getScrollInfo().clientHeight; + var y = charCoords.top; + var lineHeight = charCoords.bottom - y; + switch (actionArgs.position) { + case 'center': y = y - (height / 2) + lineHeight; + break; + case 'bottom': y = y - height + lineHeight*1.4; + break; + case 'top': y = y + lineHeight*0.4; + break; + } + cm.scrollTo(null, y); + }, + replayMacro: function(cm, actionArgs, vim) { + var registerName = actionArgs.selectedCharacter; + var repeat = actionArgs.repeat; + var macroModeState = vimGlobalState.macroModeState; + if (registerName == '@') { + registerName = macroModeState.latestRegister; + } + while(repeat--){ + executeMacroRegister(cm, vim, macroModeState, registerName); + } + }, + enterMacroRecordMode: function(cm, actionArgs) { + var macroModeState = vimGlobalState.macroModeState; + var registerName = actionArgs.selectedCharacter; + macroModeState.enterMacroRecordMode(cm, registerName); + }, + enterInsertMode: function(cm, actionArgs, vim) { + if (cm.getOption('readOnly')) { return; } + vim.insertMode = true; + vim.insertModeRepeat = actionArgs && actionArgs.repeat || 1; + var insertAt = (actionArgs) ? actionArgs.insertAt : null; + var sel = vim.sel; + var head = actionArgs.head || cm.getCursor('head'); + var height = cm.listSelections().length; + if (insertAt == 'eol') { + head = Pos(head.line, lineLength(cm, head.line)); + } else if (insertAt == 'charAfter') { + head = offsetCursor(head, 0, 1); + } else if (insertAt == 'firstNonBlank') { + head = motions.moveToFirstNonWhiteSpaceCharacter(cm, head); + } else if (insertAt == 'startOfSelectedArea') { + if (!vim.visualBlock) { + if (sel.head.line < sel.anchor.line) { + head = sel.head; + } else { + head = Pos(sel.anchor.line, 0); + } + } else { + head = Pos( + Math.min(sel.head.line, sel.anchor.line), + Math.min(sel.head.ch, sel.anchor.ch)); + height = Math.abs(sel.head.line - sel.anchor.line) + 1; + } + } else if (insertAt == 'endOfSelectedArea') { + if (!vim.visualBlock) { + if (sel.head.line >= sel.anchor.line) { + head = offsetCursor(sel.head, 0, 1); + } else { + head = Pos(sel.anchor.line, 0); + } + } else { + head = Pos( + Math.min(sel.head.line, sel.anchor.line), + Math.max(sel.head.ch + 1, sel.anchor.ch)); + height = Math.abs(sel.head.line - sel.anchor.line) + 1; + } + } else if (insertAt == 'inplace') { + if (vim.visualMode){ + return; + } + } + cm.setOption('keyMap', 'vim-insert'); + cm.setOption('disableInput', false); + if (actionArgs && actionArgs.replace) { + // Handle Replace-mode as a special case of insert mode. + cm.toggleOverwrite(true); + cm.setOption('keyMap', 'vim-replace'); + CodeMirror.signal(cm, "vim-mode-change", {mode: "replace"}); + } else { + cm.setOption('keyMap', 'vim-insert'); + CodeMirror.signal(cm, "vim-mode-change", {mode: "insert"}); + } + if (!vimGlobalState.macroModeState.isPlaying) { + // Only record if not replaying. + cm.on('change', onChange); + CodeMirror.on(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown); + } + if (vim.visualMode) { + exitVisualMode(cm); + } + selectForInsert(cm, head, height); + }, + toggleVisualMode: function(cm, actionArgs, vim) { + var repeat = actionArgs.repeat; + var anchor = cm.getCursor(); + var head; + // TODO: The repeat should actually select number of characters/lines + // equal to the repeat times the size of the previous visual + // operation. + if (!vim.visualMode) { + // Entering visual mode + vim.visualMode = true; + vim.visualLine = !!actionArgs.linewise; + vim.visualBlock = !!actionArgs.blockwise; + head = clipCursorToContent( + cm, Pos(anchor.line, anchor.ch + repeat - 1), + true /** includeLineBreak */); + vim.sel = { + anchor: anchor, + head: head + }; + CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: vim.visualLine ? "linewise" : vim.visualBlock ? "blockwise" : ""}); + updateCmSelection(cm); + updateMark(cm, vim, '<', cursorMin(anchor, head)); + updateMark(cm, vim, '>', cursorMax(anchor, head)); + } else if (vim.visualLine ^ actionArgs.linewise || + vim.visualBlock ^ actionArgs.blockwise) { + // Toggling between modes + vim.visualLine = !!actionArgs.linewise; + vim.visualBlock = !!actionArgs.blockwise; + CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: vim.visualLine ? "linewise" : vim.visualBlock ? "blockwise" : ""}); + updateCmSelection(cm); + } else { + exitVisualMode(cm); + } + }, + reselectLastSelection: function(cm, _actionArgs, vim) { + var lastSelection = vim.lastSelection; + if (vim.visualMode) { + updateLastSelection(cm, vim); + } + if (lastSelection) { + var anchor = lastSelection.anchorMark.find(); + var head = lastSelection.headMark.find(); + if (!anchor || !head) { + // If the marks have been destroyed due to edits, do nothing. + return; + } + vim.sel = { + anchor: anchor, + head: head + }; + vim.visualMode = true; + vim.visualLine = lastSelection.visualLine; + vim.visualBlock = lastSelection.visualBlock; + updateCmSelection(cm); + updateMark(cm, vim, '<', cursorMin(anchor, head)); + updateMark(cm, vim, '>', cursorMax(anchor, head)); + CodeMirror.signal(cm, 'vim-mode-change', { + mode: 'visual', + subMode: vim.visualLine ? 'linewise' : + vim.visualBlock ? 'blockwise' : ''}); + } + }, + joinLines: function(cm, actionArgs, vim) { + var curStart, curEnd; + if (vim.visualMode) { + curStart = cm.getCursor('anchor'); + curEnd = cm.getCursor('head'); + if (cursorIsBefore(curEnd, curStart)) { + var tmp = curEnd; + curEnd = curStart; + curStart = tmp; + } + curEnd.ch = lineLength(cm, curEnd.line) - 1; + } else { + // Repeat is the number of lines to join. Minimum 2 lines. + var repeat = Math.max(actionArgs.repeat, 2); + curStart = cm.getCursor(); + curEnd = clipCursorToContent(cm, Pos(curStart.line + repeat - 1, + Infinity)); + } + var finalCh = 0; + for (var i = curStart.line; i < curEnd.line; i++) { + finalCh = lineLength(cm, curStart.line); + var tmp = Pos(curStart.line + 1, + lineLength(cm, curStart.line + 1)); + var text = cm.getRange(curStart, tmp); + text = text.replace(/\n\s*/g, ' '); + cm.replaceRange(text, curStart, tmp); + } + var curFinalPos = Pos(curStart.line, finalCh); + if (vim.visualMode) { + exitVisualMode(cm, false); + } + cm.setCursor(curFinalPos); + }, + newLineAndEnterInsertMode: function(cm, actionArgs, vim) { + vim.insertMode = true; + var insertAt = copyCursor(cm.getCursor()); + if (insertAt.line === cm.firstLine() && !actionArgs.after) { + // Special case for inserting newline before start of document. + cm.replaceRange('\n', Pos(cm.firstLine(), 0)); + cm.setCursor(cm.firstLine(), 0); + } else { + insertAt.line = (actionArgs.after) ? insertAt.line : + insertAt.line - 1; + insertAt.ch = lineLength(cm, insertAt.line); + cm.setCursor(insertAt); + var newlineFn = CodeMirror.commands.newlineAndIndentContinueComment || + CodeMirror.commands.newlineAndIndent; + newlineFn(cm); + } + this.enterInsertMode(cm, { repeat: actionArgs.repeat }, vim); + }, + paste: function(cm, actionArgs, vim) { + var cur = copyCursor(cm.getCursor()); + var register = vimGlobalState.registerController.getRegister( + actionArgs.registerName); + var text = register.toString(); + if (!text) { + return; + } + if (actionArgs.matchIndent) { + var tabSize = cm.getOption("tabSize"); + // length that considers tabs and tabSize + var whitespaceLength = function(str) { + var tabs = (str.split("\t").length - 1); + var spaces = (str.split(" ").length - 1); + return tabs * tabSize + spaces * 1; + }; + var currentLine = cm.getLine(cm.getCursor().line); + var indent = whitespaceLength(currentLine.match(/^\s*/)[0]); + // chomp last newline b/c don't want it to match /^\s*/gm + var chompedText = text.replace(/\n$/, ''); + var wasChomped = text !== chompedText; + var firstIndent = whitespaceLength(text.match(/^\s*/)[0]); + var text = chompedText.replace(/^\s*/gm, function(wspace) { + var newIndent = indent + (whitespaceLength(wspace) - firstIndent); + if (newIndent < 0) { + return ""; + } + else if (cm.getOption("indentWithTabs")) { + var quotient = Math.floor(newIndent / tabSize); + return Array(quotient + 1).join('\t'); + } + else { + return Array(newIndent + 1).join(' '); + } + }); + text += wasChomped ? "\n" : ""; + } + if (actionArgs.repeat > 1) { + var text = Array(actionArgs.repeat + 1).join(text); + } + var linewise = register.linewise; + var blockwise = register.blockwise; + if (linewise) { + if(vim.visualMode) { + text = vim.visualLine ? text.slice(0, -1) : '\n' + text.slice(0, text.length - 1) + '\n'; + } else if (actionArgs.after) { + // Move the newline at the end to the start instead, and paste just + // before the newline character of the line we are on right now. + text = '\n' + text.slice(0, text.length - 1); + cur.ch = lineLength(cm, cur.line); + } else { + cur.ch = 0; + } + } else { + if (blockwise) { + text = text.split('\n'); + for (var i = 0; i < text.length; i++) { + text[i] = (text[i] == '') ? ' ' : text[i]; + } + } + cur.ch += actionArgs.after ? 1 : 0; + } + var curPosFinal; + var idx; + if (vim.visualMode) { + // save the pasted text for reselection if the need arises + vim.lastPastedText = text; + var lastSelectionCurEnd; + var selectedArea = getSelectedAreaRange(cm, vim); + var selectionStart = selectedArea[0]; + var selectionEnd = selectedArea[1]; + var selectedText = cm.getSelection(); + var selections = cm.listSelections(); + var emptyStrings = new Array(selections.length).join('1').split('1'); + // save the curEnd marker before it get cleared due to cm.replaceRange. + if (vim.lastSelection) { + lastSelectionCurEnd = vim.lastSelection.headMark.find(); + } + // push the previously selected text to unnamed register + vimGlobalState.registerController.unnamedRegister.setText(selectedText); + if (blockwise) { + // first delete the selected text + cm.replaceSelections(emptyStrings); + // Set new selections as per the block length of the yanked text + selectionEnd = Pos(selectionStart.line + text.length-1, selectionStart.ch); + cm.setCursor(selectionStart); + selectBlock(cm, selectionEnd); + cm.replaceSelections(text); + curPosFinal = selectionStart; + } else if (vim.visualBlock) { + cm.replaceSelections(emptyStrings); + cm.setCursor(selectionStart); + cm.replaceRange(text, selectionStart, selectionStart); + curPosFinal = selectionStart; + } else { + cm.replaceRange(text, selectionStart, selectionEnd); + curPosFinal = cm.posFromIndex(cm.indexFromPos(selectionStart) + text.length - 1); + } + // restore the the curEnd marker + if(lastSelectionCurEnd) { + vim.lastSelection.headMark = cm.setBookmark(lastSelectionCurEnd); + } + if (linewise) { + curPosFinal.ch=0; + } + } else { + if (blockwise) { + cm.setCursor(cur); + for (var i = 0; i < text.length; i++) { + var line = cur.line+i; + if (line > cm.lastLine()) { + cm.replaceRange('\n', Pos(line, 0)); + } + var lastCh = lineLength(cm, line); + if (lastCh < cur.ch) { + extendLineToColumn(cm, line, cur.ch); + } + } + cm.setCursor(cur); + selectBlock(cm, Pos(cur.line + text.length-1, cur.ch)); + cm.replaceSelections(text); + curPosFinal = cur; + } else { + cm.replaceRange(text, cur); + // Now fine tune the cursor to where we want it. + if (linewise && actionArgs.after) { + curPosFinal = Pos( + cur.line + 1, + findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line + 1))); + } else if (linewise && !actionArgs.after) { + curPosFinal = Pos( + cur.line, + findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line))); + } else if (!linewise && actionArgs.after) { + idx = cm.indexFromPos(cur); + curPosFinal = cm.posFromIndex(idx + text.length - 1); + } else { + idx = cm.indexFromPos(cur); + curPosFinal = cm.posFromIndex(idx + text.length); + } + } + } + if (vim.visualMode) { + exitVisualMode(cm, false); + } + cm.setCursor(curPosFinal); + }, + undo: function(cm, actionArgs) { + cm.operation(function() { + repeatFn(cm, CodeMirror.commands.undo, actionArgs.repeat)(); + cm.setCursor(cm.getCursor('anchor')); + }); + }, + redo: function(cm, actionArgs) { + repeatFn(cm, CodeMirror.commands.redo, actionArgs.repeat)(); + }, + setRegister: function(_cm, actionArgs, vim) { + vim.inputState.registerName = actionArgs.selectedCharacter; + }, + setMark: function(cm, actionArgs, vim) { + var markName = actionArgs.selectedCharacter; + updateMark(cm, vim, markName, cm.getCursor()); + }, + replace: function(cm, actionArgs, vim) { + var replaceWith = actionArgs.selectedCharacter; + var curStart = cm.getCursor(); + var replaceTo; + var curEnd; + var selections = cm.listSelections(); + if (vim.visualMode) { + curStart = cm.getCursor('start'); + curEnd = cm.getCursor('end'); + } else { + var line = cm.getLine(curStart.line); + replaceTo = curStart.ch + actionArgs.repeat; + if (replaceTo > line.length) { + replaceTo=line.length; + } + curEnd = Pos(curStart.line, replaceTo); + } + if (replaceWith=='\n') { + if (!vim.visualMode) cm.replaceRange('', curStart, curEnd); + // special case, where vim help says to replace by just one line-break + (CodeMirror.commands.newlineAndIndentContinueComment || CodeMirror.commands.newlineAndIndent)(cm); + } else { + var replaceWithStr = cm.getRange(curStart, curEnd); + //replace all characters in range by selected, but keep linebreaks + replaceWithStr = replaceWithStr.replace(/[^\n]/g, replaceWith); + if (vim.visualBlock) { + // Tabs are split in visua block before replacing + var spaces = new Array(cm.getOption("tabSize")+1).join(' '); + replaceWithStr = cm.getSelection(); + replaceWithStr = replaceWithStr.replace(/\t/g, spaces).replace(/[^\n]/g, replaceWith).split('\n'); + cm.replaceSelections(replaceWithStr); + } else { + cm.replaceRange(replaceWithStr, curStart, curEnd); + } + if (vim.visualMode) { + curStart = cursorIsBefore(selections[0].anchor, selections[0].head) ? + selections[0].anchor : selections[0].head; + cm.setCursor(curStart); + exitVisualMode(cm, false); + } else { + cm.setCursor(offsetCursor(curEnd, 0, -1)); + } + } + }, + incrementNumberToken: function(cm, actionArgs) { + var cur = cm.getCursor(); + var lineStr = cm.getLine(cur.line); + var re = /-?\d+/g; + var match; + var start; + var end; + var numberStr; + var token; + while ((match = re.exec(lineStr)) !== null) { + token = match[0]; + start = match.index; + end = start + token.length; + if (cur.ch < end)break; + } + if (!actionArgs.backtrack && (end <= cur.ch))return; + if (token) { + var increment = actionArgs.increase ? 1 : -1; + var number = parseInt(token) + (increment * actionArgs.repeat); + var from = Pos(cur.line, start); + var to = Pos(cur.line, end); + numberStr = number.toString(); + cm.replaceRange(numberStr, from, to); + } else { + return; + } + cm.setCursor(Pos(cur.line, start + numberStr.length - 1)); + }, + repeatLastEdit: function(cm, actionArgs, vim) { + var lastEditInputState = vim.lastEditInputState; + if (!lastEditInputState) { return; } + var repeat = actionArgs.repeat; + if (repeat && actionArgs.repeatIsExplicit) { + vim.lastEditInputState.repeatOverride = repeat; + } else { + repeat = vim.lastEditInputState.repeatOverride || repeat; + } + repeatLastEdit(cm, vim, repeat, false /** repeatForInsert */); + }, + exitInsertMode: exitInsertMode + }; + + function defineAction(name, fn) { + actions[name] = fn; + } + + /* + * Below are miscellaneous utility functions used by vim.js + */ + + /** + * Clips cursor to ensure that line is within the buffer's range + * If includeLineBreak is true, then allow cur.ch == lineLength. + */ + function clipCursorToContent(cm, cur, includeLineBreak) { + var line = Math.min(Math.max(cm.firstLine(), cur.line), cm.lastLine() ); + var maxCh = lineLength(cm, line) - 1; + maxCh = (includeLineBreak) ? maxCh + 1 : maxCh; + var ch = Math.min(Math.max(0, cur.ch), maxCh); + return Pos(line, ch); + } + function copyArgs(args) { + var ret = {}; + for (var prop in args) { + if (args.hasOwnProperty(prop)) { + ret[prop] = args[prop]; + } + } + return ret; + } + function offsetCursor(cur, offsetLine, offsetCh) { + if (typeof offsetLine === 'object') { + offsetCh = offsetLine.ch; + offsetLine = offsetLine.line; + } + return Pos(cur.line + offsetLine, cur.ch + offsetCh); + } + function getOffset(anchor, head) { + return { + line: head.line - anchor.line, + ch: head.line - anchor.line + }; + } + function commandMatches(keys, keyMap, context, inputState) { + // Partial matches are not applied. They inform the key handler + // that the current key sequence is a subsequence of a valid key + // sequence, so that the key buffer is not cleared. + var match, partial = [], full = []; + for (var i = 0; i < keyMap.length; i++) { + var command = keyMap[i]; + if (context == 'insert' && command.context != 'insert' || + command.context && command.context != context || + inputState.operator && command.type == 'action' || + !(match = commandMatch(keys, command.keys))) { continue; } + if (match == 'partial') { partial.push(command); } + if (match == 'full') { full.push(command); } + } + return { + partial: partial.length && partial, + full: full.length && full + }; + } + function commandMatch(pressed, mapped) { + if (mapped.slice(-11) == '') { + // Last character matches anything. + var prefixLen = mapped.length - 11; + var pressedPrefix = pressed.slice(0, prefixLen); + var mappedPrefix = mapped.slice(0, prefixLen); + return pressedPrefix == mappedPrefix && pressed.length > prefixLen ? 'full' : + mappedPrefix.indexOf(pressedPrefix) == 0 ? 'partial' : false; + } else { + return pressed == mapped ? 'full' : + mapped.indexOf(pressed) == 0 ? 'partial' : false; + } + } + function lastChar(keys) { + var match = /^.*(<[\w\-]+>)$/.exec(keys); + var selectedCharacter = match ? match[1] : keys.slice(-1); + if (selectedCharacter.length > 1){ + switch(selectedCharacter){ + case '': + selectedCharacter='\n'; + break; + case '': + selectedCharacter=' '; + break; + default: + break; + } + } + return selectedCharacter; + } + function repeatFn(cm, fn, repeat) { + return function() { + for (var i = 0; i < repeat; i++) { + fn(cm); + } + }; + } + function copyCursor(cur) { + return Pos(cur.line, cur.ch); + } + function cursorEqual(cur1, cur2) { + return cur1.ch == cur2.ch && cur1.line == cur2.line; + } + function cursorIsBefore(cur1, cur2) { + if (cur1.line < cur2.line) { + return true; + } + if (cur1.line == cur2.line && cur1.ch < cur2.ch) { + return true; + } + return false; + } + function cursorMin(cur1, cur2) { + if (arguments.length > 2) { + cur2 = cursorMin.apply(undefined, Array.prototype.slice.call(arguments, 1)); + } + return cursorIsBefore(cur1, cur2) ? cur1 : cur2; + } + function cursorMax(cur1, cur2) { + if (arguments.length > 2) { + cur2 = cursorMax.apply(undefined, Array.prototype.slice.call(arguments, 1)); + } + return cursorIsBefore(cur1, cur2) ? cur2 : cur1; + } + function cursorIsBetween(cur1, cur2, cur3) { + // returns true if cur2 is between cur1 and cur3. + var cur1before2 = cursorIsBefore(cur1, cur2); + var cur2before3 = cursorIsBefore(cur2, cur3); + return cur1before2 && cur2before3; + } + function lineLength(cm, lineNum) { + return cm.getLine(lineNum).length; + } + function trim(s) { + if (s.trim) { + return s.trim(); + } + return s.replace(/^\s+|\s+$/g, ''); + } + function escapeRegex(s) { + return s.replace(/([.?*+$\[\]\/\\(){}|\-])/g, '\\$1'); + } + function extendLineToColumn(cm, lineNum, column) { + var endCh = lineLength(cm, lineNum); + var spaces = new Array(column-endCh+1).join(' '); + cm.setCursor(Pos(lineNum, endCh)); + cm.replaceRange(spaces, cm.getCursor()); + } + // This functions selects a rectangular block + // of text with selectionEnd as any of its corner + // Height of block: + // Difference in selectionEnd.line and first/last selection.line + // Width of the block: + // Distance between selectionEnd.ch and any(first considered here) selection.ch + function selectBlock(cm, selectionEnd) { + var selections = [], ranges = cm.listSelections(); + var head = copyCursor(cm.clipPos(selectionEnd)); + var isClipped = !cursorEqual(selectionEnd, head); + var curHead = cm.getCursor('head'); + var primIndex = getIndex(ranges, curHead); + var wasClipped = cursorEqual(ranges[primIndex].head, ranges[primIndex].anchor); + var max = ranges.length - 1; + var index = max - primIndex > primIndex ? max : 0; + var base = ranges[index].anchor; + + var firstLine = Math.min(base.line, head.line); + var lastLine = Math.max(base.line, head.line); + var baseCh = base.ch, headCh = head.ch; + + var dir = ranges[index].head.ch - baseCh; + var newDir = headCh - baseCh; + if (dir > 0 && newDir <= 0) { + baseCh++; + if (!isClipped) { headCh--; } + } else if (dir < 0 && newDir >= 0) { + baseCh--; + if (!wasClipped) { headCh++; } + } else if (dir < 0 && newDir == -1) { + baseCh--; + headCh++; + } + for (var line = firstLine; line <= lastLine; line++) { + var range = {anchor: new Pos(line, baseCh), head: new Pos(line, headCh)}; + selections.push(range); + } + primIndex = head.line == lastLine ? selections.length - 1 : 0; + cm.setSelections(selections); + selectionEnd.ch = headCh; + base.ch = baseCh; + return base; + } + function selectForInsert(cm, head, height) { + var sel = []; + for (var i = 0; i < height; i++) { + var lineHead = offsetCursor(head, i, 0); + sel.push({anchor: lineHead, head: lineHead}); + } + cm.setSelections(sel, 0); + } + // getIndex returns the index of the cursor in the selections. + function getIndex(ranges, cursor, end) { + for (var i = 0; i < ranges.length; i++) { + var atAnchor = end != 'head' && cursorEqual(ranges[i].anchor, cursor); + var atHead = end != 'anchor' && cursorEqual(ranges[i].head, cursor); + if (atAnchor || atHead) { + return i; + } + } + return -1; + } + function getSelectedAreaRange(cm, vim) { + var lastSelection = vim.lastSelection; + var getCurrentSelectedAreaRange = function() { + var selections = cm.listSelections(); + var start = selections[0]; + var end = selections[selections.length-1]; + var selectionStart = cursorIsBefore(start.anchor, start.head) ? start.anchor : start.head; + var selectionEnd = cursorIsBefore(end.anchor, end.head) ? end.head : end.anchor; + return [selectionStart, selectionEnd]; + }; + var getLastSelectedAreaRange = function() { + var selectionStart = cm.getCursor(); + var selectionEnd = cm.getCursor(); + var block = lastSelection.visualBlock; + if (block) { + var width = block.width; + var height = block.height; + selectionEnd = Pos(selectionStart.line + height, selectionStart.ch + width); + var selections = []; + // selectBlock creates a 'proper' rectangular block. + // We do not want that in all cases, so we manually set selections. + for (var i = selectionStart.line; i < selectionEnd.line; i++) { + var anchor = Pos(i, selectionStart.ch); + var head = Pos(i, selectionEnd.ch); + var range = {anchor: anchor, head: head}; + selections.push(range); + } + cm.setSelections(selections); + } else { + var start = lastSelection.anchorMark.find(); + var end = lastSelection.headMark.find(); + var line = end.line - start.line; + var ch = end.ch - start.ch; + selectionEnd = {line: selectionEnd.line + line, ch: line ? selectionEnd.ch : ch + selectionEnd.ch}; + if (lastSelection.visualLine) { + selectionStart = Pos(selectionStart.line, 0); + selectionEnd = Pos(selectionEnd.line, lineLength(cm, selectionEnd.line)); + } + cm.setSelection(selectionStart, selectionEnd); + } + return [selectionStart, selectionEnd]; + }; + if (!vim.visualMode) { + // In case of replaying the action. + return getLastSelectedAreaRange(); + } else { + return getCurrentSelectedAreaRange(); + } + } + // Updates the previous selection with the current selection's values. This + // should only be called in visual mode. + function updateLastSelection(cm, vim) { + var anchor = vim.sel.anchor; + var head = vim.sel.head; + // To accommodate the effect of lastPastedText in the last selection + if (vim.lastPastedText) { + head = cm.posFromIndex(cm.indexFromPos(anchor) + vim.lastPastedText.length); + vim.lastPastedText = null; + } + vim.lastSelection = {'anchorMark': cm.setBookmark(anchor), + 'headMark': cm.setBookmark(head), + 'anchor': copyCursor(anchor), + 'head': copyCursor(head), + 'visualMode': vim.visualMode, + 'visualLine': vim.visualLine, + 'visualBlock': vim.visualBlock}; + } + function expandSelection(cm, start, end) { + var sel = cm.state.vim.sel; + var head = sel.head; + var anchor = sel.anchor; + var tmp; + if (cursorIsBefore(end, start)) { + tmp = end; + end = start; + start = tmp; + } + if (cursorIsBefore(head, anchor)) { + head = cursorMin(start, head); + anchor = cursorMax(anchor, end); + } else { + anchor = cursorMin(start, anchor); + head = cursorMax(head, end); + head = offsetCursor(head, 0, -1); + if (head.ch == -1 && head.line != cm.firstLine()) { + head = Pos(head.line - 1, lineLength(cm, head.line - 1)); + } + } + return [anchor, head]; + } + /** + * Updates the CodeMirror selection to match the provided vim selection. + * If no arguments are given, it uses the current vim selection state. + */ + function updateCmSelection(cm, sel, mode) { + var vim = cm.state.vim; + sel = sel || vim.sel; + var mode = mode || + vim.visualLine ? 'line' : vim.visualBlock ? 'block' : 'char'; + var cmSel = makeCmSelection(cm, sel, mode); + cm.setSelections(cmSel.ranges, cmSel.primary); + updateFakeCursor(cm); + } + function makeCmSelection(cm, sel, mode, exclusive) { + var head = copyCursor(sel.head); + var anchor = copyCursor(sel.anchor); + if (mode == 'char') { + var headOffset = !exclusive && !cursorIsBefore(sel.head, sel.anchor) ? 1 : 0; + var anchorOffset = cursorIsBefore(sel.head, sel.anchor) ? 1 : 0; + head = offsetCursor(sel.head, 0, headOffset); + anchor = offsetCursor(sel.anchor, 0, anchorOffset); + return { + ranges: [{anchor: anchor, head: head}], + primary: 0 + }; + } else if (mode == 'line') { + if (!cursorIsBefore(sel.head, sel.anchor)) { + anchor.ch = 0; + + var lastLine = cm.lastLine(); + if (head.line > lastLine) { + head.line = lastLine; + } + head.ch = lineLength(cm, head.line); + } else { + head.ch = 0; + anchor.ch = lineLength(cm, anchor.line); + } + return { + ranges: [{anchor: anchor, head: head}], + primary: 0 + }; + } else if (mode == 'block') { + var top = Math.min(anchor.line, head.line), + left = Math.min(anchor.ch, head.ch), + bottom = Math.max(anchor.line, head.line), + right = Math.max(anchor.ch, head.ch) + 1; + var height = bottom - top + 1; + var primary = head.line == top ? 0 : height - 1; + var ranges = []; + for (var i = 0; i < height; i++) { + ranges.push({ + anchor: Pos(top + i, left), + head: Pos(top + i, right) + }); + } + return { + ranges: ranges, + primary: primary + }; + } + } + function getHead(cm) { + var cur = cm.getCursor('head'); + if (cm.getSelection().length == 1) { + // Small corner case when only 1 character is selected. The "real" + // head is the left of head and anchor. + cur = cursorMin(cur, cm.getCursor('anchor')); + } + return cur; + } + + /** + * If moveHead is set to false, the CodeMirror selection will not be + * touched. The caller assumes the responsibility of putting the cursor + * in the right place. + */ + function exitVisualMode(cm, moveHead) { + var vim = cm.state.vim; + if (moveHead !== false) { + cm.setCursor(clipCursorToContent(cm, vim.sel.head)); + } + updateLastSelection(cm, vim); + vim.visualMode = false; + vim.visualLine = false; + vim.visualBlock = false; + CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"}); + if (vim.fakeCursor) { + vim.fakeCursor.clear(); + } + } + + // Remove any trailing newlines from the selection. For + // example, with the caret at the start of the last word on the line, + // 'dw' should word, but not the newline, while 'w' should advance the + // caret to the first character of the next line. + function clipToLine(cm, curStart, curEnd) { + var selection = cm.getRange(curStart, curEnd); + // Only clip if the selection ends with trailing newline + whitespace + if (/\n\s*$/.test(selection)) { + var lines = selection.split('\n'); + // We know this is all whitepsace. + lines.pop(); + + // Cases: + // 1. Last word is an empty line - do not clip the trailing '\n' + // 2. Last word is not an empty line - clip the trailing '\n' + var line; + // Find the line containing the last word, and clip all whitespace up + // to it. + for (var line = lines.pop(); lines.length > 0 && line && isWhiteSpaceString(line); line = lines.pop()) { + curEnd.line--; + curEnd.ch = 0; + } + // If the last word is not an empty line, clip an additional newline + if (line) { + curEnd.line--; + curEnd.ch = lineLength(cm, curEnd.line); + } else { + curEnd.ch = 0; + } + } + } + + // Expand the selection to line ends. + function expandSelectionToLine(_cm, curStart, curEnd) { + curStart.ch = 0; + curEnd.ch = 0; + curEnd.line++; + } + + function findFirstNonWhiteSpaceCharacter(text) { + if (!text) { + return 0; + } + var firstNonWS = text.search(/\S/); + return firstNonWS == -1 ? text.length : firstNonWS; + } + + function expandWordUnderCursor(cm, inclusive, _forward, bigWord, noSymbol) { + var cur = getHead(cm); + var line = cm.getLine(cur.line); + var idx = cur.ch; + + // Seek to first word or non-whitespace character, depending on if + // noSymbol is true. + var test = noSymbol ? wordCharTest[0] : bigWordCharTest [0]; + while (!test(line.charAt(idx))) { + idx++; + if (idx >= line.length) { return null; } + } + + if (bigWord) { + test = bigWordCharTest[0]; + } else { + test = wordCharTest[0]; + if (!test(line.charAt(idx))) { + test = wordCharTest[1]; + } + } + + var end = idx, start = idx; + while (test(line.charAt(end)) && end < line.length) { end++; } + while (test(line.charAt(start)) && start >= 0) { start--; } + start++; + + if (inclusive) { + // If present, include all whitespace after word. + // Otherwise, include all whitespace before word, except indentation. + var wordEnd = end; + while (/\s/.test(line.charAt(end)) && end < line.length) { end++; } + if (wordEnd == end) { + var wordStart = start; + while (/\s/.test(line.charAt(start - 1)) && start > 0) { start--; } + if (!start) { start = wordStart; } + } + } + return { start: Pos(cur.line, start), end: Pos(cur.line, end) }; + } + + function recordJumpPosition(cm, oldCur, newCur) { + if (!cursorEqual(oldCur, newCur)) { + vimGlobalState.jumpList.add(cm, oldCur, newCur); + } + } + + function recordLastCharacterSearch(increment, args) { + vimGlobalState.lastChararacterSearch.increment = increment; + vimGlobalState.lastChararacterSearch.forward = args.forward; + vimGlobalState.lastChararacterSearch.selectedCharacter = args.selectedCharacter; + } + + var symbolToMode = { + '(': 'bracket', ')': 'bracket', '{': 'bracket', '}': 'bracket', + '[': 'section', ']': 'section', + '*': 'comment', '/': 'comment', + 'm': 'method', 'M': 'method', + '#': 'preprocess' + }; + var findSymbolModes = { + bracket: { + isComplete: function(state) { + if (state.nextCh === state.symb) { + state.depth++; + if (state.depth >= 1)return true; + } else if (state.nextCh === state.reverseSymb) { + state.depth--; + } + return false; + } + }, + section: { + init: function(state) { + state.curMoveThrough = true; + state.symb = (state.forward ? ']' : '[') === state.symb ? '{' : '}'; + }, + isComplete: function(state) { + return state.index === 0 && state.nextCh === state.symb; + } + }, + comment: { + isComplete: function(state) { + var found = state.lastCh === '*' && state.nextCh === '/'; + state.lastCh = state.nextCh; + return found; + } + }, + // TODO: The original Vim implementation only operates on level 1 and 2. + // The current implementation doesn't check for code block level and + // therefore it operates on any levels. + method: { + init: function(state) { + state.symb = (state.symb === 'm' ? '{' : '}'); + state.reverseSymb = state.symb === '{' ? '}' : '{'; + }, + isComplete: function(state) { + if (state.nextCh === state.symb)return true; + return false; + } + }, + preprocess: { + init: function(state) { + state.index = 0; + }, + isComplete: function(state) { + if (state.nextCh === '#') { + var token = state.lineText.match(/#(\w+)/)[1]; + if (token === 'endif') { + if (state.forward && state.depth === 0) { + return true; + } + state.depth++; + } else if (token === 'if') { + if (!state.forward && state.depth === 0) { + return true; + } + state.depth--; + } + if (token === 'else' && state.depth === 0)return true; + } + return false; + } + } + }; + function findSymbol(cm, repeat, forward, symb) { + var cur = copyCursor(cm.getCursor()); + var increment = forward ? 1 : -1; + var endLine = forward ? cm.lineCount() : -1; + var curCh = cur.ch; + var line = cur.line; + var lineText = cm.getLine(line); + var state = { + lineText: lineText, + nextCh: lineText.charAt(curCh), + lastCh: null, + index: curCh, + symb: symb, + reverseSymb: (forward ? { ')': '(', '}': '{' } : { '(': ')', '{': '}' })[symb], + forward: forward, + depth: 0, + curMoveThrough: false + }; + var mode = symbolToMode[symb]; + if (!mode)return cur; + var init = findSymbolModes[mode].init; + var isComplete = findSymbolModes[mode].isComplete; + if (init) { init(state); } + while (line !== endLine && repeat) { + state.index += increment; + state.nextCh = state.lineText.charAt(state.index); + if (!state.nextCh) { + line += increment; + state.lineText = cm.getLine(line) || ''; + if (increment > 0) { + state.index = 0; + } else { + var lineLen = state.lineText.length; + state.index = (lineLen > 0) ? (lineLen-1) : 0; + } + state.nextCh = state.lineText.charAt(state.index); + } + if (isComplete(state)) { + cur.line = line; + cur.ch = state.index; + repeat--; + } + } + if (state.nextCh || state.curMoveThrough) { + return Pos(line, state.index); + } + return cur; + } + + /* + * Returns the boundaries of the next word. If the cursor in the middle of + * the word, then returns the boundaries of the current word, starting at + * the cursor. If the cursor is at the start/end of a word, and we are going + * forward/backward, respectively, find the boundaries of the next word. + * + * @param {CodeMirror} cm CodeMirror object. + * @param {Cursor} cur The cursor position. + * @param {boolean} forward True to search forward. False to search + * backward. + * @param {boolean} bigWord True if punctuation count as part of the word. + * False if only [a-zA-Z0-9] characters count as part of the word. + * @param {boolean} emptyLineIsWord True if empty lines should be treated + * as words. + * @return {Object{from:number, to:number, line: number}} The boundaries of + * the word, or null if there are no more words. + */ + function findWord(cm, cur, forward, bigWord, emptyLineIsWord) { + var lineNum = cur.line; + var pos = cur.ch; + var line = cm.getLine(lineNum); + var dir = forward ? 1 : -1; + var charTests = bigWord ? bigWordCharTest: wordCharTest; + + if (emptyLineIsWord && line == '') { + lineNum += dir; + line = cm.getLine(lineNum); + if (!isLine(cm, lineNum)) { + return null; + } + pos = (forward) ? 0 : line.length; + } + + while (true) { + if (emptyLineIsWord && line == '') { + return { from: 0, to: 0, line: lineNum }; + } + var stop = (dir > 0) ? line.length : -1; + var wordStart = stop, wordEnd = stop; + // Find bounds of next word. + while (pos != stop) { + var foundWord = false; + for (var i = 0; i < charTests.length && !foundWord; ++i) { + if (charTests[i](line.charAt(pos))) { + wordStart = pos; + // Advance to end of word. + while (pos != stop && charTests[i](line.charAt(pos))) { + pos += dir; + } + wordEnd = pos; + foundWord = wordStart != wordEnd; + if (wordStart == cur.ch && lineNum == cur.line && + wordEnd == wordStart + dir) { + // We started at the end of a word. Find the next one. + continue; + } else { + return { + from: Math.min(wordStart, wordEnd + 1), + to: Math.max(wordStart, wordEnd), + line: lineNum }; + } + } + } + if (!foundWord) { + pos += dir; + } + } + // Advance to next/prev line. + lineNum += dir; + if (!isLine(cm, lineNum)) { + return null; + } + line = cm.getLine(lineNum); + pos = (dir > 0) ? 0 : line.length; + } + // Should never get here. + throw new Error('The impossible happened.'); + } + + /** + * @param {CodeMirror} cm CodeMirror object. + * @param {Pos} cur The position to start from. + * @param {int} repeat Number of words to move past. + * @param {boolean} forward True to search forward. False to search + * backward. + * @param {boolean} wordEnd True to move to end of word. False to move to + * beginning of word. + * @param {boolean} bigWord True if punctuation count as part of the word. + * False if only alphabet characters count as part of the word. + * @return {Cursor} The position the cursor should move to. + */ + function moveToWord(cm, cur, repeat, forward, wordEnd, bigWord) { + var curStart = copyCursor(cur); + var words = []; + if (forward && !wordEnd || !forward && wordEnd) { + repeat++; + } + // For 'e', empty lines are not considered words, go figure. + var emptyLineIsWord = !(forward && wordEnd); + for (var i = 0; i < repeat; i++) { + var word = findWord(cm, cur, forward, bigWord, emptyLineIsWord); + if (!word) { + var eodCh = lineLength(cm, cm.lastLine()); + words.push(forward + ? {line: cm.lastLine(), from: eodCh, to: eodCh} + : {line: 0, from: 0, to: 0}); + break; + } + words.push(word); + cur = Pos(word.line, forward ? (word.to - 1) : word.from); + } + var shortCircuit = words.length != repeat; + var firstWord = words[0]; + var lastWord = words.pop(); + if (forward && !wordEnd) { + // w + if (!shortCircuit && (firstWord.from != curStart.ch || firstWord.line != curStart.line)) { + // We did not start in the middle of a word. Discard the extra word at the end. + lastWord = words.pop(); + } + return Pos(lastWord.line, lastWord.from); + } else if (forward && wordEnd) { + return Pos(lastWord.line, lastWord.to - 1); + } else if (!forward && wordEnd) { + // ge + if (!shortCircuit && (firstWord.to != curStart.ch || firstWord.line != curStart.line)) { + // We did not start in the middle of a word. Discard the extra word at the end. + lastWord = words.pop(); + } + return Pos(lastWord.line, lastWord.to); + } else { + // b + return Pos(lastWord.line, lastWord.from); + } + } + + function moveToCharacter(cm, repeat, forward, character) { + var cur = cm.getCursor(); + var start = cur.ch; + var idx; + for (var i = 0; i < repeat; i ++) { + var line = cm.getLine(cur.line); + idx = charIdxInLine(start, line, character, forward, true); + if (idx == -1) { + return null; + } + start = idx; + } + return Pos(cm.getCursor().line, idx); + } + + function moveToColumn(cm, repeat) { + // repeat is always >= 1, so repeat - 1 always corresponds + // to the column we want to go to. + var line = cm.getCursor().line; + return clipCursorToContent(cm, Pos(line, repeat - 1)); + } + + function updateMark(cm, vim, markName, pos) { + if (!inArray(markName, validMarks)) { + return; + } + if (vim.marks[markName]) { + vim.marks[markName].clear(); + } + vim.marks[markName] = cm.setBookmark(pos); + } + + function charIdxInLine(start, line, character, forward, includeChar) { + // Search for char in line. + // motion_options: {forward, includeChar} + // If includeChar = true, include it too. + // If forward = true, search forward, else search backwards. + // If char is not found on this line, do nothing + var idx; + if (forward) { + idx = line.indexOf(character, start + 1); + if (idx != -1 && !includeChar) { + idx -= 1; + } + } else { + idx = line.lastIndexOf(character, start - 1); + if (idx != -1 && !includeChar) { + idx += 1; + } + } + return idx; + } + + function findParagraph(cm, head, repeat, dir, inclusive) { + var line = head.line; + var min = cm.firstLine(); + var max = cm.lastLine(); + var start, end, i = line; + function isEmpty(i) { return !/\S/.test(cm.getLine(i)); } + function isBoundary(i, dir, any) { + if (any) { return isEmpty(i) != isEmpty(i + dir); } + return !isEmpty(i) && isEmpty(i + dir); + } + if (dir) { + while (min <= i && i <= max && repeat > 0) { + if (isBoundary(i, dir)) { repeat--; } + i += dir; + } + return new Pos(i, 0); + } + + var vim = cm.state.vim; + if (vim.visualLine && isBoundary(line, 1, true)) { + var anchor = vim.sel.anchor; + if (isBoundary(anchor.line, -1, true)) { + if (!inclusive || anchor.line != line) { + line += 1; + } + } + } + var startState = isEmpty(line); + for (i = line; i <= max && repeat; i++) { + if (isBoundary(i, 1, true)) { + if (!inclusive || isEmpty(i) != startState) { + repeat--; + } + } + } + end = new Pos(i, 0); + // select boundary before paragraph for the last one + if (i > max && !startState) { startState = true; } + else { inclusive = false; } + for (i = line; i > min; i--) { + if (!inclusive || isEmpty(i) == startState || i == line) { + if (isBoundary(i, -1, true)) { break; } + } + } + start = new Pos(i, 0); + return { start: start, end: end }; + } + + // TODO: perhaps this finagling of start and end positions belonds + // in codmirror/replaceRange? + function selectCompanionObject(cm, head, symb, inclusive) { + var cur = head, start, end; + + var bracketRegexp = ({ + '(': /[()]/, ')': /[()]/, + '[': /[[\]]/, ']': /[[\]]/, + '{': /[{}]/, '}': /[{}]/})[symb]; + var openSym = ({ + '(': '(', ')': '(', + '[': '[', ']': '[', + '{': '{', '}': '{'})[symb]; + var curChar = cm.getLine(cur.line).charAt(cur.ch); + // Due to the behavior of scanForBracket, we need to add an offset if the + // cursor is on a matching open bracket. + var offset = curChar === openSym ? 1 : 0; + + start = cm.scanForBracket(Pos(cur.line, cur.ch + offset), -1, null, {'bracketRegex': bracketRegexp}); + end = cm.scanForBracket(Pos(cur.line, cur.ch + offset), 1, null, {'bracketRegex': bracketRegexp}); + + if (!start || !end) { + return { start: cur, end: cur }; + } + + start = start.pos; + end = end.pos; + + if ((start.line == end.line && start.ch > end.ch) + || (start.line > end.line)) { + var tmp = start; + start = end; + end = tmp; + } + + if (inclusive) { + end.ch += 1; + } else { + start.ch += 1; + } + + return { start: start, end: end }; + } + + // Takes in a symbol and a cursor and tries to simulate text objects that + // have identical opening and closing symbols + // TODO support across multiple lines + function findBeginningAndEnd(cm, head, symb, inclusive) { + var cur = copyCursor(head); + var line = cm.getLine(cur.line); + var chars = line.split(''); + var start, end, i, len; + var firstIndex = chars.indexOf(symb); + + // the decision tree is to always look backwards for the beginning first, + // but if the cursor is in front of the first instance of the symb, + // then move the cursor forward + if (cur.ch < firstIndex) { + cur.ch = firstIndex; + // Why is this line even here??? + // cm.setCursor(cur.line, firstIndex+1); + } + // otherwise if the cursor is currently on the closing symbol + else if (firstIndex < cur.ch && chars[cur.ch] == symb) { + end = cur.ch; // assign end to the current cursor + --cur.ch; // make sure to look backwards + } + + // if we're currently on the symbol, we've got a start + if (chars[cur.ch] == symb && !end) { + start = cur.ch + 1; // assign start to ahead of the cursor + } else { + // go backwards to find the start + for (i = cur.ch; i > -1 && !start; i--) { + if (chars[i] == symb) { + start = i + 1; + } + } + } + + // look forwards for the end symbol + if (start && !end) { + for (i = start, len = chars.length; i < len && !end; i++) { + if (chars[i] == symb) { + end = i; + } + } + } + + // nothing found + if (!start || !end) { + return { start: cur, end: cur }; + } + + // include the symbols + if (inclusive) { + --start; ++end; + } + + return { + start: Pos(cur.line, start), + end: Pos(cur.line, end) + }; + } + + // Search functions + defineOption('pcre', true, 'boolean'); + function SearchState() {} + SearchState.prototype = { + getQuery: function() { + return vimGlobalState.query; + }, + setQuery: function(query) { + vimGlobalState.query = query; + }, + getOverlay: function() { + return this.searchOverlay; + }, + setOverlay: function(overlay) { + this.searchOverlay = overlay; + }, + isReversed: function() { + return vimGlobalState.isReversed; + }, + setReversed: function(reversed) { + vimGlobalState.isReversed = reversed; + }, + getScrollbarAnnotate: function() { + return this.annotate; + }, + setScrollbarAnnotate: function(annotate) { + this.annotate = annotate; + } + }; + function getSearchState(cm) { + var vim = cm.state.vim; + return vim.searchState_ || (vim.searchState_ = new SearchState()); + } + function dialog(cm, template, shortText, onClose, options) { + if (cm.openDialog) { + cm.openDialog(template, onClose, { bottom: true, value: options.value, + onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp, + selectValueOnOpen: false}); + } + else { + onClose(prompt(shortText, '')); + } + } + function splitBySlash(argString) { + var slashes = findUnescapedSlashes(argString) || []; + if (!slashes.length) return []; + var tokens = []; + // in case of strings like foo/bar + if (slashes[0] !== 0) return; + for (var i = 0; i < slashes.length; i++) { + if (typeof slashes[i] == 'number') + tokens.push(argString.substring(slashes[i] + 1, slashes[i+1])); + } + return tokens; + } + + function findUnescapedSlashes(str) { + var escapeNextChar = false; + var slashes = []; + for (var i = 0; i < str.length; i++) { + var c = str.charAt(i); + if (!escapeNextChar && c == '/') { + slashes.push(i); + } + escapeNextChar = !escapeNextChar && (c == '\\'); + } + return slashes; + } + + // Translates a search string from ex (vim) syntax into javascript form. + function translateRegex(str) { + // When these match, add a '\' if unescaped or remove one if escaped. + var specials = '|(){'; + // Remove, but never add, a '\' for these. + var unescape = '}'; + var escapeNextChar = false; + var out = []; + for (var i = -1; i < str.length; i++) { + var c = str.charAt(i) || ''; + var n = str.charAt(i+1) || ''; + var specialComesNext = (n && specials.indexOf(n) != -1); + if (escapeNextChar) { + if (c !== '\\' || !specialComesNext) { + out.push(c); + } + escapeNextChar = false; + } else { + if (c === '\\') { + escapeNextChar = true; + // Treat the unescape list as special for removing, but not adding '\'. + if (n && unescape.indexOf(n) != -1) { + specialComesNext = true; + } + // Not passing this test means removing a '\'. + if (!specialComesNext || n === '\\') { + out.push(c); + } + } else { + out.push(c); + if (specialComesNext && n !== '\\') { + out.push('\\'); + } + } + } + } + return out.join(''); + } + + // Translates the replace part of a search and replace from ex (vim) syntax into + // javascript form. Similar to translateRegex, but additionally fixes back references + // (translates '\[0..9]' to '$[0..9]') and follows different rules for escaping '$'. + function translateRegexReplace(str) { + var escapeNextChar = false; + var out = []; + for (var i = -1; i < str.length; i++) { + var c = str.charAt(i) || ''; + var n = str.charAt(i+1) || ''; + if (escapeNextChar) { + // At any point in the loop, escapeNextChar is true if the previous + // character was a '\' and was not escaped. + out.push(c); + escapeNextChar = false; + } else { + if (c === '\\') { + escapeNextChar = true; + if ((isNumber(n) || n === '$')) { + out.push('$'); + } else if (n !== '/' && n !== '\\') { + out.push('\\'); + } + } else { + if (c === '$') { + out.push('$'); + } + out.push(c); + if (n === '/') { + out.push('\\'); + } + } + } + } + return out.join(''); + } + + // Unescape \ and / in the replace part, for PCRE mode. + function unescapeRegexReplace(str) { + var stream = new CodeMirror.StringStream(str); + var output = []; + while (!stream.eol()) { + // Search for \. + while (stream.peek() && stream.peek() != '\\') { + output.push(stream.next()); + } + if (stream.match('\\/', true)) { + // \/ => / + output.push('/'); + } else if (stream.match('\\\\', true)) { + // \\ => \ + output.push('\\'); + } else { + // Don't change anything + output.push(stream.next()); + } + } + return output.join(''); + } + + /** + * Extract the regular expression from the query and return a Regexp object. + * Returns null if the query is blank. + * If ignoreCase is passed in, the Regexp object will have the 'i' flag set. + * If smartCase is passed in, and the query contains upper case letters, + * then ignoreCase is overridden, and the 'i' flag will not be set. + * If the query contains the /i in the flag part of the regular expression, + * then both ignoreCase and smartCase are ignored, and 'i' will be passed + * through to the Regex object. + */ + function parseQuery(query, ignoreCase, smartCase) { + // First update the last search register + var lastSearchRegister = vimGlobalState.registerController.getRegister('/'); + lastSearchRegister.setText(query); + // Check if the query is already a regex. + if (query instanceof RegExp) { return query; } + // First try to extract regex + flags from the input. If no flags found, + // extract just the regex. IE does not accept flags directly defined in + // the regex string in the form /regex/flags + var slashes = findUnescapedSlashes(query); + var regexPart; + var forceIgnoreCase; + if (!slashes.length) { + // Query looks like 'regexp' + regexPart = query; + } else { + // Query looks like 'regexp/...' + regexPart = query.substring(0, slashes[0]); + var flagsPart = query.substring(slashes[0]); + forceIgnoreCase = (flagsPart.indexOf('i') != -1); + } + if (!regexPart) { + return null; + } + if (!getOption('pcre')) { + regexPart = translateRegex(regexPart); + } + if (smartCase) { + ignoreCase = (/^[^A-Z]*$/).test(regexPart); + } + var regexp = new RegExp(regexPart, + (ignoreCase || forceIgnoreCase) ? 'i' : undefined); + return regexp; + } + function showConfirm(cm, text) { + if (cm.openNotification) { + cm.openNotification('' + text + '', + {bottom: true, duration: 5000}); + } else { + alert(text); + } + } + function makePrompt(prefix, desc) { + var raw = ''; + if (prefix) { + raw += '' + prefix + ''; + } + raw += ' ' + + ''; + if (desc) { + raw += ''; + raw += desc; + raw += ''; + } + return raw; + } + var searchPromptDesc = '(Javascript regexp)'; + function showPrompt(cm, options) { + var shortText = (options.prefix || '') + ' ' + (options.desc || ''); + var prompt = makePrompt(options.prefix, options.desc); + dialog(cm, prompt, shortText, options.onClose, options); + } + function regexEqual(r1, r2) { + if (r1 instanceof RegExp && r2 instanceof RegExp) { + var props = ['global', 'multiline', 'ignoreCase', 'source']; + for (var i = 0; i < props.length; i++) { + var prop = props[i]; + if (r1[prop] !== r2[prop]) { + return false; + } + } + return true; + } + return false; + } + // Returns true if the query is valid. + function updateSearchQuery(cm, rawQuery, ignoreCase, smartCase) { + if (!rawQuery) { + return; + } + var state = getSearchState(cm); + var query = parseQuery(rawQuery, !!ignoreCase, !!smartCase); + if (!query) { + return; + } + highlightSearchMatches(cm, query); + if (regexEqual(query, state.getQuery())) { + return query; + } + state.setQuery(query); + return query; + } + function searchOverlay(query) { + if (query.source.charAt(0) == '^') { + var matchSol = true; + } + return { + token: function(stream) { + if (matchSol && !stream.sol()) { + stream.skipToEnd(); + return; + } + var match = stream.match(query, false); + if (match) { + if (match[0].length == 0) { + // Matched empty string, skip to next. + stream.next(); + return 'searching'; + } + if (!stream.sol()) { + // Backtrack 1 to match \b + stream.backUp(1); + if (!query.exec(stream.next() + match[0])) { + stream.next(); + return null; + } + } + stream.match(query); + return 'searching'; + } + while (!stream.eol()) { + stream.next(); + if (stream.match(query, false)) break; + } + }, + query: query + }; + } + function highlightSearchMatches(cm, query) { + var searchState = getSearchState(cm); + var overlay = searchState.getOverlay(); + if (!overlay || query != overlay.query) { + if (overlay) { + cm.removeOverlay(overlay); + } + overlay = searchOverlay(query); + cm.addOverlay(overlay); + if (cm.showMatchesOnScrollbar) { + if (searchState.getScrollbarAnnotate()) { + searchState.getScrollbarAnnotate().clear(); + } + searchState.setScrollbarAnnotate(cm.showMatchesOnScrollbar(query)); + } + searchState.setOverlay(overlay); + } + } + function findNext(cm, prev, query, repeat) { + if (repeat === undefined) { repeat = 1; } + return cm.operation(function() { + var pos = cm.getCursor(); + var cursor = cm.getSearchCursor(query, pos); + for (var i = 0; i < repeat; i++) { + var found = cursor.find(prev); + if (i == 0 && found && cursorEqual(cursor.from(), pos)) { found = cursor.find(prev); } + if (!found) { + // SearchCursor may have returned null because it hit EOF, wrap + // around and try again. + cursor = cm.getSearchCursor(query, + (prev) ? Pos(cm.lastLine()) : Pos(cm.firstLine(), 0) ); + if (!cursor.find(prev)) { + return; + } + } + } + return cursor.from(); + }); + } + function clearSearchHighlight(cm) { + var state = getSearchState(cm); + cm.removeOverlay(getSearchState(cm).getOverlay()); + state.setOverlay(null); + if (state.getScrollbarAnnotate()) { + state.getScrollbarAnnotate().clear(); + state.setScrollbarAnnotate(null); + } + } + /** + * Check if pos is in the specified range, INCLUSIVE. + * Range can be specified with 1 or 2 arguments. + * If the first range argument is an array, treat it as an array of line + * numbers. Match pos against any of the lines. + * If the first range argument is a number, + * if there is only 1 range argument, check if pos has the same line + * number + * if there are 2 range arguments, then check if pos is in between the two + * range arguments. + */ + function isInRange(pos, start, end) { + if (typeof pos != 'number') { + // Assume it is a cursor position. Get the line number. + pos = pos.line; + } + if (start instanceof Array) { + return inArray(pos, start); + } else { + if (end) { + return (pos >= start && pos <= end); + } else { + return pos == start; + } + } + } + function getUserVisibleLines(cm) { + var renderer = cm.ace.renderer; + return { + top: renderer.getFirstFullyVisibleRow(), + bottom: renderer.getLastFullyVisibleRow() + } + } + + // Ex command handling + // Care must be taken when adding to the default Ex command map. For any + // pair of commands that have a shared prefix, at least one of their + // shortNames must not match the prefix of the other command. + var defaultExCommandMap = [ + { name: 'colorscheme', shortName: 'colo' }, + { name: 'map' }, + { name: 'imap', shortName: 'im' }, + { name: 'nmap', shortName: 'nm' }, + { name: 'vmap', shortName: 'vm' }, + { name: 'unmap' }, + { name: 'write', shortName: 'w' }, + { name: 'undo', shortName: 'u' }, + { name: 'redo', shortName: 'red' }, + { name: 'set', shortName: 'se' }, + { name: 'set', shortName: 'se' }, + { name: 'setlocal', shortName: 'setl' }, + { name: 'setglobal', shortName: 'setg' }, + { name: 'sort', shortName: 'sor' }, + { name: 'substitute', shortName: 's', possiblyAsync: true }, + { name: 'nohlsearch', shortName: 'noh' }, + { name: 'delmarks', shortName: 'delm' }, + { name: 'registers', shortName: 'reg', excludeFromCommandHistory: true }, + { name: 'global', shortName: 'g' } + ]; + var ExCommandDispatcher = function() { + this.buildCommandMap_(); + }; + ExCommandDispatcher.prototype = { + processCommand: function(cm, input, opt_params) { + var that = this; + cm.operation(function () { + cm.curOp.isVimOp = true; + that._processCommand(cm, input, opt_params); + }); + }, + _processCommand: function(cm, input, opt_params) { + var vim = cm.state.vim; + var commandHistoryRegister = vimGlobalState.registerController.getRegister(':'); + var previousCommand = commandHistoryRegister.toString(); + if (vim.visualMode) { + exitVisualMode(cm); + } + var inputStream = new CodeMirror.StringStream(input); + // update ": with the latest command whether valid or invalid + commandHistoryRegister.setText(input); + var params = opt_params || {}; + params.input = input; + try { + this.parseInput_(cm, inputStream, params); + } catch(e) { + showConfirm(cm, e); + throw e; + } + var command; + var commandName; + if (!params.commandName) { + // If only a line range is defined, move to the line. + if (params.line !== undefined) { + commandName = 'move'; + } + } else { + command = this.matchCommand_(params.commandName); + if (command) { + commandName = command.name; + if (command.excludeFromCommandHistory) { + commandHistoryRegister.setText(previousCommand); + } + this.parseCommandArgs_(inputStream, params, command); + if (command.type == 'exToKey') { + // Handle Ex to Key mapping. + for (var i = 0; i < command.toKeys.length; i++) { + CodeMirror.Vim.handleKey(cm, command.toKeys[i], 'mapping'); + } + return; + } else if (command.type == 'exToEx') { + // Handle Ex to Ex mapping. + this.processCommand(cm, command.toInput); + return; + } + } + } + if (!commandName) { + showConfirm(cm, 'Not an editor command ":' + input + '"'); + return; + } + try { + exCommands[commandName](cm, params); + // Possibly asynchronous commands (e.g. substitute, which might have a + // user confirmation), are responsible for calling the callback when + // done. All others have it taken care of for them here. + if ((!command || !command.possiblyAsync) && params.callback) { + params.callback(); + } + } catch(e) { + showConfirm(cm, e); + throw e; + } + }, + parseInput_: function(cm, inputStream, result) { + inputStream.eatWhile(':'); + // Parse range. + if (inputStream.eat('%')) { + result.line = cm.firstLine(); + result.lineEnd = cm.lastLine(); + } else { + result.line = this.parseLineSpec_(cm, inputStream); + if (result.line !== undefined && inputStream.eat(',')) { + result.lineEnd = this.parseLineSpec_(cm, inputStream); + } + } + + // Parse command name. + var commandMatch = inputStream.match(/^(\w+)/); + if (commandMatch) { + result.commandName = commandMatch[1]; + } else { + result.commandName = inputStream.match(/.*/)[0]; + } + + return result; + }, + parseLineSpec_: function(cm, inputStream) { + var numberMatch = inputStream.match(/^(\d+)/); + if (numberMatch) { + return parseInt(numberMatch[1], 10) - 1; + } + switch (inputStream.next()) { + case '.': + return cm.getCursor().line; + case '$': + return cm.lastLine(); + case '\'': + var mark = cm.state.vim.marks[inputStream.next()]; + if (mark && mark.find()) { + return mark.find().line; + } + throw new Error('Mark not set'); + default: + inputStream.backUp(1); + return undefined; + } + }, + parseCommandArgs_: function(inputStream, params, command) { + if (inputStream.eol()) { + return; + } + params.argString = inputStream.match(/.*/)[0]; + // Parse command-line arguments + var delim = command.argDelimiter || /\s+/; + var args = trim(params.argString).split(delim); + if (args.length && args[0]) { + params.args = args; + } + }, + matchCommand_: function(commandName) { + // Return the command in the command map that matches the shortest + // prefix of the passed in command name. The match is guaranteed to be + // unambiguous if the defaultExCommandMap's shortNames are set up + // correctly. (see @code{defaultExCommandMap}). + for (var i = commandName.length; i > 0; i--) { + var prefix = commandName.substring(0, i); + if (this.commandMap_[prefix]) { + var command = this.commandMap_[prefix]; + if (command.name.indexOf(commandName) === 0) { + return command; + } + } + } + return null; + }, + buildCommandMap_: function() { + this.commandMap_ = {}; + for (var i = 0; i < defaultExCommandMap.length; i++) { + var command = defaultExCommandMap[i]; + var key = command.shortName || command.name; + this.commandMap_[key] = command; + } + }, + map: function(lhs, rhs, ctx) { + if (lhs != ':' && lhs.charAt(0) == ':') { + if (ctx) { throw Error('Mode not supported for ex mappings'); } + var commandName = lhs.substring(1); + if (rhs != ':' && rhs.charAt(0) == ':') { + // Ex to Ex mapping + this.commandMap_[commandName] = { + name: commandName, + type: 'exToEx', + toInput: rhs.substring(1), + user: true + }; + } else { + // Ex to key mapping + this.commandMap_[commandName] = { + name: commandName, + type: 'exToKey', + toKeys: rhs, + user: true + }; + } + } else { + if (rhs != ':' && rhs.charAt(0) == ':') { + // Key to Ex mapping. + var mapping = { + keys: lhs, + type: 'keyToEx', + exArgs: { input: rhs.substring(1) }, + user: true}; + if (ctx) { mapping.context = ctx; } + defaultKeymap.unshift(mapping); + } else { + // Key to key mapping + var mapping = { + keys: lhs, + type: 'keyToKey', + toKeys: rhs, + user: true + }; + if (ctx) { mapping.context = ctx; } + defaultKeymap.unshift(mapping); + } + } + }, + unmap: function(lhs, ctx) { + if (lhs != ':' && lhs.charAt(0) == ':') { + // Ex to Ex or Ex to key mapping + if (ctx) { throw Error('Mode not supported for ex mappings'); } + var commandName = lhs.substring(1); + if (this.commandMap_[commandName] && this.commandMap_[commandName].user) { + delete this.commandMap_[commandName]; + return; + } + } else { + // Key to Ex or key to key mapping + var keys = lhs; + for (var i = 0; i < defaultKeymap.length; i++) { + if (keys == defaultKeymap[i].keys + && defaultKeymap[i].context === ctx + && defaultKeymap[i].user) { + defaultKeymap.splice(i, 1); + return; + } + } + } + throw Error('No such mapping.'); + } + }; + + var exCommands = { + colorscheme: function(cm, params) { + if (!params.args || params.args.length < 1) { + showConfirm(cm, cm.getOption('theme')); + return; + } + cm.setOption('theme', params.args[0]); + }, + map: function(cm, params, ctx) { + var mapArgs = params.args; + if (!mapArgs || mapArgs.length < 2) { + if (cm) { + showConfirm(cm, 'Invalid mapping: ' + params.input); + } + return; + } + exCommandDispatcher.map(mapArgs[0], mapArgs[1], ctx); + }, + imap: function(cm, params) { this.map(cm, params, 'insert'); }, + nmap: function(cm, params) { this.map(cm, params, 'normal'); }, + vmap: function(cm, params) { this.map(cm, params, 'visual'); }, + unmap: function(cm, params, ctx) { + var mapArgs = params.args; + if (!mapArgs || mapArgs.length < 1) { + if (cm) { + showConfirm(cm, 'No such mapping: ' + params.input); + } + return; + } + exCommandDispatcher.unmap(mapArgs[0], ctx); + }, + move: function(cm, params) { + commandDispatcher.processCommand(cm, cm.state.vim, { + type: 'motion', + motion: 'moveToLineOrEdgeOfDocument', + motionArgs: { forward: false, explicitRepeat: true, + linewise: true }, + repeatOverride: params.line+1}); + }, + set: function(cm, params) { + var setArgs = params.args; + // Options passed through to the setOption/getOption calls. May be passed in by the + // local/global versions of the set command + var setCfg = params.setCfg || {}; + if (!setArgs || setArgs.length < 1) { + if (cm) { + showConfirm(cm, 'Invalid mapping: ' + params.input); + } + return; + } + var expr = setArgs[0].split('='); + var optionName = expr[0]; + var value = expr[1]; + var forceGet = false; + + if (optionName.charAt(optionName.length - 1) == '?') { + // If post-fixed with ?, then the set is actually a get. + if (value) { throw Error('Trailing characters: ' + params.argString); } + optionName = optionName.substring(0, optionName.length - 1); + forceGet = true; + } + if (value === undefined && optionName.substring(0, 2) == 'no') { + // To set boolean options to false, the option name is prefixed with + // 'no'. + optionName = optionName.substring(2); + value = false; + } + + var optionIsBoolean = options[optionName] && options[optionName].type == 'boolean'; + if (optionIsBoolean && value == undefined) { + // Calling set with a boolean option sets it to true. + value = true; + } + // If no value is provided, then we assume this is a get. + if (!optionIsBoolean && value === undefined || forceGet) { + var oldValue = getOption(optionName, cm, setCfg); + if (oldValue === true || oldValue === false) { + showConfirm(cm, ' ' + (oldValue ? '' : 'no') + optionName); + } else { + showConfirm(cm, ' ' + optionName + '=' + oldValue); + } + } else { + setOption(optionName, value, cm, setCfg); + } + }, + setlocal: function (cm, params) { + // setCfg is passed through to setOption + params.setCfg = {scope: 'local'}; + this.set(cm, params); + }, + setglobal: function (cm, params) { + // setCfg is passed through to setOption + params.setCfg = {scope: 'global'}; + this.set(cm, params); + }, + registers: function(cm, params) { + var regArgs = params.args; + var registers = vimGlobalState.registerController.registers; + var regInfo = '----------Registers----------

    '; + if (!regArgs) { + for (var registerName in registers) { + var text = registers[registerName].toString(); + if (text.length) { + regInfo += '"' + registerName + ' ' + text + '
    '; + } + } + } else { + var registerName; + regArgs = regArgs.join(''); + for (var i = 0; i < regArgs.length; i++) { + registerName = regArgs.charAt(i); + if (!vimGlobalState.registerController.isValidRegister(registerName)) { + continue; + } + var register = registers[registerName] || new Register(); + regInfo += '"' + registerName + ' ' + register.toString() + '
    '; + } + } + showConfirm(cm, regInfo); + }, + sort: function(cm, params) { + var reverse, ignoreCase, unique, number; + function parseArgs() { + if (params.argString) { + var args = new CodeMirror.StringStream(params.argString); + if (args.eat('!')) { reverse = true; } + if (args.eol()) { return; } + if (!args.eatSpace()) { return 'Invalid arguments'; } + var opts = args.match(/[a-z]+/); + if (opts) { + opts = opts[0]; + ignoreCase = opts.indexOf('i') != -1; + unique = opts.indexOf('u') != -1; + var decimal = opts.indexOf('d') != -1 && 1; + var hex = opts.indexOf('x') != -1 && 1; + var octal = opts.indexOf('o') != -1 && 1; + if (decimal + hex + octal > 1) { return 'Invalid arguments'; } + number = decimal && 'decimal' || hex && 'hex' || octal && 'octal'; + } + if (args.eatSpace() && args.match(/\/.*\//)) { 'patterns not supported'; } + } + } + var err = parseArgs(); + if (err) { + showConfirm(cm, err + ': ' + params.argString); + return; + } + var lineStart = params.line || cm.firstLine(); + var lineEnd = params.lineEnd || params.line || cm.lastLine(); + if (lineStart == lineEnd) { return; } + var curStart = Pos(lineStart, 0); + var curEnd = Pos(lineEnd, lineLength(cm, lineEnd)); + var text = cm.getRange(curStart, curEnd).split('\n'); + var numberRegex = (number == 'decimal') ? /(-?)([\d]+)/ : + (number == 'hex') ? /(-?)(?:0x)?([0-9a-f]+)/i : + (number == 'octal') ? /([0-7]+)/ : null; + var radix = (number == 'decimal') ? 10 : (number == 'hex') ? 16 : (number == 'octal') ? 8 : null; + var numPart = [], textPart = []; + if (number) { + for (var i = 0; i < text.length; i++) { + if (numberRegex.exec(text[i])) { + numPart.push(text[i]); + } else { + textPart.push(text[i]); + } + } + } else { + textPart = text; + } + function compareFn(a, b) { + if (reverse) { var tmp; tmp = a; a = b; b = tmp; } + if (ignoreCase) { a = a.toLowerCase(); b = b.toLowerCase(); } + var anum = number && numberRegex.exec(a); + var bnum = number && numberRegex.exec(b); + if (!anum) { return a < b ? -1 : 1; } + anum = parseInt((anum[1] + anum[2]).toLowerCase(), radix); + bnum = parseInt((bnum[1] + bnum[2]).toLowerCase(), radix); + return anum - bnum; + } + numPart.sort(compareFn); + textPart.sort(compareFn); + text = (!reverse) ? textPart.concat(numPart) : numPart.concat(textPart); + if (unique) { // Remove duplicate lines + var textOld = text; + var lastLine; + text = []; + for (var i = 0; i < textOld.length; i++) { + if (textOld[i] != lastLine) { + text.push(textOld[i]); + } + lastLine = textOld[i]; + } + } + cm.replaceRange(text.join('\n'), curStart, curEnd); + }, + global: function(cm, params) { + // a global command is of the form + // :[range]g/pattern/[cmd] + // argString holds the string /pattern/[cmd] + var argString = params.argString; + if (!argString) { + showConfirm(cm, 'Regular Expression missing from global'); + return; + } + // range is specified here + var lineStart = (params.line !== undefined) ? params.line : cm.firstLine(); + var lineEnd = params.lineEnd || params.line || cm.lastLine(); + // get the tokens from argString + var tokens = splitBySlash(argString); + var regexPart = argString, cmd; + if (tokens.length) { + regexPart = tokens[0]; + cmd = tokens.slice(1, tokens.length).join('/'); + } + if (regexPart) { + // If regex part is empty, then use the previous query. Otherwise + // use the regex part as the new query. + try { + updateSearchQuery(cm, regexPart, true /** ignoreCase */, + true /** smartCase */); + } catch (e) { + showConfirm(cm, 'Invalid regex: ' + regexPart); + return; + } + } + // now that we have the regexPart, search for regex matches in the + // specified range of lines + var query = getSearchState(cm).getQuery(); + var matchedLines = [], content = ''; + for (var i = lineStart; i <= lineEnd; i++) { + var matched = query.test(cm.getLine(i)); + if (matched) { + matchedLines.push(i+1); + content+= cm.getLine(i) + '
    '; + } + } + // if there is no [cmd], just display the list of matched lines + if (!cmd) { + showConfirm(cm, content); + return; + } + var index = 0; + var nextCommand = function() { + if (index < matchedLines.length) { + var command = matchedLines[index] + cmd; + exCommandDispatcher.processCommand(cm, command, { + callback: nextCommand + }); + } + index++; + }; + nextCommand(); + }, + substitute: function(cm, params) { + if (!cm.getSearchCursor) { + throw new Error('Search feature not available. Requires searchcursor.js or ' + + 'any other getSearchCursor implementation.'); + } + var argString = params.argString; + var tokens = argString ? splitBySlash(argString) : []; + var regexPart, replacePart = '', trailing, flagsPart, count; + var confirm = false; // Whether to confirm each replace. + var global = false; // True to replace all instances on a line, false to replace only 1. + if (tokens.length) { + regexPart = tokens[0]; + replacePart = tokens[1]; + if (replacePart !== undefined) { + if (getOption('pcre')) { + replacePart = unescapeRegexReplace(replacePart); + } else { + replacePart = translateRegexReplace(replacePart); + } + vimGlobalState.lastSubstituteReplacePart = replacePart; + } + trailing = tokens[2] ? tokens[2].split(' ') : []; + } else { + // either the argString is empty or its of the form ' hello/world' + // actually splitBySlash returns a list of tokens + // only if the string starts with a '/' + if (argString && argString.length) { + showConfirm(cm, 'Substitutions should be of the form ' + + ':s/pattern/replace/'); + return; + } + } + // After the 3rd slash, we can have flags followed by a space followed + // by count. + if (trailing) { + flagsPart = trailing[0]; + count = parseInt(trailing[1]); + if (flagsPart) { + if (flagsPart.indexOf('c') != -1) { + confirm = true; + flagsPart.replace('c', ''); + } + if (flagsPart.indexOf('g') != -1) { + global = true; + flagsPart.replace('g', ''); + } + regexPart = regexPart + '/' + flagsPart; + } + } + if (regexPart) { + // If regex part is empty, then use the previous query. Otherwise use + // the regex part as the new query. + try { + updateSearchQuery(cm, regexPart, true /** ignoreCase */, + true /** smartCase */); + } catch (e) { + showConfirm(cm, 'Invalid regex: ' + regexPart); + return; + } + } + replacePart = replacePart || vimGlobalState.lastSubstituteReplacePart; + if (replacePart === undefined) { + showConfirm(cm, 'No previous substitute regular expression'); + return; + } + var state = getSearchState(cm); + var query = state.getQuery(); + var lineStart = (params.line !== undefined) ? params.line : cm.getCursor().line; + var lineEnd = params.lineEnd || lineStart; + if (count) { + lineStart = lineEnd; + lineEnd = lineStart + count - 1; + } + var startPos = clipCursorToContent(cm, Pos(lineStart, 0)); + var cursor = cm.getSearchCursor(query, startPos); + doReplace(cm, confirm, global, lineStart, lineEnd, cursor, query, replacePart, params.callback); + }, + redo: CodeMirror.commands.redo, + undo: CodeMirror.commands.undo, + write: function(cm) { + if (CodeMirror.commands.save) { + // If a save command is defined, call it. + CodeMirror.commands.save(cm); + } else { + // Saves to text area if no save command is defined. + cm.save(); + } + }, + nohlsearch: function(cm) { + clearSearchHighlight(cm); + }, + delmarks: function(cm, params) { + if (!params.argString || !trim(params.argString)) { + showConfirm(cm, 'Argument required'); + return; + } + + var state = cm.state.vim; + var stream = new CodeMirror.StringStream(trim(params.argString)); + while (!stream.eol()) { + stream.eatSpace(); + + // Record the streams position at the beginning of the loop for use + // in error messages. + var count = stream.pos; + + if (!stream.match(/[a-zA-Z]/, false)) { + showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count)); + return; + } + + var sym = stream.next(); + // Check if this symbol is part of a range + if (stream.match('-', true)) { + // This symbol is part of a range. + + // The range must terminate at an alphabetic character. + if (!stream.match(/[a-zA-Z]/, false)) { + showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count)); + return; + } + + var startMark = sym; + var finishMark = stream.next(); + // The range must terminate at an alphabetic character which + // shares the same case as the start of the range. + if (isLowerCase(startMark) && isLowerCase(finishMark) || + isUpperCase(startMark) && isUpperCase(finishMark)) { + var start = startMark.charCodeAt(0); + var finish = finishMark.charCodeAt(0); + if (start >= finish) { + showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count)); + return; + } + + // Because marks are always ASCII values, and we have + // determined that they are the same case, we can use + // their char codes to iterate through the defined range. + for (var j = 0; j <= finish - start; j++) { + var mark = String.fromCharCode(start + j); + delete state.marks[mark]; + } + } else { + showConfirm(cm, 'Invalid argument: ' + startMark + '-'); + return; + } + } else { + // This symbol is a valid mark, and is not part of a range. + delete state.marks[sym]; + } + } + } + }; + + var exCommandDispatcher = new ExCommandDispatcher(); + + /** + * @param {CodeMirror} cm CodeMirror instance we are in. + * @param {boolean} confirm Whether to confirm each replace. + * @param {Cursor} lineStart Line to start replacing from. + * @param {Cursor} lineEnd Line to stop replacing at. + * @param {RegExp} query Query for performing matches with. + * @param {string} replaceWith Text to replace matches with. May contain $1, + * $2, etc for replacing captured groups using Javascript replace. + * @param {function()} callback A callback for when the replace is done. + */ + function doReplace(cm, confirm, global, lineStart, lineEnd, searchCursor, query, + replaceWith, callback) { + // Set up all the functions. + cm.state.vim.exMode = true; + var done = false; + var lastPos = searchCursor.from(); + function replaceAll() { + cm.operation(function() { + while (!done) { + replace(); + next(); + } + stop(); + }); + } + function replace() { + var text = cm.getRange(searchCursor.from(), searchCursor.to()); + var newText = text.replace(query, replaceWith); + searchCursor.replace(newText); + } + function next() { + var found; + // The below only loops to skip over multiple occurrences on the same + // line when 'global' is not true. + while(found = searchCursor.findNext() && + isInRange(searchCursor.from(), lineStart, lineEnd)) { + if (!global && lastPos && searchCursor.from().line == lastPos.line) { + continue; + } + cm.scrollIntoView(searchCursor.from(), 30); + cm.setSelection(searchCursor.from(), searchCursor.to()); + lastPos = searchCursor.from(); + done = false; + return; + } + done = true; + } + function stop(close) { + if (close) { close(); } + cm.focus(); + if (lastPos) { + cm.setCursor(lastPos); + var vim = cm.state.vim; + vim.exMode = false; + vim.lastHPos = vim.lastHSPos = lastPos.ch; + } + if (callback) { callback(); } + } + function onPromptKeyDown(e, _value, close) { + // Swallow all keys. + CodeMirror.e_stop(e); + var keyName = CodeMirror.keyName(e); + switch (keyName) { + case 'Y': + replace(); next(); break; + case 'N': + next(); break; + case 'A': + // replaceAll contains a call to close of its own. We don't want it + // to fire too early or multiple times. + var savedCallback = callback; + callback = undefined; + cm.operation(replaceAll); + callback = savedCallback; + break; + case 'L': + replace(); + // fall through and exit. + case 'Q': + case 'Esc': + case 'Ctrl-C': + case 'Ctrl-[': + stop(close); + break; + } + if (done) { stop(close); } + return true; + } + + // Actually do replace. + next(); + if (done) { + showConfirm(cm, 'No matches for ' + query.source); + return; + } + if (!confirm) { + replaceAll(); + if (callback) { callback(); }; + return; + } + showPrompt(cm, { + prefix: 'replace with ' + replaceWith + ' (y/n/a/q/l)', + onKeyDown: onPromptKeyDown + }); + } + + CodeMirror.keyMap.vim = { + attach: attachVimMap, + detach: detachVimMap, + call: cmKey + }; + + function exitInsertMode(cm) { + var vim = cm.state.vim; + var macroModeState = vimGlobalState.macroModeState; + var insertModeChangeRegister = vimGlobalState.registerController.getRegister('.'); + var isPlaying = macroModeState.isPlaying; + var lastChange = macroModeState.lastInsertModeChanges; + // In case of visual block, the insertModeChanges are not saved as a + // single word, so we convert them to a single word + // so as to update the ". register as expected in real vim. + var text = []; + if (!isPlaying) { + var selLength = lastChange.inVisualBlock ? vim.lastSelection.visualBlock.height : 1; + var changes = lastChange.changes; + var text = []; + var i = 0; + // In case of multiple selections in blockwise visual, + // the inserted text, for example: 'foo', is stored as + // 'f', 'f', InsertModeKey 'o', 'o', 'o', 'o'. (if you have a block with 2 lines). + // We push the contents of the changes array as per the following: + // 1. In case of InsertModeKey, just increment by 1. + // 2. In case of a character, jump by selLength (2 in the example). + while (i < changes.length) { + // This loop will convert 'ffoooo' to 'foo'. + text.push(changes[i]); + if (changes[i] instanceof InsertModeKey) { + i++; + } else { + i+= selLength; + } + } + lastChange.changes = text; + cm.off('change', onChange); + CodeMirror.off(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown); + } + if (!isPlaying && vim.insertModeRepeat > 1) { + // Perform insert mode repeat for commands like 3,a and 3,o. + repeatLastEdit(cm, vim, vim.insertModeRepeat - 1, + true /** repeatForInsert */); + vim.lastEditInputState.repeatOverride = vim.insertModeRepeat; + } + delete vim.insertModeRepeat; + vim.insertMode = false; + cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1); + cm.setOption('keyMap', 'vim'); + cm.setOption('disableInput', true); + cm.toggleOverwrite(false); // exit replace mode if we were in it. + // update the ". register before exiting insert mode + insertModeChangeRegister.setText(lastChange.changes.join('')); + CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"}); + if (macroModeState.isRecording) { + logInsertModeChange(macroModeState); + } + } + + function _mapCommand(command) { + defaultKeymap.push(command); + } + + function mapCommand(keys, type, name, args, extra) { + var command = {keys: keys, type: type}; + command[type] = name; + command[type + "Args"] = args; + for (var key in extra) + command[key] = extra[key]; + _mapCommand(command); + } + + // The timeout in milliseconds for the two-character ESC keymap should be + // adjusted according to your typing speed to prevent false positives. + defineOption('insertModeEscKeysTimeout', 200, 'number'); + + CodeMirror.keyMap['vim-insert'] = { + // TODO: override navigation keys so that Esc will cancel automatic + // indentation from o, O, i_ + 'Ctrl-N': 'autocomplete', + 'Ctrl-P': 'autocomplete', + 'Enter': function(cm) { + var fn = CodeMirror.commands.newlineAndIndentContinueComment || + CodeMirror.commands.newlineAndIndent; + fn(cm); + }, + fallthrough: ['default'], + attach: attachVimMap, + detach: detachVimMap, + call: cmKey + }; + + CodeMirror.keyMap['vim-replace'] = { + 'Backspace': 'goCharLeft', + fallthrough: ['vim-insert'], + attach: attachVimMap, + detach: detachVimMap, + call: cmKey + }; + + function executeMacroRegister(cm, vim, macroModeState, registerName) { + var register = vimGlobalState.registerController.getRegister(registerName); + var keyBuffer = register.keyBuffer; + var imc = 0; + macroModeState.isPlaying = true; + macroModeState.replaySearchQueries = register.searchQueries.slice(0); + for (var i = 0; i < keyBuffer.length; i++) { + var text = keyBuffer[i]; + var match, key; + while (text) { + // Pull off one command key, which is either a single character + // or a special sequence wrapped in '<' and '>', e.g. ''. + match = (/<\w+-.+?>|<\w+>|./).exec(text); + key = match[0]; + text = text.substring(match.index + key.length); + CodeMirror.Vim.handleKey(cm, key, 'macro'); + if (vim.insertMode) { + var changes = register.insertModeChanges[imc++].changes; + vimGlobalState.macroModeState.lastInsertModeChanges.changes = + changes; + repeatInsertModeChanges(cm, changes, 1); + exitInsertMode(cm); + } + } + }; + macroModeState.isPlaying = false; + } + + function logKey(macroModeState, key) { + if (macroModeState.isPlaying) { return; } + var registerName = macroModeState.latestRegister; + var register = vimGlobalState.registerController.getRegister(registerName); + if (register) { + register.pushText(key); + } + } + + function logInsertModeChange(macroModeState) { + if (macroModeState.isPlaying) { return; } + var registerName = macroModeState.latestRegister; + var register = vimGlobalState.registerController.getRegister(registerName); + if (register) { + register.pushInsertModeChanges(macroModeState.lastInsertModeChanges); + } + } + + function logSearchQuery(macroModeState, query) { + if (macroModeState.isPlaying) { return; } + var registerName = macroModeState.latestRegister; + var register = vimGlobalState.registerController.getRegister(registerName); + if (register) { + register.pushSearchQuery(query); + } + } + + /** + * Listens for changes made in insert mode. + * Should only be active in insert mode. + */ + function onChange(_cm, changeObj) { + var macroModeState = vimGlobalState.macroModeState; + var lastChange = macroModeState.lastInsertModeChanges; + if (!macroModeState.isPlaying) { + while(changeObj) { + lastChange.expectCursorActivityForChange = true; + if (changeObj.origin == '+input' || changeObj.origin == 'paste' + || changeObj.origin === undefined /* only in testing */) { + var text = changeObj.text.join('\n'); + lastChange.changes.push(text); + } + // Change objects may be chained with next. + changeObj = changeObj.next; + } + } + } + + /** + * Listens for any kind of cursor activity on CodeMirror. + */ + function onCursorActivity(cm) { + var vim = cm.state.vim; + if (vim.insertMode) { + // Tracking cursor activity in insert mode (for macro support). + var macroModeState = vimGlobalState.macroModeState; + if (macroModeState.isPlaying) { return; } + var lastChange = macroModeState.lastInsertModeChanges; + if (lastChange.expectCursorActivityForChange) { + lastChange.expectCursorActivityForChange = false; + } else { + // Cursor moved outside the context of an edit. Reset the change. + lastChange.changes = []; + } + } else if (!cm.curOp.isVimOp) { + handleExternalSelection(cm, vim); + } + if (vim.visualMode) { + updateFakeCursor(cm); + } + } + function updateFakeCursor(cm) { + var vim = cm.state.vim; + var from = clipCursorToContent(cm, copyCursor(vim.sel.head)); + var to = offsetCursor(from, 0, 1); + if (vim.fakeCursor) { + vim.fakeCursor.clear(); + } + vim.fakeCursor = cm.markText(from, to, {className: 'cm-animate-fat-cursor'}); + } + function handleExternalSelection(cm, vim) { + var anchor = cm.getCursor('anchor'); + var head = cm.getCursor('head'); + // Enter or exit visual mode to match mouse selection. + if (vim.visualMode && !cm.somethingSelected()) { + exitVisualMode(cm, false); + } else if (!vim.visualMode && !vim.insertMode && cm.somethingSelected()) { + vim.visualMode = true; + vim.visualLine = false; + CodeMirror.signal(cm, "vim-mode-change", {mode: "visual"}); + } + if (vim.visualMode) { + // Bind CodeMirror selection model to vim selection model. + // Mouse selections are considered visual characterwise. + var headOffset = !cursorIsBefore(head, anchor) ? -1 : 0; + var anchorOffset = cursorIsBefore(head, anchor) ? -1 : 0; + head = offsetCursor(head, 0, headOffset); + anchor = offsetCursor(anchor, 0, anchorOffset); + vim.sel = { + anchor: anchor, + head: head + }; + updateMark(cm, vim, '<', cursorMin(head, anchor)); + updateMark(cm, vim, '>', cursorMax(head, anchor)); + } else if (!vim.insertMode) { + // Reset lastHPos if selection was modified by something outside of vim mode e.g. by mouse. + vim.lastHPos = cm.getCursor().ch; + } + } + + /** Wrapper for special keys pressed in insert mode */ + function InsertModeKey(keyName) { + this.keyName = keyName; + } + + /** + * Handles raw key down events from the text area. + * - Should only be active in insert mode. + * - For recording deletes in insert mode. + */ + function onKeyEventTargetKeyDown(e) { + var macroModeState = vimGlobalState.macroModeState; + var lastChange = macroModeState.lastInsertModeChanges; + var keyName = CodeMirror.keyName(e); + if (!keyName) { return; } + function onKeyFound() { + lastChange.changes.push(new InsertModeKey(keyName)); + return true; + } + if (keyName.indexOf('Delete') != -1 || keyName.indexOf('Backspace') != -1) { + CodeMirror.lookupKey(keyName, 'vim-insert', onKeyFound); + } + } + + /** + * Repeats the last edit, which includes exactly 1 command and at most 1 + * insert. Operator and motion commands are read from lastEditInputState, + * while action commands are read from lastEditActionCommand. + * + * If repeatForInsert is true, then the function was called by + * exitInsertMode to repeat the insert mode changes the user just made. The + * corresponding enterInsertMode call was made with a count. + */ + function repeatLastEdit(cm, vim, repeat, repeatForInsert) { + var macroModeState = vimGlobalState.macroModeState; + macroModeState.isPlaying = true; + var isAction = !!vim.lastEditActionCommand; + var cachedInputState = vim.inputState; + function repeatCommand() { + if (isAction) { + commandDispatcher.processAction(cm, vim, vim.lastEditActionCommand); + } else { + commandDispatcher.evalInput(cm, vim); + } + } + function repeatInsert(repeat) { + if (macroModeState.lastInsertModeChanges.changes.length > 0) { + // For some reason, repeat cw in desktop VIM does not repeat + // insert mode changes. Will conform to that behavior. + repeat = !vim.lastEditActionCommand ? 1 : repeat; + var changeObject = macroModeState.lastInsertModeChanges; + repeatInsertModeChanges(cm, changeObject.changes, repeat); + } + } + vim.inputState = vim.lastEditInputState; + if (isAction && vim.lastEditActionCommand.interlaceInsertRepeat) { + // o and O repeat have to be interlaced with insert repeats so that the + // insertions appear on separate lines instead of the last line. + for (var i = 0; i < repeat; i++) { + repeatCommand(); + repeatInsert(1); + } + } else { + if (!repeatForInsert) { + // Hack to get the cursor to end up at the right place. If I is + // repeated in insert mode repeat, cursor will be 1 insert + // change set left of where it should be. + repeatCommand(); + } + repeatInsert(repeat); + } + vim.inputState = cachedInputState; + if (vim.insertMode && !repeatForInsert) { + // Don't exit insert mode twice. If repeatForInsert is set, then we + // were called by an exitInsertMode call lower on the stack. + exitInsertMode(cm); + } + macroModeState.isPlaying = false; + }; + + function repeatInsertModeChanges(cm, changes, repeat) { + function keyHandler(binding) { + if (typeof binding == 'string') { + CodeMirror.commands[binding](cm); + } else { + binding(cm); + } + return true; + } + var head = cm.getCursor('head'); + var inVisualBlock = vimGlobalState.macroModeState.lastInsertModeChanges.inVisualBlock; + if (inVisualBlock) { + // Set up block selection again for repeating the changes. + var vim = cm.state.vim; + var lastSel = vim.lastSelection; + var offset = getOffset(lastSel.anchor, lastSel.head); + selectForInsert(cm, head, offset.line + 1); + repeat = cm.listSelections().length; + cm.setCursor(head); + } + for (var i = 0; i < repeat; i++) { + if (inVisualBlock) { + cm.setCursor(offsetCursor(head, i, 0)); + } + for (var j = 0; j < changes.length; j++) { + var change = changes[j]; + if (change instanceof InsertModeKey) { + CodeMirror.lookupKey(change.keyName, 'vim-insert', keyHandler); + } else { + var cur = cm.getCursor(); + cm.replaceRange(change, cur, cur); + } + } + } + if (inVisualBlock) { + cm.setCursor(offsetCursor(head, 0, 1)); + } + } + + resetVimGlobalState(); + //}; + // Initialize Vim and make it available as an API. + CodeMirror.Vim = Vim(); + + Vim = CodeMirror.Vim; + + var specialKey = {'return':'CR',backspace:'BS','delete':'Del',esc:'Esc', + left:'Left',right:'Right',up:'Up',down:'Down',space: 'Space', + home:'Home',end:'End',pageup:'PageUp',pagedown:'PageDown', enter: 'CR' + }; + function lookupKey(hashId, key, e) { + if (key.length > 1 && key[0] == "n") { + key = key.replace("numpad", ""); + } + key = specialKey[key] || key; + var name = ''; + if (e.ctrlKey) { name += 'C-'; } + if (e.altKey) { name += 'A-'; } + if (e.shiftKey) { name += 'S-'; } + + name += key; + if (name.length > 1) { name = '<' + name + '>'; } + return name; + } + var handleKey = Vim.handleKey.bind(Vim); + Vim.handleKey = function(cm, key, origin) { + return cm.operation(function() { + return handleKey(cm, key, origin); + }, true); + } + function cloneVimState(state) { + var n = new state.constructor(); + Object.keys(state).forEach(function(key) { + var o = state[key]; + if (Array.isArray(o)) + o = o.slice(); + else if (o && typeof o == "object" && o.constructor != Object) + o = cloneVimState(o); + n[key] = o; + }); + if (state.sel) { + n.sel = { + head: state.sel.head && copyCursor(state.sel.head), + anchor: state.sel.anchor && copyCursor(state.sel.anchor) + }; + } + return n; + } + function multiSelectHandleKey(cm, key, origin) { + var isHandled = false; + var vim = Vim.maybeInitVimState_(cm); + var visualBlock = vim.visualBlock || vim.wasInVisualBlock; + if (vim.wasInVisualBlock && !cm.ace.inMultiSelectMode) { + vim.wasInVisualBlock = false; + } else if (cm.ace.inMultiSelectMode && vim.visualBlock) { + vim.wasInVisualBlock = true; + } + + if (key == '' && !vim.insertMode && !vim.visualMode && cm.ace.inMultiSelectMode) { + cm.ace.exitMultiSelectMode(); + } else if (visualBlock || !cm.ace.inMultiSelectMode || cm.ace.inVirtualSelectionMode) { + isHandled = Vim.handleKey(cm, key, origin); + } else { + var old = cloneVimState(vim); + cm.operation(function() { + cm.ace.forEachSelection(function() { + var sel = cm.ace.selection; + cm.state.vim.lastHPos = sel.$desiredColumn == null ? sel.lead.column : sel.$desiredColumn; + var head = cm.getCursor("head"); + var anchor = cm.getCursor("anchor"); + var headOffset = !cursorIsBefore(head, anchor) ? -1 : 0; + var anchorOffset = cursorIsBefore(head, anchor) ? -1 : 0; + head = offsetCursor(head, 0, headOffset); + anchor = offsetCursor(anchor, 0, anchorOffset); + cm.state.vim.sel.head = head; + cm.state.vim.sel.anchor = anchor; + + isHandled = handleKey(cm, key, origin); + sel.$desiredColumn = cm.state.vim.lastHPos == -1 ? null : cm.state.vim.lastHPos; + if (cm.virtualSelectionMode()) { + cm.state.vim = cloneVimState(old); + } + }); + if (cm.curOp.cursorActivity && !isHandled) + cm.curOp.cursorActivity = false; + }, true); + } + return isHandled; + } + exports.CodeMirror = CodeMirror; + var getVim = Vim.maybeInitVimState_; + exports.handler = { + $id: "ace/keyboard/vim", + drawCursor: function(style, pixelPos, config, sel, session) { + var vim = this.state.vim || {}; + var w = config.characterWidth; + var h = config.lineHeight; + var top = pixelPos.top; + var left = pixelPos.left; + if (!vim.insertMode) { + var isbackwards = !sel.cursor + ? session.selection.isBackwards() || session.selection.isEmpty() + : Range.comparePoints(sel.cursor, sel.start) <= 0; + if (!isbackwards && left > w) + left -= w; + } + if (!vim.insertMode && vim.status) { + h = h / 2; + top += h; + } + style.left = left + "px"; + style.top = top + "px"; + style.width = w + "px"; + style.height = h + "px"; + }, + handleKeyboard: function(data, hashId, key, keyCode, e) { + var editor = data.editor; + var cm = editor.state.cm; + var vim = getVim(cm); + if (keyCode == -1) return; + + if (key == "c" && hashId == 1) { // key == "ctrl-c" + if (!useragent.isMac && editor.getCopyText()) { + editor.once("copy", function() { + editor.selection.clearSelection(); + }); + return {command: "null", passEvent: true}; + } + } else if (!vim.insertMode) { + if (useragent.isMac && this.handleMacRepeat(data, hashId, key)) { + hashId = -1; + key = data.inputChar; + } + } + + if (hashId == -1 || hashId & 1 || hashId === 0 && key.length > 1) { + var insertMode = vim.insertMode; + var name = lookupKey(hashId, key, e || {}); + if (vim.status == null) + vim.status = ""; + var isHandled = multiSelectHandleKey(cm, name, 'user'); + vim = getVim(cm); // may be changed by multiSelectHandleKey + if (isHandled && vim.status != null) + vim.status += name; + else if (vim.status == null) + vim.status = ""; + cm._signal("changeStatus"); + if (!isHandled && (hashId != -1 || insertMode)) + return; + return {command: "null", passEvent: !isHandled}; + } + }, + attach: function(editor) { + if (!editor.state) editor.state = {}; + var cm = new CodeMirror(editor); + editor.state.cm = cm; + editor.$vimModeHandler = this; + CodeMirror.keyMap.vim.attach(cm); + getVim(cm).status = null; + cm.on('vim-command-done', function() { + if (cm.virtualSelectionMode()) return; + getVim(cm).status = null; + cm.ace._signal("changeStatus"); + cm.ace.session.markUndoGroup(); + }); + cm.on("changeStatus", function() { + cm.ace.renderer.updateCursor(); + cm.ace._signal("changeStatus"); + }); + cm.on("vim-mode-change", function() { + if (cm.virtualSelectionMode()) return; + cm.ace.renderer.setStyle("normal-mode", !getVim(cm).insertMode); + cm._signal("changeStatus"); + }); + cm.ace.renderer.setStyle("normal-mode", !getVim(cm).insertMode); + editor.renderer.$cursorLayer.drawCursor = this.drawCursor.bind(cm); + // renderVirtualNumbers.attach(editor); + this.updateMacCompositionHandlers(editor, true); + }, + detach: function(editor) { + var cm = editor.state.cm; + CodeMirror.keyMap.vim.detach(cm); + cm.destroy(); + editor.state.cm = null; + editor.$vimModeHandler = null; + editor.renderer.$cursorLayer.drawCursor = null; + editor.renderer.setStyle("normal-mode", false); + // renderVirtualNumbers.detach(editor); + this.updateMacCompositionHandlers(editor, false); + }, + getStatusText: function(editor) { + var cm = editor.state.cm; + var vim = getVim(cm); + if (vim.insertMode) + return "INSERT"; + var status = ""; + if (vim.visualMode) { + status += "VISUAL"; + if (vim.visualLine) + status += " LINE"; + if (vim.visualBlock) + status += " BLOCK"; + } + if (vim.status) + status += (status ? " " : "") + vim.status; + return status; + }, + // workaround for j not repeating with `defaults write -g ApplePressAndHoldEnabled -bool true` + handleMacRepeat: function(data, hashId, key) { + if (hashId == -1) { + // record key + data.inputChar = key; + data.lastEvent = "input"; + } else if (data.inputChar && data.$lastHash == hashId && data.$lastKey == key) { + // check for repeated keypress + if (data.lastEvent == "input") { + data.lastEvent = "input1"; + } else if (data.lastEvent == "input1") { + // simulate textinput + return true; + } + } else { + // reset + data.$lastHash = hashId; + data.$lastKey = key; + data.lastEvent = "keypress"; + } + }, + // on mac, with some keyboard layouts (e.g swedish) ^ starts composition, we don't need it in normal mode + updateMacCompositionHandlers: function(editor, enable) { + var onCompositionUpdateOverride = function(text) { + var cm = editor.state.cm; + var vim = getVim(cm); + if (!vim.insertMode) { + var el = this.textInput.getElement(); + el.blur(); + el.focus(); + el.value = text; + } else { + this.onCompositionUpdateOrig(text); + } + }; + var onCompositionStartOverride = function(text) { + var cm = editor.state.cm; + var vim = getVim(cm); + if (!vim.insertMode) { + this.onCompositionStartOrig(text); + } + }; + if (enable) { + if (!editor.onCompositionUpdateOrig) { + editor.onCompositionUpdateOrig = editor.onCompositionUpdate; + editor.onCompositionUpdate = onCompositionUpdateOverride; + editor.onCompositionStartOrig = editor.onCompositionStart; + editor.onCompositionStart = onCompositionStartOverride; + } + } else { + if (editor.onCompositionUpdateOrig) { + editor.onCompositionUpdate = editor.onCompositionUpdateOrig; + editor.onCompositionUpdateOrig = null; + editor.onCompositionStart = editor.onCompositionStartOrig; + editor.onCompositionStartOrig = null; + } + } + } + }; + var renderVirtualNumbers = { + getText: function(session, row) { + return (Math.abs(session.selection.lead.row - row) || (row + 1 + (row < 9? "\xb7" : "" ))) + ""; + }, + getWidth: function(session, lastLineNumber, config) { + return session.getLength().toString().length * config.characterWidth; + }, + update: function(e, editor) { + editor.renderer.$loop.schedule(editor.renderer.CHANGE_GUTTER); + }, + attach: function(editor) { + editor.renderer.$gutterLayer.$renderer = this; + editor.on("changeSelection", this.update); + }, + detach: function(editor) { + editor.renderer.$gutterLayer.$renderer = null; + editor.off("changeSelection", this.update); + } + }; + Vim.defineOption({ + name: "wrap", + set: function(value, cm) { + if (cm) {cm.ace.setOption("wrap", value)} + }, + type: "boolean" + }, false); + Vim.defineEx('write', 'w', function() { + console.log(':write is not implemented') + }); + defaultKeymap.push( + { keys: 'zc', type: 'action', action: 'fold', actionArgs: { open: false } }, + { keys: 'zC', type: 'action', action: 'fold', actionArgs: { open: false, all: true } }, + { keys: 'zo', type: 'action', action: 'fold', actionArgs: { open: true, } }, + { keys: 'zO', type: 'action', action: 'fold', actionArgs: { open: true, all: true } }, + { keys: 'za', type: 'action', action: 'fold', actionArgs: { toggle: true } }, + { keys: 'zA', type: 'action', action: 'fold', actionArgs: { toggle: true, all: true } }, + { keys: 'zf', type: 'action', action: 'fold', actionArgs: { open: true, all: true } }, + { keys: 'zd', type: 'action', action: 'fold', actionArgs: { open: true, all: true } }, + + { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorAbove" } }, + { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorBelow" } }, + { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorAboveSkipCurrent" } }, + { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorBelowSkipCurrent" } }, + { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "selectMoreBefore" } }, + { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "selectMoreAfter" } }, + { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "selectNextBefore" } }, + { keys: '', type: 'action', action: 'aceCommand', actionArgs: { name: "selectNextAfter" } } + ); + actions.aceCommand = function(cm, actionArgs, vim) { + cm.vimCmd = actionArgs; + if (cm.ace.inVirtualSelectionMode) + cm.ace.on("beforeEndOperation", delayedExecAceCommand); + else + delayedExecAceCommand(null, cm.ace); + }; + function delayedExecAceCommand(op, ace) { + ace.off("beforeEndOperation", delayedExecAceCommand); + var cmd = ace.state.cm.vimCmd; + if (cmd) { + ace.execCommand(cmd.exec ? cmd : cmd.name, cmd.args); + } + ace.curOp = ace.prevOp; + } + actions.fold = function(cm, actionArgs, vim) { + cm.ace.execCommand(['toggleFoldWidget', 'toggleFoldWidget', 'foldOther', 'unfoldall' + ][(actionArgs.all ? 2 : 0) + (actionArgs.open ? 1 : 0)]); + }, + + exports.handler.defaultKeymap = defaultKeymap; + exports.handler.actions = actions; + exports.Vim = Vim; + + Vim.map("Y", "yy", "normal"); +}); diff --git a/lib/ace/keyboard/vim_test.js b/lib/ace/keyboard/vim_test.js new file mode 100644 index 00000000..127f0706 --- /dev/null +++ b/lib/ace/keyboard/vim_test.js @@ -0,0 +1,4041 @@ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { + +var EditSession = require("./../edit_session").EditSession; +var Editor = require("./../editor").Editor; +var UndoManager = require("./../undomanager").UndoManager; +var MockRenderer = require("./../test/mockrenderer").MockRenderer; +var JavaScriptMode = require("./../mode/javascript").Mode; +var VirtualRenderer = require("./../virtual_renderer").VirtualRenderer; +var assert = require("./../test/assertions"); +var keys = require("./../lib/keys"); +var vim = require("./vim"); + +var el = document.createElement("div"); +el.style.position = "fixed"; +el.style.left = "20px"; +el.style.top = "30px"; +el.style.width = "500px"; +el.style.height = "300px"; +document.body.appendChild(el); + +if (!el.getBoundingClientRect) + return console.log("Skipping test: This test only runs in the browser"); + +var renderer = new VirtualRenderer(el); +editor = new Editor(renderer);//(new MockRenderer()); +editor.session.setUndoManager(new UndoManager()); +editor.session.setUseWorker(false); +editor.session.setMode(new JavaScriptMode()); +function CodeMirror(place, opts) { + if (opts.value != null) + editor.session.setValue(opts.value); + editor.setOption("indentedSoftWrap", false); + editor.setOption("wrap", opts.lineWrapping); + editor.setOption("useSoftTabs", !opts.indentWithTabs); + editor.setKeyboardHandler(null); + editor.setKeyboardHandler(vim.handler); + var cm = editor.state.cm; + cm.setOption("tabSize", opts.tabSize || 4); + cm.setOption("indentUnit", opts.indentUnit || 2); + + cm.setSize = function(w, h) { + var changed = false; + if (w && editor.w != w) { + changed = true; + el.style.width = (editor.w = w) + "px"; + } + if (h && editor.h != h) { + changed = true; + el.style.height = (editor.h = h) + "px"; + } + if (changed) + editor.resize(true); + }; + cm.setSize(500, 300); + return cm; +} +CodeMirror.defineMode = function() {} +for (var key in vim.CodeMirror) + CodeMirror[key] = vim.CodeMirror[key]; +var editor; +var i = 0; +function test(name, fn) { + // if (name != 'vim_search_history') return + // for (i = 0; i < 1000; i++) + // exports["test " + name + i] = fn; // vim_ex_global_confirm + if (i++ < 0 || /- /.test(name)) + exports["test " + name] = function() {}; + else + exports["test " + name] = fn; +} + +vim.CodeMirror.Vim.unmap("Y"); +vim.CodeMirror.Vim.defineEx('write', 'w', function(cm) { + CodeMirror.commands.save(cm); +}); + + + +// cm.setBookmark({ch: 5, line: 0}) +// cm.setBookmark({ch: 4, line: 0}) +// cm.replaceRange("x-", {ch: 4, line: 0}, {ch: 5, line: 0}); [editor.$vimModeHandler.cm.marks[0].find(),editor.$vimModeHandler.cm.marks[1].find()] + +var lineText, verbose, phantom; +var Pos = CodeMirror.Pos; +var place = document.createElement("div"); +var eqPos = assert.deepEqual; +var eq = assert.equal; +var is = assert.ok; + + +var code = '' + +' wOrd1 (#%\n' + +' word3] \n' + +'aopop pop 0 1 2 3 4\n' + +' (a) [b] {c} \n' + +'int getchar(void) {\n' + +' static char buf[BUFSIZ];\n' + +' static char *bufp = buf;\n' + +' if (n == 0) { /* buffer is empty */\n' + +' n = read(0, buf, sizeof buf);\n' + +' bufp = buf;\n' + +' }\n' + +'\n' + +' return (--n >= 0) ? (unsigned char) *bufp++ : EOF;\n' + +' \n' + +'}\n'; + +var lines = (function() { + lineText = code.split('\n'); + var ret = []; + for (var i = 0; i < lineText.length; i++) { + ret[i] = { + line: i, + length: lineText[i].length, + lineText: lineText[i], + textStart: /^\s*/.exec(lineText[i])[0].length + }; + } + return ret; +})(); +var endOfDocument = makeCursor(lines.length - 1, + lines[lines.length - 1].length); +var wordLine = lines[0]; +var bigWordLine = lines[1]; +var charLine = lines[2]; +var bracesLine = lines[3]; +var seekBraceLine = lines[4]; + +var word1 = { + start: { line: wordLine.line, ch: 1 }, + end: { line: wordLine.line, ch: 5 } +}; +var word2 = { + start: { line: wordLine.line, ch: word1.end.ch + 2 }, + end: { line: wordLine.line, ch: word1.end.ch + 4 } +}; +var word3 = { + start: { line: bigWordLine.line, ch: 1 }, + end: { line: bigWordLine.line, ch: 5 } +}; +var bigWord1 = word1; +var bigWord2 = word2; +var bigWord3 = { + start: { line: bigWordLine.line, ch: 1 }, + end: { line: bigWordLine.line, ch: 7 } +}; +var bigWord4 = { + start: { line: bigWordLine.line, ch: bigWord1.end.ch + 3 }, + end: { line: bigWordLine.line, ch: bigWord1.end.ch + 7 } +}; + +var oChars = [ { line: charLine.line, ch: 1 }, + { line: charLine.line, ch: 3 }, + { line: charLine.line, ch: 7 } ]; +var pChars = [ { line: charLine.line, ch: 2 }, + { line: charLine.line, ch: 4 }, + { line: charLine.line, ch: 6 }, + { line: charLine.line, ch: 8 } ]; +var numChars = [ { line: charLine.line, ch: 10 }, + { line: charLine.line, ch: 12 }, + { line: charLine.line, ch: 14 }, + { line: charLine.line, ch: 16 }, + { line: charLine.line, ch: 18 }]; +var parens1 = { + start: { line: bracesLine.line, ch: 1 }, + end: { line: bracesLine.line, ch: 3 } +}; +var squares1 = { + start: { line: bracesLine.line, ch: 5 }, + end: { line: bracesLine.line, ch: 7 } +}; +var curlys1 = { + start: { line: bracesLine.line, ch: 9 }, + end: { line: bracesLine.line, ch: 11 } +}; +var seekOutside = { + start: { line: seekBraceLine.line, ch: 1 }, + end: { line: seekBraceLine.line, ch: 16 } +}; +var seekInside = { + start: { line: seekBraceLine.line, ch: 14 }, + end: { line: seekBraceLine.line, ch: 11 } +}; + +function copyCursor(cur) { + return { ch: cur.ch, line: cur.line }; +} + +function forEach(arr, func) { + for (var i = 0; i < arr.length; i++) { + func(arr[i], i, arr); + } +} + +function testVim(name, run, opts, expectedFail) { + var vimOpts = { + lineNumbers: true, + vimMode: true, + showCursorWhenSelecting: true, + value: code + }; + for (var prop in opts) { + if (opts.hasOwnProperty(prop)) { + vimOpts[prop] = opts[prop]; + } + } + return test('vim_' + name, function() { + var place = document.getElementById("testground"); + var cm = CodeMirror(place, vimOpts); + var vim = CodeMirror.Vim.maybeInitVimState_(cm); + + function doKeysFn(cm) { + return function(args) { + if (args instanceof Array) { + arguments = args; + } + for (var i = 0; i < arguments.length; i++) { + CodeMirror.Vim.handleKey(cm, arguments[i]); + } + } + } + function doInsertModeKeysFn(cm) { + return function(args) { + if (args instanceof Array) { arguments = args; } + function executeHandler(handler) { + if (typeof handler == 'string') { + CodeMirror.commands[handler](cm); + } else { + handler(cm); + } + return true; + } + for (var i = 0; i < arguments.length; i++) { + var key = arguments[i]; + // Find key in keymap and handle. + var handled = CodeMirror.lookupKey(key, 'vim-insert', executeHandler); + // Record for insert mode. + if (handled == "handled" && cm.state.vim.insertMode && arguments[i] != 'Esc') { + var lastChange = CodeMirror.Vim.getVimGlobalState_().macroModeState.lastInsertModeChanges; + if (lastChange) { + lastChange.changes.push(new CodeMirror.Vim.InsertModeKey(key)); + } + } + } + } + } + function doExFn(cm) { + return function(command) { + cm.openDialog = helpers.fakeOpenDialog(command); + helpers.doKeys(':'); + } + } + function assertCursorAtFn(cm) { + return function(line, ch) { + var pos; + if (ch == null && typeof line.line == 'number') { + pos = line; + } else { + pos = makeCursor(line, ch); + } + eqPos(pos, cm.getCursor()); + } + } + function fakeOpenDialog(result) { + return function(text, callback) { + return callback(result); + } + } + function fakeOpenNotification(matcher) { + return function(text) { + matcher(text); + } + } + var helpers = { + doKeys: doKeysFn(cm), + // Warning: Only emulates keymap events, not character insertions. Use + // replaceRange to simulate character insertions. + // Keys are in CodeMirror format, NOT vim format. + doInsertModeKeys: doInsertModeKeysFn(cm), + doEx: doExFn(cm), + assertCursorAt: assertCursorAtFn(cm), + fakeOpenDialog: fakeOpenDialog, + fakeOpenNotification: fakeOpenNotification, + getRegisterController: function() { + return CodeMirror.Vim.getRegisterController(); + } + } + CodeMirror.Vim.resetVimGlobalState_(); + var successful = false; + var savedOpenNotification = cm.openNotification; + try { + run(cm, vim, helpers); + successful = true; + } finally { + cm.openNotification = savedOpenNotification; + // if (!successful || verbose) { + // place.style.visibility = "visible"; + // } else { + // place.removeChild(cm.getWrapperElement()); + // } + } + }, expectedFail); +}; +testVim('qq@q', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'q', 'l', 'l', 'q'); + helpers.assertCursorAt(0,2); + helpers.doKeys('@', 'q'); + helpers.assertCursorAt(0,4); +}, { value: ' '}); +testVim('@@', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'q', 'l', 'l', 'q'); + helpers.assertCursorAt(0,2); + helpers.doKeys('@', 'q'); + helpers.assertCursorAt(0,4); + helpers.doKeys('@', '@'); + helpers.assertCursorAt(0,6); +}, { value: ' '}); +var jumplistScene = ''+ + 'word\n'+ + '(word)\n'+ + '{word\n'+ + 'word.\n'+ + '\n'+ + 'word search\n'+ + '}word\n'+ + 'word\n'+ + 'word\n'; +function testJumplist(name, keys, endPos, startPos, dialog) { + endPos = makeCursor(endPos[0], endPos[1]); + startPos = makeCursor(startPos[0], startPos[1]); + testVim(name, function(cm, vim, helpers) { + CodeMirror.Vim.resetVimGlobalState_(); + if(dialog)cm.openDialog = helpers.fakeOpenDialog('word'); + cm.setCursor(startPos); + helpers.doKeys.apply(null, keys); + helpers.assertCursorAt(endPos); + }, {value: jumplistScene}); +}; +testJumplist('jumplist_H', ['H', ''], [5,2], [5,2]); +testJumplist('jumplist_M', ['M', ''], [2,2], [2,2]); +testJumplist('jumplist_L', ['L', ''], [2,2], [2,2]); +testJumplist('jumplist_[[', ['[', '[', ''], [5,2], [5,2]); +testJumplist('jumplist_]]', [']', ']', ''], [2,2], [2,2]); +testJumplist('jumplist_G', ['G', ''], [5,2], [5,2]); +testJumplist('jumplist_gg', ['g', 'g', ''], [5,2], [5,2]); +testJumplist('jumplist_%', ['%', ''], [1,5], [1,5]); +testJumplist('jumplist_{', ['{', ''], [1,5], [1,5]); +testJumplist('jumplist_}', ['}', ''], [1,5], [1,5]); +testJumplist('jumplist_\'', ['m', 'a', 'h', '\'', 'a', 'h', ''], [1,0], [1,5]); +testJumplist('jumplist_`', ['m', 'a', 'h', '`', 'a', 'h', ''], [1,5], [1,5]); +testJumplist('jumplist_*_cachedCursor', ['*', ''], [1,3], [1,3]); +testJumplist('jumplist_#_cachedCursor', ['#', ''], [1,3], [1,3]); +testJumplist('jumplist_n', ['#', 'n', ''], [1,1], [2,3]); +testJumplist('jumplist_N', ['#', 'N', ''], [1,1], [2,3]); +testJumplist('jumplist_repeat_', ['*', '*', '*', '3', ''], [2,3], [2,3]); +testJumplist('jumplist_repeat_', ['*', '*', '*', '3', '', '2', ''], [5,0], [2,3]); +testJumplist('jumplist_repeated_motion', ['3', '*', ''], [2,3], [2,3]); +testJumplist('jumplist_/', ['/', ''], [2,3], [2,3], 'dialog'); +testJumplist('jumplist_?', ['?', ''], [2,3], [2,3], 'dialog'); +testJumplist('jumplist_skip_delted_mark', + ['*', 'n', 'n', 'k', 'd', 'k', '', '', ''], + [0,2], [0,2]); +testJumplist('jumplist_skip_delted_mark', + ['*', 'n', 'n', 'k', 'd', 'k', '', '', ''], + [1,0], [0,2]); + +/** + * @param name Name of the test + * @param keys An array of keys or a string with a single key to simulate. + * @param endPos The expected end position of the cursor. + * @param startPos The position the cursor should start at, defaults to 0, 0. + */ +function testMotion(name, keys, endPos, startPos) { + testVim(name, function(cm, vim, helpers) { + if (!startPos) { + startPos = { line: 0, ch: 0 }; + } + cm.setCursor(startPos); + helpers.doKeys(keys); + helpers.assertCursorAt(endPos); + }); +}; + +function makeCursor(line, ch) { + return { line: line, ch: ch }; +}; + +function offsetCursor(cur, offsetLine, offsetCh) { + return { line: cur.line + offsetLine, ch: cur.ch + offsetCh }; +}; + +// Motion tests +testMotion('|', '|', makeCursor(0, 0), makeCursor(0,4)); +testMotion('|_repeat', ['3', '|'], makeCursor(0, 2), makeCursor(0,4)); +testMotion('h', 'h', makeCursor(0, 0), word1.start); +testMotion('h_repeat', ['3', 'h'], offsetCursor(word1.end, 0, -3), word1.end); +testMotion('l', 'l', makeCursor(0, 1)); +testMotion('l_repeat', ['2', 'l'], makeCursor(0, 2)); +testMotion('j', 'j', offsetCursor(word1.end, 1, 0), word1.end); +testMotion('j_repeat', ['2', 'j'], offsetCursor(word1.end, 2, 0), word1.end); +testMotion('j_repeat_clip', ['1000', 'j'], endOfDocument); +testMotion('k', 'k', offsetCursor(word3.end, -1, 0), word3.end); +testMotion('k_repeat', ['2', 'k'], makeCursor(0, 4), makeCursor(2, 4)); +testMotion('k_repeat_clip', ['1000', 'k'], makeCursor(0, 4), makeCursor(2, 4)); +testMotion('w', 'w', word1.start); +testMotion('w_multiple_newlines_no_space', 'w', makeCursor(12, 2), makeCursor(11, 2)); +testMotion('w_multiple_newlines_with_space', 'w', makeCursor(14, 0), makeCursor(12, 51)); +testMotion('w_repeat', ['2', 'w'], word2.start); +testMotion('w_wrap', ['w'], word3.start, word2.start); +testMotion('w_endOfDocument', 'w', endOfDocument, endOfDocument); +testMotion('w_start_to_end', ['1000', 'w'], endOfDocument, makeCursor(0, 0)); +testMotion('W', 'W', bigWord1.start); +testMotion('W_repeat', ['2', 'W'], bigWord3.start, bigWord1.start); +testMotion('e', 'e', word1.end); +testMotion('e_repeat', ['2', 'e'], word2.end); +testMotion('e_wrap', 'e', word3.end, word2.end); +testMotion('e_endOfDocument', 'e', endOfDocument, endOfDocument); +testMotion('e_start_to_end', ['1000', 'e'], endOfDocument, makeCursor(0, 0)); +testMotion('b', 'b', word3.start, word3.end); +testMotion('b_repeat', ['2', 'b'], word2.start, word3.end); +testMotion('b_wrap', 'b', word2.start, word3.start); +testMotion('b_startOfDocument', 'b', makeCursor(0, 0), makeCursor(0, 0)); +testMotion('b_end_to_start', ['1000', 'b'], makeCursor(0, 0), endOfDocument); +testMotion('ge', ['g', 'e'], word2.end, word3.end); +testMotion('ge_repeat', ['2', 'g', 'e'], word1.end, word3.start); +testMotion('ge_wrap', ['g', 'e'], word2.end, word3.start); +testMotion('ge_startOfDocument', ['g', 'e'], makeCursor(0, 0), + makeCursor(0, 0)); +testMotion('ge_end_to_start', ['1000', 'g', 'e'], makeCursor(0, 0), endOfDocument); +testMotion('gg', ['g', 'g'], makeCursor(lines[0].line, lines[0].textStart), + makeCursor(3, 1)); +testMotion('gg_repeat', ['3', 'g', 'g'], + makeCursor(lines[2].line, lines[2].textStart)); +testMotion('G', 'G', + makeCursor(lines[lines.length - 1].line, lines[lines.length - 1].textStart), + makeCursor(3, 1)); +testMotion('G_repeat', ['3', 'G'], makeCursor(lines[2].line, + lines[2].textStart)); +// TODO: Make the test code long enough to test Ctrl-F and Ctrl-B. +testMotion('0', '0', makeCursor(0, 0), makeCursor(0, 8)); +testMotion('^', '^', makeCursor(0, lines[0].textStart), makeCursor(0, 8)); +testMotion('+', '+', makeCursor(1, lines[1].textStart), makeCursor(0, 8)); +testMotion('-', '-', makeCursor(0, lines[0].textStart), makeCursor(1, 4)); +testMotion('_', ['6','_'], makeCursor(5, lines[5].textStart), makeCursor(0, 8)); +testMotion('$', '$', makeCursor(0, lines[0].length - 1), makeCursor(0, 1)); +testMotion('$_repeat', ['2', '$'], makeCursor(1, lines[1].length - 1), + makeCursor(0, 3)); +testMotion('f', ['f', 'p'], pChars[0], makeCursor(charLine.line, 0)); +testMotion('f_repeat', ['2', 'f', 'p'], pChars[2], pChars[0]); +testMotion('f_num', ['f', '2'], numChars[2], makeCursor(charLine.line, 0)); +testMotion('t', ['t','p'], offsetCursor(pChars[0], 0, -1), + makeCursor(charLine.line, 0)); +testMotion('t_repeat', ['2', 't', 'p'], offsetCursor(pChars[2], 0, -1), + pChars[0]); +testMotion('F', ['F', 'p'], pChars[0], pChars[1]); +testMotion('F_repeat', ['2', 'F', 'p'], pChars[0], pChars[2]); +testMotion('T', ['T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[1]); +testMotion('T_repeat', ['2', 'T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[2]); +testMotion('%_parens', ['%'], parens1.end, parens1.start); +testMotion('%_squares', ['%'], squares1.end, squares1.start); +testMotion('%_braces', ['%'], curlys1.end, curlys1.start); +testMotion('%_seek_outside', ['%'], seekOutside.end, seekOutside.start); +testMotion('%_seek_inside', ['%'], seekInside.end, seekInside.start); +testVim('%_seek_skip', function(cm, vim, helpers) { + cm.setCursor(0,0); + helpers.doKeys(['%']); + helpers.assertCursorAt(0,9); +}, {value:'01234"("()'}); +testVim('%_skip_string', function(cm, vim, helpers) { + cm.setCursor(0,0); + helpers.doKeys(['%']); + helpers.assertCursorAt(0,4); + cm.setCursor(0,2); + helpers.doKeys(['%']); + helpers.assertCursorAt(0,0); +}, {value:'(")")'}); +(')') +testVim('%_skip_comment', function(cm, vim, helpers) { + cm.setCursor(0,0); + helpers.doKeys(['%']); + helpers.assertCursorAt(0,6); + cm.setCursor(0,3); + helpers.doKeys(['%']); + helpers.assertCursorAt(0,0); +}, {value:'(/*)*/)'}); +// Make sure that moving down after going to the end of a line always leaves you +// at the end of a line, but preserves the offset in other cases +testVim('Changing lines after Eol operation', function(cm, vim, helpers) { + cm.setCursor(0,0); + helpers.doKeys(['$']); + helpers.doKeys(['j']); + // After moving to Eol and then down, we should be at Eol of line 2 + helpers.assertCursorAt({ line: 1, ch: lines[1].length - 1 }); + helpers.doKeys(['j']); + // After moving down, we should be at Eol of line 3 + helpers.assertCursorAt({ line: 2, ch: lines[2].length - 1 }); + helpers.doKeys(['h']); + helpers.doKeys(['j']); + // After moving back one space and then down, since line 4 is shorter than line 2, we should + // be at Eol of line 2 - 1 + helpers.assertCursorAt({ line: 3, ch: lines[3].length - 1 }); + helpers.doKeys(['j']); + helpers.doKeys(['j']); + // After moving down again, since line 3 has enough characters, we should be back to the + // same place we were at on line 1 + helpers.assertCursorAt({ line: 5, ch: lines[2].length - 2 }); +}); +//making sure gj and gk recover from clipping +testVim('gj_gk_clipping', function(cm,vim,helpers){ + cm.setCursor(0, 1); + helpers.doKeys('g','j','g','j'); + helpers.assertCursorAt(2, 1); + helpers.doKeys('g','k','g','k'); + helpers.assertCursorAt(0, 1); +},{value: 'line 1\n\nline 2'}); +//testing a mix of j/k and gj/gk +testVim('j_k_and_gj_gk', function(cm,vim,helpers){ + cm.setSize(120); + cm.setCursor(0, 0); + //go to the last character on the first line + helpers.doKeys('$'); + //move up/down on the column within the wrapped line + //side-effect: cursor is not locked to eol anymore + helpers.doKeys('g','k'); + var cur=cm.getCursor(); + eq(cur.line,0); + is((cur.ch<176),'gk didn\'t move cursor back (1)'); + helpers.doKeys('g','j'); + helpers.assertCursorAt(0, 176); + //should move to character 177 on line 2 (j/k preserve character index within line) + helpers.doKeys('j'); + //due to different line wrapping, the cursor can be on a different screen-x now + //gj and gk preserve screen-x on movement, much like moveV + helpers.doKeys('3','g','k'); + cur=cm.getCursor(); + eq(cur.line,1); + is((cur.ch<176),'gk didn\'t move cursor back (2)'); + helpers.doKeys('g','j','2','g','j'); + //should return to the same character-index + helpers.doKeys('k'); + helpers.assertCursorAt(0, 176); +},{ lineWrapping:true, value: 'This line is intentially long to test movement of gj and gk over wrapped lines. I will start on the end of this line, then make a step up and back to set the origin for j and k.\nThis line is supposed to be even longer than the previous. I will jump here and make another wiggle with gj and gk, before I jump back to the line above. Both wiggles should not change my cursor\'s target character but both j/k and gj/gk change each other\'s reference position.'}); +testVim('gj_gk', function(cm, vim, helpers) { + if (phantom) return; + cm.setSize(120); + // Test top of document edge case. + cm.setCursor(0, 4); + helpers.doKeys('g', 'j'); + helpers.doKeys('10', 'g', 'k'); + helpers.assertCursorAt(0, 4); + + // Test moving down preserves column position. + helpers.doKeys('g', 'j'); + var pos1 = cm.getCursor(); + var expectedPos2 = { line: 0, ch: (pos1.ch - 4) * 2 + 4}; + helpers.doKeys('g', 'j'); + helpers.assertCursorAt(expectedPos2); + + // Move to the last character + cm.setCursor(0, 0); + // Move left to reset HSPos + helpers.doKeys('h'); + // Test bottom of document edge case. + helpers.doKeys('100', 'g', 'j'); + var endingPos = cm.getCursor(); + is(endingPos != 0, 'gj should not be on wrapped line 0'); + var topLeftCharCoords = cm.charCoords(makeCursor(0, 0)); + var endingCharCoords = cm.charCoords(endingPos); + is(topLeftCharCoords.left == endingCharCoords.left, 'gj should end up on column 0'); +},{ lineNumbers: false, lineWrapping:true, value: 'Thislineisintentiallylongtotestmovementofgjandgkoverwrappedlines.' }); +testVim('}', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('}'); + helpers.assertCursorAt(1, 0); + cm.setCursor(0, 0); + helpers.doKeys('2', '}'); + helpers.assertCursorAt(4, 0); + cm.setCursor(0, 0); + helpers.doKeys('6', '}'); + helpers.assertCursorAt(5, 0); +}, { value: 'a\n\nb\nc\n\nd' }); +testVim('{', function(cm, vim, helpers) { + cm.setCursor(5, 0); + helpers.doKeys('{'); + helpers.assertCursorAt(4, 0); + cm.setCursor(5, 0); + helpers.doKeys('2', '{'); + helpers.assertCursorAt(1, 0); + cm.setCursor(5, 0); + helpers.doKeys('6', '{'); + helpers.assertCursorAt(0, 0); +}, { value: 'a\n\nb\nc\n\nd' }); +testVim('paragraph_motions', function(cm, vim, helpers) { + cm.setCursor(10, 0); + helpers.doKeys('{'); + helpers.assertCursorAt(4, 0); + helpers.doKeys('{'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('2', '}'); + helpers.assertCursorAt(7, 0); + helpers.doKeys('2', '}'); + helpers.assertCursorAt(16, 0); + + cm.setCursor(9, 0); + helpers.doKeys('}'); + helpers.assertCursorAt(14, 0); + + cm.setCursor(6, 0); + helpers.doKeys('}'); + helpers.assertCursorAt(7, 0); + + // ip inside empty space + cm.setCursor(10, 0); + helpers.doKeys('v', 'i', 'p'); + eqPos(Pos(7, 0), cm.getCursor('anchor')); + eqPos(Pos(12, 0), cm.getCursor('head')); + helpers.doKeys('i', 'p'); + eqPos(Pos(7, 0), cm.getCursor('anchor')); + eqPos(Pos(13, 1), cm.getCursor('head')); + helpers.doKeys('2', 'i', 'p'); + eqPos(Pos(7, 0), cm.getCursor('anchor')); + eqPos(Pos(16, 1), cm.getCursor('head')); + + // should switch to visualLine mode + cm.setCursor(14, 0); + helpers.doKeys('', 'v', 'i', 'p'); + helpers.assertCursorAt(14, 0); + + cm.setCursor(14, 0); + helpers.doKeys('', 'V', 'i', 'p'); + eqPos(Pos(16, 1), cm.getCursor('head')); + + // ap inside empty space + cm.setCursor(10, 0); + helpers.doKeys('', 'v', 'a', 'p'); + eqPos(Pos(7, 0), cm.getCursor('anchor')); + eqPos(Pos(13, 1), cm.getCursor('head')); + helpers.doKeys('a', 'p'); + eqPos(Pos(7, 0), cm.getCursor('anchor')); + eqPos(Pos(16, 1), cm.getCursor('head')); + + cm.setCursor(13, 0); + helpers.doKeys('v', 'a', 'p'); + eqPos(Pos(13, 0), cm.getCursor('anchor')); + eqPos(Pos(14, 0), cm.getCursor('head')); + + cm.setCursor(16, 0); + helpers.doKeys('v', 'a', 'p'); + eqPos(Pos(14, 0), cm.getCursor('anchor')); + eqPos(Pos(16, 1), cm.getCursor('head')); + + cm.setCursor(0, 0); + helpers.doKeys('v', 'a', 'p'); + eqPos(Pos(0, 0), cm.getCursor('anchor')); + eqPos(Pos(4, 0), cm.getCursor('head')); + + cm.setCursor(0, 0); + helpers.doKeys('d', 'i', 'p'); + var register = helpers.getRegisterController().getRegister(); + eq('a\na\n', register.toString()); + is(register.linewise); + helpers.doKeys('3', 'j', 'p'); + helpers.doKeys('y', 'i', 'p'); + is(register.linewise); + eq('b\na\na\nc\n', register.toString()); +}, { value: 'a\na\n\n\n\nb\nc\n\n\n\n\n\n\nd\n\ne\nf' }); + +// Operator tests +testVim('dl', function(cm, vim, helpers) { + var curStart = makeCursor(0, 0); + cm.setCursor(curStart); + helpers.doKeys('d', 'l'); + eq('word1 ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' ', register.toString()); + is(!register.linewise); + eqPos(curStart, cm.getCursor()); +}, { value: ' word1 ' }); +testVim('dl_eol', function(cm, vim, helpers) { + cm.setCursor(0, 6); + helpers.doKeys('d', 'l'); + eq(' word1', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' ', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 5); +}, { value: ' word1 ' }); +testVim('dl_repeat', function(cm, vim, helpers) { + var curStart = makeCursor(0, 0); + cm.setCursor(curStart); + helpers.doKeys('2', 'd', 'l'); + eq('ord1 ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' w', register.toString()); + is(!register.linewise); + eqPos(curStart, cm.getCursor()); +}, { value: ' word1 ' }); +testVim('dh', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + helpers.doKeys('d', 'h'); + eq(' wrd1 ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('o', register.toString()); + is(!register.linewise); + eqPos(offsetCursor(curStart, 0 , -1), cm.getCursor()); +}, { value: ' word1 ' }); +testVim('dj', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + helpers.doKeys('d', 'j'); + eq(' word3', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' word1\nword2\n', register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, 1); +}, { value: ' word1\nword2\n word3' }); +testVim('dj_end_of_document', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + helpers.doKeys('d', 'j'); + eq(' word1 ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 3); +}, { value: ' word1 ' }); +testVim('dk', function(cm, vim, helpers) { + var curStart = makeCursor(1, 3); + cm.setCursor(curStart); + helpers.doKeys('d', 'k'); + eq(' word3', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' word1\nword2\n', register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, 1); +}, { value: ' word1\nword2\n word3' }); +testVim('dk_start_of_document', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + helpers.doKeys('d', 'k'); + eq(' word1 ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 3); +}, { value: ' word1 ' }); +testVim('dw_space', function(cm, vim, helpers) { + var curStart = makeCursor(0, 0); + cm.setCursor(curStart); + helpers.doKeys('d', 'w'); + eq('word1 ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(' ', register.toString()); + is(!register.linewise); + eqPos(curStart, cm.getCursor()); +}, { value: ' word1 ' }); +testVim('dw_word', function(cm, vim, helpers) { + var curStart = makeCursor(0, 1); + cm.setCursor(curStart); + helpers.doKeys('d', 'w'); + eq(' word2', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1 ', register.toString()); + is(!register.linewise); + eqPos(curStart, cm.getCursor()); +}, { value: ' word1 word2' }); +testVim('dw_unicode_word', function(cm, vim, helpers) { + helpers.doKeys('d', 'w'); + eq(cm.getValue().length, 10); + helpers.doKeys('d', 'w'); + eq(cm.getValue().length, 6); + helpers.doKeys('d', 'w'); + eq(cm.getValue().length, 5); + helpers.doKeys('d', 'e'); + eq(cm.getValue().length, 2); +}, { value: ' \u0562\u0561\u0580\u0587\xbbe\xb5g ' }); +testVim('dw_only_word', function(cm, vim, helpers) { + // Test that if there is only 1 word left, dw deletes till the end of the + // line. + cm.setCursor(0, 1); + helpers.doKeys('d', 'w'); + eq(' ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1 ', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 0); +}, { value: ' word1 ' }); +testVim('dw_eol', function(cm, vim, helpers) { + // Assert that dw does not delete the newline if last word to delete is at end + // of line. + cm.setCursor(0, 1); + helpers.doKeys('d', 'w'); + eq(' \nword2', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 0); +}, { value: ' word1\nword2' }); +testVim('dw_eol_with_multiple_newlines', function(cm, vim, helpers) { + // Assert that dw does not delete the newline if last word to delete is at end + // of line and it is followed by multiple newlines. + cm.setCursor(0, 1); + helpers.doKeys('d', 'w'); + eq(' \n\nword2', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 0); +}, { value: ' word1\n\nword2' }); +testVim('dw_empty_line_followed_by_whitespace', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'w'); + eq(' \nword', cm.getValue()); +}, { value: '\n \nword' }); +testVim('dw_empty_line_followed_by_word', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'w'); + eq('word', cm.getValue()); +}, { value: '\nword' }); +testVim('dw_empty_line_followed_by_empty_line', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'w'); + eq('\n', cm.getValue()); +}, { value: '\n\n' }); +testVim('dw_whitespace_followed_by_whitespace', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'w'); + eq('\n \n', cm.getValue()); +}, { value: ' \n \n' }); +testVim('dw_whitespace_followed_by_empty_line', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'w'); + eq('\n\n', cm.getValue()); +}, { value: ' \n\n' }); +testVim('dw_word_whitespace_word', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'w'); + eq('\n \nword2', cm.getValue()); +}, { value: 'word1\n \nword2'}) +testVim('dw_end_of_document', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('d', 'w'); + eq('\nab', cm.getValue()); +}, { value: '\nabc' }); +testVim('dw_repeat', function(cm, vim, helpers) { + // Assert that dw does delete newline if it should go to the next line, and + // that repeat works properly. + cm.setCursor(0, 1); + helpers.doKeys('d', '2', 'w'); + eq(' ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1\nword2', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 0); +}, { value: ' word1\nword2' }); +testVim('de_word_start_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'e'); + eq('\n\n', cm.getValue()); +}, { value: 'word\n\n' }); +testVim('de_word_end_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(0, 3); + helpers.doKeys('d', 'e'); + eq('wor', cm.getValue()); +}, { value: 'word\n\n\n' }); +testVim('de_whitespace_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'e'); + eq('', cm.getValue()); +}, { value: ' \n\n\n' }); +testVim('de_end_of_document', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('d', 'e'); + eq('\nab', cm.getValue()); +}, { value: '\nabc' }); +testVim('db_empty_lines', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('d', 'b'); + eq('\n\n', cm.getValue()); +}, { value: '\n\n\n' }); +testVim('db_word_start_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('d', 'b'); + eq('\nword', cm.getValue()); +}, { value: '\n\nword' }); +testVim('db_word_end_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(2, 3); + helpers.doKeys('d', 'b'); + eq('\n\nd', cm.getValue()); +}, { value: '\n\nword' }); +testVim('db_whitespace_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('d', 'b'); + eq('', cm.getValue()); +}, { value: '\n \n' }); +testVim('db_start_of_document', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'b'); + eq('abc\n', cm.getValue()); +}, { value: 'abc\n' }); +testVim('dge_empty_lines', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doKeys('d', 'g', 'e'); + // Note: In real VIM the result should be '', but it's not quite consistent, + // since 2 newlines are deleted. But in the similar case of word\n\n, only + // 1 newline is deleted. We'll diverge from VIM's behavior since it's much + // easier this way. + eq('\n', cm.getValue()); +}, { value: '\n\n' }); +testVim('dge_word_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doKeys('d', 'g', 'e'); + eq('wor\n', cm.getValue()); +}, { value: 'word\n\n'}); +testVim('dge_whitespace_and_empty_lines', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('d', 'g', 'e'); + eq('', cm.getValue()); +}, { value: '\n \n' }); +testVim('dge_start_of_document', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('d', 'g', 'e'); + eq('bc\n', cm.getValue()); +}, { value: 'abc\n' }); +testVim('d_inclusive', function(cm, vim, helpers) { + // Assert that when inclusive is set, the character the cursor is on gets + // deleted too. + var curStart = makeCursor(0, 1); + cm.setCursor(curStart); + helpers.doKeys('d', 'e'); + eq(' ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1', register.toString()); + is(!register.linewise); + eqPos(curStart, cm.getCursor()); +}, { value: ' word1 ' }); +testVim('d_reverse', function(cm, vim, helpers) { + // Test that deleting in reverse works. + cm.setCursor(1, 0); + helpers.doKeys('d', 'b'); + eq(' word2 ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1\n', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 1); +}, { value: ' word1\nword2 ' }); +testVim('dd', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedBuffer = cm.getRange({ line: 0, ch: 0 }, + { line: 1, ch: 0 }); + var expectedLineCount = cm.lineCount() - 1; + helpers.doKeys('d', 'd'); + eq(expectedLineCount, cm.lineCount()); + var register = helpers.getRegisterController().getRegister(); + eq(expectedBuffer, register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, lines[1].textStart); +}); +testVim('dd_prefix_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedBuffer = cm.getRange({ line: 0, ch: 0 }, + { line: 2, ch: 0 }); + var expectedLineCount = cm.lineCount() - 2; + helpers.doKeys('2', 'd', 'd'); + eq(expectedLineCount, cm.lineCount()); + var register = helpers.getRegisterController().getRegister(); + eq(expectedBuffer, register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, lines[2].textStart); +}); +testVim('dd_motion_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedBuffer = cm.getRange({ line: 0, ch: 0 }, + { line: 2, ch: 0 }); + var expectedLineCount = cm.lineCount() - 2; + helpers.doKeys('d', '2', 'd'); + eq(expectedLineCount, cm.lineCount()); + var register = helpers.getRegisterController().getRegister(); + eq(expectedBuffer, register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, lines[2].textStart); +}); +testVim('dd_multiply_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedBuffer = cm.getRange({ line: 0, ch: 0 }, + { line: 6, ch: 0 }); + var expectedLineCount = cm.lineCount() - 6; + helpers.doKeys('2', 'd', '3', 'd'); + eq(expectedLineCount, cm.lineCount()); + var register = helpers.getRegisterController().getRegister(); + eq(expectedBuffer, register.toString()); + is(register.linewise); + helpers.assertCursorAt(0, lines[6].textStart); +}); +testVim('dd_lastline', function(cm, vim, helpers) { + cm.setCursor(cm.lineCount(), 0); + var expectedLineCount = cm.lineCount() - 1; + helpers.doKeys('d', 'd'); + eq(expectedLineCount, cm.lineCount()); + helpers.assertCursorAt(cm.lineCount() - 1, 0); +}); +testVim('dd_only_line', function(cm, vim, helpers) { + cm.setCursor(0, 0); + var expectedRegister = cm.getValue() + "\n"; + helpers.doKeys('d','d'); + eq(1, cm.lineCount()); + eq('', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq(expectedRegister, register.toString()); +}, { value: "thisistheonlyline" }); +// Yank commands should behave the exact same as d commands, expect that nothing +// gets deleted. +testVim('yw_repeat', function(cm, vim, helpers) { + // Assert that yw does yank newline if it should go to the next line, and + // that repeat works properly. + var curStart = makeCursor(0, 1); + cm.setCursor(curStart); + helpers.doKeys('y', '2', 'w'); + eq(' word1\nword2', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1\nword2', register.toString()); + is(!register.linewise); + eqPos(curStart, cm.getCursor()); +}, { value: ' word1\nword2' }); +testVim('yy_multiply_repeat', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + var expectedBuffer = cm.getRange({ line: 0, ch: 0 }, + { line: 6, ch: 0 }); + var expectedLineCount = cm.lineCount(); + helpers.doKeys('2', 'y', '3', 'y'); + eq(expectedLineCount, cm.lineCount()); + var register = helpers.getRegisterController().getRegister(); + eq(expectedBuffer, register.toString()); + is(register.linewise); + eqPos(curStart, cm.getCursor()); +}); +// Change commands behave like d commands except that it also enters insert +// mode. In addition, when the change is linewise, an additional newline is +// inserted so that insert mode starts on that line. +testVim('cw', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('c', '2', 'w'); + eq(' word3', cm.getValue()); + helpers.assertCursorAt(0, 0); +}, { value: 'word1 word2 word3'}); +testVim('cw_repeat', function(cm, vim, helpers) { + // Assert that cw does delete newline if it should go to the next line, and + // that repeat works properly. + var curStart = makeCursor(0, 1); + cm.setCursor(curStart); + helpers.doKeys('c', '2', 'w'); + eq(' ', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('word1\nword2', register.toString()); + is(!register.linewise); + eqPos(curStart, cm.getCursor()); + eq('vim-insert', cm.getOption('keyMap')); +}, { value: ' word1\nword2' }); +testVim('cc_multiply_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedBuffer = cm.getRange({ line: 0, ch: 0 }, + { line: 6, ch: 0 }); + var expectedLineCount = cm.lineCount() - 5; + helpers.doKeys('2', 'c', '3', 'c'); + eq(expectedLineCount, cm.lineCount()); + var register = helpers.getRegisterController().getRegister(); + eq(expectedBuffer, register.toString()); + is(register.linewise); + eq('vim-insert', cm.getOption('keyMap')); +}); +testVim('ct', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('c', 't', 'w'); + eq(' word1 word3', cm.getValue()); + helpers.doKeys('', 'c', '|'); + eq(' word3', cm.getValue()); + helpers.assertCursorAt(0, 0); + helpers.doKeys('', '2', 'u', 'w', 'h'); + helpers.doKeys('c', '2', 'g', 'e'); + eq(' wordword3', cm.getValue()); +}, { value: ' word1 word2 word3'}); +testVim('cc_should_not_append_to_document', function(cm, vim, helpers) { + var expectedLineCount = cm.lineCount(); + cm.setCursor(cm.lastLine(), 0); + helpers.doKeys('c', 'c'); + eq(expectedLineCount, cm.lineCount()); +}); +function fillArray(val, times) { + var arr = []; + for (var i = 0; i < times; i++) { + arr.push(val); + } + return arr; +} +testVim('c_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('', '2', 'j', 'l', 'l', 'l', 'c'); + var replacement = fillArray('hello', 3); + cm.replaceSelections(replacement); + eq('1hello\n5hello\nahellofg', cm.getValue()); + helpers.doKeys(''); + cm.setCursor(2, 3); + helpers.doKeys('', '2', 'k', 'h', 'C'); + replacement = fillArray('world', 3); + cm.replaceSelections(replacement); + eq('1hworld\n5hworld\nahworld', cm.getValue()); +}, {value: '1234\n5678\nabcdefg'}); +testVim('c_visual_block_replay', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('', '2', 'j', 'l', 'c'); + var replacement = fillArray('fo', 3); + cm.replaceSelections(replacement); + eq('1fo4\n5fo8\nafodefg', cm.getValue()); + helpers.doKeys(''); + cm.setCursor(0, 0); + helpers.doKeys('.'); + eq('foo4\nfoo8\nfoodefg', cm.getValue()); +}, {value: '1234\n5678\nabcdefg'}); + +testVim('d_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('', '2', 'j', 'l', 'l', 'l', 'd'); + eq('1\n5\nafg', cm.getValue()); +}, {value: '1234\n5678\nabcdefg'}); +testVim('D_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('', '2', 'j', 'l', 'D'); + eq('1\n5\na', cm.getValue()); +}, {value: '1234\n5678\nabcdefg'}); + +// Swapcase commands edit in place and do not modify registers. +testVim('g~w_repeat', function(cm, vim, helpers) { + // Assert that dw does delete newline if it should go to the next line, and + // that repeat works properly. + var curStart = makeCursor(0, 1); + cm.setCursor(curStart); + helpers.doKeys('g', '~', '2', 'w'); + eq(' WORD1\nWORD2', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); + eqPos(curStart, cm.getCursor()); +}, { value: ' word1\nword2' }); +testVim('g~g~', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + var expectedLineCount = cm.lineCount(); + var expectedValue = cm.getValue().toUpperCase(); + helpers.doKeys('2', 'g', '~', '3', 'g', '~'); + eq(expectedValue, cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); + eqPos(curStart, cm.getCursor()); +}, { value: ' word1\nword2\nword3\nword4\nword5\nword6' }); +testVim('gu_and_gU', function(cm, vim, helpers) { + var curStart = makeCursor(0, 7); + var value = cm.getValue(); + cm.setCursor(curStart); + helpers.doKeys('2', 'g', 'U', 'w'); + eq(cm.getValue(), 'wa wb xX WC wd'); + eqPos(curStart, cm.getCursor()); + helpers.doKeys('2', 'g', 'u', 'w'); + eq(cm.getValue(), value); + + helpers.doKeys('2', 'g', 'U', 'B'); + eq(cm.getValue(), 'wa WB Xx wc wd'); + eqPos(makeCursor(0, 3), cm.getCursor()); + + cm.setCursor(makeCursor(0, 4)); + helpers.doKeys('g', 'u', 'i', 'w'); + eq(cm.getValue(), 'wa wb Xx wc wd'); + eqPos(makeCursor(0, 3), cm.getCursor()); + + // TODO: support gUgU guu + // eqPos(makeCursor(0, 0), cm.getCursor()); + + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); +}, { value: 'wa wb xx wc wd' }); +testVim('visual_block_~', function(cm, vim, helpers) { + cm.setCursor(1, 1); + helpers.doKeys('', 'l', 'l', 'j', '~'); + helpers.assertCursorAt(1, 1); + eq('hello\nwoRLd\naBCDe', cm.getValue()); + cm.setCursor(2, 0); + helpers.doKeys('v', 'l', 'l', '~'); + helpers.assertCursorAt(2, 0); + eq('hello\nwoRLd\nAbcDe', cm.getValue()); +},{value: 'hello\nwOrld\nabcde' }); +testVim('._swapCase_visualBlock', function(cm, vim, helpers) { + helpers.doKeys('', 'j', 'j', 'l', '~'); + cm.setCursor(0, 3); + helpers.doKeys('.'); + eq('HelLO\nWorLd\nAbcdE', cm.getValue()); +},{value: 'hEllo\nwOrlD\naBcDe' }); +testVim('._delete_visualBlock', function(cm, vim, helpers) { + helpers.doKeys('', 'j', 'x'); + eq('ive\ne\nsome\nsugar', cm.getValue()); + helpers.doKeys('.'); + eq('ve\n\nsome\nsugar', cm.getValue()); + helpers.doKeys('j', 'j', '.'); + eq('ve\n\nome\nugar', cm.getValue()); + helpers.doKeys('u', '', '.'); + eq('ve\n\nme\ngar', cm.getValue()); +},{value: 'give\nme\nsome\nsugar' }); +testVim('>{motion}', function(cm, vim, helpers) { + cm.setCursor(1, 3); + var expectedLineCount = cm.lineCount(); + var expectedValue = ' word1\n word2\nword3 '; + helpers.doKeys('>', 'k'); + eq(expectedValue, cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 3); +}, { value: ' word1\nword2\nword3 ', indentUnit: 2 }); +testVim('>>', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedLineCount = cm.lineCount(); + var expectedValue = ' word1\n word2\nword3 '; + helpers.doKeys('2', '>', '>'); + eq(expectedValue, cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 3); +}, { value: ' word1\nword2\nword3 ', indentUnit: 2 }); +testVim('<{motion}', function(cm, vim, helpers) { + cm.setCursor(1, 3); + var expectedLineCount = cm.lineCount(); + var expectedValue = ' word1\nword2\nword3 '; + helpers.doKeys('<', 'k'); + eq(expectedValue, cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 1); +}, { value: ' word1\n word2\nword3 ', indentUnit: 2 }); +testVim('<<', function(cm, vim, helpers) { + cm.setCursor(0, 3); + var expectedLineCount = cm.lineCount(); + var expectedValue = ' word1\nword2\nword3 '; + helpers.doKeys('2', '<', '<'); + eq(expectedValue, cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 1); +}, { value: ' word1\n word2\nword3 ', indentUnit: 2 }); + +// Edit tests +function testEdit(name, before, pos, edit, after) { + return testVim(name, function(cm, vim, helpers) { + var ch = before.search(pos) + var line = before.substring(0, ch).split('\n').length - 1; + if (line) { + ch = before.substring(0, ch).split('\n').pop().length; + } + cm.setCursor(line, ch); + helpers.doKeys.apply(this, edit.split('')); + eq(after, cm.getValue()); + }, {value: before}); +} + +// These Delete tests effectively cover word-wise Change, Visual & Yank. +// Tabs are used as differentiated whitespace to catch edge cases. +// Normal word: +testEdit('diw_mid_spc', 'foo \tbAr\t baz', /A/, 'diw', 'foo \t\t baz'); +testEdit('daw_mid_spc', 'foo \tbAr\t baz', /A/, 'daw', 'foo \tbaz'); +testEdit('diw_mid_punct', 'foo \tbAr.\t baz', /A/, 'diw', 'foo \t.\t baz'); +testEdit('daw_mid_punct', 'foo \tbAr.\t baz', /A/, 'daw', 'foo.\t baz'); +testEdit('diw_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'diw', 'foo \t,.\t baz'); +testEdit('daw_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'daw', 'foo \t,.\t baz'); +testEdit('diw_start_spc', 'bAr \tbaz', /A/, 'diw', ' \tbaz'); +testEdit('daw_start_spc', 'bAr \tbaz', /A/, 'daw', 'baz'); +testEdit('diw_start_punct', 'bAr. \tbaz', /A/, 'diw', '. \tbaz'); +testEdit('daw_start_punct', 'bAr. \tbaz', /A/, 'daw', '. \tbaz'); +testEdit('diw_end_spc', 'foo \tbAr', /A/, 'diw', 'foo \t'); +testEdit('daw_end_spc', 'foo \tbAr', /A/, 'daw', 'foo'); +testEdit('diw_end_punct', 'foo \tbAr.', /A/, 'diw', 'foo \t.'); +testEdit('daw_end_punct', 'foo \tbAr.', /A/, 'daw', 'foo.'); +// Big word: +testEdit('diW_mid_spc', 'foo \tbAr\t baz', /A/, 'diW', 'foo \t\t baz'); +testEdit('daW_mid_spc', 'foo \tbAr\t baz', /A/, 'daW', 'foo \tbaz'); +testEdit('diW_mid_punct', 'foo \tbAr.\t baz', /A/, 'diW', 'foo \t\t baz'); +testEdit('daW_mid_punct', 'foo \tbAr.\t baz', /A/, 'daW', 'foo \tbaz'); +testEdit('diW_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'diW', 'foo \t\t baz'); +testEdit('daW_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'daW', 'foo \tbaz'); +testEdit('diW_start_spc', 'bAr\t baz', /A/, 'diW', '\t baz'); +testEdit('daW_start_spc', 'bAr\t baz', /A/, 'daW', 'baz'); +testEdit('diW_start_punct', 'bAr.\t baz', /A/, 'diW', '\t baz'); +testEdit('daW_start_punct', 'bAr.\t baz', /A/, 'daW', 'baz'); +testEdit('diW_end_spc', 'foo \tbAr', /A/, 'diW', 'foo \t'); +testEdit('daW_end_spc', 'foo \tbAr', /A/, 'daW', 'foo'); +testEdit('diW_end_punct', 'foo \tbAr.', /A/, 'diW', 'foo \t'); +testEdit('daW_end_punct', 'foo \tbAr.', /A/, 'daW', 'foo'); +// Deleting text objects +// Open and close on same line +testEdit('di(_open_spc', 'foo (bAr) baz', /\(/, 'di(', 'foo () baz'); +testEdit('di)_open_spc', 'foo (bAr) baz', /\(/, 'di)', 'foo () baz'); +testEdit('dib_open_spc', 'foo (bAr) baz', /\(/, 'dib', 'foo () baz'); +testEdit('da(_open_spc', 'foo (bAr) baz', /\(/, 'da(', 'foo baz'); +testEdit('da)_open_spc', 'foo (bAr) baz', /\(/, 'da)', 'foo baz'); + +testEdit('di(_middle_spc', 'foo (bAr) baz', /A/, 'di(', 'foo () baz'); +testEdit('di)_middle_spc', 'foo (bAr) baz', /A/, 'di)', 'foo () baz'); +testEdit('da(_middle_spc', 'foo (bAr) baz', /A/, 'da(', 'foo baz'); +testEdit('da)_middle_spc', 'foo (bAr) baz', /A/, 'da)', 'foo baz'); + +testEdit('di(_close_spc', 'foo (bAr) baz', /\)/, 'di(', 'foo () baz'); +testEdit('di)_close_spc', 'foo (bAr) baz', /\)/, 'di)', 'foo () baz'); +testEdit('da(_close_spc', 'foo (bAr) baz', /\)/, 'da(', 'foo baz'); +testEdit('da)_close_spc', 'foo (bAr) baz', /\)/, 'da)', 'foo baz'); + +// delete around and inner b. +testEdit('dab_on_(_should_delete_around_()block', 'o( in(abc) )', /\(a/, 'dab', 'o( in )'); + +// delete around and inner B. +testEdit('daB_on_{_should_delete_around_{}block', 'o{ in{abc} }', /{a/, 'daB', 'o{ in }'); +testEdit('diB_on_{_should_delete_inner_{}block', 'o{ in{abc} }', /{a/, 'diB', 'o{ in{} }'); + +testEdit('da{_on_{_should_delete_inner_block', 'o{ in{abc} }', /{a/, 'da{', 'o{ in }'); +testEdit('di[_on_(_should_not_delete', 'foo (bAr) baz', /\(/, 'di[', 'foo (bAr) baz'); +testEdit('di[_on_)_should_not_delete', 'foo (bAr) baz', /\)/, 'di[', 'foo (bAr) baz'); +testEdit('da[_on_(_should_not_delete', 'foo (bAr) baz', /\(/, 'da[', 'foo (bAr) baz'); +testEdit('da[_on_)_should_not_delete', 'foo (bAr) baz', /\)/, 'da[', 'foo (bAr) baz'); +testMotion('di(_outside_should_stay', ['d', 'i', '('], { line: 0, ch: 0}, { line: 0, ch: 0}); + +// Open and close on different lines, equally indented +testEdit('di{_middle_spc', 'a{\n\tbar\n}b', /r/, 'di{', 'a{}b'); +testEdit('di}_middle_spc', 'a{\n\tbar\n}b', /r/, 'di}', 'a{}b'); +testEdit('da{_middle_spc', 'a{\n\tbar\n}b', /r/, 'da{', 'ab'); +testEdit('da}_middle_spc', 'a{\n\tbar\n}b', /r/, 'da}', 'ab'); +testEdit('daB_middle_spc', 'a{\n\tbar\n}b', /r/, 'daB', 'ab'); + +// open and close on diff lines, open indented less than close +testEdit('di{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'di{', 'a{}b'); +testEdit('di}_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'di}', 'a{}b'); +testEdit('da{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'da{', 'ab'); +testEdit('da}_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'da}', 'ab'); + +// open and close on diff lines, open indented more than close +testEdit('di[_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'di[', 'a\t[]b'); +testEdit('di]_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'di]', 'a\t[]b'); +testEdit('da[_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'da[', 'a\tb'); +testEdit('da]_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'da]', 'a\tb'); + +function testSelection(name, before, pos, keys, sel) { + return testVim(name, function(cm, vim, helpers) { + var ch = before.search(pos) + var line = before.substring(0, ch).split('\n').length - 1; + if (line) { + ch = before.substring(0, ch).split('\n').pop().length; + } + cm.setCursor(line, ch); + helpers.doKeys.apply(this, keys.split('')); + eq(sel, cm.getSelection()); + }, {value: before}); +} +testSelection('viw_middle_spc', 'foo \tbAr\t baz', /A/, 'viw', 'bAr'); +testSelection('vaw_middle_spc', 'foo \tbAr\t baz', /A/, 'vaw', 'bAr\t '); +testSelection('viw_middle_punct', 'foo \tbAr,\t baz', /A/, 'viw', 'bAr'); +testSelection('vaW_middle_punct', 'foo \tbAr,\t baz', /A/, 'vaW', 'bAr,\t '); +testSelection('viw_start_spc', 'foo \tbAr\t baz', /b/, 'viw', 'bAr'); +testSelection('viw_end_spc', 'foo \tbAr\t baz', /r/, 'viw', 'bAr'); +testSelection('viw_eol', 'foo \tbAr', /r/, 'viw', 'bAr'); +testSelection('vi{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'vi{', '\n\tbar\n\t'); +testSelection('va{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'va{', '{\n\tbar\n\t}'); + +testVim('mouse_select', function(cm, vim, helpers) { + cm.setSelection(Pos(0, 2), Pos(0, 4), {origin: '*mouse'}); + is(cm.state.vim.visualMode); + is(!cm.state.vim.visualLine); + is(!cm.state.vim.visualBlock); + helpers.doKeys(''); + is(!cm.somethingSelected()); + helpers.doKeys('g', 'v'); + eq('cd', cm.getSelection()); +}, {value: 'abcdef'}); + +// Operator-motion tests +testVim('D', function(cm, vim, helpers) { + cm.setCursor(0, 3); + helpers.doKeys('D'); + eq(' wo\nword2\n word3', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('rd1', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 2); +}, { value: ' word1\nword2\n word3' }); +testVim('C', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + helpers.doKeys('C'); + eq(' wo\nword2\n word3', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('rd1', register.toString()); + is(!register.linewise); + eqPos(curStart, cm.getCursor()); + eq('vim-insert', cm.getOption('keyMap')); +}, { value: ' word1\nword2\n word3' }); +testVim('Y', function(cm, vim, helpers) { + var curStart = makeCursor(0, 3); + cm.setCursor(curStart); + helpers.doKeys('Y'); + eq(' word1\nword2\n word3', cm.getValue()); + var register = helpers.getRegisterController().getRegister(); + eq('rd1', register.toString()); + is(!register.linewise); + helpers.assertCursorAt(0, 3); +}, { value: ' word1\nword2\n word3' }); +testVim('~', function(cm, vim, helpers) { + helpers.doKeys('3', '~'); + eq('ABCdefg', cm.getValue()); + helpers.assertCursorAt(0, 3); +}, { value: 'abcdefg' }); + +// Action tests +testVim('ctrl-a', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys(''); + eq('-9', cm.getValue()); + helpers.assertCursorAt(0, 1); + helpers.doKeys('2',''); + eq('-7', cm.getValue()); +}, {value: '-10'}); +testVim('ctrl-x', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys(''); + eq('-1', cm.getValue()); + helpers.assertCursorAt(0, 1); + helpers.doKeys('2',''); + eq('-3', cm.getValue()); +}, {value: '0'}); +testVim('/ search forward', function(cm, vim, helpers) { + forEach(['', ''], function(key) { + cm.setCursor(0, 0); + helpers.doKeys(key); + helpers.assertCursorAt(0, 5); + helpers.doKeys('l'); + helpers.doKeys(key); + helpers.assertCursorAt(0, 10); + cm.setCursor(0, 11); + helpers.doKeys(key); + helpers.assertCursorAt(0, 11); + }); +}, {value: '__jmp1 jmp2 jmp'}); +testVim('a', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('a'); + helpers.assertCursorAt(0, 2); + eq('vim-insert', cm.getOption('keyMap')); +}); +testVim('a_eol', function(cm, vim, helpers) { + cm.setCursor(0, lines[0].length - 1); + helpers.doKeys('a'); + helpers.assertCursorAt(0, lines[0].length); + eq('vim-insert', cm.getOption('keyMap')); +}); +testVim('A_endOfSelectedArea', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('v', 'j', 'l'); + helpers.doKeys('A'); + helpers.assertCursorAt(1, 2); + eq('vim-insert', cm.getOption('keyMap')); +}, {value: 'foo\nbar'}); +testVim('i', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('i'); + helpers.assertCursorAt(0, 1); + eq('vim-insert', cm.getOption('keyMap')); +}); +testVim('i_repeat', function(cm, vim, helpers) { + helpers.doKeys('3', 'i'); + cm.replaceRange('test', cm.getCursor()); + helpers.doKeys(''); + eq('testtesttest', cm.getValue()); + helpers.assertCursorAt(0, 11); +}, { value: '' }); +testVim('i_repeat_delete', function(cm, vim, helpers) { + cm.setCursor(0, 4); + helpers.doKeys('2', 'i'); + cm.replaceRange('z', cm.getCursor()); + helpers.doInsertModeKeys('Backspace', 'Backspace'); + helpers.doKeys(''); + eq('abe', cm.getValue()); + helpers.assertCursorAt(0, 1); +}, { value: 'abcde' }); +testVim('A', function(cm, vim, helpers) { + helpers.doKeys('A'); + helpers.assertCursorAt(0, lines[0].length); + eq('vim-insert', cm.getOption('keyMap')); +}); +testVim('A_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('', '2', 'j', 'l', 'l', 'A'); + var replacement = new Array(cm.listSelections().length+1).join('hello ').split(' '); + replacement.pop(); + cm.replaceSelections(replacement); + eq('testhello\nmehello\npleahellose', cm.getValue()); + helpers.doKeys(''); + cm.setCursor(0, 0); + helpers.doKeys('.'); + // TODO this doesn't work yet + // eq('teshellothello\nme hello hello\nplehelloahellose', cm.getValue()); +}, {value: 'test\nme\nplease'}); +testVim('I', function(cm, vim, helpers) { + cm.setCursor(0, 4); + helpers.doKeys('I'); + helpers.assertCursorAt(0, lines[0].textStart); + eq('vim-insert', cm.getOption('keyMap')); +}); +testVim('I_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('3', 'I'); + cm.replaceRange('test', cm.getCursor()); + helpers.doKeys(''); + eq('testtesttestblah', cm.getValue()); + helpers.assertCursorAt(0, 11); +}, { value: 'blah' }); +testVim('I_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('', '2', 'j', 'l', 'l', 'I'); + var replacement = new Array(cm.listSelections().length+1).join('hello ').split(' '); + replacement.pop(); + cm.replaceSelections(replacement); + eq('hellotest\nhellome\nhelloplease', cm.getValue()); +}, {value: 'test\nme\nplease'}); +testVim('o', function(cm, vim, helpers) { + cm.setCursor(0, 4); + helpers.doKeys('o'); + eq('word1\n\nword2', cm.getValue()); + helpers.assertCursorAt(1, 0); + eq('vim-insert', cm.getOption('keyMap')); +}, { value: 'word1\nword2' }); +testVim('o_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('3', 'o'); + cm.replaceRange('test', cm.getCursor()); + helpers.doKeys(''); + eq('\ntest\ntest\ntest', cm.getValue()); + helpers.assertCursorAt(3, 3); +}, { value: '' }); +testVim('O', function(cm, vim, helpers) { + cm.setCursor(0, 4); + helpers.doKeys('O'); + eq('\nword1\nword2', cm.getValue()); + helpers.assertCursorAt(0, 0); + eq('vim-insert', cm.getOption('keyMap')); +}, { value: 'word1\nword2' }); +testVim('J', function(cm, vim, helpers) { + cm.setCursor(0, 4); + helpers.doKeys('J'); + var expectedValue = 'word1 word2\nword3\n word4'; + eq(expectedValue, cm.getValue()); + helpers.assertCursorAt(0, expectedValue.indexOf('word2') - 1); +}, { value: 'word1 \n word2\nword3\n word4' }); +testVim('J_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 4); + helpers.doKeys('3', 'J'); + var expectedValue = 'word1 word2 word3\n word4'; + eq(expectedValue, cm.getValue()); + helpers.assertCursorAt(0, expectedValue.indexOf('word3') - 1); +}, { value: 'word1 \n word2\nword3\n word4' }); +testVim('p', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.getRegisterController().pushText('"', 'yank', 'abc\ndef', false); + helpers.doKeys('p'); + eq('__abc\ndef_', cm.getValue()); + helpers.assertCursorAt(1, 2); +}, { value: '___' }); +testVim('p_register', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.getRegisterController().getRegister('a').setText('abc\ndef', false); + helpers.doKeys('"', 'a', 'p'); + eq('__abc\ndef_', cm.getValue()); + helpers.assertCursorAt(1, 2); +}, { value: '___' }); +testVim('p_wrong_register', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.getRegisterController().getRegister('a').setText('abc\ndef', false); + helpers.doKeys('p'); + eq('___', cm.getValue()); + helpers.assertCursorAt(0, 1); +}, { value: '___' }); +testVim('p_line', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.getRegisterController().pushText('"', 'yank', ' a\nd\n', true); + helpers.doKeys('2', 'p'); + eq('___\n a\nd\n a\nd', cm.getValue()); + helpers.assertCursorAt(1, 2); +}, { value: '___' }); +testVim('p_lastline', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.getRegisterController().pushText('"', 'yank', ' a\nd', true); + helpers.doKeys('2', 'p'); + eq('___\n a\nd\n a\nd', cm.getValue()); + helpers.assertCursorAt(1, 2); +}, { value: '___' }); +testVim(']p_first_indent_is_smaller', function(cm, vim, helpers) { + helpers.getRegisterController().pushText('"', 'yank', ' abc\n def\n', true); + helpers.doKeys(']', 'p'); + eq(' ___\n abc\n def', cm.getValue()); +}, { value: ' ___' }); +testVim(']p_first_indent_is_larger', function(cm, vim, helpers) { + helpers.getRegisterController().pushText('"', 'yank', ' abc\n def\n', true); + helpers.doKeys(']', 'p'); + eq(' ___\n abc\ndef', cm.getValue()); +}, { value: ' ___' }); +testVim(']p_with_tab_indents', function(cm, vim, helpers) { + helpers.getRegisterController().pushText('"', 'yank', '\t\tabc\n\t\t\tdef\n', true); + helpers.doKeys(']', 'p'); + eq('\t___\n\tabc\n\t\tdef', cm.getValue()); +}, { value: '\t___', indentWithTabs: true}); +testVim(']p_with_spaces_translated_to_tabs', function(cm, vim, helpers) { + helpers.getRegisterController().pushText('"', 'yank', ' abc\n def\n', true); + helpers.doKeys(']', 'p'); + eq('\t___\n\tabc\n\t\tdef', cm.getValue()); +}, { value: '\t___', indentWithTabs: true, tabSize: 2 }); +testVim('[p', function(cm, vim, helpers) { + helpers.getRegisterController().pushText('"', 'yank', ' abc\n def\n', true); + helpers.doKeys('[', 'p'); + eq(' abc\n def\n ___', cm.getValue()); +}, { value: ' ___' }); +testVim('P', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.getRegisterController().pushText('"', 'yank', 'abc\ndef', false); + helpers.doKeys('P'); + eq('_abc\ndef__', cm.getValue()); + helpers.assertCursorAt(1, 3); +}, { value: '___' }); +testVim('P_line', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.getRegisterController().pushText('"', 'yank', ' a\nd\n', true); + helpers.doKeys('2', 'P'); + eq(' a\nd\n a\nd\n___', cm.getValue()); + helpers.assertCursorAt(0, 2); +}, { value: '___' }); +testVim('r', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('3', 'r', 'u'); + eq('wuuuet\nanother', cm.getValue(),'3r failed'); + helpers.assertCursorAt(0, 3); + cm.setCursor(0, 4); + helpers.doKeys('v', 'j', 'h', 'r', ''); + eq('wuuu \n her', cm.getValue(),'Replacing selection by space-characters failed'); +}, { value: 'wordet\nanother' }); +testVim('r_visual_block', function(cm, vim, helpers) { + cm.setCursor(2, 3); + helpers.doKeys('', 'k', 'k', 'h', 'h', 'r', 'l'); + eq('1lll\n5lll\nalllefg', cm.getValue()); + helpers.doKeys('', 'l', 'j', 'r', ''); + eq('1 l\n5 l\nalllefg', cm.getValue()); + cm.setCursor(2, 0); + helpers.doKeys('o'); + helpers.doKeys(''); + cm.replaceRange('\t\t', cm.getCursor()); + helpers.doKeys('', 'h', 'h', 'r', 'r'); + eq('1 l\n5 l\nalllefg\nrrrrrrrr', cm.getValue()); +}, {value: '1234\n5678\nabcdefg'}); +testVim('R', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('R'); + helpers.assertCursorAt(0, 1); + eq('vim-replace', cm.getOption('keyMap')); + is(cm.state.overwrite, 'Setting overwrite state failed'); +}); +testVim('mark', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 't'); + cm.setCursor(0, 0); + helpers.doKeys('`', 't'); + helpers.assertCursorAt(2, 2); + cm.setCursor(2, 0); + cm.replaceRange(' h', cm.getCursor()); + cm.setCursor(0, 0); + helpers.doKeys('\'', 't'); + helpers.assertCursorAt(2, 3); +}); +testVim('jumpToMark_next', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 't'); + cm.setCursor(0, 0); + helpers.doKeys(']', '`'); + helpers.assertCursorAt(2, 2); + cm.setCursor(0, 0); + helpers.doKeys(']', '\''); + helpers.assertCursorAt(2, 0); +}); +testVim('jumpToMark_next_repeat', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(3, 2); + helpers.doKeys('m', 'b'); + cm.setCursor(4, 2); + helpers.doKeys('m', 'c'); + cm.setCursor(0, 0); + helpers.doKeys('2', ']', '`'); + helpers.assertCursorAt(3, 2); + cm.setCursor(0, 0); + helpers.doKeys('2', ']', '\''); + helpers.assertCursorAt(3, 1); +}); +testVim('jumpToMark_next_sameline', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('m', 'a'); + cm.setCursor(2, 4); + helpers.doKeys('m', 'b'); + cm.setCursor(2, 2); + helpers.doKeys(']', '`'); + helpers.assertCursorAt(2, 4); +}); +testVim('jumpToMark_next_onlyprev', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('m', 'a'); + cm.setCursor(4, 0); + helpers.doKeys(']', '`'); + helpers.assertCursorAt(4, 0); +}); +testVim('jumpToMark_next_nomark', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys(']', '`'); + helpers.assertCursorAt(2, 2); + helpers.doKeys(']', '\''); + helpers.assertCursorAt(2, 0); +}); +testVim('jumpToMark_next_linewise_over', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(3, 4); + helpers.doKeys('m', 'b'); + cm.setCursor(2, 1); + helpers.doKeys(']', '\''); + helpers.assertCursorAt(3, 1); +}); +testVim('jumpToMark_next_action', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 't'); + cm.setCursor(0, 0); + helpers.doKeys('d', ']', '`'); + helpers.assertCursorAt(0, 0); + var actual = cm.getLine(0); + var expected = 'pop pop 0 1 2 3 4'; + eq(actual, expected, "Deleting while jumping to the next mark failed."); +}); +testVim('jumpToMark_next_line_action', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 't'); + cm.setCursor(0, 0); + helpers.doKeys('d', ']', '\''); + helpers.assertCursorAt(0, 1); + var actual = cm.getLine(0); + var expected = ' (a) [b] {c} ' + eq(actual, expected, "Deleting while jumping to the next mark line failed."); +}); +testVim('jumpToMark_prev', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 't'); + cm.setCursor(4, 0); + helpers.doKeys('[', '`'); + helpers.assertCursorAt(2, 2); + cm.setCursor(4, 0); + helpers.doKeys('[', '\''); + helpers.assertCursorAt(2, 0); +}); +testVim('jumpToMark_prev_repeat', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(3, 2); + helpers.doKeys('m', 'b'); + cm.setCursor(4, 2); + helpers.doKeys('m', 'c'); + cm.setCursor(5, 0); + helpers.doKeys('2', '[', '`'); + helpers.assertCursorAt(3, 2); + cm.setCursor(5, 0); + helpers.doKeys('2', '[', '\''); + helpers.assertCursorAt(3, 1); +}); +testVim('jumpToMark_prev_sameline', function(cm, vim, helpers) { + cm.setCursor(2, 0); + helpers.doKeys('m', 'a'); + cm.setCursor(2, 4); + helpers.doKeys('m', 'b'); + cm.setCursor(2, 2); + helpers.doKeys('[', '`'); + helpers.assertCursorAt(2, 0); +}); +testVim('jumpToMark_prev_onlynext', function(cm, vim, helpers) { + cm.setCursor(4, 4); + helpers.doKeys('m', 'a'); + cm.setCursor(2, 0); + helpers.doKeys('[', '`'); + helpers.assertCursorAt(2, 0); +}); +testVim('jumpToMark_prev_nomark', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('[', '`'); + helpers.assertCursorAt(2, 2); + helpers.doKeys('[', '\''); + helpers.assertCursorAt(2, 0); +}); +testVim('jumpToMark_prev_linewise_over', function(cm, vim, helpers) { + cm.setCursor(2, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(3, 4); + helpers.doKeys('m', 'b'); + cm.setCursor(3, 6); + helpers.doKeys('[', '\''); + helpers.assertCursorAt(2, 0); +}); +testVim('delmark_single', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('m', 't'); + helpers.doEx('delmarks t'); + cm.setCursor(0, 0); + helpers.doKeys('`', 't'); + helpers.assertCursorAt(0, 0); +}); +testVim('delmark_range', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(2, 2); + helpers.doKeys('m', 'b'); + cm.setCursor(3, 2); + helpers.doKeys('m', 'c'); + cm.setCursor(4, 2); + helpers.doKeys('m', 'd'); + cm.setCursor(5, 2); + helpers.doKeys('m', 'e'); + helpers.doEx('delmarks b-d'); + cm.setCursor(0, 0); + helpers.doKeys('`', 'a'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'b'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'c'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'd'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'e'); + helpers.assertCursorAt(5, 2); +}); +testVim('delmark_multi', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(2, 2); + helpers.doKeys('m', 'b'); + cm.setCursor(3, 2); + helpers.doKeys('m', 'c'); + cm.setCursor(4, 2); + helpers.doKeys('m', 'd'); + cm.setCursor(5, 2); + helpers.doKeys('m', 'e'); + helpers.doEx('delmarks bcd'); + cm.setCursor(0, 0); + helpers.doKeys('`', 'a'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'b'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'c'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'd'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'e'); + helpers.assertCursorAt(5, 2); +}); +testVim('delmark_multi_space', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(2, 2); + helpers.doKeys('m', 'b'); + cm.setCursor(3, 2); + helpers.doKeys('m', 'c'); + cm.setCursor(4, 2); + helpers.doKeys('m', 'd'); + cm.setCursor(5, 2); + helpers.doKeys('m', 'e'); + helpers.doEx('delmarks b c d'); + cm.setCursor(0, 0); + helpers.doKeys('`', 'a'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'b'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'c'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'd'); + helpers.assertCursorAt(1, 2); + helpers.doKeys('`', 'e'); + helpers.assertCursorAt(5, 2); +}); +testVim('delmark_all', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('m', 'a'); + cm.setCursor(2, 2); + helpers.doKeys('m', 'b'); + cm.setCursor(3, 2); + helpers.doKeys('m', 'c'); + cm.setCursor(4, 2); + helpers.doKeys('m', 'd'); + cm.setCursor(5, 2); + helpers.doKeys('m', 'e'); + helpers.doEx('delmarks a b-de'); + cm.setCursor(0, 0); + helpers.doKeys('`', 'a'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('`', 'b'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('`', 'c'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('`', 'd'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('`', 'e'); + helpers.assertCursorAt(0, 0); +}); +testVim('visual', function(cm, vim, helpers) { + helpers.doKeys('l', 'v', 'l', 'l'); + helpers.assertCursorAt(0, 4); + eqPos(makeCursor(0, 1), cm.getCursor('anchor')); + helpers.doKeys('d'); + eq('15', cm.getValue()); +}, { value: '12345' }); +testVim('visual_yank', function(cm, vim, helpers) { + helpers.doKeys('v', '3', 'l', 'y'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('p'); + eq('aa te test for yank', cm.getValue()); +}, { value: 'a test for yank' }) +testVim('visual_w', function(cm, vim, helpers) { + helpers.doKeys('v', 'w'); + eq(cm.getSelection(), 'motion t'); +}, { value: 'motion test'}); +testVim('visual_initial_selection', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('v'); + cm.getSelection('n'); +}, { value: 'init'}); +testVim('visual_crossover_left', function(cm, vim, helpers) { + cm.setCursor(0, 2); + helpers.doKeys('v', 'l', 'h', 'h'); + cm.getSelection('ro'); +}, { value: 'cross'}); +testVim('visual_crossover_left', function(cm, vim, helpers) { + cm.setCursor(0, 2); + helpers.doKeys('v', 'h', 'l', 'l'); + cm.getSelection('os'); +}, { value: 'cross'}); +testVim('visual_crossover_up', function(cm, vim, helpers) { + cm.setCursor(3, 2); + helpers.doKeys('v', 'j', 'k', 'k'); + eqPos(Pos(2, 2), cm.getCursor('head')); + eqPos(Pos(3, 3), cm.getCursor('anchor')); + helpers.doKeys('k'); + eqPos(Pos(1, 2), cm.getCursor('head')); + eqPos(Pos(3, 3), cm.getCursor('anchor')); +}, { value: 'cross\ncross\ncross\ncross\ncross\n'}); +testVim('visual_crossover_down', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('v', 'k', 'j', 'j'); + eqPos(Pos(2, 3), cm.getCursor('head')); + eqPos(Pos(1, 2), cm.getCursor('anchor')); + helpers.doKeys('j'); + eqPos(Pos(3, 3), cm.getCursor('head')); + eqPos(Pos(1, 2), cm.getCursor('anchor')); +}, { value: 'cross\ncross\ncross\ncross\ncross\n'}); +testVim('visual_exit', function(cm, vim, helpers) { + helpers.doKeys('', 'l', 'j', 'j', ''); + eqPos(cm.getCursor('anchor'), cm.getCursor('head')); + eq(vim.visualMode, false); +}, { value: 'hello\nworld\nfoo' }); +testVim('visual_line', function(cm, vim, helpers) { + helpers.doKeys('l', 'V', 'l', 'j', 'j', 'd'); + eq(' 4\n 5', cm.getValue()); +}, { value: ' 1\n 2\n 3\n 4\n 5' }); +testVim('visual_block_move_to_eol', function(cm, vim, helpers) { + // moveToEol should move all block cursors to end of line + cm.setCursor(0, 0); + helpers.doKeys('', 'G', '$'); + var selections = cm.getSelections().join(); + eq('123,45,6', selections); + // Checks that with cursor at Infinity, finding words backwards still works. + helpers.doKeys('2', 'k', 'b'); + selections = cm.getSelections().join(); + eq('1', selections); +}, {value: '123\n45\n6'}); +testVim('visual_block_different_line_lengths', function(cm, vim, helpers) { + // test the block selection with lines of different length + // i.e. extending the selection + // till the end of the longest line. + helpers.doKeys('', 'l', 'j', 'j', '6', 'l', 'd'); + helpers.doKeys('d', 'd', 'd', 'd'); + eq('', cm.getValue()); +}, {value: '1234\n5678\nabcdefg'}); +testVim('visual_block_truncate_on_short_line', function(cm, vim, helpers) { + // check for left side selection in case + // of moving up to a shorter line. + cm.replaceRange('', cm.getCursor()); + cm.setCursor(3, 4); + helpers.doKeys('', 'l', 'k', 'k', 'd'); + eq('hello world\n{\ntis\nsa!', cm.getValue()); +}, {value: 'hello world\n{\nthis is\nsparta!'}); +testVim('visual_block_corners', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('', '2', 'l', 'k'); + // circle around the anchor + // and check the selections + var selections = cm.getSelections(); + eq('345891', selections.join('')); + helpers.doKeys('4', 'h'); + selections = cm.getSelections(); + eq('123678', selections.join('')); + helpers.doKeys('j', 'j'); + selections = cm.getSelections(); + eq('678abc', selections.join('')); + helpers.doKeys('4', 'l'); + selections = cm.getSelections(); + eq('891cde', selections.join('')); +}, {value: '12345\n67891\nabcde'}); +testVim('visual_block_mode_switch', function(cm, vim, helpers) { + // switch between visual modes + cm.setCursor(1, 1); + // blockwise to characterwise visual + helpers.doKeys('', 'j', 'l', 'v'); + selections = cm.getSelections(); + eq('7891\nabc', selections.join('')); + // characterwise to blockwise + helpers.doKeys(''); + selections = cm.getSelections(); + eq('78bc', selections.join('')); + // blockwise to linewise visual + helpers.doKeys('V'); + selections = cm.getSelections(); + eq('67891\nabcde', selections.join('')); +}, {value: '12345\n67891\nabcde'}); +testVim('visual_block_crossing_short_line', function(cm, vim, helpers) { + // visual block with long and short lines + cm.setCursor(0, 3); + helpers.doKeys('', 'j', 'j', 'j'); + var selections = cm.getSelections().join(); + eq('4,,d,b', selections); + helpers.doKeys('3', 'k'); + selections = cm.getSelections().join(); + eq('4', selections); + helpers.doKeys('5', 'j', 'k'); + selections = cm.getSelections().join(""); + eq(10, selections.length); +}, {value: '123456\n78\nabcdefg\nfoobar\n}\n'}); +testVim('visual_block_curPos_on_exit', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('', '3' , 'l', ''); + eqPos(makeCursor(0, 3), cm.getCursor()); + helpers.doKeys('h', '', '2' , 'j' ,'3' , 'l'); + eq(cm.getSelections().join(), "3456,,cdef"); + helpers.doKeys('4' , 'h'); + eq(cm.getSelections().join(), "23,8,bc"); + helpers.doKeys('2' , 'l'); + eq(cm.getSelections().join(), "34,,cd"); +}, {value: '123456\n78\nabcdefg\nfoobar'}); + +testVim('visual_marks', function(cm, vim, helpers) { + helpers.doKeys('l', 'v', 'l', 'l', 'j', 'j', 'v'); + // Test visual mode marks + cm.setCursor(2, 1); + helpers.doKeys('\'', '<'); + helpers.assertCursorAt(0, 1); + helpers.doKeys('\'', '>'); + helpers.assertCursorAt(2, 0); +}); +testVim('visual_join', function(cm, vim, helpers) { + helpers.doKeys('l', 'V', 'l', 'j', 'j', 'J'); + eq(' 1 2 3\n 4\n 5', cm.getValue()); + is(!vim.visualMode); +}, { value: ' 1\n 2\n 3\n 4\n 5' }); +testVim('visual_join_2', function(cm, vim, helpers) { + helpers.doKeys('G', 'V', 'g', 'g', 'J'); + eq('1 2 3 4 5 6 ', cm.getValue()); + is(!vim.visualMode); +}, { value: '1\n2\n3\n4\n5\n6\n'}); +testVim('visual_blank', function(cm, vim, helpers) { + helpers.doKeys('v', 'k'); + eq(vim.visualMode, true); +}, { value: '\n' }); +testVim('reselect_visual', function(cm, vim, helpers) { + helpers.doKeys('l', 'v', 'l', 'l', 'l', 'y', 'g', 'v'); + helpers.assertCursorAt(0, 5); + eqPos(makeCursor(0, 1), cm.getCursor('anchor')); + helpers.doKeys('v'); + cm.setCursor(1, 0); + helpers.doKeys('v', 'l', 'l', 'p'); + eq('123456\n2345\nbar', cm.getValue()); + cm.setCursor(0, 0); + helpers.doKeys('g', 'v'); + // here the fake cursor is at (1, 3) + helpers.assertCursorAt(1, 4); + eqPos(makeCursor(1, 0), cm.getCursor('anchor')); + helpers.doKeys('v'); + cm.setCursor(2, 0); + helpers.doKeys('v', 'l', 'l', 'g', 'v'); + helpers.assertCursorAt(1, 4); + eqPos(makeCursor(1, 0), cm.getCursor('anchor')); + helpers.doKeys('g', 'v'); + helpers.assertCursorAt(2, 3); + eqPos(makeCursor(2, 0), cm.getCursor('anchor')); + eq('123456\n2345\nbar', cm.getValue()); +}, { value: '123456\nfoo\nbar' }); +testVim('reselect_visual_line', function(cm, vim, helpers) { + helpers.doKeys('l', 'V', 'j', 'j', 'V', 'g', 'v', 'd'); + eq('foo\nand\nbar', cm.getValue()); + cm.setCursor(1, 0); + helpers.doKeys('V', 'y', 'j'); + helpers.doKeys('V', 'p' , 'g', 'v', 'd'); + eq('foo\nand', cm.getValue()); +}, { value: 'hello\nthis\nis\nfoo\nand\nbar' }); +testVim('reselect_visual_block', function(cm, vim, helpers) { + cm.setCursor(1, 2); + helpers.doKeys('', 'k', 'h', ''); + cm.setCursor(2, 1); + helpers.doKeys('v', 'l', 'g', 'v'); + eqPos(Pos(1, 2), vim.sel.anchor); + eqPos(Pos(0, 1), vim.sel.head); + // Ensure selection is done with visual block mode rather than one + // continuous range. + eq(cm.getSelections().join(''), '23oo') + helpers.doKeys('g', 'v'); + eqPos(Pos(2, 1), vim.sel.anchor); + eqPos(Pos(2, 2), vim.sel.head); + helpers.doKeys(''); + // Ensure selection of deleted range + cm.setCursor(1, 1); + helpers.doKeys('v', '', 'j', 'd', 'g', 'v'); + eq(cm.getSelections().join(''), 'or'); +}, { value: '123456\nfoo\nbar' }); +testVim('s_normal', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('s'); + helpers.doKeys(''); + eq('ac', cm.getValue()); +}, { value: 'abc'}); +testVim('s_visual', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('v', 's'); + helpers.doKeys(''); + helpers.assertCursorAt(0, 0); + eq('ac', cm.getValue()); +}, { value: 'abc'}); +testVim('o_visual', function(cm, vim, helpers) { + cm.setCursor(0,0); + helpers.doKeys('v','l','l','l','o'); + helpers.assertCursorAt(0,0); + helpers.doKeys('v','v','j','j','j','o'); + helpers.assertCursorAt(0,0); + helpers.doKeys('O'); + helpers.doKeys('l','l') + helpers.assertCursorAt(3, 3); + helpers.doKeys('d'); + eq('p',cm.getValue()); +}, { value: 'abcd\nefgh\nijkl\nmnop'}); +testVim('o_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('','3','j','l','l', 'o'); + eqPos(Pos(3, 3), vim.sel.anchor); + eqPos(Pos(0, 1), vim.sel.head); + helpers.doKeys('O'); + eqPos(Pos(3, 1), vim.sel.anchor); + eqPos(Pos(0, 3), vim.sel.head); + helpers.doKeys('o'); + eqPos(Pos(0, 3), vim.sel.anchor); + eqPos(Pos(3, 1), vim.sel.head); +}, { value: 'abcd\nefgh\nijkl\nmnop'}); +testVim('changeCase_visual', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('v', 'l', 'l'); + helpers.doKeys('U'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('v', 'l', 'l'); + helpers.doKeys('u'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('l', 'l', 'l', '.'); + helpers.assertCursorAt(0, 3); + cm.setCursor(0, 0); + helpers.doKeys('q', 'a', 'v', 'j', 'U', 'q'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('j', '@', 'a'); + helpers.assertCursorAt(1, 0); + cm.setCursor(3, 0); + helpers.doKeys('V', 'U', 'j', '.'); + eq('ABCDEF\nGHIJKL\nMnopq\nSHORT LINE\nLONG LINE OF TEXT', cm.getValue()); +}, { value: 'abcdef\nghijkl\nmnopq\nshort line\nlong line of text'}); +testVim('changeCase_visual_block', function(cm, vim, helpers) { + cm.setCursor(2, 1); + helpers.doKeys('', 'k', 'k', 'h', 'U'); + eq('ABcdef\nGHijkl\nMNopq\nfoo', cm.getValue()); + cm.setCursor(0, 2); + helpers.doKeys('.'); + eq('ABCDef\nGHIJkl\nMNOPq\nfoo', cm.getValue()); + // check when last line is shorter. + cm.setCursor(2, 2); + helpers.doKeys('.'); + eq('ABCDef\nGHIJkl\nMNOPq\nfoO', cm.getValue()); +}, { value: 'abcdef\nghijkl\nmnopq\nfoo'}); +testVim('visual_paste', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('v', 'l', 'l', 'y'); + helpers.assertCursorAt(0, 0); + helpers.doKeys('3', 'l', 'j', 'v', 'l', 'p'); + helpers.assertCursorAt(1, 5); + eq('this is a\nunithitest for visual paste', cm.getValue()); + cm.setCursor(0, 0); + // in case of pasting whole line + helpers.doKeys('y', 'y'); + cm.setCursor(1, 6); + helpers.doKeys('v', 'l', 'l', 'l', 'p'); + helpers.assertCursorAt(2, 0); + eq('this is a\nunithi\nthis is a\n for visual paste', cm.getValue()); +}, { value: 'this is a\nunit test for visual paste'}); + +// This checks the contents of the register used to paste the text +testVim('v_paste_from_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('"', 'a', 'y', 'w'); + cm.setCursor(1, 0); + helpers.doKeys('v', 'p'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+register/.test(text)); + }); +}, { value: 'register contents\nare not erased'}); +testVim('S_normal', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('j', 'S'); + helpers.doKeys(''); + helpers.assertCursorAt(1, 0); + eq('aa\n\ncc', cm.getValue()); +}, { value: 'aa\nbb\ncc'}); +testVim('blockwise_paste', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('', '3', 'j', 'l', 'y'); + cm.setCursor(0, 2); + // paste one char after the current cursor position + helpers.doKeys('p'); + eq('helhelo\nworwold\nfoofo\nbarba', cm.getValue()); + cm.setCursor(0, 0); + helpers.doKeys('v', '4', 'l', 'y'); + cm.setCursor(0, 0); + helpers.doKeys('', '3', 'j', 'p'); + eq('helheelhelo\norwold\noofo\narba', cm.getValue()); +}, { value: 'hello\nworld\nfoo\nbar'}); +testVim('blockwise_paste_long/short_line', function(cm, vim, helpers) { + // extend short lines in case of different line lengths. + cm.setCursor(0, 0); + helpers.doKeys('', 'j', 'j', 'y'); + cm.setCursor(0, 3); + helpers.doKeys('p'); + eq('hellho\nfoo f\nbar b', cm.getValue()); +}, { value: 'hello\nfoo\nbar'}); +testVim('blockwise_paste_cut_paste', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('', '2', 'j', 'x'); + cm.setCursor(0, 0); + helpers.doKeys('P'); + eq('cut\nand\npaste\nme', cm.getValue()); +}, { value: 'cut\nand\npaste\nme'}); +testVim('blockwise_paste_from_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('', '2', 'j', '"', 'a', 'y'); + cm.setCursor(0, 3); + helpers.doKeys('"', 'a', 'p'); + eq('foobfar\nhellho\nworlwd', cm.getValue()); +}, { value: 'foobar\nhello\nworld'}); +testVim('blockwise_paste_last_line', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('', '2', 'j', 'l', 'y'); + cm.setCursor(3, 0); + helpers.doKeys('p'); + eq('cut\nand\npaste\nmcue\n an\n pa', cm.getValue()); +}, { value: 'cut\nand\npaste\nme'}); + +testVim('S_visual', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('v', 'j', 'S'); + helpers.doKeys(''); + helpers.assertCursorAt(0, 0); + eq('\ncc', cm.getValue()); +}, { value: 'aa\nbb\ncc'}); + +testVim('d_/', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('match'); + helpers.doKeys('2', 'd', '/'); + helpers.assertCursorAt(0, 0); + eq('match \n next', cm.getValue()); + cm.openDialog = helpers.fakeOpenDialog('2'); + helpers.doKeys('d', ':'); + // TODO eq(' next', cm.getValue()); +}, { value: 'text match match \n next' }); +testVim('/ and n/N', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('match'); + helpers.doKeys('/'); + helpers.assertCursorAt(0, 11); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 6); + helpers.doKeys('N'); + helpers.assertCursorAt(0, 11); + + cm.setCursor(0, 0); + helpers.doKeys('2', '/'); + helpers.assertCursorAt(1, 6); +}, { value: 'match nope match \n nope Match' }); +testVim('/_case', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('Match'); + helpers.doKeys('/'); + helpers.assertCursorAt(1, 6); +}, { value: 'match nope match \n nope Match' }); +testVim('/_2_pcre', function(cm, vim, helpers) { + CodeMirror.Vim.setOption('pcre', true); + cm.openDialog = helpers.fakeOpenDialog('(word){2}'); + helpers.doKeys('/'); + helpers.assertCursorAt(1, 9); + helpers.doKeys('n'); + helpers.assertCursorAt(2, 1); +}, { value: 'word\n another wordword\n wordwordword\n' }); +testVim('/_2_nopcre', function(cm, vim, helpers) { + CodeMirror.Vim.setOption('pcre', false); + cm.openDialog = helpers.fakeOpenDialog('\\(word\\)\\{2}'); + helpers.doKeys('/'); + helpers.assertCursorAt(1, 9); + helpers.doKeys('n'); + helpers.assertCursorAt(2, 1); +}, { value: 'word\n another wordword\n wordwordword\n' }); +testVim('/_nongreedy', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('aa'); + helpers.doKeys('/'); + helpers.assertCursorAt(0, 4); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 3); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 0); +}, { value: 'aaa aa \n a aa'}); +testVim('?_nongreedy', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('aa'); + helpers.doKeys('?'); + helpers.assertCursorAt(1, 3); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 4); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 0); +}, { value: 'aaa aa \n a aa'}); +testVim('/_greedy', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('a+'); + helpers.doKeys('/'); + helpers.assertCursorAt(0, 4); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 1); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 3); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 0); +}, { value: 'aaa aa \n a aa'}); +testVim('?_greedy', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('a+'); + helpers.doKeys('?'); + helpers.assertCursorAt(1, 3); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 1); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 4); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 0); +}, { value: 'aaa aa \n a aa'}); +testVim('/_greedy_0_or_more', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('a*'); + helpers.doKeys('/'); + helpers.assertCursorAt(0, 3); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 4); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 5); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 0); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 1); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 0); +}, { value: 'aaa aa\n aa'}); +testVim('?_greedy_0_or_more', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('a*'); + helpers.doKeys('?'); + helpers.assertCursorAt(1, 1); + helpers.doKeys('n'); + helpers.assertCursorAt(1, 0); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 5); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 4); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 3); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 0); +}, { value: 'aaa aa\n aa'}); +testVim('? and n/N', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('match'); + helpers.doKeys('?'); + helpers.assertCursorAt(1, 6); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 11); + helpers.doKeys('N'); + helpers.assertCursorAt(1, 6); + + cm.setCursor(0, 0); + helpers.doKeys('2', '?'); + helpers.assertCursorAt(0, 11); +}, { value: 'match nope match \n nope Match' }); +testVim('*', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('*'); + helpers.assertCursorAt(0, 22); + + cm.setCursor(0, 9); + helpers.doKeys('2', '*'); + helpers.assertCursorAt(1, 8); +}, { value: 'nomatch match nomatch match \nnomatch Match' }); +testVim('*_no_word', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('*'); + helpers.assertCursorAt(0, 0); +}, { value: ' \n match \n' }); +testVim('*_symbol', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('*'); + helpers.assertCursorAt(1, 0); +}, { value: ' /}\n/} match \n' }); +testVim('#', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('#'); + helpers.assertCursorAt(1, 8); + + cm.setCursor(0, 9); + helpers.doKeys('2', '#'); + helpers.assertCursorAt(0, 22); +}, { value: 'nomatch match nomatch match \nnomatch Match' }); +testVim('*_seek', function(cm, vim, helpers) { + // Should skip over space and symbols. + cm.setCursor(0, 3); + helpers.doKeys('*'); + helpers.assertCursorAt(0, 22); +}, { value: ' := match nomatch match \nnomatch Match' }); +testVim('#', function(cm, vim, helpers) { + // Should skip over space and symbols. + cm.setCursor(0, 3); + helpers.doKeys('#'); + helpers.assertCursorAt(1, 8); +}, { value: ' := match nomatch match \nnomatch Match' }); +testVim('g*', function(cm, vim, helpers) { + cm.setCursor(0, 8); + helpers.doKeys('g', '*'); + helpers.assertCursorAt(0, 18); + cm.setCursor(0, 8); + helpers.doKeys('3', 'g', '*'); + helpers.assertCursorAt(1, 8); +}, { value: 'matches match alsoMatch\nmatchme matching' }); +testVim('g#', function(cm, vim, helpers) { + cm.setCursor(0, 8); + helpers.doKeys('g', '#'); + helpers.assertCursorAt(0, 0); + cm.setCursor(0, 8); + helpers.doKeys('3', 'g', '#'); + helpers.assertCursorAt(1, 0); +}, { value: 'matches match alsoMatch\nmatchme matching' }); +testVim('macro_insert', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'a', '0', 'i'); + cm.replaceRange('foo', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('q', '@', 'a'); + eq('foofoo', cm.getValue()); +}, { value: ''}); +testVim('macro_insert_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'a', '$', 'a'); + cm.replaceRange('larry.', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('a'); + cm.replaceRange('curly.', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('q'); + helpers.doKeys('a'); + cm.replaceRange('moe.', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('@', 'a'); + // At this point, the most recent edit should be the 2nd insert change + // inside the macro, i.e. "curly.". + helpers.doKeys('.'); + eq('larry.curly.moe.larry.curly.curly.', cm.getValue()); +}, { value: ''}); +testVim('macro_space', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('', ''); + helpers.assertCursorAt(0, 2); + helpers.doKeys('q', 'a', '', '', 'q'); + helpers.assertCursorAt(0, 4); + helpers.doKeys('@', 'a'); + helpers.assertCursorAt(0, 6); + helpers.doKeys('@', 'a'); + helpers.assertCursorAt(0, 8); +}, { value: 'one line of text.'}); +testVim('macro_t_search', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'a', 't', 'e', 'q'); + helpers.assertCursorAt(0, 1); + helpers.doKeys('l', '@', 'a'); + helpers.assertCursorAt(0, 6); + helpers.doKeys('l', ';'); + helpers.assertCursorAt(0, 12); +}, { value: 'one line of text.'}); +testVim('macro_f_search', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'b', 'f', 'e', 'q'); + helpers.assertCursorAt(0, 2); + helpers.doKeys('@', 'b'); + helpers.assertCursorAt(0, 7); + helpers.doKeys(';'); + helpers.assertCursorAt(0, 13); +}, { value: 'one line of text.'}); +testVim('macro_slash_search', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'c'); + cm.openDialog = helpers.fakeOpenDialog('e'); + helpers.doKeys('/', 'q'); + helpers.assertCursorAt(0, 2); + helpers.doKeys('@', 'c'); + helpers.assertCursorAt(0, 7); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 13); +}, { value: 'one line of text.'}); +testVim('macro_multislash_search', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'd'); + cm.openDialog = helpers.fakeOpenDialog('e'); + helpers.doKeys('/'); + cm.openDialog = helpers.fakeOpenDialog('t'); + helpers.doKeys('/', 'q'); + helpers.assertCursorAt(0, 12); + helpers.doKeys('@', 'd'); + helpers.assertCursorAt(0, 15); +}, { value: 'one line of text to rule them all.'}); +testVim('macro_parens', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'z', 'i'); + cm.replaceRange('(', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('e', 'a'); + cm.replaceRange(')', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('q'); + helpers.doKeys('w', '@', 'z'); + helpers.doKeys('w', '@', 'z'); + eq('(see) (spot) (run)', cm.getValue()); +}, { value: 'see spot run'}); +testVim('macro_overwrite', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'z', '0', 'i'); + cm.replaceRange('I ', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('q'); + helpers.doKeys('e'); + // Now replace the macro with something else. + helpers.doKeys('q', 'z', 'a'); + cm.replaceRange('.', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('q'); + helpers.doKeys('e', '@', 'z'); + helpers.doKeys('e', '@', 'z'); + eq('I see. spot. run.', cm.getValue()); +}, { value: 'see spot run'}); +testVim('macro_search_f', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'a', 'f', ' '); + helpers.assertCursorAt(0,3); + helpers.doKeys('q', '0'); + helpers.assertCursorAt(0,0); + helpers.doKeys('@', 'a'); + helpers.assertCursorAt(0,3); +}, { value: 'The quick brown fox jumped over the lazy dog.'}); +testVim('macro_search_2f', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'a', '2', 'f', ' '); + helpers.assertCursorAt(0,9); + helpers.doKeys('q', '0'); + helpers.assertCursorAt(0,0); + helpers.doKeys('@', 'a'); + helpers.assertCursorAt(0,9); +}, { value: 'The quick brown fox jumped over the lazy dog.'}); +testVim('yank_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('"', 'a', 'y', 'y'); + helpers.doKeys('j', '"', 'b', 'y', 'y'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+foo/.test(text)); + is(/b\s+bar/.test(text)); + }); + helpers.doKeys(':'); +}, { value: 'foo\nbar'}); +testVim('yank_visual_block', function(cm, vim, helpers) { + cm.setCursor(0, 1); + helpers.doKeys('', 'l', 'j', '"', 'a', 'y'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+oo\nar/.test(text)); + }); + helpers.doKeys(':'); +}, { value: 'foo\nbar'}); +testVim('yank_append_line_to_line_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('"', 'a', 'y', 'y'); + helpers.doKeys('j', '"', 'A', 'y', 'y'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+foo\nbar/.test(text)); + is(/"\s+foo\nbar/.test(text)); + }); + helpers.doKeys(':'); +}, { value: 'foo\nbar'}); +testVim('yank_append_word_to_word_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('"', 'a', 'y', 'w'); + helpers.doKeys('j', '"', 'A', 'y', 'w'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+foobar/.test(text)); + is(/"\s+foobar/.test(text)); + }); + helpers.doKeys(':'); +}, { value: 'foo\nbar'}); +testVim('yank_append_line_to_word_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('"', 'a', 'y', 'w'); + helpers.doKeys('j', '"', 'A', 'y', 'y'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+foo\nbar/.test(text)); + is(/"\s+foo\nbar/.test(text)); + }); + helpers.doKeys(':'); +}, { value: 'foo\nbar'}); +testVim('yank_append_word_to_line_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('"', 'a', 'y', 'y'); + helpers.doKeys('j', '"', 'A', 'y', 'w'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+foo\nbar/.test(text)); + is(/"\s+foo\nbar/.test(text)); + }); + helpers.doKeys(':'); +}, { value: 'foo\nbar'}); +testVim('macro_register', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('q', 'a', 'i'); + cm.replaceRange('gangnam', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('q'); + helpers.doKeys('q', 'b', 'o'); + cm.replaceRange('style', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('q'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/a\s+i/.test(text)); + is(/b\s+o/.test(text)); + }); + helpers.doKeys(':'); +}, { value: ''}); +testVim('._register', function(cm,vim,helpers) { + cm.setCursor(0,0); + helpers.doKeys('i'); + cm.replaceRange('foo',cm.getCursor()); + helpers.doKeys(''); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/\.\s+foo/.test(text)); + }); + helpers.doKeys(':'); +}, {value: ''}); +testVim(':_register', function(cm,vim,helpers) { + helpers.doEx('bar'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/:\s+bar/.test(text)); + }); + helpers.doKeys(':'); +}, {value: ''}); +testVim('search_register_escape', function(cm, vim, helpers) { + // Check that the register is restored if the user escapes rather than confirms. + cm.openDialog = helpers.fakeOpenDialog('waldo'); + helpers.doKeys('/'); + var onKeyDown; + var onKeyUp; + var KEYCODES = { + f: 70, + o: 79, + Esc: 27 + }; + cm.openDialog = function(template, callback, options) { + onKeyDown = options.onKeyDown; + onKeyUp = options.onKeyUp; + }; + var close = function() {}; + helpers.doKeys('/'); + // Fake some keyboard events coming in. + onKeyDown({keyCode: KEYCODES.f}, '', close); + onKeyUp({keyCode: KEYCODES.f}, '', close); + onKeyDown({keyCode: KEYCODES.o}, 'f', close); + onKeyUp({keyCode: KEYCODES.o}, 'f', close); + onKeyDown({keyCode: KEYCODES.o}, 'fo', close); + onKeyUp({keyCode: KEYCODES.o}, 'fo', close); + onKeyDown({keyCode: KEYCODES.Esc}, 'foo', close); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/waldo/.test(text)); + is(!/foo/.test(text)); + }); + helpers.doKeys(':'); +}, {value: ''}); +testVim('search_register', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('foo'); + helpers.doKeys('/'); + cm.openDialog = helpers.fakeOpenDialog('registers'); + cm.openNotification = helpers.fakeOpenNotification(function(text) { + is(/\/\s+foo/.test(text)); + }); + helpers.doKeys(':'); +}, {value: ''}); +testVim('search_history', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('this'); + helpers.doKeys('/'); + cm.openDialog = helpers.fakeOpenDialog('checks'); + helpers.doKeys('/'); + cm.openDialog = helpers.fakeOpenDialog('search'); + helpers.doKeys('/'); + cm.openDialog = helpers.fakeOpenDialog('history'); + helpers.doKeys('/'); + cm.openDialog = helpers.fakeOpenDialog('checks'); + helpers.doKeys('/'); + var onKeyDown; + var onKeyUp; + var query = ''; + var keyCodes = { + Up: 38, + Down: 40 + }; + cm.openDialog = function(template, callback, options) { + onKeyUp = options.onKeyUp; + onKeyDown = options.onKeyDown; + }; + var close = function(newVal) { + if (typeof newVal == 'string') query = newVal; + } + helpers.doKeys('/'); + onKeyDown({keyCode: keyCodes.Up}, query, close); + onKeyUp({keyCode: keyCodes.Up}, query, close); + eq(query, 'checks'); + onKeyDown({keyCode: keyCodes.Up}, query, close); + onKeyUp({keyCode: keyCodes.Up}, query, close); + eq(query, 'history'); + onKeyDown({keyCode: keyCodes.Up}, query, close); + onKeyUp({keyCode: keyCodes.Up}, query, close); + eq(query, 'search'); + onKeyDown({keyCode: keyCodes.Up}, query, close); + onKeyUp({keyCode: keyCodes.Up}, query, close); + eq(query, 'this'); + onKeyDown({keyCode: keyCodes.Down}, query, close); + onKeyUp({keyCode: keyCodes.Down}, query, close); + eq(query, 'search'); +}, {value: ''}); +testVim('exCommand_history', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('registers'); + helpers.doKeys(':'); + cm.openDialog = helpers.fakeOpenDialog('sort'); + helpers.doKeys(':'); + cm.openDialog = helpers.fakeOpenDialog('map'); + helpers.doKeys(':'); + cm.openDialog = helpers.fakeOpenDialog('invalid'); + helpers.doKeys(':'); + var onKeyDown; + var onKeyUp; + var input = ''; + var keyCodes = { + Up: 38, + Down: 40, + s: 115 + }; + cm.openDialog = function(template, callback, options) { + onKeyUp = options.onKeyUp; + onKeyDown = options.onKeyDown; + }; + var close = function(newVal) { + if (typeof newVal == 'string') input = newVal; + } + helpers.doKeys(':'); + onKeyDown({keyCode: keyCodes.Up}, input, close); + eq(input, 'invalid'); + onKeyDown({keyCode: keyCodes.Up}, input, close); + eq(input, 'map'); + onKeyDown({keyCode: keyCodes.Up}, input, close); + eq(input, 'sort'); + onKeyDown({keyCode: keyCodes.Up}, input, close); + eq(input, 'registers'); + onKeyDown({keyCode: keyCodes.s}, '', close); + input = 's'; + onKeyDown({keyCode: keyCodes.Up}, input, close); + eq(input, 'sort'); +}, {value: ''}); +testVim('search_clear', function(cm, vim, helpers) { + var onKeyDown; + var input = ''; + var keyCodes = { + Ctrl: 17, + u: 85 + }; + cm.openDialog = function(template, callback, options) { + onKeyDown = options.onKeyDown; + }; + var close = function(newVal) { + if (typeof newVal == 'string') input = newVal; + } + helpers.doKeys('/'); + input = 'foo'; + onKeyDown({keyCode: keyCodes.Ctrl}, input, close); + onKeyDown({keyCode: keyCodes.u, ctrlKey: true}, input, close); + eq(input, ''); +}); +testVim('exCommand_clear', function(cm, vim, helpers) { + var onKeyDown; + var input = ''; + var keyCodes = { + Ctrl: 17, + u: 85 + }; + cm.openDialog = function(template, callback, options) { + onKeyDown = options.onKeyDown; + }; + var close = function(newVal) { + if (typeof newVal == 'string') input = newVal; + } + helpers.doKeys(':'); + input = 'foo'; + onKeyDown({keyCode: keyCodes.Ctrl}, input, close); + onKeyDown({keyCode: keyCodes.u, ctrlKey: true}, input, close); + eq(input, ''); +}); +testVim('.', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('2', 'd', 'w'); + helpers.doKeys('.'); + eq('5 6', cm.getValue()); +}, { value: '1 2 3 4 5 6'}); +testVim('._repeat', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('2', 'd', 'w'); + helpers.doKeys('3', '.'); + eq('6', cm.getValue()); +}, { value: '1 2 3 4 5 6'}); +testVim('._insert', function(cm, vim, helpers) { + helpers.doKeys('i'); + cm.replaceRange('test', cm.getCursor()); + helpers.doKeys(''); + helpers.doKeys('.'); + eq('testestt', cm.getValue()); + helpers.assertCursorAt(0, 6); +}, { value: ''}); +testVim('._insert_repeat', function(cm, vim, helpers) { + helpers.doKeys('i'); + cm.replaceRange('test', cm.getCursor()); + cm.setCursor(0, 4); + helpers.doKeys(''); + helpers.doKeys('2', '.'); + eq('testesttestt', cm.getValue()); + helpers.assertCursorAt(0, 10); +}, { value: ''}); +testVim('._repeat_insert', function(cm, vim, helpers) { + helpers.doKeys('3', 'i'); + cm.replaceRange('te', cm.getCursor()); + cm.setCursor(0, 2); + helpers.doKeys(''); + helpers.doKeys('.'); + eq('tetettetetee', cm.getValue()); + helpers.assertCursorAt(0, 10); +}, { value: ''}); +testVim('._insert_o', function(cm, vim, helpers) { + helpers.doKeys('o'); + cm.replaceRange('z', cm.getCursor()); + cm.setCursor(1, 1); + helpers.doKeys(''); + helpers.doKeys('.'); + eq('\nz\nz', cm.getValue()); + helpers.assertCursorAt(2, 0); +}, { value: ''}); +testVim('._insert_o_repeat', function(cm, vim, helpers) { + helpers.doKeys('o'); + cm.replaceRange('z', cm.getCursor()); + helpers.doKeys(''); + cm.setCursor(1, 0); + helpers.doKeys('2', '.'); + eq('\nz\nz\nz', cm.getValue()); + helpers.assertCursorAt(3, 0); +}, { value: ''}); +testVim('._insert_o_indent', function(cm, vim, helpers) { + helpers.doKeys('o'); + cm.replaceRange('z', cm.getCursor()); + helpers.doKeys(''); + cm.setCursor(1, 2); + helpers.doKeys('.'); + eq('{\n z\n z', cm.getValue()); + helpers.assertCursorAt(2, 2); +}, { value: '{'}); +testVim('._insert_cw', function(cm, vim, helpers) { + helpers.doKeys('c', 'w'); + cm.replaceRange('test', cm.getCursor()); + helpers.doKeys(''); + cm.setCursor(0, 3); + helpers.doKeys('2', 'l'); + helpers.doKeys('.'); + eq('test test word3', cm.getValue()); + helpers.assertCursorAt(0, 8); +}, { value: 'word1 word2 word3' }); +testVim('._insert_cw_repeat', function(cm, vim, helpers) { + // For some reason, repeat cw in desktop VIM will does not repeat insert mode + // changes. Will conform to that behavior. + helpers.doKeys('c', 'w'); + cm.replaceRange('test', cm.getCursor()); + helpers.doKeys(''); + cm.setCursor(0, 4); + helpers.doKeys('l'); + helpers.doKeys('2', '.'); + eq('test test', cm.getValue()); + helpers.assertCursorAt(0, 8); +}, { value: 'word1 word2 word3' }); +testVim('._delete', function(cm, vim, helpers) { + cm.setCursor(0, 5); + helpers.doKeys('i'); + helpers.doInsertModeKeys('Backspace'); + helpers.doKeys(''); + helpers.doKeys('.'); + eq('zace', cm.getValue()); + helpers.assertCursorAt(0, 1); +}, { value: 'zabcde'}); +testVim('._delete_repeat', function(cm, vim, helpers) { + cm.setCursor(0, 6); + helpers.doKeys('i'); + helpers.doInsertModeKeys('Backspace'); + helpers.doKeys(''); + helpers.doKeys('2', '.'); + eq('zzce', cm.getValue()); + helpers.assertCursorAt(0, 1); +}, { value: 'zzabcde'}); +testVim('._visual_>', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('V', 'j', '>'); + cm.setCursor(2, 0) + helpers.doKeys('.'); + eq(' 1\n 2\n 3\n 4', cm.getValue()); + helpers.assertCursorAt(2, 2); +}, { value: '1\n2\n3\n4'}); +testVim('f;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('f', 'x'); + helpers.doKeys(';'); + helpers.doKeys('2', ';'); + eq(9, cm.getCursor().ch); +}, { value: '01x3xx678x'}); +testVim('F;', function(cm, vim, helpers) { + cm.setCursor(0, 8); + helpers.doKeys('F', 'x'); + helpers.doKeys(';'); + helpers.doKeys('2', ';'); + eq(2, cm.getCursor().ch); +}, { value: '01x3xx6x8x'}); +testVim('t;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('t', 'x'); + helpers.doKeys(';'); + helpers.doKeys('2', ';'); + eq(8, cm.getCursor().ch); +}, { value: '01x3xx678x'}); +testVim('T;', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('T', 'x'); + helpers.doKeys(';'); + helpers.doKeys('2', ';'); + eq(2, cm.getCursor().ch); +}, { value: '0xx3xx678x'}); +testVim('f,', function(cm, vim, helpers) { + cm.setCursor(0, 6); + helpers.doKeys('f', 'x'); + helpers.doKeys(','); + helpers.doKeys('2', ','); + eq(2, cm.getCursor().ch); +}, { value: '01x3xx678x'}); +testVim('F,', function(cm, vim, helpers) { + cm.setCursor(0, 3); + helpers.doKeys('F', 'x'); + helpers.doKeys(','); + helpers.doKeys('2', ','); + eq(9, cm.getCursor().ch); +}, { value: '01x3xx678x'}); +testVim('t,', function(cm, vim, helpers) { + cm.setCursor(0, 6); + helpers.doKeys('t', 'x'); + helpers.doKeys(','); + helpers.doKeys('2', ','); + eq(3, cm.getCursor().ch); +}, { value: '01x3xx678x'}); +testVim('T,', function(cm, vim, helpers) { + cm.setCursor(0, 4); + helpers.doKeys('T', 'x'); + helpers.doKeys(','); + helpers.doKeys('2', ','); + eq(8, cm.getCursor().ch); +}, { value: '01x3xx67xx'}); +testVim('fd,;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('f', '4'); + cm.setCursor(0, 0); + helpers.doKeys('d', ';'); + eq('56789', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 9); + helpers.doKeys('d', ','); + eq('01239', cm.getValue()); +}, { value: '0123456789'}); +testVim('Fd,;', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('F', '4'); + cm.setCursor(0, 9); + helpers.doKeys('d', ';'); + eq('01239', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 0); + helpers.doKeys('d', ','); + eq('56789', cm.getValue()); +}, { value: '0123456789'}); +testVim('td,;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('t', '4'); + cm.setCursor(0, 0); + helpers.doKeys('d', ';'); + eq('456789', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 9); + helpers.doKeys('d', ','); + eq('012349', cm.getValue()); +}, { value: '0123456789'}); +testVim('Td,;', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('T', '4'); + cm.setCursor(0, 9); + helpers.doKeys('d', ';'); + eq('012349', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 0); + helpers.doKeys('d', ','); + eq('456789', cm.getValue()); +}, { value: '0123456789'}); +testVim('fc,;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('f', '4'); + cm.setCursor(0, 0); + helpers.doKeys('c', ';', ''); + eq('56789', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 9); + helpers.doKeys('c', ','); + eq('01239', cm.getValue()); +}, { value: '0123456789'}); +testVim('Fc,;', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('F', '4'); + cm.setCursor(0, 9); + helpers.doKeys('c', ';', ''); + eq('01239', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 0); + helpers.doKeys('c', ','); + eq('56789', cm.getValue()); +}, { value: '0123456789'}); +testVim('tc,;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('t', '4'); + cm.setCursor(0, 0); + helpers.doKeys('c', ';', ''); + eq('456789', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 9); + helpers.doKeys('c', ','); + eq('012349', cm.getValue()); +}, { value: '0123456789'}); +testVim('Tc,;', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('T', '4'); + cm.setCursor(0, 9); + helpers.doKeys('c', ';', ''); + eq('012349', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 0); + helpers.doKeys('c', ','); + eq('456789', cm.getValue()); +}, { value: '0123456789'}); +testVim('fy,;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('f', '4'); + cm.setCursor(0, 0); + helpers.doKeys('y', ';', 'P'); + eq('012340123456789', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 9); + helpers.doKeys('y', ',', 'P'); + eq('012345678456789', cm.getValue()); +}, { value: '0123456789'}); +testVim('Fy,;', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('F', '4'); + cm.setCursor(0, 9); + helpers.doKeys('y', ';', 'p'); + eq('012345678945678', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 0); + helpers.doKeys('y', ',', 'P'); + eq('012340123456789', cm.getValue()); +}, { value: '0123456789'}); +testVim('ty,;', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys('t', '4'); + cm.setCursor(0, 0); + helpers.doKeys('y', ';', 'P'); + eq('01230123456789', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 9); + helpers.doKeys('y', ',', 'p'); + eq('01234567895678', cm.getValue()); +}, { value: '0123456789'}); +testVim('Ty,;', function(cm, vim, helpers) { + cm.setCursor(0, 9); + helpers.doKeys('T', '4'); + cm.setCursor(0, 9); + helpers.doKeys('y', ';', 'p'); + eq('01234567895678', cm.getValue()); + helpers.doKeys('u'); + cm.setCursor(0, 0); + helpers.doKeys('y', ',', 'P'); + eq('01230123456789', cm.getValue()); +}, { value: '0123456789'}); +testVim('HML', function(cm, vim, helpers) { + var lines = 35; + var textHeight = cm.defaultTextHeight(); + cm.setSize(600, lines*textHeight); + cm.setCursor(120, 0); + cm.refresh(); //ace! + helpers.doKeys('H'); + helpers.assertCursorAt(86, 2); + helpers.doKeys('L'); + helpers.assertCursorAt(120, 4); + helpers.doKeys('M'); + helpers.assertCursorAt(103,4); +}, { value: (function(){ + var lines = new Array(100); + var upper = ' xx\n'; + var lower = ' xx\n'; + upper = lines.join(upper); + lower = lines.join(lower); + return upper + lower; +})()}); + +var zVals = []; +forEach(['zb','zz','zt','z-','z.','z'], function(e, idx){ + var lineNum = 250; + var lines = 35; + testVim(e, function(cm, vim, helpers) { + var k1 = e[0]; + var k2 = e.substring(1); + var textHeight = cm.defaultTextHeight(); + cm.setSize(600, lines*textHeight); + cm.setCursor(lineNum, 0); + helpers.doKeys(k1, k2); + zVals[idx] = cm.getScrollInfo().top; + }, { value: (function(){ + return new Array(500).join('\n'); + })()}); +}); +testVim('zb', function(cm, vim, helpers){ + eq(zVals[2], zVals[5]); +}); + +var moveTillCharacterSandbox = + 'The quick brown fox \n' + 'jumped over the lazy dog.' +testVim('moveTillCharacter', function(cm, vim, helpers){ + cm.setCursor(0, 0); + // Search for the 'q'. + cm.openDialog = helpers.fakeOpenDialog('q'); + helpers.doKeys('/'); + eq(4, cm.getCursor().ch); + // Jump to just before the first o in the list. + helpers.doKeys('t'); + helpers.doKeys('o'); + eq('The quick brown fox \n', cm.getValue()); + // Delete that one character. + helpers.doKeys('d'); + helpers.doKeys('t'); + helpers.doKeys('o'); + eq('The quick bown fox \n', cm.getValue()); + // Delete everything until the next 'o'. + helpers.doKeys('.'); + eq('The quick box \n', cm.getValue()); + // An unmatched character should have no effect. + helpers.doKeys('d'); + helpers.doKeys('t'); + helpers.doKeys('q'); + eq('The quick box \n', cm.getValue()); + // Matches should only be possible on single lines. + helpers.doKeys('d'); + helpers.doKeys('t'); + helpers.doKeys('z'); + eq('The quick box \n', cm.getValue()); + // After all that, the search for 'q' should still be active, so the 'N' command + // can run it again in reverse. Use that to delete everything back to the 'q'. + helpers.doKeys('d'); + helpers.doKeys('N'); + eq('The ox \n', cm.getValue()); + eq(4, cm.getCursor().ch); +}, { value: moveTillCharacterSandbox}); +testVim('searchForPipe', function(cm, vim, helpers){ + CodeMirror.Vim.setOption('pcre', false); + cm.setCursor(0, 0); + // Search for the '|'. + cm.openDialog = helpers.fakeOpenDialog('|'); + helpers.doKeys('/'); + eq(4, cm.getCursor().ch); +}, { value: 'this|that'}); + + +var scrollMotionSandbox = + '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n' + '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n' + '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n' + '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'; +testVim('scrollMotion', function(cm, vim, helpers){ + var prevCursor, prevScrollInfo; + cm.setCursor(0, 0); + // ctrl-y at the top of the file should have no effect. + helpers.doKeys(''); + eq(0, cm.getCursor().line); + prevScrollInfo = cm.getScrollInfo(); + helpers.doKeys(''); + eq(1, cm.getCursor().line); + is(prevScrollInfo.top < cm.getScrollInfo().top); + // Jump to the end of the sandbox. + cm.setCursor(1000, 0); + cm.refresh(); //ace! + prevCursor = cm.getCursor(); + // ctrl-e at the bottom of the file should have no effect. + helpers.doKeys(''); + eq(prevCursor.line, cm.getCursor().line); + cm.refresh(); //ace! + prevScrollInfo = cm.getScrollInfo(); + helpers.doKeys(''); + eq(prevCursor.line - 1, cm.getCursor().line, "Y"); + is(prevScrollInfo.top > cm.getScrollInfo().top); +}, { value: scrollMotionSandbox}); + +var squareBracketMotionSandbox = ''+ + '({\n'+//0 + ' ({\n'+//11 + ' /*comment {\n'+//2 + ' */(\n'+//3 + '#else \n'+//4 + ' /* )\n'+//5 + '#if }\n'+//6 + ' )}*/\n'+//7 + ')}\n'+//8 + '{}\n'+//9 + '#else {{\n'+//10 + '{}\n'+//11 + '}\n'+//12 + '{\n'+//13 + '#endif\n'+//14 + '}\n'+//15 + '}\n'+//16 + '#else';//17 +testVim('[[, ]]', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys(']', ']'); + helpers.assertCursorAt(9,0); + helpers.doKeys('2', ']', ']'); + helpers.assertCursorAt(13,0); + helpers.doKeys(']', ']'); + helpers.assertCursorAt(17,0); + helpers.doKeys('[', '['); + helpers.assertCursorAt(13,0); + helpers.doKeys('2', '[', '['); + helpers.assertCursorAt(9,0); + helpers.doKeys('[', '['); + helpers.assertCursorAt(0,0); +}, { value: squareBracketMotionSandbox}); +testVim('[], ][', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doKeys(']', '['); + helpers.assertCursorAt(12,0); + helpers.doKeys('2', ']', '['); + helpers.assertCursorAt(16,0); + helpers.doKeys(']', '['); + helpers.assertCursorAt(17,0); + helpers.doKeys('[', ']'); + helpers.assertCursorAt(16,0); + helpers.doKeys('2', '[', ']'); + helpers.assertCursorAt(12,0); + helpers.doKeys('[', ']'); + helpers.assertCursorAt(0,0); +}, { value: squareBracketMotionSandbox}); +testVim('[{, ]}', function(cm, vim, helpers) { + cm.setCursor(4, 10); + helpers.doKeys('[', '{'); + helpers.assertCursorAt(2,12); + helpers.doKeys('2', '[', '{'); + helpers.assertCursorAt(0,1); + cm.setCursor(4, 10); + helpers.doKeys(']', '}'); + helpers.assertCursorAt(6,11); + helpers.doKeys('2', ']', '}'); + helpers.assertCursorAt(8,1); + cm.setCursor(0,1); + helpers.doKeys(']', '}'); + helpers.assertCursorAt(8,1); + helpers.doKeys('[', '{'); + helpers.assertCursorAt(0,1); +}, { value: squareBracketMotionSandbox}); +testVim('[(, ])', function(cm, vim, helpers) { + cm.setCursor(4, 10); + helpers.doKeys('[', '('); + helpers.assertCursorAt(3,14); + helpers.doKeys('2', '[', '('); + helpers.assertCursorAt(0,0); + cm.setCursor(4, 10); + helpers.doKeys(']', ')'); + helpers.assertCursorAt(5,11); + helpers.doKeys('2', ']', ')'); + helpers.assertCursorAt(8,0); + helpers.doKeys('[', '('); + helpers.assertCursorAt(0,0); + helpers.doKeys(']', ')'); + helpers.assertCursorAt(8,0); +}, { value: squareBracketMotionSandbox}); +testVim('[*, ]*, [/, ]/', function(cm, vim, helpers) { + forEach(['*', '/'], function(key){ + cm.setCursor(7, 0); + helpers.doKeys('2', '[', key); + helpers.assertCursorAt(2,2); + helpers.doKeys('2', ']', key); + helpers.assertCursorAt(7,5); + }); +}, { value: squareBracketMotionSandbox}); +testVim('[#, ]#', function(cm, vim, helpers) { + cm.setCursor(10, 3); + helpers.doKeys('2', '[', '#'); + helpers.assertCursorAt(4,0); + helpers.doKeys('5', ']', '#'); + helpers.assertCursorAt(17,0); + cm.setCursor(10, 3); + helpers.doKeys(']', '#'); + helpers.assertCursorAt(14,0); +}, { value: squareBracketMotionSandbox}); +testVim('[m, ]m, [M, ]M', function(cm, vim, helpers) { + cm.setCursor(11, 0); + helpers.doKeys('[', 'm'); + helpers.assertCursorAt(10,7); + helpers.doKeys('4', '[', 'm'); + helpers.assertCursorAt(1,3); + helpers.doKeys('5', ']', 'm'); + helpers.assertCursorAt(11,0); + helpers.doKeys('[', 'M'); + helpers.assertCursorAt(9,1); + helpers.doKeys('3', ']', 'M'); + helpers.assertCursorAt(15,0); + helpers.doKeys('5', '[', 'M'); + helpers.assertCursorAt(7,3); +}, { value: squareBracketMotionSandbox}); + +// Ex mode tests +testVim('ex_go_to_line', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doEx('4'); + helpers.assertCursorAt(3, 0); +}, { value: 'a\nb\nc\nd\ne\n'}); +testVim('ex_write', function(cm, vim, helpers) { + var tmp = CodeMirror.commands.save; + var written; + var actualCm; + CodeMirror.commands.save = function(cm) { + written = true; + actualCm = cm; + }; + // Test that w, wr, wri ... write all trigger :write. + var command = 'write'; + for (var i = 1; i < command.length; i++) { + written = false; + actualCm = null; + helpers.doEx(command.substring(0, i)); + eq(written, true); + eq(actualCm, cm); + } + CodeMirror.commands.save = tmp; +}); +testVim('ex_sort', function(cm, vim, helpers) { + helpers.doEx('sort'); + eq('Z\na\nb\nc\nd', cm.getValue()); +}, { value: 'b\nZ\nd\nc\na'}); +testVim('ex_sort_reverse', function(cm, vim, helpers) { + helpers.doEx('sort!'); + eq('d\nc\nb\na', cm.getValue()); +}, { value: 'b\nd\nc\na'}); +testVim('ex_sort_range', function(cm, vim, helpers) { + helpers.doEx('2,3sort'); + eq('b\nc\nd\na', cm.getValue()); +}, { value: 'b\nd\nc\na'}); +testVim('ex_sort_oneline', function(cm, vim, helpers) { + helpers.doEx('2sort'); + // Expect no change. + eq('b\nd\nc\na', cm.getValue()); +}, { value: 'b\nd\nc\na'}); +testVim('ex_sort_ignoreCase', function(cm, vim, helpers) { + helpers.doEx('sort i'); + eq('a\nb\nc\nd\nZ', cm.getValue()); +}, { value: 'b\nZ\nd\nc\na'}); +testVim('ex_sort_unique', function(cm, vim, helpers) { + helpers.doEx('sort u'); + eq('Z\na\nb\nc\nd', cm.getValue()); +}, { value: 'b\nZ\na\na\nd\na\nc\na'}); +testVim('ex_sort_decimal', function(cm, vim, helpers) { + helpers.doEx('sort d'); + eq('d3\n s5\n6\n.9', cm.getValue()); +}, { value: '6\nd3\n s5\n.9'}); +testVim('ex_sort_decimal_negative', function(cm, vim, helpers) { + helpers.doEx('sort d'); + eq('z-9\nd3\n s5\n6\n.9', cm.getValue()); +}, { value: '6\nd3\n s5\n.9\nz-9'}); +testVim('ex_sort_decimal_reverse', function(cm, vim, helpers) { + helpers.doEx('sort! d'); + eq('.9\n6\n s5\nd3', cm.getValue()); +}, { value: '6\nd3\n s5\n.9'}); +testVim('ex_sort_hex', function(cm, vim, helpers) { + helpers.doEx('sort x'); + eq(' s5\n6\n.9\n&0xB\nd3', cm.getValue()); +}, { value: '6\nd3\n s5\n&0xB\n.9'}); +testVim('ex_sort_octal', function(cm, vim, helpers) { + helpers.doEx('sort o'); + eq('.8\n.9\nd3\n s5\n6', cm.getValue()); +}, { value: '6\nd3\n s5\n.9\n.8'}); +testVim('ex_sort_decimal_mixed', function(cm, vim, helpers) { + helpers.doEx('sort d'); + eq('y\nz\nc1\nb2\na3', cm.getValue()); +}, { value: 'a3\nz\nc1\ny\nb2'}); +testVim('ex_sort_decimal_mixed_reverse', function(cm, vim, helpers) { + helpers.doEx('sort! d'); + eq('a3\nb2\nc1\nz\ny', cm.getValue()); +}, { value: 'a3\nz\nc1\ny\nb2'}); +// test for :global command +testVim('ex_global', function(cm, vim, helpers) { + cm.setCursor(0, 0); + helpers.doEx('g/one/s//two'); + eq('two two\n two two\n two two', cm.getValue()); + helpers.doEx('1,2g/two/s//one'); + eq('one one\n one one\n two two', cm.getValue()); +}, {value: 'one one\n one one\n one one'}); +testVim('ex_global_confirm', function(cm, vim, helpers) { + cm.setCursor(0, 0); + var onKeyDown; + var openDialogSave = cm.openDialog; + var KEYCODES = { + a: 65, + n: 78, + q: 81, + y: 89 + }; + // Intercept the ex command, 'global' + cm.openDialog = function(template, callback, options) { + // Intercept the prompt for the embedded ex command, 'substitute' + cm.openDialog = function(template, callback, options) { + onKeyDown = options.onKeyDown; + }; + callback('g/one/s//two/gc'); + }; + helpers.doKeys(':'); + var close = function() {}; + onKeyDown({keyCode: KEYCODES.n}, '', close); + onKeyDown({keyCode: KEYCODES.y}, '', close); + onKeyDown({keyCode: KEYCODES.a}, '', close); + onKeyDown({keyCode: KEYCODES.q}, '', close); + onKeyDown({keyCode: KEYCODES.y}, '', close); + eq('one two\n two two\n one one\n two one\n one one', cm.getValue()); +}, {value: 'one one\n one one\n one one\n one one\n one one'}); +// Basic substitute tests. +testVim('ex_substitute_same_line', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doEx('s/one/two/g'); + eq('one one\n two two', cm.getValue()); +}, { value: 'one one\n one one'}); +testVim('ex_substitute_full_file', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doEx('%s/one/two/g'); + eq('two two\n two two', cm.getValue()); +}, { value: 'one one\n one one'}); +testVim('ex_substitute_input_range', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doEx('1,3s/\\d/0/g'); + eq('0\n0\n0\n4', cm.getValue()); +}, { value: '1\n2\n3\n4' }); +testVim('ex_substitute_visual_range', function(cm, vim, helpers) { + cm.setCursor(1, 0); + // Set last visual mode selection marks '< and '> at lines 2 and 4 + helpers.doKeys('V', '2', 'j', 'v'); + helpers.doEx('\'<,\'>s/\\d/0/g'); + eq('1\n0\n0\n0\n5', cm.getValue()); +}, { value: '1\n2\n3\n4\n5' }); +testVim('ex_substitute_empty_query', function(cm, vim, helpers) { + // If the query is empty, use last query. + cm.setCursor(1, 0); + cm.openDialog = helpers.fakeOpenDialog('1'); + helpers.doKeys('/'); + helpers.doEx('s//b/g'); + eq('abb ab2 ab3', cm.getValue()); +}, { value: 'a11 a12 a13' }); +testVim('ex_substitute_javascript', function(cm, vim, helpers) { + CodeMirror.Vim.setOption('pcre', false); + cm.setCursor(1, 0); + // Throw all the things that javascript likes to treat as special values + // into the replace part. All should be literal (this is VIM). + helpers.doEx('s/\\(\\d+\\)/$$ $\' $` $& \\1/g') + eq('a $$ $\' $` $& 0 b', cm.getValue()); +}, { value: 'a 0 b' }); +testVim('ex_substitute_empty_arguments', function(cm,vim,helpers) { + cm.setCursor(0, 0); + helpers.doEx('s/a/b/g'); + cm.setCursor(1, 0); + helpers.doEx('s'); + eq('b b\nb a', cm.getValue()); +}, {value: 'a a\na a'}); + +// More complex substitute tests that test both pcre and nopcre options. +function testSubstitute(name, options) { + testVim(name + '_pcre', function(cm, vim, helpers) { + cm.setCursor(1, 0); + CodeMirror.Vim.setOption('pcre', true); + helpers.doEx(options.expr); + eq(options.expectedValue, cm.getValue()); + }, options); + // If no noPcreExpr is defined, assume that it's the same as the expr. + var noPcreExpr = options.noPcreExpr ? options.noPcreExpr : options.expr; + testVim(name + '_nopcre', function(cm, vim, helpers) { + cm.setCursor(1, 0); + CodeMirror.Vim.setOption('pcre', false); + helpers.doEx(noPcreExpr); + eq(options.expectedValue, cm.getValue()); + }, options); +} +testSubstitute('ex_substitute_capture', { + value: 'a11 a12 a13', + expectedValue: 'a1111 a1212 a1313', + // $n is a backreference + expr: 's/(\\d+)/$1$1/g', + // \n is a backreference. + noPcreExpr: 's/\\(\\d+\\)/\\1\\1/g'}); +testSubstitute('ex_substitute_capture2', { + value: 'a 0 b', + expectedValue: 'a $00 b', + expr: 's/(\\d+)/$$$1$1/g', + noPcreExpr: 's/\\(\\d+\\)/$\\1\\1/g'}); +testSubstitute('ex_substitute_nocapture', { + value: 'a11 a12 a13', + expectedValue: 'a$1$1 a$1$1 a$1$1', + expr: 's/(\\d+)/$$1$$1/g', + noPcreExpr: 's/\\(\\d+\\)/$1$1/g'}); +testSubstitute('ex_substitute_nocapture2', { + value: 'a 0 b', + expectedValue: 'a $10 b', + expr: 's/(\\d+)/$$1$1/g', + noPcreExpr: 's/\\(\\d+\\)/\\$1\\1/g'}); +testSubstitute('ex_substitute_nocapture', { + value: 'a b c', + expectedValue: 'a $ c', + expr: 's/b/$$/', + noPcreExpr: 's/b/$/'}); +testSubstitute('ex_substitute_slash_regex', { + value: 'one/two \n three/four', + expectedValue: 'one|two \n three|four', + expr: '%s/\\//|'}); +testSubstitute('ex_substitute_pipe_regex', { + value: 'one|two \n three|four', + expectedValue: 'one,two \n three,four', + expr: '%s/\\|/,/', + noPcreExpr: '%s/|/,/'}); +testSubstitute('ex_substitute_or_regex', { + value: 'one|two \n three|four', + expectedValue: 'ana|twa \n thraa|faar', + expr: '%s/o|e|u/a/g', + noPcreExpr: '%s/o\\|e\\|u/a/g'}); +testSubstitute('ex_substitute_or_word_regex', { + value: 'one|two \n three|four', + expectedValue: 'five|five \n three|four', + expr: '%s/(one|two)/five/g', + noPcreExpr: '%s/\\(one\\|two\\)/five/g'}); +testSubstitute('ex_substitute_backslashslash_regex', { + value: 'one\\two \n three\\four', + expectedValue: 'one,two \n three,four', + expr: '%s/\\\\/,'}); +testSubstitute('ex_substitute_slash_replacement', { + value: 'one,two \n three,four', + expectedValue: 'one/two \n three/four', + expr: '%s/,/\\/'}); +testSubstitute('ex_substitute_backslash_replacement', { + value: 'one,two \n three,four', + expectedValue: 'one\\two \n three\\four', + expr: '%s/,/\\\\/g'}); +testSubstitute('ex_substitute_multibackslash_replacement', { + value: 'one,two \n three,four', + expectedValue: 'one\\\\\\\\two \n three\\\\\\\\four', // 2*8 backslashes. + expr: '%s/,/\\\\\\\\\\\\\\\\/g'}); // 16 backslashes. +testSubstitute('ex_substitute_braces_word', { + value: 'ababab abb ab{2}', + expectedValue: 'ab abb ab{2}', + expr: '%s/(ab){2}//g', + noPcreExpr: '%s/\\(ab\\)\\{2\\}//g'}); +testSubstitute('ex_substitute_braces_range', { + value: 'a aa aaa aaaa', + expectedValue: 'a a', + expr: '%s/a{2,3}//g', + noPcreExpr: '%s/a\\{2,3\\}//g'}); +testSubstitute('ex_substitute_braces_literal', { + value: 'ababab abb ab{2}', + expectedValue: 'ababab abb ', + expr: '%s/ab\\{2\\}//g', + noPcreExpr: '%s/ab{2}//g'}); +testSubstitute('ex_substitute_braces_char', { + value: 'ababab abb ab{2}', + expectedValue: 'ababab ab{2}', + expr: '%s/ab{2}//g', + noPcreExpr: '%s/ab\\{2\\}//g'}); +testSubstitute('ex_substitute_braces_no_escape', { + value: 'ababab abb ab{2}', + expectedValue: 'ababab ab{2}', + expr: '%s/ab{2}//g', + noPcreExpr: '%s/ab\\{2}//g'}); +testSubstitute('ex_substitute_count', { + value: '1\n2\n3\n4', + expectedValue: '1\n0\n0\n4', + expr: 's/\\d/0/i 2'}); +testSubstitute('ex_substitute_count_with_range', { + value: '1\n2\n3\n4', + expectedValue: '1\n2\n0\n0', + expr: '1,3s/\\d/0/ 3'}); +testSubstitute('ex_substitute_not_global', { + value: 'aaa\nbaa\ncaa', + expectedValue: 'xaa\nbxa\ncxa', + expr: '%s/a/x/'}); +function testSubstituteConfirm(name, command, initialValue, expectedValue, keys, finalPos) { + testVim(name, function(cm, vim, helpers) { + var savedOpenDialog = cm.openDialog; + var savedKeyName = CodeMirror.keyName; + var onKeyDown; + var recordedCallback; + var closed = true; // Start out closed, set false on second openDialog. + function close() { + closed = true; + } + // First openDialog should save callback. + cm.openDialog = function(template, callback, options) { + recordedCallback = callback; + } + // Do first openDialog. + helpers.doKeys(':'); + // Second openDialog should save keyDown handler. + cm.openDialog = function(template, callback, options) { + onKeyDown = options.onKeyDown; + closed = false; + }; + // Return the command to Vim and trigger second openDialog. + recordedCallback(command); + // The event should really use keyCode, but here just mock it out and use + // key and replace keyName to just return key. + CodeMirror.keyName = function (e) { return e.key; } + keys = keys.toUpperCase(); + for (var i = 0; i < keys.length; i++) { + is(!closed); + onKeyDown({ key: keys.charAt(i) }, '', close); + } + try { + eq(expectedValue, cm.getValue()); + helpers.assertCursorAt(finalPos); + is(closed); + } catch(e) { + throw e + } finally { + // Restore overriden functions. + CodeMirror.keyName = savedKeyName; + cm.openDialog = savedOpenDialog; + } + }, { value: initialValue }); +}; +testSubstituteConfirm('ex_substitute_confirm_emptydoc', + '%s/x/b/c', '', '', '', makeCursor(0, 0)); +testSubstituteConfirm('ex_substitute_confirm_nomatch', + '%s/x/b/c', 'ba a\nbab', 'ba a\nbab', '', makeCursor(0, 0)); +testSubstituteConfirm('ex_substitute_confirm_accept', + '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'yyy', makeCursor(1, 1)); +testSubstituteConfirm('ex_substitute_confirm_random_keys', + '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'ysdkywerty', makeCursor(1, 1)); +testSubstituteConfirm('ex_substitute_confirm_some', + '%s/a/b/cg', 'ba a\nbab', 'bb a\nbbb', 'yny', makeCursor(1, 1)); +testSubstituteConfirm('ex_substitute_confirm_all', + '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'a', makeCursor(1, 1)); +testSubstituteConfirm('ex_substitute_confirm_accept_then_all', + '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'ya', makeCursor(1, 1)); +testSubstituteConfirm('ex_substitute_confirm_quit', + '%s/a/b/cg', 'ba a\nbab', 'bb a\nbab', 'yq', makeCursor(0, 3)); +testSubstituteConfirm('ex_substitute_confirm_last', + '%s/a/b/cg', 'ba a\nbab', 'bb b\nbab', 'yl', makeCursor(0, 3)); +testSubstituteConfirm('ex_substitute_confirm_oneline', + '1s/a/b/cg', 'ba a\nbab', 'bb b\nbab', 'yl', makeCursor(0, 3)); +testSubstituteConfirm('ex_substitute_confirm_range_accept', + '1,2s/a/b/cg', 'aa\na \na\na', 'bb\nb \na\na', 'yyy', makeCursor(1, 0)); +testSubstituteConfirm('ex_substitute_confirm_range_some', + '1,3s/a/b/cg', 'aa\na \na\na', 'ba\nb \nb\na', 'ynyy', makeCursor(2, 0)); +testSubstituteConfirm('ex_substitute_confirm_range_all', + '1,3s/a/b/cg', 'aa\na \na\na', 'bb\nb \nb\na', 'a', makeCursor(2, 0)); +testSubstituteConfirm('ex_substitute_confirm_range_last', + '1,3s/a/b/cg', 'aa\na \na\na', 'bb\nb \na\na', 'yyl', makeCursor(1, 0)); +//:noh should clear highlighting of search-results but allow to resume search through n +testVim('ex_noh_clearSearchHighlight', function(cm, vim, helpers) { + cm.openDialog = helpers.fakeOpenDialog('match'); + helpers.doKeys('?'); + helpers.doEx('noh'); + eq(vim.searchState_.getOverlay(),null,'match-highlighting wasn\'t cleared'); + helpers.doKeys('n'); + helpers.assertCursorAt(0, 11,'can\'t resume search after clearing highlighting'); +}, { value: 'match nope match \n nope Match' }); +testVim('set_boolean', function(cm, vim, helpers) { + CodeMirror.Vim.defineOption('testoption', true, 'boolean'); + // Test default value is set. + is(CodeMirror.Vim.getOption('testoption')); + try { + // Test fail to set to non-boolean + CodeMirror.Vim.setOption('testoption', '5'); + fail(); + } catch (expected) {}; + // Test setOption + CodeMirror.Vim.setOption('testoption', false); + is(!CodeMirror.Vim.getOption('testoption')); +}); +testVim('ex_set_boolean', function(cm, vim, helpers) { + CodeMirror.Vim.defineOption('testoption', true, 'boolean'); + // Test default value is set. + is(CodeMirror.Vim.getOption('testoption')); + try { + // Test fail to set to non-boolean + helpers.doEx('set testoption=22'); + fail(); + } catch (expected) {}; + // Test setOption + helpers.doEx('set notestoption'); + is(!CodeMirror.Vim.getOption('testoption')); +}); +testVim('set_string', function(cm, vim, helpers) { + CodeMirror.Vim.defineOption('testoption', 'a', 'string'); + // Test default value is set. + eq('a', CodeMirror.Vim.getOption('testoption')); + try { + // Test fail to set non-string. + CodeMirror.Vim.setOption('testoption', true); + fail(); + } catch (expected) {}; + try { + // Test fail to set 'notestoption' + CodeMirror.Vim.setOption('notestoption', 'b'); + fail(); + } catch (expected) {}; + // Test setOption + CodeMirror.Vim.setOption('testoption', 'c'); + eq('c', CodeMirror.Vim.getOption('testoption')); +}); +testVim('ex_set_string', function(cm, vim, helpers) { + CodeMirror.Vim.defineOption('testopt', 'a', 'string'); + // Test default value is set. + eq('a', CodeMirror.Vim.getOption('testopt')); + try { + // Test fail to set 'notestopt' + helpers.doEx('set notestopt=b'); + fail(); + } catch (expected) {}; + // Test setOption + helpers.doEx('set testopt=c') + eq('c', CodeMirror.Vim.getOption('testopt')); + helpers.doEx('set testopt=c') + eq('c', CodeMirror.Vim.getOption('testopt', cm)); //local || global + eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); // local + eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); // global + eq('c', CodeMirror.Vim.getOption('testopt')); // global + // Test setOption global + helpers.doEx('setg testopt=d') + eq('c', CodeMirror.Vim.getOption('testopt', cm)); + eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); + eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); + eq('d', CodeMirror.Vim.getOption('testopt')); + // Test setOption local + helpers.doEx('setl testopt=e') + eq('e', CodeMirror.Vim.getOption('testopt', cm)); + eq('e', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); + eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); + eq('d', CodeMirror.Vim.getOption('testopt')); +}); +testVim('ex_set_callback', function(cm, vim, helpers) { + var global; + + function cb(val, cm, cfg) { + if (val === undefined) { + // Getter + if (cm) { + return cm._local; + } else { + return global; + } + } else { + // Setter + if (cm) { + cm._local = val; + } else { + global = val; + } + } + } + + CodeMirror.Vim.defineOption('testopt', 'a', 'string', cb); + // Test default value is set. + eq('a', CodeMirror.Vim.getOption('testopt')); + try { + // Test fail to set 'notestopt' + helpers.doEx('set notestopt=b'); + fail(); + } catch (expected) {}; + // Test setOption (Identical to the string tests, but via callback instead) + helpers.doEx('set testopt=c') + eq('c', CodeMirror.Vim.getOption('testopt', cm)); //local || global + eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); // local + eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); // global + eq('c', CodeMirror.Vim.getOption('testopt')); // global + // Test setOption global + helpers.doEx('setg testopt=d') + eq('c', CodeMirror.Vim.getOption('testopt', cm)); + eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); + eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); + eq('d', CodeMirror.Vim.getOption('testopt')); + // Test setOption local + helpers.doEx('setl testopt=e') + eq('e', CodeMirror.Vim.getOption('testopt', cm)); + eq('e', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); + eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); + eq('d', CodeMirror.Vim.getOption('testopt')); +}) +testVim('ex_set_filetype', function(cm, vim, helpers) { + CodeMirror.defineMode('test_mode', function() { + return {token: function(stream) { + stream.match(/^\s+|^\S+/); + }}; + }); + CodeMirror.defineMode('test_mode_2', function() { + return {token: function(stream) { + stream.match(/^\s+|^\S+/); + }}; + }); + // Test mode is set. + helpers.doEx('set filetype=test_mode'); + eq('test_mode', cm.getMode().name); + // Test 'ft' alias also sets mode. + helpers.doEx('set ft=test_mode_2'); + eq('test_mode_2', cm.getMode().name); +}); +testVim('ex_set_filetype_null', function(cm, vim, helpers) { + CodeMirror.defineMode('test_mode', function() { + return {token: function(stream) { + stream.match(/^\s+|^\S+/); + }}; + }); + cm.setOption('mode', 'test_mode'); + // Test mode is set to null. + helpers.doEx('set filetype='); + eq('null', cm.getMode().name); +}); +// TODO: Reset key maps after each test. +testVim('ex_map_key2key', function(cm, vim, helpers) { + helpers.doEx('map a x'); + helpers.doKeys('a'); + helpers.assertCursorAt(0, 0); + eq('bc', cm.getValue()); +}, { value: 'abc' }); +testVim('ex_unmap_key2key', function(cm, vim, helpers) { + helpers.doEx('unmap a'); + helpers.doKeys('a'); + eq('vim-insert', cm.getOption('keyMap')); +}, { value: 'abc' }); +testVim('ex_unmap_key2key_does_not_remove_default', function(cm, vim, helpers) { + try { + helpers.doEx('unmap a'); + fail(); + } catch (expected) {} + helpers.doKeys('a'); + eq('vim-insert', cm.getOption('keyMap')); +}, { value: 'abc' }); +testVim('ex_map_key2key_to_colon', function(cm, vim, helpers) { + helpers.doEx('map ; :'); + var dialogOpened = false; + cm.openDialog = function() { + dialogOpened = true; + } + helpers.doKeys(';'); + eq(dialogOpened, true); +}); +testVim('ex_map_ex2key:', function(cm, vim, helpers) { + helpers.doEx('map :del x'); + helpers.doEx('del'); + helpers.assertCursorAt(0, 0); + eq('bc', cm.getValue()); +}, { value: 'abc' }); +testVim('ex_map_ex2ex', function(cm, vim, helpers) { + helpers.doEx('map :del :w'); + var tmp = CodeMirror.commands.save; + var written = false; + var actualCm; + CodeMirror.commands.save = function(cm) { + written = true; + actualCm = cm; + }; + helpers.doEx('del'); + CodeMirror.commands.save = tmp; + eq(written, true); + eq(actualCm, cm); +}); +testVim('ex_map_key2ex', function(cm, vim, helpers) { + helpers.doEx('map a :w'); + var tmp = CodeMirror.commands.save; + var written = false; + var actualCm; + CodeMirror.commands.save = function(cm) { + written = true; + actualCm = cm; + }; + helpers.doKeys('a'); + CodeMirror.commands.save = tmp; + eq(written, true); + eq(actualCm, cm); +}); +testVim('ex_map_key2key_visual_api', function(cm, vim, helpers) { + CodeMirror.Vim.map('b', ':w', 'visual'); + var tmp = CodeMirror.commands.save; + var written = false; + var actualCm; + CodeMirror.commands.save = function(cm) { + written = true; + actualCm = cm; + }; + // Mapping should not work in normal mode. + helpers.doKeys('b'); + eq(written, false); + // Mapping should work in visual mode. + helpers.doKeys('v', 'b'); + eq(written, true); + eq(actualCm, cm); + + CodeMirror.commands.save = tmp; +}); +testVim('ex_imap', function(cm, vim, helpers) { + CodeMirror.Vim.map('jk', '', 'insert'); + helpers.doKeys('i'); + is(vim.insertMode); + helpers.doKeys('j', 'k'); + is(!vim.insertMode); +}) + +// Testing registration of functions as ex-commands and mapping to -keys +testVim('ex_api_test', function(cm, vim, helpers) { + var res=false; + var val='from'; + CodeMirror.Vim.defineEx('extest','ext',function(cm,params){ + if(params.args)val=params.args[0]; + else res=true; + }); + helpers.doEx(':ext to'); + eq(val,'to','Defining ex-command failed'); + CodeMirror.Vim.map('',':ext'); + helpers.doKeys('',''); + is(res,'Mapping to key failed'); +}); +// For now, this test needs to be last because it messes up : for future tests. +testVim('ex_map_key2key_from_colon', function(cm, vim, helpers) { + helpers.doEx('map : x'); + helpers.doKeys(':'); + helpers.assertCursorAt(0, 0); + eq('bc', cm.getValue()); +}, { value: 'abc' }); + +// Test event handlers +testVim('beforeSelectionChange', function(cm, vim, helpers) { + cm.setCursor(0, 100); + eqPos(cm.getCursor('head'), cm.getCursor('anchor')); +}, { value: 'abc' }); + + +}); + + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec(); +} diff --git a/lib/ace/layer/cursor.js b/lib/ace/layer/cursor.js index 4bdf012a..53c30e56 100644 --- a/lib/ace/layer/cursor.js +++ b/lib/ace/layer/cursor.js @@ -1,140 +1,237 @@ -/* vim:ts=4:sts=4:sw=4: - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var dom = require("pilot/dom"); -var useragent = require("pilot/useragent"); +var dom = require("../lib/dom"); +var IE8; var Cursor = function(parentEl) { this.element = dom.createElement("div"); this.element.className = "ace_layer ace_cursor-layer"; parentEl.appendChild(this.element); - - this.cursor = dom.createElement("div"); - this.cursor.className = "ace_cursor"; + + if (IE8 === undefined) + IE8 = "opacity" in this.element; this.isVisible = false; + this.isBlinking = true; + this.blinkInterval = 1000; + this.smoothBlinking = false; + + this.cursors = []; + this.cursor = this.addCursor(); + dom.addCssClass(this.element, "ace_hidden-cursors"); + this.$updateCursors = this.$updateVisibility.bind(this); }; (function() { + + this.$updateVisibility = function(val) { + var cursors = this.cursors; + for (var i = cursors.length; i--; ) + cursors[i].style.visibility = val ? "" : "hidden"; + }; + this.$updateOpacity = function(val) { + var cursors = this.cursors; + for (var i = cursors.length; i--; ) + cursors[i].style.opacity = val ? "" : "0"; + }; + + + this.$padding = 0; + this.setPadding = function(padding) { + this.$padding = padding; + }; this.setSession = function(session) { this.session = session; }; + this.setBlinking = function(blinking) { + if (blinking != this.isBlinking){ + this.isBlinking = blinking; + this.restartTimer(); + } + }; + + this.setBlinkInterval = function(blinkInterval) { + if (blinkInterval != this.blinkInterval){ + this.blinkInterval = blinkInterval; + this.restartTimer(); + } + }; + + this.setSmoothBlinking = function(smoothBlinking) { + if (smoothBlinking != this.smoothBlinking && !IE8) { + this.smoothBlinking = smoothBlinking; + dom.setCssClass(this.element, "ace_smooth-blinking", smoothBlinking); + this.$updateCursors(true); + this.$updateCursors = (smoothBlinking + ? this.$updateOpacity + : this.$updateVisibility).bind(this); + this.restartTimer(); + } + }; + + this.addCursor = function() { + var el = dom.createElement("div"); + el.className = "ace_cursor"; + this.element.appendChild(el); + this.cursors.push(el); + return el; + }; + + this.removeCursor = function() { + if (this.cursors.length > 1) { + var el = this.cursors.pop(); + el.parentNode.removeChild(el); + return el; + } + }; + this.hideCursor = function() { this.isVisible = false; - if (this.cursor.parentNode) { - this.cursor.parentNode.removeChild(this.cursor); - } - clearInterval(this.blinkId); + dom.addCssClass(this.element, "ace_hidden-cursors"); + this.restartTimer(); }; this.showCursor = function() { this.isVisible = true; - if (!useragent.isIPad) - this.element.appendChild(this.cursor); - - - var cursor = this.cursor; - cursor.style.visibility = "visible"; + dom.removeCssClass(this.element, "ace_hidden-cursors"); this.restartTimer(); }; this.restartTimer = function() { - clearInterval(this.blinkId); - if (!this.isVisible) { - return; + var update = this.$updateCursors; + clearInterval(this.intervalId); + clearTimeout(this.timeoutId); + if (this.smoothBlinking) { + dom.removeCssClass(this.element, "ace_smooth-blinking"); } + + update(true); - var cursor = this.cursor; - this.blinkId = setInterval(function() { - cursor.style.visibility = "hidden"; - setTimeout(function() { - cursor.style.visibility = "visible"; - }, 400); - }, 1000); + if (!this.isBlinking || !this.blinkInterval || !this.isVisible) + return; + + if (this.smoothBlinking) { + setTimeout(function(){ + dom.addCssClass(this.element, "ace_smooth-blinking"); + }.bind(this)); + } + + var blink = function(){ + this.timeoutId = setTimeout(function() { + update(false); + }, 0.6 * this.blinkInterval); + }.bind(this); + + this.intervalId = setInterval(function() { + update(true); + blink(); + }, this.blinkInterval); + + blink(); }; - this.getPixelPosition = function(onScreen) { - if (!this.config || !this.session) { - return { - left : 0, - top : 0 - }; - } + this.getPixelPosition = function(position, onScreen) { + if (!this.config || !this.session) + return {left : 0, top : 0}; - var position = this.session.selection.getCursor(); + if (!position) + position = this.session.selection.getCursor(); var pos = this.session.documentToScreenPosition(position); - var cursorLeft = Math.round(pos.column * this.config.characterWidth); + var cursorLeft = this.$padding + pos.column * this.config.characterWidth; var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) * this.config.lineHeight; - return { - left : cursorLeft, - top : cursorTop - }; + return {left : cursorLeft, top : cursorTop}; }; this.update = function(config) { this.config = config; - this.pixelPos = this.getPixelPosition(true); + var selections = this.session.$selectionMarkers; + var i = 0, cursorIndex = 0; - this.cursor.style.left = this.pixelPos.left + "px"; - this.cursor.style.top = this.pixelPos.top + "px"; - this.cursor.style.width = config.characterWidth + "px"; - this.cursor.style.height = config.lineHeight + "px"; - - if (this.isVisible && !useragent.isIPad) { - this.element.appendChild(this.cursor); + if (selections === undefined || selections.length === 0){ + selections = [{cursor: null}]; } - if (this.session.getOverwrite()) { - dom.addCssClass(this.cursor, "ace_overwrite"); - } else { - dom.removeCssClass(this.cursor, "ace_overwrite"); - } + for (var i = 0, n = selections.length; i < n; i++) { + var pixelPos = this.getPixelPosition(selections[i].cursor, true); + if ((pixelPos.top > config.height + config.offset || + pixelPos.top < 0) && i > 1) { + continue; + } + var style = (this.cursors[cursorIndex++] || this.addCursor()).style; + + if (!this.drawCursor) { + style.left = pixelPos.left + "px"; + style.top = pixelPos.top + "px"; + style.width = config.characterWidth + "px"; + style.height = config.lineHeight + "px"; + } else { + this.drawCursor(style, pixelPos, config, selections[i], this.session); + } + } + while (this.cursors.length > cursorIndex) + this.removeCursor(); + + var overwrite = this.session.getOverwrite(); + this.$setOverwrite(overwrite); + + // cache for textarea and gutter highlight + this.$pixelPos = pixelPos; this.restartTimer(); }; + + this.drawCursor = null; + + this.$setOverwrite = function(overwrite) { + if (overwrite != this.overwrite) { + this.overwrite = overwrite; + if (overwrite) + dom.addCssClass(this.element, "ace_overwrite-cursors"); + else + dom.removeCssClass(this.element, "ace_overwrite-cursors"); + } + }; + + this.destroy = function() { + clearInterval(this.intervalId); + clearTimeout(this.timeoutId); + }; }).call(Cursor.prototype); diff --git a/lib/ace/layer/font_metrics.js b/lib/ace/layer/font_metrics.js new file mode 100644 index 00000000..715c6cf3 --- /dev/null +++ b/lib/ace/layer/font_metrics.js @@ -0,0 +1,176 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +var oop = require("../lib/oop"); +var dom = require("../lib/dom"); +var lang = require("../lib/lang"); +var useragent = require("../lib/useragent"); +var EventEmitter = require("../lib/event_emitter").EventEmitter; + +var CHAR_COUNT = 0; + +var FontMetrics = exports.FontMetrics = function(parentEl, interval) { + this.el = dom.createElement("div"); + this.$setMeasureNodeStyles(this.el.style, true); + + this.$main = dom.createElement("div"); + this.$setMeasureNodeStyles(this.$main.style); + + this.$measureNode = dom.createElement("div"); + this.$setMeasureNodeStyles(this.$measureNode.style); + + + this.el.appendChild(this.$main); + this.el.appendChild(this.$measureNode); + parentEl.appendChild(this.el); + + if (!CHAR_COUNT) + this.$testFractionalRect(); + this.$measureNode.innerHTML = lang.stringRepeat("X", CHAR_COUNT); + + this.$characterSize = {width: 0, height: 0}; + this.checkForSizeChanges(); +}; + +(function() { + + oop.implement(this, EventEmitter); + + this.$characterSize = {width: 0, height: 0}; + + this.$testFractionalRect = function() { + var el = dom.createElement("div"); + this.$setMeasureNodeStyles(el.style); + el.style.width = "0.2px"; + document.documentElement.appendChild(el); + var w = el.getBoundingClientRect().width; + if (w > 0 && w < 1) + CHAR_COUNT = 50; + else + CHAR_COUNT = 100; + el.parentNode.removeChild(el); + }; + + this.$setMeasureNodeStyles = function(style, isRoot) { + style.width = style.height = "auto"; + style.left = style.top = "0px"; + style.visibility = "hidden"; + style.position = "absolute"; + style.whiteSpace = "pre"; + + if (useragent.isIE < 8) { + style["font-family"] = "inherit"; + } else { + style.font = "inherit"; + } + style.overflow = isRoot ? "hidden" : "visible"; + }; + + this.checkForSizeChanges = function() { + var size = this.$measureSizes(); + if (size && (this.$characterSize.width !== size.width || this.$characterSize.height !== size.height)) { + this.$measureNode.style.fontWeight = "bold"; + var boldSize = this.$measureSizes(); + this.$measureNode.style.fontWeight = ""; + this.$characterSize = size; + this.charSizes = Object.create(null); + this.allowBoldFonts = boldSize && boldSize.width === size.width && boldSize.height === size.height; + this._emit("changeCharacterSize", {data: size}); + } + }; + + this.$pollSizeChanges = function() { + if (this.$pollSizeChangesTimer) + return this.$pollSizeChangesTimer; + var self = this; + return this.$pollSizeChangesTimer = setInterval(function() { + self.checkForSizeChanges(); + }, 500); + }; + + this.setPolling = function(val) { + if (val) { + this.$pollSizeChanges(); + } else if (this.$pollSizeChangesTimer) { + clearInterval(this.$pollSizeChangesTimer); + this.$pollSizeChangesTimer = 0; + } + }; + + this.$measureSizes = function() { + if (CHAR_COUNT === 50) { + var rect = null; + try { + rect = this.$measureNode.getBoundingClientRect(); + } catch(e) { + rect = {width: 0, height:0 }; + }; + var size = { + height: rect.height, + width: rect.width / CHAR_COUNT + }; + } else { + var size = { + height: this.$measureNode.clientHeight, + width: this.$measureNode.clientWidth / CHAR_COUNT + }; + } + // Size and width can be null if the editor is not visible or + // detached from the document + if (size.width === 0 || size.height === 0) + return null; + return size; + }; + + this.$measureCharWidth = function(ch) { + this.$main.innerHTML = lang.stringRepeat(ch, CHAR_COUNT); + var rect = this.$main.getBoundingClientRect(); + return rect.width / CHAR_COUNT; + }; + + this.getCharacterWidth = function(ch) { + var w = this.charSizes[ch]; + if (w === undefined) { + this.charSizes[ch] = this.$measureCharWidth(ch) / this.$characterSize.width; + } + return w; + }; + + this.destroy = function() { + clearInterval(this.$pollSizeChangesTimer); + if (this.el && this.el.parentNode) + this.el.parentNode.removeChild(this.el); + }; + +}).call(FontMetrics.prototype); + +}); diff --git a/lib/ace/layer/gutter.js b/lib/ace/layer/gutter.js index b4354b5b..dc1055c2 100644 --- a/lib/ace/layer/gutter.js +++ b/lib/ace/layer/gutter.js @@ -1,119 +1,281 @@ -/* vim:ts=4:sts=4:sw=4: - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var dom = require("pilot/dom"); +var dom = require("../lib/dom"); +var oop = require("../lib/oop"); +var lang = require("../lib/lang"); +var EventEmitter = require("../lib/event_emitter").EventEmitter; var Gutter = function(parentEl) { this.element = dom.createElement("div"); this.element.className = "ace_layer ace_gutter-layer"; parentEl.appendChild(this.element); + this.setShowFoldWidgets(this.$showFoldWidgets); + + this.gutterWidth = 0; - this.$breakpoints = []; this.$annotations = []; - this.$decorations = []; + this.$updateAnnotations = this.$updateAnnotations.bind(this); + + this.$cells = []; }; (function() { + oop.implement(this, EventEmitter); + this.setSession = function(session) { + if (this.session) + this.session.removeEventListener("change", this.$updateAnnotations); this.session = session; + if (session) + session.on("change", this.$updateAnnotations); }; this.addGutterDecoration = function(row, className){ - if (!this.$decorations[row]) - this.$decorations[row] = ""; - this.$decorations[row] += " ace_" + className; - } - - this.removeGutterDecoration = function(row, className){ - this.$decorations[row] = this.$decorations[row].replace(" ace_" + className, ""); + if (window.console) + console.warn && console.warn("deprecated use session.addGutterDecoration"); + this.session.addGutterDecoration(row, className); }; - this.setBreakpoints = function(rows) { - this.$breakpoints = rows.concat(); + this.removeGutterDecoration = function(row, className){ + if (window.console) + console.warn && console.warn("deprecated use session.removeGutterDecoration"); + this.session.removeGutterDecoration(row, className); }; this.setAnnotations = function(annotations) { // iterate over sparse array - this.$annotations = []; - for (var row in annotations) if (annotations.hasOwnProperty(row)) { - var rowAnnotations = annotations[row]; - if (!rowAnnotations) - continue; - - var rowInfo = this.$annotations[row] = { - text: [] - }; - for (var i=0; i", (i+1), "
    "); + var cell = null; + var index = -1; + var row = firstRow; + while (true) { + if (row > foldStart) { + row = fold.end.row + 1; + fold = session.getNextFoldLine(row, fold); + foldStart = fold ? fold.start.row : Infinity; + } + if (row > lastRow) { + while (this.$cells.length > index + 1) { + cell = this.$cells.pop(); + this.element.removeChild(cell.element); + } + break; + } + + cell = this.$cells[++index]; + if (!cell) { + cell = {element: null, textNode: null, foldWidget: null}; + cell.element = dom.createElement("div"); + cell.textNode = document.createTextNode(''); + cell.element.appendChild(cell.textNode); + this.element.appendChild(cell.element); + this.$cells[index] = cell; + } + + var className = "ace_gutter-cell "; + if (breakpoints[row]) + className += breakpoints[row]; + if (decorations[row]) + className += decorations[row]; + if (this.$annotations[row]) + className += this.$annotations[row].className; + if (cell.element.className != className) + cell.element.className = className; + + var height = session.getRowLength(row) * config.lineHeight + "px"; + if (height != cell.element.style.height) + cell.element.style.height = height; + + if (foldWidgets) { + var c = foldWidgets[row]; + // check if cached value is invalidated and we need to recompute + if (c == null) + c = foldWidgets[row] = session.getFoldWidget(row); + } + + if (c) { + if (!cell.foldWidget) { + cell.foldWidget = dom.createElement("span"); + cell.element.appendChild(cell.foldWidget); + } + var className = "ace_fold-widget ace_" + c; + if (c == "start" && row == foldStart && row < fold.end.row) + className += " ace_closed"; + else + className += " ace_open"; + if (cell.foldWidget.className != className) + cell.foldWidget.className = className; + + var height = config.lineHeight + "px"; + if (cell.foldWidget.style.height != height) + cell.foldWidget.style.height = height; + } else { + if (cell.foldWidget) { + cell.element.removeChild(cell.foldWidget); + cell.foldWidget = null; + } + } + + var text = lastLineNumber = gutterRenderer + ? gutterRenderer.getText(session, row) + : row + firstLineNumber; + if (text != cell.textNode.data) + cell.textNode.data = text; + + row++; } - this.element = dom.setInnerHtml(this.element, html.join("")); + this.element.style.height = config.minHeight + "px"; + + if (this.$fixedWidth || session.$useWrapMode) + lastLineNumber = session.getLength() + firstLineNumber; + + var gutterWidth = gutterRenderer + ? gutterRenderer.getWidth(session, lastLineNumber, config) + : lastLineNumber.toString().length * config.characterWidth; + + var padding = this.$padding || this.$computePadding(); + gutterWidth += padding.left + padding.right; + if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) { + this.gutterWidth = gutterWidth; + this.element.style.width = Math.ceil(this.gutterWidth) + "px"; + this._emit("changeGutterWidth", gutterWidth); + } + }; + + this.$fixedWidth = false; + + this.$showLineNumbers = true; + this.$renderer = ""; + this.setShowLineNumbers = function(show) { + this.$renderer = !show && { + getWidth: function() {return ""}, + getText: function() {return ""} + }; + }; + + this.getShowLineNumbers = function() { + return this.$showLineNumbers; + }; + + this.$showFoldWidgets = true; + this.setShowFoldWidgets = function(show) { + if (show) + dom.addCssClass(this.element, "ace_folding-enabled"); + else + dom.removeCssClass(this.element, "ace_folding-enabled"); + + this.$showFoldWidgets = show; + this.$padding = null; + }; + + this.getShowFoldWidgets = function() { + return this.$showFoldWidgets; + }; + + this.$computePadding = function() { + if (!this.element.firstChild) + return {left: 0, right: 0}; + var style = dom.computedStyle(this.element.firstChild); + this.$padding = {}; + this.$padding.left = parseInt(style.paddingLeft) + 1 || 0; + this.$padding.right = parseInt(style.paddingRight) || 0; + return this.$padding; + }; + + this.getRegion = function(point) { + var padding = this.$padding || this.$computePadding(); + var rect = this.element.getBoundingClientRect(); + if (point.x < padding.left + rect.left) + return "markers"; + if (this.$showFoldWidgets && point.x > rect.right - padding.right) + return "foldWidgets"; }; }).call(Gutter.prototype); diff --git a/lib/ace/layer/marker.js b/lib/ace/layer/marker.js index 028bef33..9818d225 100644 --- a/lib/ace/layer/marker.js +++ b/lib/ace/layer/marker.js @@ -1,46 +1,38 @@ -/* vim:ts=4:sts=4:sw=4: - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var Range = require("ace/range").Range; -var dom = require("pilot/dom"); +var Range = require("../range").Range; +var dom = require("../lib/dom"); var Marker = function(parentEl) { this.element = dom.createElement("div"); @@ -50,6 +42,11 @@ var Marker = function(parentEl) { (function() { + this.$padding = 0; + + this.setPadding = function(padding) { + this.$padding = padding; + }; this.setSession = function(session) { this.session = session; }; @@ -65,111 +62,157 @@ var Marker = function(parentEl) { this.config = config; - var html = []; - for ( var key in this.markers) { + + var html = []; + for (var key in this.markers) { var marker = this.markers[key]; + if (!marker.range) { + marker.update(html, this, this.session, config); + continue; + } + var range = marker.range.clipRows(config.firstRow, config.lastRow); if (range.isEmpty()) continue; range = range.toScreenRange(this.session); - if (marker.renderer) { var top = this.$getTop(range.start.row, config); - var left = Math.round(range.start.column * config.characterWidth); + var left = this.$padding + range.start.column * config.characterWidth; marker.renderer(html, range, left, top, config); - } - else if (range.isMultiLine()) { - if (marker.type == "text") { + } else if (marker.type == "fullLine") { + this.drawFullLineMarker(html, range, marker.clazz, config); + } else if (marker.type == "screenLine") { + this.drawScreenLineMarker(html, range, marker.clazz, config); + } else if (range.isMultiLine()) { + if (marker.type == "text") this.drawTextMarker(html, range, marker.clazz, config); - } else { + else this.drawMultiLineMarker(html, range, marker.clazz, config); - } - } - else { - this.drawSingleLineMarker(html, range, marker.clazz, config); + } else { + this.drawSingleLineMarker(html, range, marker.clazz + " ace_start" + " ace_br15", config); } } - this.element = dom.setInnerHtml(this.element, html.join("")); + this.element.innerHTML = html.join(""); }; this.$getTop = function(row, layerConfig) { return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight; }; - this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) { - // selection start - var row = range.start.row; - - var lineRange = new Range(row, range.start.column, - row, this.session.getScreenLastRowColumn(row)); - this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1); - - // selection end - var row = range.end.row; - var lineRange = new Range(row, 0, row, range.end.column); - this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig); - - for (var row = range.start.row + 1; row < range.end.row; row++) { - lineRange.start.row = row; - lineRange.end.row = row; - lineRange.end.column = this.session.getScreenLastRowColumn(row); - this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1); + function getBorderClass(tl, tr, br, bl) { + return (tl ? 1 : 0) | (tr ? 2 : 0) | (br ? 4 : 0) | (bl ? 8 : 0); + } + // Draws a marker, which spans a range of text on multiple lines + this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig, extraStyle) { + var session = this.session; + var start = range.start.row; + var end = range.end.row; + var row = start; + var prev = 0; + var curr = 0; + var next = session.getScreenLastRowColumn(row); + var lineRange = new Range(row, range.start.column, row, curr); + for (; row <= end; row++) { + lineRange.start.row = lineRange.end.row = row; + lineRange.start.column = row == start ? range.start.column : session.getRowWrapIndent(row); + lineRange.end.column = next; + prev = curr; + curr = next; + next = row + 1 < end ? session.getScreenLastRowColumn(row + 1) : row == end ? 0 : range.end.column; + this.drawSingleLineMarker(stringBuilder, lineRange, + clazz + (row == start ? " ace_start" : "") + " ace_br" + + getBorderClass(row == start || row == start + 1 && range.start.column, prev < curr, curr > next, row == end), + layerConfig, row == end ? 0 : 1, extraStyle); } }; - this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig) { + // Draws a multi line marker, where lines span the full width + this.drawMultiLineMarker = function(stringBuilder, range, clazz, config, extraStyle) { // from selection start to the end of the line - var height = layerConfig.lineHeight; - var width = Math.round(layerConfig.width - (range.start.column * layerConfig.characterWidth)); - var top = this.$getTop(range.start.row, layerConfig); - var left = Math.round(range.start.column * layerConfig.characterWidth); + var padding = this.$padding; + var height = config.lineHeight; + var top = this.$getTop(range.start.row, config); + var left = padding + range.start.column * config.characterWidth; + extraStyle = extraStyle || ""; stringBuilder.push( - "
    " + "left:", left, "px;", extraStyle, "'>" ); // from start of the last line to the selection end - var top = this.$getTop(range.end.row, layerConfig); - var width = Math.round(range.end.column * layerConfig.characterWidth); + top = this.$getTop(range.end.row, config); + var width = range.end.column * config.characterWidth; stringBuilder.push( - "
    " + "left:", padding, "px;", extraStyle, "'>" ); // all the complete lines - var height = (range.end.row - range.start.row - 1) * layerConfig.lineHeight; - if (height < 0) + height = (range.end.row - range.start.row - 1) * config.lineHeight; + if (height <= 0) return; - var top = this.$getTop(range.start.row + 1, layerConfig); + top = this.$getTop(range.start.row + 1, config); + + var radiusClass = (range.start.column ? 1 : 0) | (range.end.column ? 0 : 8); stringBuilder.push( - "
    " + "right:0;", + "top:", top, "px;", + "left:", padding, "px;", extraStyle, "'>" ); }; - this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig, extraLength) { - var height = layerConfig.lineHeight; - var width = Math.round((range.end.column + (extraLength || 0) - range.start.column) * layerConfig.characterWidth); - var top = this.$getTop(range.start.row, layerConfig); - var left = Math.round(range.start.column * layerConfig.characterWidth); + // Draws a marker which covers part or whole width of a single screen line + this.drawSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) { + var height = config.lineHeight; + var width = (range.end.column + (extraLength || 0) - range.start.column) * config.characterWidth; + + var top = this.$getTop(range.start.row, config); + var left = this.$padding + range.start.column * config.characterWidth; stringBuilder.push( "
    " + "left:", left, "px;", extraStyle || "", "'>" + ); + }; + + this.drawFullLineMarker = function(stringBuilder, range, clazz, config, extraStyle) { + var top = this.$getTop(range.start.row, config); + var height = config.lineHeight; + if (range.start.row != range.end.row) + height += this.$getTop(range.end.row, config) - top; + + stringBuilder.push( + "
    " + ); + }; + + this.drawScreenLineMarker = function(stringBuilder, range, clazz, config, extraStyle) { + var top = this.$getTop(range.start.row, config); + var height = config.lineHeight; + + stringBuilder.push( + "
    " ); }; diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js index f78bbc46..01afb9f3 100644 --- a/lib/ace/layer/text.js +++ b/lib/ace/layer/text.js @@ -1,145 +1,102 @@ -/* vim:ts=4:sts=4:sw=4: +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: * - * ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Julian Viereck - * Mihai Sucan - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var oop = require("pilot/oop"); -var dom = require("pilot/dom"); -var lang = require("pilot/lang"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; +var oop = require("../lib/oop"); +var dom = require("../lib/dom"); +var lang = require("../lib/lang"); +var useragent = require("../lib/useragent"); +var EventEmitter = require("../lib/event_emitter").EventEmitter; var Text = function(parentEl) { this.element = dom.createElement("div"); this.element.className = "ace_layer ace_text-layer"; parentEl.appendChild(this.element); - - this.$characterSize = this.$measureSizes(); - this.$pollSizeChanges(); + this.$updateEolChar = this.$updateEolChar.bind(this); }; (function() { oop.implement(this, EventEmitter); - this.EOF_CHAR = "¶"; - this.EOL_CHAR = "¬"; - this.TAB_CHAR = "→"; - this.SPACE_CHAR = "·"; + this.EOF_CHAR = "\xB6"; + this.EOL_CHAR_LF = "\xAC"; + this.EOL_CHAR_CRLF = "\xa4"; + this.EOL_CHAR = this.EOL_CHAR_LF; + this.TAB_CHAR = "\u2014"; //"\u21E5"; + this.SPACE_CHAR = "\xB7"; + this.$padding = 0; - this.setTokenizer = function(tokenizer) { - this.tokenizer = tokenizer; + this.$updateEolChar = function() { + var EOL_CHAR = this.session.doc.getNewLineCharacter() == "\n" + ? this.EOL_CHAR_LF + : this.EOL_CHAR_CRLF; + if (this.EOL_CHAR != EOL_CHAR) { + this.EOL_CHAR = EOL_CHAR; + return true; + } + } + + this.setPadding = function(padding) { + this.$padding = padding; + this.element.style.padding = "0 " + padding + "px"; }; this.getLineHeight = function() { - return this.$characterSize.height || 1; + return this.$fontMetrics.$characterSize.height || 0; }; this.getCharacterWidth = function() { - return this.$characterSize.width || 1; + return this.$fontMetrics.$characterSize.width || 0; }; + + this.$setFontMetrics = function(measure) { + this.$fontMetrics = measure; + this.$fontMetrics.on("changeCharacterSize", function(e) { + this._signal("changeCharacterSize", e); + }.bind(this)); + this.$pollSizeChanges(); + } + this.checkForSizeChanges = function() { + this.$fontMetrics.checkForSizeChanges(); + }; this.$pollSizeChanges = function() { - var self = this; - //setInterval(function() { - var size = self.$measureSizes(); - if (self.$characterSize.width !== size.width || self.$characterSize.height !== size.height) { - self.$characterSize = size; - self._dispatchEvent("changeCharaterSize", {data: size}); - } - //}, 500); + return this.$pollSizeChangesTimer = this.$fontMetrics.$pollSizeChanges(); }; - - this.$fontStyles = { - fontFamily : 1, - fontSize : 1, - fontWeight : 1, - fontStyle : 1, - lineHeight : 1 - }, - - this.$measureSizes = function() { - var n = 1000; - if (!this.$measureNode) { - var measureNode = this.$measureNode = dom.createElement("div"); - var style = measureNode.style; - - style.width = style.height = "auto"; - style.left = style.top = (-n * 40) + "px"; - - style.visibility = "hidden"; - style.position = "absolute"; - style.overflow = "visible"; - style.whiteSpace = "nowrap"; - - // in FF 3.6 monospace fonts can have a fixed sub pixel width. - // that's why we have to measure many characters - // Note: characterWidth can be a float! - measureNode.innerHTML = lang.stringRepeat("Xy", n); - - if (document.body) { - document.body.appendChild(measureNode); - } else { - var container = this.element.parentNode; - while (!dom.hasCssClass(container, "ace_editor")) - container = container.parentNode; - container.appendChild(measureNode); - } - - } - - var style = this.$measureNode.style; - for (var prop in this.$fontStyles) { - var value = dom.computedStyle(this.element, prop); - style[prop] = value; - } - - var size = { - height: this.$measureNode.offsetHeight, - width: this.$measureNode.offsetWidth / (n * 2) - }; - return size; - }; - this.setSession = function(session) { this.session = session; + if (session) + this.$computeTabString(); }; this.showInvisibles = false; @@ -148,25 +105,57 @@ var Text = function(parentEl) { return false; this.showInvisibles = showInvisibles; + this.$computeTabString(); return true; }; + this.displayIndentGuides = true; + this.setDisplayIndentGuides = function(display) { + if (this.displayIndentGuides == display) + return false; + + this.displayIndentGuides = display; + this.$computeTabString(); + return true; + }; + + this.$tabStrings = []; + this.onChangeTabSize = this.$computeTabString = function() { var tabSize = this.session.getTabSize(); - if (this.showInvisibles) { - var halfTab = (tabSize) / 2; - this.$tabString = "" - + new Array(Math.floor(halfTab)).join(" ") - + this.TAB_CHAR - + new Array(Math.ceil(halfTab)+1).join(" ") - + ""; - } else { - this.$tabString = new Array(tabSize+1).join(" "); + this.tabSize = tabSize; + var tabStr = this.$tabStrings = [0]; + for (var i = 1; i < tabSize + 1; i++) { + if (this.showInvisibles) { + tabStr.push("" + + lang.stringRepeat(this.TAB_CHAR, i) + + ""); + } else { + tabStr.push(lang.stringRepeat(" ", i)); + } + } + if (this.displayIndentGuides) { + this.$indentGuideRe = /\s\S| \t|\t |\s$/; + var className = "ace_indent-guide"; + var spaceClass = ""; + var tabClass = ""; + if (this.showInvisibles) { + className += " ace_invisible"; + spaceClass = " ace_invisible_space"; + tabClass = " ace_invisible_tab"; + var spaceContent = lang.stringRepeat(this.SPACE_CHAR, this.tabSize); + var tabContent = lang.stringRepeat(this.TAB_CHAR, this.tabSize); + } else{ + var spaceContent = lang.stringRepeat(" ", this.tabSize); + var tabContent = spaceContent; + } + + this.$tabStrings[" "] = "" + spaceContent + ""; + this.$tabStrings["\t"] = "" + tabContent + ""; } }; this.updateLines = function(config, firstRow, lastRow) { - this.$computeTabString(); // Due to wrap line changes there can be new lines if e.g. // the line to updated wrapped in the meantime. if (this.config.lastRow != config.lastRow || @@ -179,22 +168,48 @@ var Text = function(parentEl) { var last = Math.min(lastRow, config.lastRow); var lineElements = this.element.childNodes; - var tokens = this.tokenizer.getTokens(first, last); - for (var i=first; i<=last; i++) { - var lineElement = lineElements[i - config.firstRow]; - if (!lineElement) - continue; + var lineElementsIdx = 0; - var html = []; - this.$renderLine(html, i, tokens[i-first].tokens); - lineElement = dom.setInnerHtml(lineElement, html.join("")); - lineElement.style.height = - this.session.getRowHeight(config, i) + "px"; + for (var row = config.firstRow; row < first; row++) { + var foldLine = this.session.getFoldLine(row); + if (foldLine) { + if (foldLine.containsRow(first)) { + first = foldLine.start.row; + break; + } else { + row = foldLine.end.row; + } + } + lineElementsIdx ++; + } + + var row = first; + var foldLine = this.session.getNextFoldLine(row); + var foldStart = foldLine ? foldLine.start.row : Infinity; + + while (true) { + if (row > foldStart) { + row = foldLine.end.row+1; + foldLine = this.session.getNextFoldLine(row, foldLine); + foldStart = foldLine ? foldLine.start.row :Infinity; + } + if (row > last) + break; + + var lineElement = lineElements[lineElementsIdx++]; + if (lineElement) { + var html = []; + this.$renderLine( + html, row, !this.$useLineGroups(), row == foldStart ? foldLine : false + ); + lineElement.style.height = config.lineHeight * this.session.getRowLength(row) + "px"; + lineElement.innerHTML = html.join(""); + } + row++; } }; this.scrollLines = function(config) { - this.$computeTabString(); var oldConfig = this.config; this.config = config; @@ -205,13 +220,12 @@ var Text = function(parentEl) { return this.update(config); var el = this.element; - if (oldConfig.firstRow < config.firstRow) - for (var row=oldConfig.firstRow; row0; row--) el.removeChild(el.firstChild); if (oldConfig.lastRow > config.lastRow) - for (var row=config.lastRow+1; row<=oldConfig.lastRow; row++) + for (var row=this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row>0; row--) el.removeChild(el.lastChild); if (config.firstRow < oldConfig.firstRow) { @@ -229,36 +243,74 @@ var Text = function(parentEl) { }; this.$renderLinesFragment = function(config, firstRow, lastRow) { - var fragment = document.createDocumentFragment(); - var tokens = this.tokenizer.getTokens(firstRow, lastRow); - for (var row=firstRow; row<=lastRow; row++) { - var lineEl = dom.createElement("div"); - lineEl.className = "ace_line"; - var style = lineEl.style; - style.height = this.session.getRowHeight(config, row) + "px"; - style.width = config.width + "px"; + var fragment = this.element.ownerDocument.createDocumentFragment(); + var row = firstRow; + var foldLine = this.session.getNextFoldLine(row); + var foldStart = foldLine ? foldLine.start.row : Infinity; + + while (true) { + if (row > foldStart) { + row = foldLine.end.row+1; + foldLine = this.session.getNextFoldLine(row, foldLine); + foldStart = foldLine ? foldLine.start.row : Infinity; + } + if (row > lastRow) + break; + + var container = dom.createElement("div"); var html = []; - if (tokens.length > row-firstRow) - this.$renderLine(html, row, tokens[row-firstRow].tokens); + // Get the tokens per line as there might be some lines in between + // beeing folded. + this.$renderLine(html, row, false, row == foldStart ? foldLine : false); + // don't use setInnerHtml since we are working with an empty DIV - lineEl.innerHTML = html.join(""); - fragment.appendChild(lineEl); + container.innerHTML = html.join(""); + if (this.$useLineGroups()) { + container.className = 'ace_line_group'; + fragment.appendChild(container); + container.style.height = config.lineHeight * this.session.getRowLength(row) + "px"; + + } else { + while(container.firstChild) + fragment.appendChild(container.firstChild); + } + + row++; } return fragment; }; this.update = function(config) { - this.$computeTabString(); this.config = config; var html = []; - var tokens = this.tokenizer.getTokens(config.firstRow, config.lastRow) - var fragment = this.$renderLinesFragment(config, config.firstRow, config.lastRow); + var firstRow = config.firstRow, lastRow = config.lastRow; - // Clear the current content of the element and add the rendered fragment. - this.element.innerHTML = ""; - this.element.appendChild(fragment); + var row = firstRow; + var foldLine = this.session.getNextFoldLine(row); + var foldStart = foldLine ? foldLine.start.row : Infinity; + + while (true) { + if (row > foldStart) { + row = foldLine.end.row+1; + foldLine = this.session.getNextFoldLine(row, foldLine); + foldStart = foldLine ? foldLine.start.row :Infinity; + } + if (row > lastRow) + break; + + if (this.$useLineGroups()) + html.push("
    ") + + this.$renderLine(html, row, false, row == foldStart ? foldLine : false); + + if (this.$useLineGroups()) + html.push("
    "); // end the line group + + row++; + } + this.element.innerHTML = html.join(""); }; this.$textToken = { @@ -267,92 +319,254 @@ var Text = function(parentEl) { "lparen": true }; - this.$renderLine = function(stringBuilder, row, tokens) { - if (this.showInvisibles) { - var self = this; - var spaceRe = /( +)|([\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000])/g; - var spaceReplace = function(space) { - if (space.charCodeAt(0) == 32) - return new Array(space.length+1).join(" "); - else { - var space = new Array(space.length+1).join(self.SPACE_CHAR); - return "" + space + ""; - } + this.$renderToken = function(stringBuilder, screenColumn, token, value) { + var self = this; + var replaceReg = /\t|&|<|( +)|([\x00-\x1f\x80-\xa0\xad\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\u3000\uFEFF])|[\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 (a) { + return self.showInvisibles + ? "" + lang.stringRepeat(self.SPACE_CHAR, c.length) + "" + : c; + } 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 == "\u3000") { + // U+3000 is both invisible AND full-width, so must be handled uniquely + var classToUse = self.showInvisibles ? "ace_cjk ace_invisible ace_invisible_space" : "ace_cjk"; + var space = self.showInvisibles ? self.SPACE_CHAR : ""; + screenColumn += 1; + return "" + space + ""; + } else if (b) { + return "" + self.SPACE_CHAR + ""; + } else { + screenColumn += 1; + return "" + c + ""; + } + }; - }; + var output = value.replace(replaceReg, replaceFunc); + + if (!this.$textToken[token.type]) { + var classes = "ace_" + token.type.replace(/\./g, " ace_"); + var style = ""; + if (token.type == "fold") + style = " style='width:" + (token.value.length * this.config.characterWidth) + "px;' "; + stringBuilder.push("", output, ""); } else { - var spaceRe = /[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/g; - var spaceReplace = " "; + stringBuilder.push(output); } + return screenColumn + value.length; + }; - var _self = this; - var characterWidth = this.config.characterWidth; - function addToken(token, value) { - var output = value - .replace(/&/g, "&") - .replace(/" + c + "" - }); - - if (!_self.$textToken[token.type]) { - var classes = "ace_" + token.type.replace(/\./g, " ace_"); - stringBuilder.push("", output, ""); - } - else { - stringBuilder.push(output); - } + this.renderIndentGuide = function(stringBuilder, value, max) { + var cols = value.search(this.$indentGuideRe); + if (cols <= 0 || cols >= max) + return value; + if (value[0] == " ") { + cols -= cols % this.tabSize; + stringBuilder.push(lang.stringRepeat(this.$tabStrings[" "], cols/this.tabSize)); + return value.substr(cols); + } else if (value[0] == "\t") { + stringBuilder.push(lang.stringRepeat(this.$tabStrings["\t"], cols)); + return value.substr(cols); } + return value; + }; - var splits = this.session.getRowSplitData(row); - var chars = 0, split = 0, splitChars; + this.$renderWrappedLine = function(stringBuilder, tokens, splits, onlyContents) { + var chars = 0; + var split = 0; + var splitChars = splits[0]; + var screenColumn = 0; - if (!splits || splits.length == 0) { - splitChars = Number.MAX_VALUE; - } else { - splitChars = splits[0]; - } - - stringBuilder.push("
    "); for (var i = 0; i < tokens.length; i++) { var token = tokens[i]; var value = token.value; + if (i == 0 && this.displayIndentGuides) { + chars = value.length; + value = this.renderIndentGuide(stringBuilder, value, splitChars); + if (!value) + continue; + chars -= value.length; + } if (chars + value.length < splitChars) { - addToken(token, value); + screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value); chars += value.length; } else { while (chars + value.length >= splitChars) { - addToken(token, value.substring(0, splitChars - chars)); + screenColumn = this.$renderToken( + stringBuilder, screenColumn, + token, value.substring(0, splitChars - chars) + ); value = value.substring(splitChars - chars); chars = splitChars; - stringBuilder.push("
    ", - "
    "); + + if (!onlyContents) { + stringBuilder.push("
    ", + "
    " + ); + } + + stringBuilder.push(lang.stringRepeat("\xa0", splits.indent)); + split ++; + screenColumn = 0; splitChars = splits[split] || Number.MAX_VALUE; } if (value.length != 0) { chars += value.length; - addToken(token, value); + screenColumn = this.$renderToken( + stringBuilder, screenColumn, token, value + ); } } - }; + } + }; + + this.$renderSimpleLine = function(stringBuilder, tokens) { + var screenColumn = 0; + var token = tokens[0]; + var value = token.value; + if (this.displayIndentGuides) + value = this.renderIndentGuide(stringBuilder, value); + if (value) + screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value); + for (var i = 1; i < tokens.length; i++) { + token = tokens[i]; + value = token.value; + screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value); + } + }; + + // row is either first row of foldline or not in fold + this.$renderLine = function(stringBuilder, row, onlyContents, foldLine) { + if (!foldLine && foldLine != false) + foldLine = this.session.getFoldLine(row); + + if (foldLine) + var tokens = this.$getFoldLineTokens(row, foldLine); + else + var tokens = this.session.getTokens(row); + + + if (!onlyContents) { + stringBuilder.push( + "
    " + ); + } + + if (tokens.length) { + var splits = this.session.getRowSplitData(row); + if (splits && splits.length) + this.$renderWrappedLine(stringBuilder, tokens, splits, onlyContents); + else + this.$renderSimpleLine(stringBuilder, tokens); + } if (this.showInvisibles) { - if (row !== this.session.getLength() - 1) { - stringBuilder.push("" + this.EOL_CHAR + ""); - } else { - stringBuilder.push("" + this.EOF_CHAR + ""); + if (foldLine) + row = foldLine.end.row + + stringBuilder.push( + "", + row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR, + "" + ); + } + if (!onlyContents) + stringBuilder.push("
    "); + }; + + this.$getFoldLineTokens = function(row, foldLine) { + var session = this.session; + var renderTokens = []; + + function addTokens(tokens, from, to) { + var idx = 0, col = 0; + while ((col + tokens[idx].value.length) < from) { + col += tokens[idx].value.length; + idx++; + + if (idx == tokens.length) + return; + } + if (col != from) { + var value = tokens[idx].value.substring(from - col); + // Check if the token value is longer then the from...to spacing. + if (value.length > (to - from)) + value = value.substring(0, to - from); + + renderTokens.push({ + type: tokens[idx].type, + value: value + }); + + col = from + value.length; + idx += 1; + } + + while (col < to && idx < tokens.length) { + var value = tokens[idx].value; + if (value.length + col > to) { + renderTokens.push({ + type: tokens[idx].type, + value: value.substring(0, to - col) + }); + } else + renderTokens.push(tokens[idx]); + col += value.length; + idx += 1; } } - stringBuilder.push("
    "); + + var tokens = session.getTokens(row); + foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) { + if (placeholder != null) { + renderTokens.push({ + type: "fold", + value: placeholder + }); + } else { + if (isNewRow) + tokens = session.getTokens(row); + + if (tokens.length) + addTokens(tokens, lastColumn, column); + } + }, foldLine.end.row, this.session.getLine(foldLine.end.row).length); + + return renderTokens; + }; + + this.$useLineGroups = function() { + // For the updateLines function to work correctly, it's important that the + // child nodes of this.element correspond on a 1-to-1 basis to rows in the + // document (as distinct from lines on the screen). For sessions that are + // wrapped, this means we need to add a layer to the node hierarchy (tagged + // with the class name ace_line_group). + return this.session.getUseWrapMode(); + }; + + this.destroy = function() { + clearInterval(this.$pollSizeChangesTimer); + if (this.$measureNode) + this.$measureNode.parentNode.removeChild(this.$measureNode); + delete this.$measureNode; }; }).call(Text.prototype); diff --git a/lib/ace/layer/text_test.js b/lib/ace/layer/text_test.js new file mode 100644 index 00000000..3946ec66 --- /dev/null +++ b/lib/ace/layer/text_test.js @@ -0,0 +1,126 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); + require("../test/mockdom"); +} + +define(function(require, exports, module) { +"use strict"; + +var assert = require("../test/assertions"); +var EditSession = require("../edit_session").EditSession; +var TextLayer = require("./text").Text; +var JavaScriptMode = require("../mode/javascript").Mode; + +module.exports = { + + setUp: function(next) { + this.session = new EditSession(""); + this.session.setMode(new JavaScriptMode()); + this.textLayer = new TextLayer(document.createElement("div")); + this.textLayer.setSession(this.session); + this.textLayer.config = { + characterWidth: 10, + lineHeight: 20 + }; + next() + }, + + "test: render line with hard tabs should render the same as lines with soft tabs" : function() { + this.session.setValue("a\ta\ta\t\na a a \n"); + this.textLayer.$computeTabString(); + + // row with hard tabs + var stringBuilder = []; + this.textLayer.$renderLine(stringBuilder, 0); + + // row with soft tabs + var stringBuilder2 = []; + this.textLayer.$renderLine(stringBuilder2, 1); + assert.equal(stringBuilder.join(""), stringBuilder2.join("")); + }, + + "test rendering width of ideographic space (U+3000)" : function() { + this.session.setValue("\u3000"); + + var stringBuilder = []; + this.textLayer.$renderLine(stringBuilder, 0, true); + assert.equal(stringBuilder.join(""), ""); + + this.textLayer.setShowInvisibles(true); + var stringBuilder = []; + this.textLayer.$renderLine(stringBuilder, 0, true); + assert.equal( + stringBuilder.join(""), + "" + this.textLayer.SPACE_CHAR + "" + + "\xB6" + ); + }, + + "test rendering of indent guides" : function() { + var textLayer = this.textLayer + var EOL = "" + textLayer.EOL_CHAR + ""; + var SPACE = function(i) {return Array(i+1).join(" ")} + var DOT = function(i) {return Array(i+1).join(textLayer.SPACE_CHAR)} + var TAB = function(i) {return Array(i+1).join(textLayer.TAB_CHAR)} + function testRender(results) { + for (var i = results.length; i--; ) { + var stringBuilder = []; + textLayer.$renderLine(stringBuilder, i, true); + assert.equal(stringBuilder.join(""), results[i]); + } + } + + this.session.setValue(" \n\t\tf\n "); + testRender([ + "" + SPACE(4) + "" + SPACE(2), + "" + SPACE(4) + "" + SPACE(4) + "f", + SPACE(3) + ]); + this.textLayer.setShowInvisibles(true); + testRender([ + "" + DOT(4) + "" + DOT(2) + "" + EOL, + "" + TAB(4) + "" + TAB(4) + "f" + EOL, + ]); + this.textLayer.setDisplayIndentGuides(false); + testRender([ + "" + DOT(6) + "" + EOL, + "" + TAB(4) + "" + TAB(4) + "f" + EOL + ]); + } +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} diff --git a/lib/ace/lib/app_config.js b/lib/ace/lib/app_config.js new file mode 100644 index 00000000..4fe78a1d --- /dev/null +++ b/lib/ace/lib/app_config.js @@ -0,0 +1,157 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"no use strict"; + +var oop = require("./oop"); +var EventEmitter = require("./event_emitter").EventEmitter; + +var optionsProvider = { + setOptions: function(optList) { + Object.keys(optList).forEach(function(key) { + this.setOption(key, optList[key]); + }, this); + }, + getOptions: function(optionNames) { + var result = {}; + if (!optionNames) { + optionNames = Object.keys(this.$options); + } else if (!Array.isArray(optionNames)) { + result = optionNames; + optionNames = Object.keys(result); + } + optionNames.forEach(function(key) { + result[key] = this.getOption(key); + }, this); + return result; + }, + setOption: function(name, value) { + if (this["$" + name] === value) + return; + var opt = this.$options[name]; + if (!opt) { + return warn('misspelled option "' + name + '"'); + } + if (opt.forwardTo) + return this[opt.forwardTo] && this[opt.forwardTo].setOption(name, value); + + if (!opt.handlesSet) + this["$" + name] = value; + if (opt && opt.set) + opt.set.call(this, value); + }, + getOption: function(name) { + var opt = this.$options[name]; + if (!opt) { + return warn('misspelled option "' + name + '"'); + } + if (opt.forwardTo) + return this[opt.forwardTo] && this[opt.forwardTo].getOption(name); + return opt && opt.get ? opt.get.call(this) : this["$" + name]; + } +}; + +function warn(message) { + if (typeof console != "undefined" && console.warn) + console.warn.apply(console, arguments); +} + +function reportError(msg, data) { + var e = new Error(msg); + e.data = data; + if (typeof console == "object" && console.error) + console.error(e); + setTimeout(function() { throw e; }); +} + +var AppConfig = function() { + this.$defaultOptions = {}; +}; + +(function() { + // module loading + oop.implement(this, EventEmitter); + /* + * option {name, value, initialValue, setterName, set, get } + */ + this.defineOptions = function(obj, path, options) { + if (!obj.$options) + this.$defaultOptions[path] = obj.$options = {}; + + Object.keys(options).forEach(function(key) { + var opt = options[key]; + if (typeof opt == "string") + opt = {forwardTo: opt}; + + opt.name || (opt.name = key); + obj.$options[opt.name] = opt; + if ("initialValue" in opt) + obj["$" + opt.name] = opt.initialValue; + }); + + // implement option provider interface + oop.implement(obj, optionsProvider); + + return this; + }; + + this.resetOptions = function(obj) { + Object.keys(obj.$options).forEach(function(key) { + var opt = obj.$options[key]; + if ("value" in opt) + obj.setOption(key, opt.value); + }); + }; + + this.setDefaultValue = function(path, name, value) { + var opts = this.$defaultOptions[path] || (this.$defaultOptions[path] = {}); + if (opts[name]) { + if (opts.forwardTo) + this.setDefaultValue(opts.forwardTo, name, value); + else + opts[name].value = value; + } + }; + + this.setDefaultValues = function(path, optionHash) { + Object.keys(optionHash).forEach(function(key) { + this.setDefaultValue(path, key, optionHash[key]); + }, this); + }; + + this.warn = warn; + this.reportError = reportError; + +}).call(AppConfig.prototype); + +exports.AppConfig = AppConfig; + +}); diff --git a/lib/ace/lib/dom.js b/lib/ace/lib/dom.js new file mode 100644 index 00000000..2cbfe23e --- /dev/null +++ b/lib/ace/lib/dom.js @@ -0,0 +1,286 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var XHTML_NS = "http://www.w3.org/1999/xhtml"; + +exports.getDocumentHead = function(doc) { + if (!doc) + doc = document; + return doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement; +} + +exports.createElement = function(tag, ns) { + return document.createElementNS ? + document.createElementNS(ns || XHTML_NS, tag) : + document.createElement(tag); +}; + +exports.hasCssClass = function(el, name) { + var classes = (el.className || "").split(/\s+/g); + return classes.indexOf(name) !== -1; +}; + +/* +* Add a CSS class to the list of classes on the given node +*/ +exports.addCssClass = function(el, name) { + if (!exports.hasCssClass(el, name)) { + el.className += " " + name; + } +}; + +/* +* Remove a CSS class from the list of classes on the given node +*/ +exports.removeCssClass = function(el, name) { + var classes = el.className.split(/\s+/g); + while (true) { + var index = classes.indexOf(name); + if (index == -1) { + break; + } + classes.splice(index, 1); + } + el.className = classes.join(" "); +}; + +exports.toggleCssClass = function(el, name) { + var classes = el.className.split(/\s+/g), add = true; + while (true) { + var index = classes.indexOf(name); + if (index == -1) { + break; + } + add = false; + classes.splice(index, 1); + } + if(add) + classes.push(name); + + el.className = classes.join(" "); + return add; +}; + +if (typeof document == "undefined") { + exports.importCssString = function() {}; + return; +} + +/* + * Add or remove a CSS class from the list of classes on the given node + * depending on the value of include + */ +exports.setCssClass = function(node, className, include) { + if (include) { + exports.addCssClass(node, className); + } else { + exports.removeCssClass(node, className); + } +}; + +exports.hasCssString = function(id, doc) { + var index = 0, sheets; + doc = doc || document; + + if (doc.createStyleSheet && (sheets = doc.styleSheets)) { + while (index < sheets.length) + if (sheets[index++].owningElement.id === id) return true; + } else if ((sheets = doc.getElementsByTagName("style"))) { + while (index < sheets.length) + if (sheets[index++].id === id) return true; + } + + return false; +}; + +exports.importCssString = function importCssString(cssText, id, doc) { + doc = doc || document; + // If style is already imported return immediately. + if (id && exports.hasCssString(id, doc)) + return null; + + var style; + + if (doc.createStyleSheet) { + style = doc.createStyleSheet(); + style.cssText = cssText; + if (id) + style.owningElement.id = id; + } else { + style = doc.createElementNS + ? doc.createElementNS(XHTML_NS, "style") + : doc.createElement("style"); + + style.appendChild(doc.createTextNode(cssText)); + if (id) + style.id = id; + + exports.getDocumentHead(doc).appendChild(style); + } +}; + +exports.importCssStylsheet = function(uri, doc) { + if (doc.createStyleSheet) { + doc.createStyleSheet(uri); + } else { + var link = exports.createElement('link'); + link.rel = 'stylesheet'; + link.href = uri; + + exports.getDocumentHead(doc).appendChild(link); + } +}; + +exports.getInnerWidth = function(element) { + return ( + parseInt(exports.computedStyle(element, "paddingLeft"), 10) + + parseInt(exports.computedStyle(element, "paddingRight"), 10) + + element.clientWidth + ); +}; + +exports.getInnerHeight = function(element) { + return ( + parseInt(exports.computedStyle(element, "paddingTop"), 10) + + parseInt(exports.computedStyle(element, "paddingBottom"), 10) + + element.clientHeight + ); +}; + + +if (window.pageYOffset !== undefined) { + exports.getPageScrollTop = function() { + return window.pageYOffset; + }; + + exports.getPageScrollLeft = function() { + return window.pageXOffset; + }; +} +else { + exports.getPageScrollTop = function() { + return document.body.scrollTop; + }; + + exports.getPageScrollLeft = function() { + return document.body.scrollLeft; + }; +} + +if (window.getComputedStyle) + exports.computedStyle = function(element, style) { + if (style) + return (window.getComputedStyle(element, "") || {})[style] || ""; + return window.getComputedStyle(element, "") || {}; + }; +else + exports.computedStyle = function(element, style) { + if (style) + return element.currentStyle[style]; + return element.currentStyle; + }; + +exports.scrollbarWidth = function(document) { + var inner = exports.createElement("ace_inner"); + inner.style.width = "100%"; + inner.style.minWidth = "0px"; + inner.style.height = "200px"; + inner.style.display = "block"; + + var outer = exports.createElement("ace_outer"); + var style = outer.style; + + style.position = "absolute"; + style.left = "-10000px"; + style.overflow = "hidden"; + style.width = "200px"; + style.minWidth = "0px"; + style.height = "150px"; + style.display = "block"; + + outer.appendChild(inner); + + var body = document.documentElement; + body.appendChild(outer); + + var noScrollbar = inner.offsetWidth; + + style.overflow = "scroll"; + var withScrollbar = inner.offsetWidth; + + if (noScrollbar == withScrollbar) { + withScrollbar = outer.clientWidth; + } + + body.removeChild(outer); + + return noScrollbar-withScrollbar; +}; + +/* + * Optimized set innerHTML. This is faster than plain innerHTML if the element + * already contains a lot of child elements. + * + * See http://blog.stevenlevithan.com/archives/faster-than-innerhtml for details + */ +exports.setInnerHtml = function(el, innerHtml) { + var element = el.cloneNode(false);//document.createElement("div"); + element.innerHTML = innerHtml; + el.parentNode.replaceChild(element, el); + return element; +}; + +if ("textContent" in document.documentElement) { + exports.setInnerText = function(el, innerText) { + el.textContent = innerText; + }; + + exports.getInnerText = function(el) { + return el.textContent; + }; +} +else { + exports.setInnerText = function(el, innerText) { + el.innerText = innerText; + }; + + exports.getInnerText = function(el) { + return el.innerText; + }; +} + +exports.getParentWindow = function(document) { + return document.defaultView || document.parentWindow; +}; + +}); diff --git a/lib/ace/lib/es5-shim.js b/lib/ace/lib/es5-shim.js new file mode 100644 index 00000000..217bdc61 --- /dev/null +++ b/lib/ace/lib/es5-shim.js @@ -0,0 +1,1062 @@ +// https://github.com/kriskowal/es5-shim +// Copyright 2009-2012 by contributors, MIT License + +define(function(require, exports, module) { + +/* + * Brings an environment as close to ECMAScript 5 compliance + * as is possible with the facilities of erstwhile engines. + * + * Annotated ES5: http://es5.github.com/ (specific links below) + * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf + * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/ + */ + +// +// Function +// ======== +// + +// ES-5 15.3.4.5 +// http://es5.github.com/#x15.3.4.5 + +function Empty() {} + +if (!Function.prototype.bind) { + Function.prototype.bind = function bind(that) { // .length is 1 + // 1. Let Target be the this value. + var target = this; + // 2. If IsCallable(Target) is false, throw a TypeError exception. + if (typeof target != "function") { + throw new TypeError("Function.prototype.bind called on incompatible " + target); + } + // 3. Let A be a new (possibly empty) internal list of all of the + // argument values provided after thisArg (arg1, arg2 etc), in order. + // XXX slicedArgs will stand in for "A" if used + var args = slice.call(arguments, 1); // for normal call + // 4. Let F be a new native ECMAScript object. + // 11. Set the [[Prototype]] internal property of F to the standard + // built-in Function prototype object as specified in 15.3.3.1. + // 12. Set the [[Call]] internal property of F as described in + // 15.3.4.5.1. + // 13. Set the [[Construct]] internal property of F as described in + // 15.3.4.5.2. + // 14. Set the [[HasInstance]] internal property of F as described in + // 15.3.4.5.3. + var bound = function () { + + if (this instanceof bound) { + // 15.3.4.5.2 [[Construct]] + // When the [[Construct]] internal method of a function object, + // F that was created using the bind function is called with a + // list of arguments ExtraArgs, the following steps are taken: + // 1. Let target be the value of F's [[TargetFunction]] + // internal property. + // 2. If target has no [[Construct]] internal method, a + // TypeError exception is thrown. + // 3. Let boundArgs be the value of F's [[BoundArgs]] internal + // property. + // 4. Let args be a new list containing the same values as the + // list boundArgs in the same order followed by the same + // values as the list ExtraArgs in the same order. + // 5. Return the result of calling the [[Construct]] internal + // method of target providing args as the arguments. + + var result = target.apply( + this, + args.concat(slice.call(arguments)) + ); + if (Object(result) === result) { + return result; + } + return this; + + } else { + // 15.3.4.5.1 [[Call]] + // When the [[Call]] internal method of a function object, F, + // which was created using the bind function is called with a + // this value and a list of arguments ExtraArgs, the following + // steps are taken: + // 1. Let boundArgs be the value of F's [[BoundArgs]] internal + // property. + // 2. Let boundThis be the value of F's [[BoundThis]] internal + // property. + // 3. Let target be the value of F's [[TargetFunction]] internal + // property. + // 4. Let args be a new list containing the same values as the + // list boundArgs in the same order followed by the same + // values as the list ExtraArgs in the same order. + // 5. Return the result of calling the [[Call]] internal method + // of target providing boundThis as the this value and + // providing args as the arguments. + + // equiv: target.call(this, ...boundArgs, ...args) + return target.apply( + that, + args.concat(slice.call(arguments)) + ); + + } + + }; + if(target.prototype) { + Empty.prototype = target.prototype; + bound.prototype = new Empty(); + // Clean up dangling references. + Empty.prototype = null; + } + // XXX bound.length is never writable, so don't even try + // + // 15. If the [[Class]] internal property of Target is "Function", then + // a. Let L be the length property of Target minus the length of A. + // b. Set the length own property of F to either 0 or L, whichever is + // larger. + // 16. Else set the length own property of F to 0. + // 17. Set the attributes of the length own property of F to the values + // specified in 15.3.5.1. + + // TODO + // 18. Set the [[Extensible]] internal property of F to true. + + // TODO + // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3). + // 20. Call the [[DefineOwnProperty]] internal method of F with + // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: + // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and + // false. + // 21. Call the [[DefineOwnProperty]] internal method of F with + // arguments "arguments", PropertyDescriptor {[[Get]]: thrower, + // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, + // and false. + + // TODO + // NOTE Function objects created using Function.prototype.bind do not + // have a prototype property or the [[Code]], [[FormalParameters]], and + // [[Scope]] internal properties. + // XXX can't delete prototype in pure-js. + + // 22. Return F. + return bound; + }; +} + +// Shortcut to an often accessed properties, in order to avoid multiple +// dereference that costs universally. +// _Please note: Shortcuts are defined after `Function.prototype.bind` as we +// us it in defining shortcuts. +var call = Function.prototype.call; +var prototypeOfArray = Array.prototype; +var prototypeOfObject = Object.prototype; +var slice = prototypeOfArray.slice; +// Having a toString local variable name breaks in Opera so use _toString. +var _toString = call.bind(prototypeOfObject.toString); +var owns = call.bind(prototypeOfObject.hasOwnProperty); + +// If JS engine supports accessors creating shortcuts. +var defineGetter; +var defineSetter; +var lookupGetter; +var lookupSetter; +var supportsAccessors; +if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) { + defineGetter = call.bind(prototypeOfObject.__defineGetter__); + defineSetter = call.bind(prototypeOfObject.__defineSetter__); + lookupGetter = call.bind(prototypeOfObject.__lookupGetter__); + lookupSetter = call.bind(prototypeOfObject.__lookupSetter__); +} + +// +// Array +// ===== +// + +// ES5 15.4.4.12 +// http://es5.github.com/#x15.4.4.12 +// Default value for second param +// [bugfix, ielt9, old browsers] +// IE < 9 bug: [1,2].splice(0).join("") == "" but should be "12" +if ([1,2].splice(0).length != 2) { + if(function() { // test IE < 9 to splice bug - see issue #138 + function makeArray(l) { + var a = new Array(l+2); + a[0] = a[1] = 0; + return a; + } + var array = [], lengthBefore; + + array.splice.apply(array, makeArray(20)); + array.splice.apply(array, makeArray(26)); + + lengthBefore = array.length; //46 + array.splice(5, 0, "XXX"); // add one element + + lengthBefore + 1 == array.length + + if (lengthBefore + 1 == array.length) { + return true;// has right splice implementation without bugs + } + // else { + // IE8 bug + // } + }()) {//IE 6/7 + var array_splice = Array.prototype.splice; + Array.prototype.splice = function(start, deleteCount) { + if (!arguments.length) { + return []; + } else { + return array_splice.apply(this, [ + start === void 0 ? 0 : start, + deleteCount === void 0 ? (this.length - start) : deleteCount + ].concat(slice.call(arguments, 2))) + } + }; + } else {//IE8 + // taken from http://docs.sencha.com/ext-js/4-1/source/Array2.html + Array.prototype.splice = function(pos, removeCount){ + var length = this.length; + if (pos > 0) { + if (pos > length) + pos = length; + } else if (pos == void 0) { + pos = 0; + } else if (pos < 0) { + pos = Math.max(length + pos, 0); + } + + if (!(pos+removeCount < length)) + removeCount = length - pos; + + var removed = this.slice(pos, pos+removeCount); + var insert = slice.call(arguments, 2); + var add = insert.length; + + // we try to use Array.push when we can for efficiency... + if (pos === length) { + if (add) { + this.push.apply(this, insert); + } + } else { + var remove = Math.min(removeCount, length - pos); + var tailOldPos = pos + remove; + var tailNewPos = tailOldPos + add - remove; + var tailCount = length - tailOldPos; + var lengthAfterRemove = length - remove; + + if (tailNewPos < tailOldPos) { // case A + for (var i = 0; i < tailCount; ++i) { + this[tailNewPos+i] = this[tailOldPos+i]; + } + } else if (tailNewPos > tailOldPos) { // case B + for (i = tailCount; i--; ) { + this[tailNewPos+i] = this[tailOldPos+i]; + } + } // else, add == remove (nothing to do) + + if (add && pos === lengthAfterRemove) { + this.length = lengthAfterRemove; // truncate array + this.push.apply(this, insert); + } else { + this.length = lengthAfterRemove + add; // reserves space + for (i = 0; i < add; ++i) { + this[pos+i] = insert[i]; + } + } + } + return removed; + }; + } +} + +// ES5 15.4.3.2 +// http://es5.github.com/#x15.4.3.2 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray +if (!Array.isArray) { + Array.isArray = function isArray(obj) { + return _toString(obj) == "[object Array]"; + }; +} + +// The IsCallable() check in the Array functions +// has been replaced with a strict check on the +// internal class of the object to trap cases where +// the provided function was actually a regular +// expression literal, which in V8 and +// JavaScriptCore is a typeof "function". Only in +// V8 are regular expression literals permitted as +// reduce parameters, so it is desirable in the +// general case for the shim to match the more +// strict and common behavior of rejecting regular +// expressions. + +// ES5 15.4.4.18 +// http://es5.github.com/#x15.4.4.18 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach + +// Check failure of by-index access of string characters (IE < 9) +// and failure of `0 in boxedString` (Rhino) +var boxedString = Object("a"), + splitString = boxedString[0] != "a" || !(0 in boxedString); + +if (!Array.prototype.forEach) { + Array.prototype.forEach = function forEach(fun /*, thisp*/) { + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, + thisp = arguments[1], + i = -1, + length = self.length >>> 0; + + // If no callback function or if callback is not a callable function + if (_toString(fun) != "[object Function]") { + throw new TypeError(); // TODO message + } + + while (++i < length) { + if (i in self) { + // Invoke the callback function with call, passing arguments: + // context, property value, property key, thisArg object + // context + fun.call(thisp, self[i], i, object); + } + } + }; +} + +// ES5 15.4.4.19 +// http://es5.github.com/#x15.4.4.19 +// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map +if (!Array.prototype.map) { + Array.prototype.map = function map(fun /*, thisp*/) { + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, + length = self.length >>> 0, + result = Array(length), + thisp = arguments[1]; + + // If no callback function or if callback is not a callable function + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + for (var i = 0; i < length; i++) { + if (i in self) + result[i] = fun.call(thisp, self[i], i, object); + } + return result; + }; +} + +// ES5 15.4.4.20 +// http://es5.github.com/#x15.4.4.20 +// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter +if (!Array.prototype.filter) { + Array.prototype.filter = function filter(fun /*, thisp */) { + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, + length = self.length >>> 0, + result = [], + value, + thisp = arguments[1]; + + // If no callback function or if callback is not a callable function + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + for (var i = 0; i < length; i++) { + if (i in self) { + value = self[i]; + if (fun.call(thisp, value, i, object)) { + result.push(value); + } + } + } + return result; + }; +} + +// ES5 15.4.4.16 +// http://es5.github.com/#x15.4.4.16 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every +if (!Array.prototype.every) { + Array.prototype.every = function every(fun /*, thisp */) { + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, + length = self.length >>> 0, + thisp = arguments[1]; + + // If no callback function or if callback is not a callable function + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + for (var i = 0; i < length; i++) { + if (i in self && !fun.call(thisp, self[i], i, object)) { + return false; + } + } + return true; + }; +} + +// ES5 15.4.4.17 +// http://es5.github.com/#x15.4.4.17 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some +if (!Array.prototype.some) { + Array.prototype.some = function some(fun /*, thisp */) { + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, + length = self.length >>> 0, + thisp = arguments[1]; + + // If no callback function or if callback is not a callable function + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + for (var i = 0; i < length; i++) { + if (i in self && fun.call(thisp, self[i], i, object)) { + return true; + } + } + return false; + }; +} + +// ES5 15.4.4.21 +// http://es5.github.com/#x15.4.4.21 +// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce +if (!Array.prototype.reduce) { + Array.prototype.reduce = function reduce(fun /*, initial*/) { + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, + length = self.length >>> 0; + + // If no callback function or if callback is not a callable function + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + // no value to return if no initial value and an empty array + if (!length && arguments.length == 1) { + throw new TypeError("reduce of empty array with no initial value"); + } + + var i = 0; + var result; + if (arguments.length >= 2) { + result = arguments[1]; + } else { + do { + if (i in self) { + result = self[i++]; + break; + } + + // if array contains no values, no initial value to return + if (++i >= length) { + throw new TypeError("reduce of empty array with no initial value"); + } + } while (true); + } + + for (; i < length; i++) { + if (i in self) { + result = fun.call(void 0, result, self[i], i, object); + } + } + + return result; + }; +} + +// ES5 15.4.4.22 +// http://es5.github.com/#x15.4.4.22 +// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight +if (!Array.prototype.reduceRight) { + Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) { + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, + length = self.length >>> 0; + + // If no callback function or if callback is not a callable function + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + // no value to return if no initial value, empty array + if (!length && arguments.length == 1) { + throw new TypeError("reduceRight of empty array with no initial value"); + } + + var result, i = length - 1; + if (arguments.length >= 2) { + result = arguments[1]; + } else { + do { + if (i in self) { + result = self[i--]; + break; + } + + // if array contains no values, no initial value to return + if (--i < 0) { + throw new TypeError("reduceRight of empty array with no initial value"); + } + } while (true); + } + + do { + if (i in this) { + result = fun.call(void 0, result, self[i], i, object); + } + } while (i--); + + return result; + }; +} + +// ES5 15.4.4.14 +// http://es5.github.com/#x15.4.4.14 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf +if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) { + Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) { + var self = splitString && _toString(this) == "[object String]" ? + this.split("") : + toObject(this), + length = self.length >>> 0; + + if (!length) { + return -1; + } + + var i = 0; + if (arguments.length > 1) { + i = toInteger(arguments[1]); + } + + // handle negative indices + i = i >= 0 ? i : Math.max(0, length + i); + for (; i < length; i++) { + if (i in self && self[i] === sought) { + return i; + } + } + return -1; + }; +} + +// ES5 15.4.4.15 +// http://es5.github.com/#x15.4.4.15 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf +if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) { + Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) { + var self = splitString && _toString(this) == "[object String]" ? + this.split("") : + toObject(this), + length = self.length >>> 0; + + if (!length) { + return -1; + } + var i = length - 1; + if (arguments.length > 1) { + i = Math.min(i, toInteger(arguments[1])); + } + // handle negative indices + i = i >= 0 ? i : length - Math.abs(i); + for (; i >= 0; i--) { + if (i in self && sought === self[i]) { + return i; + } + } + return -1; + }; +} + +// +// Object +// ====== +// + +// ES5 15.2.3.2 +// http://es5.github.com/#x15.2.3.2 +if (!Object.getPrototypeOf) { + // https://github.com/kriskowal/es5-shim/issues#issue/2 + // http://ejohn.org/blog/objectgetprototypeof/ + // recommended by fschaefer on github + Object.getPrototypeOf = function getPrototypeOf(object) { + return object.__proto__ || ( + object.constructor ? + object.constructor.prototype : + prototypeOfObject + ); + }; +} + +// ES5 15.2.3.3 +// http://es5.github.com/#x15.2.3.3 +if (!Object.getOwnPropertyDescriptor) { + var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " + + "non-object: "; + Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) { + if ((typeof object != "object" && typeof object != "function") || object === null) + throw new TypeError(ERR_NON_OBJECT + object); + // If object does not owns property return undefined immediately. + if (!owns(object, property)) + return; + + var descriptor, getter, setter; + + // If object has a property then it's for sure both `enumerable` and + // `configurable`. + descriptor = { enumerable: true, configurable: true }; + + // If JS engine supports accessor properties then property may be a + // getter or setter. + if (supportsAccessors) { + // Unfortunately `__lookupGetter__` will return a getter even + // if object has own non getter property along with a same named + // inherited getter. To avoid misbehavior we temporary remove + // `__proto__` so that `__lookupGetter__` will return getter only + // if it's owned by an object. + var prototype = object.__proto__; + object.__proto__ = prototypeOfObject; + + var getter = lookupGetter(object, property); + var setter = lookupSetter(object, property); + + // Once we have getter and setter we can put values back. + object.__proto__ = prototype; + + if (getter || setter) { + if (getter) descriptor.get = getter; + if (setter) descriptor.set = setter; + + // If it was accessor property we're done and return here + // in order to avoid adding `value` to the descriptor. + return descriptor; + } + } + + // If we got this far we know that object has an own property that is + // not an accessor so we set it as a value and return descriptor. + descriptor.value = object[property]; + return descriptor; + }; +} + +// ES5 15.2.3.4 +// http://es5.github.com/#x15.2.3.4 +if (!Object.getOwnPropertyNames) { + Object.getOwnPropertyNames = function getOwnPropertyNames(object) { + return Object.keys(object); + }; +} + +// ES5 15.2.3.5 +// http://es5.github.com/#x15.2.3.5 +if (!Object.create) { + var createEmpty; + if (Object.prototype.__proto__ === null) { + createEmpty = function () { + return { "__proto__": null }; + }; + } else { + // In old IE __proto__ can't be used to manually set `null` + createEmpty = function () { + var empty = {}; + for (var i in empty) + empty[i] = null; + empty.constructor = + empty.hasOwnProperty = + empty.propertyIsEnumerable = + empty.isPrototypeOf = + empty.toLocaleString = + empty.toString = + empty.valueOf = + empty.__proto__ = null; + return empty; + } + } + + Object.create = function create(prototype, properties) { + var object; + if (prototype === null) { + object = createEmpty(); + } else { + if (typeof prototype != "object") + throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'"); + var Type = function () {}; + Type.prototype = prototype; + object = new Type(); + // IE has no built-in implementation of `Object.getPrototypeOf` + // neither `__proto__`, but this manually setting `__proto__` will + // guarantee that `Object.getPrototypeOf` will work as expected with + // objects created using `Object.create` + object.__proto__ = prototype; + } + if (properties !== void 0) + Object.defineProperties(object, properties); + return object; + }; +} + +// ES5 15.2.3.6 +// http://es5.github.com/#x15.2.3.6 + +// Patch for WebKit and IE8 standard mode +// Designed by hax +// related issue: https://github.com/kriskowal/es5-shim/issues#issue/5 +// IE8 Reference: +// http://msdn.microsoft.com/en-us/library/dd282900.aspx +// http://msdn.microsoft.com/en-us/library/dd229916.aspx +// WebKit Bugs: +// https://bugs.webkit.org/show_bug.cgi?id=36423 + +function doesDefinePropertyWork(object) { + try { + Object.defineProperty(object, "sentinel", {}); + return "sentinel" in object; + } catch (exception) { + // returns falsy + } +} + +// check whether defineProperty works if it's given. Otherwise, +// shim partially. +if (Object.defineProperty) { + var definePropertyWorksOnObject = doesDefinePropertyWork({}); + var definePropertyWorksOnDom = typeof document == "undefined" || + doesDefinePropertyWork(document.createElement("div")); + if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) { + var definePropertyFallback = Object.defineProperty; + } +} + +if (!Object.defineProperty || definePropertyFallback) { + var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: "; + var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: " + var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " + + "on this javascript engine"; + + Object.defineProperty = function defineProperty(object, property, descriptor) { + if ((typeof object != "object" && typeof object != "function") || object === null) + throw new TypeError(ERR_NON_OBJECT_TARGET + object); + if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null) + throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor); + + // make a valiant attempt to use the real defineProperty + // for I8's DOM elements. + if (definePropertyFallback) { + try { + return definePropertyFallback.call(Object, object, property, descriptor); + } catch (exception) { + // try the shim if the real one doesn't work + } + } + + // If it's a data property. + if (owns(descriptor, "value")) { + // fail silently if "writable", "enumerable", or "configurable" + // are requested but not supported + /* + // alternate approach: + if ( // can't implement these features; allow false but not true + !(owns(descriptor, "writable") ? descriptor.writable : true) || + !(owns(descriptor, "enumerable") ? descriptor.enumerable : true) || + !(owns(descriptor, "configurable") ? descriptor.configurable : true) + ) + throw new RangeError( + "This implementation of Object.defineProperty does not " + + "support configurable, enumerable, or writable." + ); + */ + + if (supportsAccessors && (lookupGetter(object, property) || + lookupSetter(object, property))) + { + // As accessors are supported only on engines implementing + // `__proto__` we can safely override `__proto__` while defining + // a property to make sure that we don't hit an inherited + // accessor. + var prototype = object.__proto__; + object.__proto__ = prototypeOfObject; + // Deleting a property anyway since getter / setter may be + // defined on object itself. + delete object[property]; + object[property] = descriptor.value; + // Setting original `__proto__` back now. + object.__proto__ = prototype; + } else { + object[property] = descriptor.value; + } + } else { + if (!supportsAccessors) + throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED); + // If we got that far then getters and setters can be defined !! + if (owns(descriptor, "get")) + defineGetter(object, property, descriptor.get); + if (owns(descriptor, "set")) + defineSetter(object, property, descriptor.set); + } + + return object; + }; +} + +// ES5 15.2.3.7 +// http://es5.github.com/#x15.2.3.7 +if (!Object.defineProperties) { + Object.defineProperties = function defineProperties(object, properties) { + for (var property in properties) { + if (owns(properties, property)) + Object.defineProperty(object, property, properties[property]); + } + return object; + }; +} + +// ES5 15.2.3.8 +// http://es5.github.com/#x15.2.3.8 +if (!Object.seal) { + Object.seal = function seal(object) { + // this is misleading and breaks feature-detection, but + // allows "securable" code to "gracefully" degrade to working + // but insecure code. + return object; + }; +} + +// ES5 15.2.3.9 +// http://es5.github.com/#x15.2.3.9 +if (!Object.freeze) { + Object.freeze = function freeze(object) { + // this is misleading and breaks feature-detection, but + // allows "securable" code to "gracefully" degrade to working + // but insecure code. + return object; + }; +} + +// detect a Rhino bug and patch it +try { + Object.freeze(function () {}); +} catch (exception) { + Object.freeze = (function freeze(freezeObject) { + return function freeze(object) { + if (typeof object == "function") { + return object; + } else { + return freezeObject(object); + } + }; + })(Object.freeze); +} + +// ES5 15.2.3.10 +// http://es5.github.com/#x15.2.3.10 +if (!Object.preventExtensions) { + Object.preventExtensions = function preventExtensions(object) { + // this is misleading and breaks feature-detection, but + // allows "securable" code to "gracefully" degrade to working + // but insecure code. + return object; + }; +} + +// ES5 15.2.3.11 +// http://es5.github.com/#x15.2.3.11 +if (!Object.isSealed) { + Object.isSealed = function isSealed(object) { + return false; + }; +} + +// ES5 15.2.3.12 +// http://es5.github.com/#x15.2.3.12 +if (!Object.isFrozen) { + Object.isFrozen = function isFrozen(object) { + return false; + }; +} + +// ES5 15.2.3.13 +// http://es5.github.com/#x15.2.3.13 +if (!Object.isExtensible) { + Object.isExtensible = function isExtensible(object) { + // 1. If Type(O) is not Object throw a TypeError exception. + if (Object(object) === object) { + throw new TypeError(); // TODO message + } + // 2. Return the Boolean value of the [[Extensible]] internal property of O. + var name = ''; + while (owns(object, name)) { + name += '?'; + } + object[name] = true; + var returnValue = owns(object, name); + delete object[name]; + return returnValue; + }; +} + +// ES5 15.2.3.14 +// http://es5.github.com/#x15.2.3.14 +if (!Object.keys) { + // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation + var hasDontEnumBug = true, + dontEnums = [ + "toString", + "toLocaleString", + "valueOf", + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable", + "constructor" + ], + dontEnumsLength = dontEnums.length; + + for (var key in {"toString": null}) { + hasDontEnumBug = false; + } + + Object.keys = function keys(object) { + + if ( + (typeof object != "object" && typeof object != "function") || + object === null + ) { + throw new TypeError("Object.keys called on a non-object"); + } + + var keys = []; + for (var name in object) { + if (owns(object, name)) { + keys.push(name); + } + } + + if (hasDontEnumBug) { + for (var i = 0, ii = dontEnumsLength; i < ii; i++) { + var dontEnum = dontEnums[i]; + if (owns(object, dontEnum)) { + keys.push(dontEnum); + } + } + } + return keys; + }; + +} + +// +// most of es5-shim Date section is removed since ace doesn't need it, it is too intrusive and it causes problems for users +// ==== +// + +// ES5 15.9.4.4 +// http://es5.github.com/#x15.9.4.4 +if (!Date.now) { + Date.now = function now() { + return new Date().getTime(); + }; +} + + +// +// String +// ====== +// + +// ES5 15.5.4.20 +// http://es5.github.com/#x15.5.4.20 +var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" + + "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + + "\u2029\uFEFF"; +if (!String.prototype.trim || ws.trim()) { + // http://blog.stevenlevithan.com/archives/faster-trim-javascript + // http://perfectionkills.com/whitespace-deviations/ + ws = "[" + ws + "]"; + var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), + trimEndRegexp = new RegExp(ws + ws + "*$"); + String.prototype.trim = function trim() { + return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, ""); + }; +} + +// +// Util +// ====== +// + +// ES5 9.4 +// http://es5.github.com/#x9.4 +// http://jsperf.com/to-integer + +function toInteger(n) { + n = +n; + if (n !== n) { // isNaN + n = 0; + } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) { + n = (n > 0 || -1) * Math.floor(Math.abs(n)); + } + return n; +} + +function isPrimitive(input) { + var type = typeof input; + return ( + input === null || + type === "undefined" || + type === "boolean" || + type === "number" || + type === "string" + ); +} + +function toPrimitive(input) { + var val, valueOf, toString; + if (isPrimitive(input)) { + return input; + } + valueOf = input.valueOf; + if (typeof valueOf === "function") { + val = valueOf.call(input); + if (isPrimitive(val)) { + return val; + } + } + toString = input.toString; + if (typeof toString === "function") { + val = toString.call(input); + if (isPrimitive(val)) { + return val; + } + } + throw new TypeError(); +} + +// ES5 9.9 +// http://es5.github.com/#x9.9 +var toObject = function (o) { + if (o == null) { // this matches both null and undefined + throw new TypeError("can't convert "+o+" to object"); + } + return Object(o); +}; + +}); diff --git a/lib/ace/lib/event.js b/lib/ace/lib/event.js new file mode 100644 index 00000000..57924056 --- /dev/null +++ b/lib/ace/lib/event.js @@ -0,0 +1,367 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var keys = require("./keys"); +var useragent = require("./useragent"); + +exports.addListener = function(elem, type, callback) { + if (elem.addEventListener) { + return elem.addEventListener(type, callback, false); + } + if (elem.attachEvent) { + var wrapper = function() { + callback.call(elem, window.event); + }; + callback._wrapper = wrapper; + elem.attachEvent("on" + type, wrapper); + } +}; + +exports.removeListener = function(elem, type, callback) { + if (elem.removeEventListener) { + return elem.removeEventListener(type, callback, false); + } + if (elem.detachEvent) { + elem.detachEvent("on" + type, callback._wrapper || callback); + } +}; + +/* +* Prevents propagation and clobbers the default action of the passed event +*/ +exports.stopEvent = function(e) { + exports.stopPropagation(e); + exports.preventDefault(e); + return false; +}; + +exports.stopPropagation = function(e) { + if (e.stopPropagation) + e.stopPropagation(); + else + e.cancelBubble = true; +}; + +exports.preventDefault = function(e) { + if (e.preventDefault) + e.preventDefault(); + else + e.returnValue = false; +}; + +/* + * @return {Number} 0 for left button, 1 for middle button, 2 for right button + */ +exports.getButton = function(e) { + if (e.type == "dblclick") + return 0; + if (e.type == "contextmenu" || (useragent.isMac && (e.ctrlKey && !e.altKey && !e.shiftKey))) + return 2; + + // DOM Event + if (e.preventDefault) { + return e.button; + } + // old IE + else { + return {1:0, 2:2, 4:1}[e.button]; + } +}; + +exports.capture = function(el, eventHandler, releaseCaptureHandler) { + function onMouseUp(e) { + eventHandler && eventHandler(e); + releaseCaptureHandler && releaseCaptureHandler(e); + + exports.removeListener(document, "mousemove", eventHandler, true); + exports.removeListener(document, "mouseup", onMouseUp, true); + exports.removeListener(document, "dragstart", onMouseUp, true); + } + + exports.addListener(document, "mousemove", eventHandler, true); + exports.addListener(document, "mouseup", onMouseUp, true); + exports.addListener(document, "dragstart", onMouseUp, true); + + return onMouseUp; +}; + +exports.addMouseWheelListener = function(el, callback) { + if ("onmousewheel" in el) { + exports.addListener(el, "mousewheel", function(e) { + var factor = 8; + if (e.wheelDeltaX !== undefined) { + e.wheelX = -e.wheelDeltaX / factor; + e.wheelY = -e.wheelDeltaY / factor; + } else { + e.wheelX = 0; + e.wheelY = -e.wheelDelta / factor; + } + callback(e); + }); + } else if ("onwheel" in el) { + exports.addListener(el, "wheel", function(e) { + var factor = 0.35; + switch (e.deltaMode) { + case e.DOM_DELTA_PIXEL: + e.wheelX = e.deltaX * factor || 0; + e.wheelY = e.deltaY * factor || 0; + break; + case e.DOM_DELTA_LINE: + case e.DOM_DELTA_PAGE: + e.wheelX = (e.deltaX || 0) * 5; + e.wheelY = (e.deltaY || 0) * 5; + break; + } + + callback(e); + }); + } else { + exports.addListener(el, "DOMMouseScroll", function(e) { + if (e.axis && e.axis == e.HORIZONTAL_AXIS) { + e.wheelX = (e.detail || 0) * 5; + e.wheelY = 0; + } else { + e.wheelX = 0; + e.wheelY = (e.detail || 0) * 5; + } + callback(e); + }); + } +}; + +exports.addMultiMouseDownListener = function(el, timeouts, eventHandler, callbackName) { + var clicks = 0; + var startX, startY, timer; + var eventNames = { + 2: "dblclick", + 3: "tripleclick", + 4: "quadclick" + }; + + exports.addListener(el, "mousedown", function(e) { + if (exports.getButton(e) !== 0) { + clicks = 0; + } else if (e.detail > 1) { + clicks++; + if (clicks > 4) + clicks = 1; + } else { + clicks = 1; + } + if (useragent.isIE) { + var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5; + if (!timer || isNewClick) + clicks = 1; + if (timer) + clearTimeout(timer); + timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600); + + if (clicks == 1) { + startX = e.clientX; + startY = e.clientY; + } + } + + e._clicks = clicks; + + eventHandler[callbackName]("mousedown", e); + + if (clicks > 4) + clicks = 0; + else if (clicks > 1) + return eventHandler[callbackName](eventNames[clicks], e); + }); + + if (useragent.isOldIE) { + exports.addListener(el, "dblclick", function(e) { + clicks = 2; + if (timer) + clearTimeout(timer); + timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600); + eventHandler[callbackName]("mousedown", e); + eventHandler[callbackName](eventNames[clicks], e); + }); + } +}; + +var getModifierHash = useragent.isMac && useragent.isOpera && !("KeyboardEvent" in window) + ? function(e) { + return 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0); + } + : function(e) { + return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0); + }; + +exports.getModifierString = function(e) { + return keys.KEY_MODS[getModifierHash(e)]; +}; + +function normalizeCommandKeys(callback, e, keyCode) { + var hashId = getModifierHash(e); + + if (!useragent.isMac && pressedKeys) { + if (pressedKeys[91] || pressedKeys[92]) + hashId |= 8; + if (pressedKeys.altGr) { + if ((3 & hashId) != 3) + pressedKeys.altGr = 0; + else + return; + } + if (keyCode === 18 || keyCode === 17) { + var location = "location" in e ? e.location : e.keyLocation; + if (keyCode === 17 && location === 1) { + if (pressedKeys[keyCode] == 1) + ts = e.timeStamp; + } else if (keyCode === 18 && hashId === 3 && location === 2) { + var dt = e.timeStamp - ts; + if (dt < 50) + pressedKeys.altGr = true; + } + } + } + + if (keyCode in keys.MODIFIER_KEYS) { + keyCode = -1; + } + + if (hashId & 8 && (keyCode === 91 || keyCode === 93)) { + keyCode = -1; + } + + if (!hashId && keyCode === 13) { + var location = "location" in e ? e.location : e.keyLocation; + if (location === 3) { + callback(e, hashId, -keyCode); + if (e.defaultPrevented) + return; + } + } + + if (useragent.isChromeOS && hashId & 8) { + callback(e, hashId, keyCode); + if (e.defaultPrevented) + return; + else + hashId &= ~8; + } + + // If there is no hashId and the keyCode is not a function key, then + // we don't call the callback as we don't handle a command key here + // (it's a normal key/character input). + if (!hashId && !(keyCode in keys.FUNCTION_KEYS) && !(keyCode in keys.PRINTABLE_KEYS)) { + return false; + } + + return callback(e, hashId, keyCode); +} + +var pressedKeys = null; +var ts = 0; +exports.addCommandKeyListener = function(el, callback) { + var addListener = exports.addListener; + if (useragent.isOldGecko || (useragent.isOpera && !("KeyboardEvent" in window))) { + // Old versions of Gecko aka. Firefox < 4.0 didn't repeat the keydown + // event if the user pressed the key for a longer time. Instead, the + // keydown event was fired once and later on only the keypress event. + // To emulate the 'right' keydown behavior, the keyCode of the initial + // keyDown event is stored and in the following keypress events the + // stores keyCode is used to emulate a keyDown event. + var lastKeyDownKeyCode = null; + addListener(el, "keydown", function(e) { + lastKeyDownKeyCode = e.keyCode; + }); + addListener(el, "keypress", function(e) { + return normalizeCommandKeys(callback, e, lastKeyDownKeyCode); + }); + } else { + var lastDefaultPrevented = null; + + addListener(el, "keydown", function(e) { + pressedKeys[e.keyCode] = (pressedKeys[e.keyCode] || 0) + 1; + var result = normalizeCommandKeys(callback, e, e.keyCode); + lastDefaultPrevented = e.defaultPrevented; + return result; + }); + + addListener(el, "keypress", function(e) { + if (lastDefaultPrevented && (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey)) { + exports.stopEvent(e); + lastDefaultPrevented = null; + } + }); + + addListener(el, "keyup", function(e) { + pressedKeys[e.keyCode] = null; + }); + + if (!pressedKeys) { + resetPressedKeys(); + addListener(window, "focus", resetPressedKeys); + } + } +}; +function resetPressedKeys(e) { + pressedKeys = Object.create(null); +} + +if (window.postMessage && !useragent.isOldIE) { + var postMessageId = 1; + exports.nextTick = function(callback, win) { + win = win || window; + var messageName = "zero-timeout-message-" + postMessageId; + exports.addListener(win, "message", function listener(e) { + if (e.data == messageName) { + exports.stopPropagation(e); + exports.removeListener(win, "message", listener); + callback(); + } + }); + win.postMessage(messageName, "*"); + }; +} + + +exports.nextFrame = window.requestAnimationFrame || + window.mozRequestAnimationFrame || + window.webkitRequestAnimationFrame || + window.msRequestAnimationFrame || + window.oRequestAnimationFrame; + +if (exports.nextFrame) + exports.nextFrame = exports.nextFrame.bind(window); +else + exports.nextFrame = function(callback) { + setTimeout(callback, 17); + }; +}); diff --git a/lib/ace/lib/event_emitter.js b/lib/ace/lib/event_emitter.js new file mode 100644 index 00000000..b9860145 --- /dev/null +++ b/lib/ace/lib/event_emitter.js @@ -0,0 +1,155 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var EventEmitter = {}; +var stopPropagation = function() { this.propagationStopped = true; }; +var preventDefault = function() { this.defaultPrevented = true; }; + +EventEmitter._emit = +EventEmitter._dispatchEvent = function(eventName, e) { + this._eventRegistry || (this._eventRegistry = {}); + this._defaultHandlers || (this._defaultHandlers = {}); + + var listeners = this._eventRegistry[eventName] || []; + var defaultHandler = this._defaultHandlers[eventName]; + if (!listeners.length && !defaultHandler) + return; + + if (typeof e != "object" || !e) + e = {}; + + if (!e.type) + e.type = eventName; + if (!e.stopPropagation) + e.stopPropagation = stopPropagation; + if (!e.preventDefault) + e.preventDefault = preventDefault; + + listeners = listeners.slice(); + for (var i=0; i 0) { + if (count & 1) + result += string; + + if (count >>= 1) + string += string; + } + return result; +}; + +var trimBeginRegexp = /^\s\s*/; +var trimEndRegexp = /\s\s*$/; + +exports.stringTrimLeft = function (string) { + return string.replace(trimBeginRegexp, ''); +}; + +exports.stringTrimRight = function (string) { + return string.replace(trimEndRegexp, ''); +}; + +exports.copyObject = function(obj) { + var copy = {}; + for (var key in obj) { + copy[key] = obj[key]; + } + return copy; +}; + +exports.copyArray = function(array){ + var copy = []; + for (var i=0, l=array.length; i + * Provides an augmented, extensible, cross-browser implementation of regular expressions, + * including support for additional syntax, flags, and methods + */ + +define(function(require, exports, module) { +"use strict"; + + //--------------------------------- + // Private variables + //--------------------------------- + + var real = { + exec: RegExp.prototype.exec, + test: RegExp.prototype.test, + match: String.prototype.match, + replace: String.prototype.replace, + split: String.prototype.split + }, + compliantExecNpcg = real.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups + compliantLastIndexIncrement = function () { + var x = /^/g; + real.test.call(x, ""); + return !x.lastIndex; + }(); + + if (compliantLastIndexIncrement && compliantExecNpcg) + return; + + //--------------------------------- + // Overriden native methods + //--------------------------------- + + // Adds named capture support (with backreferences returned as `result.name`), and fixes two + // cross-browser issues per ES3: + // - Captured values for nonparticipating capturing groups should be returned as `undefined`, + // rather than the empty string. + // - `lastIndex` should not be incremented after zero-length matches. + RegExp.prototype.exec = function (str) { + var match = real.exec.apply(this, arguments), + name, r2; + if ( typeof(str) == 'string' && match) { + // Fix browsers whose `exec` methods don't consistently return `undefined` for + // nonparticipating capturing groups + if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) { + r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), "g", "")); + // Using `str.slice(match.index)` rather than `match[0]` in case lookahead allowed + // matching due to characters outside the match + real.replace.call(str.slice(match.index), r2, function () { + for (var i = 1; i < arguments.length - 2; i++) { + if (arguments[i] === undefined) + match[i] = undefined; + } + }); + } + // Attach named capture properties + if (this._xregexp && this._xregexp.captureNames) { + for (var i = 1; i < match.length; i++) { + name = this._xregexp.captureNames[i - 1]; + if (name) + match[name] = match[i]; + } + } + // Fix browsers that increment `lastIndex` after zero-length matches + if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index)) + this.lastIndex--; + } + return match; + }; + + // Don't override `test` if it won't change anything + if (!compliantLastIndexIncrement) { + // Fix browser bug in native method + RegExp.prototype.test = function (str) { + // Use the native `exec` to skip some processing overhead, even though the overriden + // `exec` would take care of the `lastIndex` fix + var match = real.exec.call(this, str); + // Fix browsers that increment `lastIndex` after zero-length matches + if (match && this.global && !match[0].length && (this.lastIndex > match.index)) + this.lastIndex--; + return !!match; + }; + } + + //--------------------------------- + // Private helper functions + //--------------------------------- + + function getNativeFlags (regex) { + return (regex.global ? "g" : "") + + (regex.ignoreCase ? "i" : "") + + (regex.multiline ? "m" : "") + + (regex.extended ? "x" : "") + // Proposed for ES4; included in AS3 + (regex.sticky ? "y" : ""); + } + + function indexOf (array, item, from) { + if (Array.prototype.indexOf) // Use the native array method if available + return array.indexOf(item, from); + for (var i = from || 0; i < array.length; i++) { + if (array[i] === item) + return i; + } + return -1; + } + +}); diff --git a/lib/ace/lib/useragent.js b/lib/ace/lib/useragent.js new file mode 100644 index 00000000..0d1d9f4d --- /dev/null +++ b/lib/ace/lib/useragent.js @@ -0,0 +1,106 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +/* + * 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. + * + * Take copy as an example, Mac people expect to use CMD or APPLE + C + * Windows folks expect to use CTRL + C + */ +exports.OS = { + LINUX: "LINUX", + MAC: "MAC", + WINDOWS: "WINDOWS" +}; + +/* + * Return an exports.OS constant + */ +exports.getOS = function() { + if (exports.isMac) { + return exports.OS.MAC; + } else if (exports.isLinux) { + return exports.OS.LINUX; + } else { + return exports.OS.WINDOWS; + } +}; + +// this can be called in non browser environments (e.g. from ace/requirejs/text) +if (typeof navigator != "object") + return; + +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 +exports.isWin = (os == "win"); + +// 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 +exports.isLinux = (os == "linux"); + +// Windows Store JavaScript apps (aka Metro apps written in HTML5 and JavaScript) do not use the "Microsoft Internet Explorer" string in their user agent, but "MSAppHost" instead. +exports.isIE = + (navigator.appName == "Microsoft Internet Explorer" || navigator.appName.indexOf("MSAppHost") >= 0) + ? parseFloat((ua.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]) + : parseFloat((ua.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]); // for ie + +exports.isOldIE = exports.isIE && exports.isIE < 9; + +// Is this Firefox or related? +exports.isGecko = exports.isMozilla = (window.Controllers || window.controllers) && window.navigator.product === "Gecko"; + +// oldGecko == rev < 2.0 +exports.isOldGecko = exports.isGecko && parseInt((ua.match(/rv\:(\d+)/)||[])[1], 10) < 4; + +// 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 +exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined; + +exports.isChrome = parseFloat(ua.split(" Chrome/")[1]) || undefined; + +exports.isAIR = ua.indexOf("AdobeAIR") >= 0; + +exports.isIPad = ua.indexOf("iPad") >= 0; + +exports.isTouchPad = ua.indexOf("TouchPad") >= 0; + +exports.isChromeOS = ua.indexOf(" CrOS ") >= 0; + +}); diff --git a/lib/ace/line_widgets.js b/lib/ace/line_widgets.js new file mode 100644 index 00000000..ba87d857 --- /dev/null +++ b/lib/ace/line_widgets.js @@ -0,0 +1,295 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var dom = require("./lib/dom"); +var Range = require("./range").Range; + + +function LineWidgets(session) { + this.session = session; + this.session.widgetManager = this; + this.session.getRowLength = this.getRowLength; + this.session.$getWidgetScreenLength = this.$getWidgetScreenLength; + this.updateOnChange = this.updateOnChange.bind(this); + this.renderWidgets = this.renderWidgets.bind(this); + this.measureWidgets = this.measureWidgets.bind(this); + this.session._changedWidgets = []; + this.$onChangeEditor = this.$onChangeEditor.bind(this); + + this.session.on("change", this.updateOnChange); + this.session.on("changeEditor", this.$onChangeEditor); +} + +(function() { + this.getRowLength = function(row) { + var h; + if (this.lineWidgets) + h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0; + else + h = 0; + if (!this.$useWrapMode || !this.$wrapData[row]) { + return 1 + h; + } else { + return this.$wrapData[row].length + 1 + h; + } + }; + + this.$getWidgetScreenLength = function() { + var screenRows = 0; + this.lineWidgets.forEach(function(w){ + if (w && w.rowCount) + screenRows +=w.rowCount; + }); + return screenRows; + }; + + this.$onChangeEditor = function(e) { + this.attach(e.editor); + }; + + this.attach = function(editor) { + if (editor && editor.widgetManager && editor.widgetManager != this) + editor.widgetManager.detach(); + + if (this.editor == editor) + return; + + this.detach(); + this.editor = editor; + + if (editor) { + editor.widgetManager = this; + editor.renderer.on("beforeRender", this.measureWidgets); + editor.renderer.on("afterRender", this.renderWidgets); + } + }; + this.detach = function(e) { + var editor = this.editor; + if (!editor) + return; + + this.editor = null; + editor.widgetManager = null; + + editor.renderer.off("beforeRender", this.measureWidgets); + editor.renderer.off("afterRender", this.renderWidgets); + var lineWidgets = this.session.lineWidgets; + lineWidgets && lineWidgets.forEach(function(w) { + if (w && w.el && w.el.parentNode) { + w._inDocument = false; + w.el.parentNode.removeChild(w.el); + } + }); + }; + + this.updateOnChange = function(delta) { + var lineWidgets = this.session.lineWidgets; + if (!lineWidgets) return; + + var startRow = delta.start.row; + var len = delta.end.row - startRow; + + if (len === 0) { + // return + } else if (delta.action == 'remove') { + var removed = lineWidgets.splice(startRow + 1, len); + removed.forEach(function(w) { + w && this.removeLineWidget(w); + }, this); + this.$updateRows(); + } else { + var args = new Array(len); + args.unshift(startRow, 0); + lineWidgets.splice.apply(lineWidgets, args); + this.$updateRows(); + } + }; + + this.$updateRows = function() { + var lineWidgets = this.session.lineWidgets; + if (!lineWidgets) return; + var noWidgets = true; + lineWidgets.forEach(function(w, i) { + if (w) { + noWidgets = false; + w.row = i; + } + }); + if (noWidgets) + this.session.lineWidgets = null; + }; + + this.addLineWidget = function(w) { + if (!this.session.lineWidgets) + this.session.lineWidgets = new Array(this.session.getLength()); + + this.session.lineWidgets[w.row] = w; + + var renderer = this.editor.renderer; + if (w.html && !w.el) { + w.el = dom.createElement("div"); + w.el.innerHTML = w.html; + } + if (w.el) { + dom.addCssClass(w.el, "ace_lineWidgetContainer"); + w.el.style.position = "absolute"; + w.el.style.zIndex = 5; + renderer.container.appendChild(w.el); + w._inDocument = true; + } + + if (!w.coverGutter) { + w.el.style.zIndex = 3; + } + if (!w.pixelHeight) { + w.pixelHeight = w.el.offsetHeight; + } + if (w.rowCount == null) + w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight; + + this.session._emit("changeFold", {data:{start:{row: w.row}}}); + + this.$updateRows(); + this.renderWidgets(null, renderer); + return w; + }; + + this.removeLineWidget = function(w) { + w._inDocument = false; + if (w.el && w.el.parentNode) + w.el.parentNode.removeChild(w.el); + if (w.editor && w.editor.destroy) try { + w.editor.destroy(); + } catch(e){} + if (this.session.lineWidgets) + this.session.lineWidgets[w.row] = undefined; + this.session._emit("changeFold", {data:{start:{row: w.row}}}); + this.$updateRows(); + }; + + this.onWidgetChanged = function(w) { + this.session._changedWidgets.push(w); + this.editor && this.editor.renderer.updateFull(); + }; + + this.measureWidgets = function(e, renderer) { + var changedWidgets = this.session._changedWidgets; + var config = renderer.layerConfig; + + if (!changedWidgets || !changedWidgets.length) return; + var min = Infinity; + for (var i = 0; i < changedWidgets.length; i++) { + var w = changedWidgets[i]; + if (!w._inDocument) { + w._inDocument = true; + renderer.container.appendChild(w.el); + } + + w.h = w.el.offsetHeight; + + if (!w.fixedWidth) { + w.w = w.el.offsetWidth; + w.screenWidth = Math.ceil(w.w / config.characterWidth); + } + + var rowCount = w.h / config.lineHeight; + if (w.coverLine) { + rowCount -= this.session.getRowLineCount(w.row); + if (rowCount < 0) + rowCount = 0; + } + if (w.rowCount != rowCount) { + w.rowCount = rowCount; + if (w.row < min) + min = w.row; + } + } + if (min != Infinity) { + this.session._emit("changeFold", {data:{start:{row: min}}}); + this.session.lineWidgetWidth = null; + } + this.session._changedWidgets = []; + }; + + this.renderWidgets = function(e, renderer) { + var config = renderer.layerConfig; + var lineWidgets = this.session.lineWidgets; + if (!lineWidgets) + return; + var first = Math.min(this.firstRow, config.firstRow); + var last = Math.max(this.lastRow, config.lastRow, lineWidgets.length); + + while (first > 0 && !lineWidgets[first]) + first--; + + this.firstRow = config.firstRow; + this.lastRow = config.lastRow; + + renderer.$cursorLayer.config = config; + for (var i = first; i <= last; i++) { + var w = lineWidgets[i]; + if (!w || !w.el) continue; + + if (!w._inDocument) { + w._inDocument = true; + renderer.container.appendChild(w.el); + } + var top = renderer.$cursorLayer.getPixelPosition({row: i, column:0}, true).top; + if (!w.coverLine) + top += config.lineHeight * this.session.getRowLineCount(w.row); + w.el.style.top = top - config.offset + "px"; + + var left = w.coverGutter ? 0 : renderer.gutterWidth; + if (!w.fixedWidth) + left -= renderer.scrollLeft; + w.el.style.left = left + "px"; + + if (w.fixedWidth) { + w.el.style.right = renderer.scrollBar.getWidth() + "px"; + } else { + w.el.style.right = ""; + } + } + }; + +}).call(LineWidgets.prototype); + + +exports.LineWidgets = LineWidgets; + +}); + + + + diff --git a/lib/ace/mode/_test/Readme.md b/lib/ace/mode/_test/Readme.md new file mode 100644 index 00000000..c2871c0d --- /dev/null +++ b/lib/ace/mode/_test/Readme.md @@ -0,0 +1,9 @@ +`tokens_.json` files keep information about correct tokens and tokenizer states for all modes supported by ace. +They are generated from `text_.txt` or `demo/kitchen-sink/doc/*` with + +```sh +node highlight_rules_test.js -gen +``` + +command. + diff --git a/lib/ace/mode/_test/highlight_rules_test.js b/lib/ace/mode/_test/highlight_rules_test.js new file mode 100644 index 00000000..c3b877ec --- /dev/null +++ b/lib/ace/mode/_test/highlight_rules_test.js @@ -0,0 +1,210 @@ +var fs = require("fs"); +var path = require("path"); +if (!fs.existsSync) + fs.existsSync = path.existsSync; + +require("amd-loader"); + +var cwd = __dirname + "/"; +var root = path.normalize(cwd + Array(5).join("../")); + +function jsFileList(path, filter) { + if (!filter) filter = /_test/; + return fs.readdirSync(path).map(function(x) { + if (x.slice(-3) == ".js" && !filter.test(x) && !/\s/.test(x)) + return x.slice(0, -3); + }).filter(Boolean); +} + +function modeList() { + return jsFileList(cwd + "../", /_highlight_rules|_test|_worker|xml_util|_outdent|behaviour|completions/); +} + +function checkModes() { + modeList().forEach(function(modeName) { + try { + var Mode = require("../" + modeName).Mode; + } catch(e) { + console.warn("Can't load mode :" + modeName, e); + return; + } + var m = new Mode(); + if (!m.lineCommentStart && !m.blockComment) + console.warn("missing comment in " + modeName); + if (!m.$id) + console.warn("missing id in " + modeName); + var tokenizer = (new Mode).getTokenizer(); + if (m.lineCommentStart) { + if (Array.isArray(m.lineCommentStart)) { + m.lineCommentStart.forEach(function(x) { + testLineComment(tokenizer, x, modeName) + }); + } else { + testLineComment(tokenizer, m.lineCommentStart, modeName) + } + } + // if (m.blockComment) { + // var tokens = tok.getLineTokens(m.lineCommentStart, "start"); + // if (!/comment/.test(tokens[0])) + // console.warn("broken lineCommentStart in " + modeName); + // } + }); + + function testLineComment(tokenizer, commentStart, modeName) { + var tokens = tokenizer.getLineTokens(commentStart + " ", "start").tokens; + if (!/comment/.test(tokens[0].type)) + console.warn("broken lineCommentStart in " + modeName); + } +} + +function generateTestData() { + var docRoot = root + "/demo/kitchen-sink/docs"; + var docs = fs.readdirSync(docRoot); + var specialDocs = fs.readdirSync(cwd); + var modes = modeList(); + + // console.log("Docs:", docs); + // console.log("Modes:", modes); + + docs.forEach(function(docName) { + var p = docName.toLowerCase().split("."); + if (!p[1]) + return; + var modeName; + if (modes.indexOf(p[0]) != -1) + modeName = p[0]; + else if (modes.indexOf(p[1]) != -1) + modeName = p[1]; + else + modeName = {"txt": "text", cpp: "c_cpp"}[p[1]]; + + var filePath = "text_" + modeName + ".txt"; + if (specialDocs.indexOf(filePath) == -1) { + filePath = docRoot + "/" + docName; + } else { + filePath = cwd + filePath; + } + + var text = fs.readFileSync(filePath, "utf8"); + try { + var Mode = require("../" + modeName).Mode; + } catch(e) { + console.warn("Can't load mode :" + modeName, p, e); + return; + } + console.log(modeName); + var tokenizer = new Mode().getTokenizer(); + + var state = "start"; + var data = text.split(/\r\n|\r|\n/).map(function(line) { + var data = tokenizer.getLineTokens(line, state); + var tmp = []; + tmp.push(JSON.stringify(data.state)); + var tokenizedLine = ""; + data.tokens.forEach(function(x) { + tokenizedLine += x.value; + tmp.push(JSON.stringify([x.type, x.value])); + }); + if (tokenizedLine != line) + tmp.push(JSON.stringify(line)); + state = data.state; + return tmp.join(",\n "); + }); + + var jsonStr = "[[\n " + data.join("\n],[\n ") + "\n]]"; + fs.writeFileSync(cwd + "tokens_" + modeName + ".json", jsonStr, "utf8"); + }); +} + +function test(startAt) { + var modes = fs.readdirSync(cwd).map(function(x) { + return (x.match(/tokens_(.*).json/) || {})[1]; + }).filter(function(x){return !!x}); + + for (var i = Math.max(0, startAt||0); i < modes.length; i++) + testMode(modes[i], i); + + console.log("\u001b[32m" + "all ok" + "\u001b[0m"); +} +function testMode(modeName, i) { + console.log(padNumber(i+1, 3) + ") testing: \u001b[33m" + modeName + "\u001b[0m"); + + var text = fs.readFileSync(cwd + "tokens_" + modeName + ".json", "utf8"); + var data = JSON.parse(text); + var Mode = require("../" + modeName).Mode; + var tokenizer = new Mode().getTokenizer(); + + var state = "start"; + data.forEach(function(lineData) { + lineData.values = []; + lineData.types = []; + lineData.state = lineData.shift(); + var line = null; + if (typeof lineData[lineData.length - 1] == "string") + line = lineData.pop(); + lineData.forEach(function(x) { + lineData.types.push(x[0]); + lineData.values.push(x[1]); + }); + if (typeof line != "string") + line = lineData.values.join(""); + + var tokens = tokenizer.getLineTokens(line, state); + var values = tokens.tokens.map(function(x) {return x.value;}); + var types = tokens.tokens.map(function(x) {return x.type;}); + + var err = testEqual([ + JSON.stringify(lineData.state), JSON.stringify(tokens.state), + lineData.types, types, + lineData.values, values]); + + if (err) { + console.log(line); + throw "error"; + } + + state = tokens.state; + }); +} +function testEqual(a) { + var err; + if (a[0] + "" !== a[1] + "") { + console.log(a[0],a[1]); + err = 1; + } + + if ( a[2] + "" !== a[3] + "" || a[4] + "" !== a[5] + "") { + arrayDiff(a[2],a[3]); + arrayDiff(a[4],a[5]); + err = 1; + } + return err; +} +function arrayDiff(a1, a2) { + var l = Math.max(a1.length, a2.length); + var out = []; + for (var i = 0; i < l; i++) { + out.push("\n", padNumber(i+1, 3), ") "); + if (a1[i] !== a2[i]) + out.push("\u001b[31m", a1[i], "\u001b[0m != \u001b[32m", a2[i], "\u001b[0m"); + else + out.push(a1[i]); + } + console.log(out.join("")); +} +function padNumber(num, digits) { + return (" " + num).slice(-digits); +} + +// cli +var arg = process.argv[2]; +if (!arg) + test(); +else if (/--?g(en)?/.test(arg)) + generateTestData(process.argv.splice(3)); +else if (/--?c(heck)?/.test(arg)) + checkModes(process.argv.splice(3)); +else if (/\d+/.test(arg)) + test(parseInt(process.argv[2],10) || 0); +else + testMode(arg, -1); \ No newline at end of file diff --git a/lib/ace/mode/_test/package.json b/lib/ace/mode/_test/package.json new file mode 100644 index 00000000..3fdc706d --- /dev/null +++ b/lib/ace/mode/_test/package.json @@ -0,0 +1,8 @@ +{ + "name": "ace-mode-creator", + "version": "0.1.0", + "dependencies": { + "connect": "", + "socket.io": "" + } +} \ No newline at end of file diff --git a/lib/ace/mode/_test/text_asciidoc.txt b/lib/ace/mode/_test/text_asciidoc.txt new file mode 100644 index 00000000..af7eaecc --- /dev/null +++ b/lib/ace/mode/_test/text_asciidoc.txt @@ -0,0 +1,111 @@ +------------------------------------ +----------------------------------- +_ita_lic_, *bo*ld*, +mo+no+, normal. +``double quoted'', `single quoted'. + normal, ^super^, ~sub~. + +'''' +Escaped: +\_italic_, +++_italic_+++, +t\__e__st, +++t__e__st+++, ++++bold+++, $$normal$$ +\¶ ¶ +\`not single quoted' +\`\`not double quoted'' + + +[fffff] ++++++++++++++++++++++++++++++++++++++ +(C) {ss} ss ++++++++++++++++++++++++++++++++++++++ + +............. +callout <1> +.............. + +> 1 +1> 2 +<2> 3 + +Escaped: +\_italic_, +t\__e__st, o__ + +.optional title +............. +callout <1> +.............. + + +:macro: dddd + +.lists +. 1 +.. 2 +... d +..... big ++ +continue + +next line +xi) no ++la+tin++ + +xi) la++tin++ +2. num__ber__ [red]#red# +-- + 5. f <> {macro} +-- +image::path[beauty] ->--<= -- replacements + + image::s +sssss +sss +sssss + + +== 1 + heading +=== not a heading +==================================== + +================================== +====4 +NOTE: above + +NOTE: above + +[[x6]] +WARNING: + +[options[]] +--------------------------- +literal +--------------------------- + + += Tables +|==================================== +| _italic_ | *bold* | text | (R) + +|==================================== + + +[more, options] +/////////// +comment +/////////// +// one line comment + + + +[red]#red text# [yellow-background]#on yellow# +[big]#large# [red yellow-background big]*all bold* + + +https://site text callto:ace http://ace.ajaxorg.com[awesome] + .still normal text +.break out thoug should not +--------------------------- +/////////////////////////// +--------------------------- + + diff --git a/lib/ace/mode/_test/text_coffee.txt b/lib/ace/mode/_test/text_coffee.txt new file mode 100644 index 00000000..2d9ba5ad --- /dev/null +++ b/lib/ace/mode/_test/text_coffee.txt @@ -0,0 +1,57 @@ +#test: tokenize keyword + for (i 1..2) +#test: tokenize regexp +/"[a]/ +#test: tokenize functions +foo = ({args}) -> + foo = ({a1, a2}) -> + foo = ({@a1, a2}) -> + foo : ({args}) -> + foo = ({args}) -> + foo = ({0abc}) -> + foo = ({/abc}) => + foo = ({abc/}) -> + foo = ({#abc}) -> + foo = ({abc#}) -> + foo = ({)abc}) -> + foo = ({abc)}) -> + foo = ({a{bc}) -> + foo = ({}) -> + foo = ({ }) -> + foo : ({}) -> + foo = (args) -> + foo = (arg1, arg2) -> + foo = (arg1 = 1, arg2 = 'name') -> + foo = (@arg1 = /abc/, arg2 = 'name') -> + #test: tokenize function: invalid case: + foo=(/args) -> + foo = () -> + foo = ( ) -> + foo : ( ) -> + window.foo = (args) -> + foo = -> + foo = -> + foo : -> + #test: tokenize callback function + foo bar: 1, (args) -> + foo = (1, 2 (x) -> +#test: tokenize class +class Foo +class Foo extends Bar +#test: tokenize illegal name property +foo.static.function +#!test tokenize string with interpolation +a = "#{ 22 / 7 + {x: "#{a + b}"} + 2}" +" #{ "" + {} } )" +"""heredoc + """ +do -> + ### + herecomment + ### + re = /regex/imgy.test /// + heregex # comment + ///imgy + this isnt: `just + JavaScript` + undefined diff --git a/lib/ace/mode/_test/text_curly.txt b/lib/ace/mode/_test/text_curly.txt new file mode 100644 index 00000000..1be54b59 --- /dev/null +++ b/lib/ace/mode/_test/text_curly.txt @@ -0,0 +1,9 @@ +tokenize Curly template{{test}} +tokenize embedded script +'123' +tokenize multiline attribute value with double quotes + +tokenize multiline attribute value with single quotes + diff --git a/lib/ace/mode/_test/text_html.txt b/lib/ace/mode/_test/text_html.txt new file mode 100644 index 00000000..d2ce8aaa --- /dev/null +++ b/lib/ace/mode/_test/text_html.txt @@ -0,0 +1,10 @@ + + +'123' + + + + + \ No newline at end of file diff --git a/lib/ace/mode/_test/text_javascript.txt b/lib/ace/mode/_test/text_javascript.txt new file mode 100644 index 00000000..48d4af7d --- /dev/null +++ b/lib/ace/mode/_test/text_javascript.txt @@ -0,0 +1,86 @@ +//test: tokenize 'standard' functions +string.charCodeAt(23); document.getElementById('test'); console.log('Here it is');"; +test: /**tokenize doc*/ comment +/**tokenize doc comment with @tag {}*/ +//test: tokenize parens + var line = "[{( )}]"; +//test tokenize arithmetic expression which looks like a regexp +a/b/c +a/=b/c +//test tokenize reg exps +a=/b/g +a+/b/g +a = 1 + /2 + 1/gimyxk +a=/a/ / /a/ +case /a/.test(c) +//test tokenize multi-line comment containing a single line comment +noRegex +/* foo // bar */ +canBeRegex; +/* foo // bar */ +// test tokenize identifier with umlauts +fu?e +// test // is not a regexp +{ // 123 +//test skipping escaped chars +'Meh\\nNeh' +console.log('\\u1232Feh' +"test multiline\ + strings" +a=' +b="\ +still a string + + +function foo(items, nada) { + for (var i=0; ihttp://ace.ajaxorg.com + diff --git a/lib/ace/mode/_test/text_php.txt b/lib/ace/mode/_test/text_php.txt new file mode 100644 index 00000000..b76aa8a5 --- /dev/null +++ b/lib/ace/mode/_test/text_php.txt @@ -0,0 +1,24 @@ + not &js; diff --git a/lib/ace/mode/_test/text_ruby.txt b/lib/ace/mode/_test/text_ruby.txt new file mode 100644 index 00000000..c16ff7c5 --- /dev/null +++ b/lib/ace/mode/_test/text_ruby.txt @@ -0,0 +1,34 @@ + #test: symbol tokenizer + [:@thing, :$thing, :_thing, :thing, :Thing, :thing1, :thing_a, + :THING, :thing!, :thing=, :thing?, :t?, + :, :@, :$, :1, :1thing, :th?ing, :thi=ng, :1thing, + :th!ing, :thing# + ] + + #test: namespaces aren't symbols" : function() { + Namespaced::Class + #test: hex tokenizer + 0x9a, 0XA1, 0x9_a, 0x, 0x_9a, 0x9a_, + #test: float tokenizer + [1, +1, -1, 12_345, 0.000_1, + _, 3_1, 1_2, 1_.0, 0._1]; + +{:id => ?", :key => "value", anotherKey: [x, y?]} + +=begin +=end + +=begin x +=end- +=end x + + herDocs = [<<'FOO', <//Juhu Kinners +test: two tags in the same lines should be in separate tokens" + +test: multiline attributes" + \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_abap.json b/lib/ace/mode/_test/tokens_abap.json new file mode 100644 index 00000000..95f2f811 --- /dev/null +++ b/lib/ace/mode/_test/tokens_abap.json @@ -0,0 +1,189 @@ +[[ + "start", + ["doc.comment","***************************************"] +],[ + "start", + ["doc.comment","** Program: EXAMPLE **"] +],[ + "start", + ["doc.comment","** Author: Joe Byte, 07-Jul-2007 **"] +],[ + "start", + ["doc.comment","***************************************"] +],[ + "start", + ["text"," "] +],[ + "start", + ["keyword","REPORT"], + ["text"," BOOKINGS"], + ["keyword.operator","."] +],[ + "start", + ["text"," "] +],[ + "start", + ["doc.comment","* Read flight bookings from the database"] +],[ + "start", + ["keyword","SELECT"], + ["keyword.operator"," * "], + ["keyword","FROM"], + ["text"," FLIGHTINFO"] +],[ + "start", + ["text"," "], + ["keyword","WHERE"], + ["text"," "], + ["keyword","CLASS"], + ["keyword.operator"," = "], + ["string","'Y'"], + ["text"," "], + ["comment","\"Y = economy"] +],[ + "start", + ["text"," "], + ["keyword","OR"], + ["text"," "], + ["keyword","CLASS"], + ["keyword.operator"," = "], + ["string","'C'"], + ["keyword.operator","."], + ["text"," "], + ["comment","\"C = business"] +],[ + "start", + ["paren.lparen","("], + ["invalid","..."], + ["paren.rparen",")"] +],[ + "start" +],[ + "start", + ["keyword","REPORT"], + ["text"," TEST"], + ["keyword.operator","."] +],[ + "start", + ["keyword","WRITE"], + ["text"," "], + ["string","'Hello World'"], + ["keyword.operator","."] +],[ + "start" +],[ + "start", + ["text","USERPROMPT"], + ["keyword.operator"," = "], + ["string","'Please double-click on a line in the output list '"], + ["text"," "], + ["keyword.operator","&"] +],[ + "start", + ["text"," "], + ["string","'to see the complete details of the transaction.'"], + ["keyword.operator","."] +],[ + "start" +],[ + "start" +],[ + "start", + ["keyword","DATA"], + ["text"," LAST_EOM "], + ["keyword","TYPE"], + ["text"," "], + ["support.type","D"], + ["keyword.operator","."], + ["text"," "], + ["comment","\"last end-of-month date"] +],[ + "start", + ["text"," "] +],[ + "start", + ["doc.comment","* Start from today's date"] +],[ + "start", + ["text"," LAST_EOM"], + ["keyword.operator"," = "], + ["variable.parameter","SY"], + ["keyword.operator","-"], + ["text","DATUM"], + ["keyword.operator","."] +],[ + "start", + ["doc.comment","* Set characters 6 and 7 (0-relative) of the YYYYMMDD string to \"01\","] +],[ + "start", + ["doc.comment","* giving the first day of the current month"] +],[ + "start", + ["text"," LAST_EOM"], + ["constant.numeric","+6"], + ["paren.lparen","("], + ["constant.numeric","2"], + ["paren.rparen",")"], + ["keyword.operator"," = "], + ["string","'01'"], + ["keyword.operator","."] +],[ + "start", + ["doc.comment","* Subtract one day"] +],[ + "start", + ["text"," LAST_EOM"], + ["keyword.operator"," = "], + ["text","LAST_EOM"], + ["keyword.operator"," - "], + ["constant.numeric","1"], + ["keyword.operator","."] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["keyword","WRITE"], + ["keyword.operator",":"], + ["text"," "], + ["string","'Last day of previous month was'"], + ["keyword.operator",","], + ["text"," LAST_EOM"], + ["keyword.operator","."] +],[ + "start", + ["text"," "] +],[ + "start", + ["keyword","DATA"], + ["text"," "], + ["keyword.operator",":"], + ["text"," "], + ["keyword","BEGIN OF"], + ["text"," I_VBRK "], + ["keyword","OCCURS"], + ["text"," "], + ["constant.numeric","0"], + ["keyword.operator",","] +],[ + "start", + ["text"," VBELN "], + ["keyword","LIKE"], + ["text"," "], + ["variable.parameter","VBRK-VBELN"], + ["keyword.operator",","] +],[ + "start", + ["text"," ZUONR "], + ["keyword","LIKE"], + ["text"," "], + ["variable.parameter","VBRK-ZUONR"], + ["keyword.operator",","] +],[ + "start", + ["text"," "], + ["keyword","END OF"], + ["text"," I_VBRK"], + ["keyword.operator","."] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_abc.json b/lib/ace/mode/_test/tokens_abc.json new file mode 100644 index 00000000..c65ae2a5 --- /dev/null +++ b/lib/ace/mode/_test/tokens_abc.json @@ -0,0 +1,2207 @@ +[[ + "start", + ["comment.line.percentage","%abc-2.1"] +],[ + "start", + ["information.keyword","H:"], + ["information.argument.string.unquoted","This file contains some example English tunes"] +],[ + "start", + ["comment.line.percentage","% note that the comments (like this one) are to highlight usages"] +],[ + "start", + ["comment.line.percentage","% and would not normally be included in such detail"] +],[ + "start", + ["information.keyword","O:"], + ["information.argument.string.unquoted","England "], + ["comment.line.percentage","% the origin of all tunes is England"] +],[ + "start" +],[ + "start", + ["information.keyword","X:"], + ["information.argument.string.unquoted","1 "], + ["comment.line.percentage","% tune no 1"] +],[ + "start", + ["information.keyword","T:"], + ["information.argument.string.unquoted","Dusty Miller, The "], + ["comment.line.percentage","% title"] +],[ + "start", + ["information.keyword","T:"], + ["information.argument.string.unquoted","Binny's Jig "], + ["comment.line.percentage","% an alternative title"] +],[ + "start", + ["information.keyword","C:"], + ["information.argument.string.unquoted","Trad. "], + ["comment.line.percentage","% traditional"] +],[ + "start", + ["information.keyword","R:"], + ["information.argument.string.unquoted","DH "], + ["comment.line.percentage","% double hornpipe"] +],[ + "start", + ["information.keyword","M:"], + ["information.argument.string.unquoted","3/4 "], + ["comment.line.percentage","% meter"] +],[ + "start", + ["information.keyword","K:"], + ["information.argument.string.unquoted","G "], + ["comment.line.percentage","% key"] +],[ + "start", + ["pitch.constant.numeric","B"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","c"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","D"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","B"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator",":|"] +],[ + "start", + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","d"], + ["text"," "], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["pitch.constant.numeric","g"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","c"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","d"], + ["text"," "], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["pitch.constant.numeric","a"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","B"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator",":|"] +],[ + "start", + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","/2"], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","/2"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","c"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","/2"], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","/2"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","D"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","B"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator",":|"] +],[ + "start", + ["information.keyword","W:"], + ["information.argument.string.unquoted","Hey, the dusty miller, and his dusty coat;"] +],[ + "start", + ["information.keyword","W:"], + ["information.argument.string.unquoted","He will win a shilling, or he spend a groat."] +],[ + "start", + ["information.keyword","W:"], + ["information.argument.string.unquoted","Dusty was the coat, dusty was the colour;"] +],[ + "start", + ["information.keyword","W:"], + ["information.argument.string.unquoted","Dusty was the kiss, that I got frae the miller."] +],[ + "start" +],[ + "start", + ["information.keyword","X:"], + ["information.argument.string.unquoted","2"] +],[ + "start", + ["information.keyword","T:"], + ["information.argument.string.unquoted","Old Sir Simon the King"] +],[ + "start", + ["information.keyword","C:"], + ["information.argument.string.unquoted","Trad."] +],[ + "start", + ["information.keyword","S:"], + ["information.argument.string.unquoted","Offord MSS "], + ["comment.line.percentage","% from Offord manuscript"] +],[ + "start", + ["information.keyword","N:"], + ["information.argument.string.unquoted","see also Playford "], + ["comment.line.percentage","% reference note"] +],[ + "start", + ["information.keyword","M:"], + ["information.argument.string.unquoted","9/8"] +],[ + "start", + ["information.keyword","R:"], + ["information.argument.string.unquoted","SJ "], + ["comment.line.percentage","% slip jig"] +],[ + "start", + ["information.keyword","N:"], + ["information.argument.string.unquoted","originally in C "], + ["comment.line.percentage","% transcription note"] +],[ + "start", + ["information.keyword","K:"], + ["information.argument.string.unquoted","G"] +],[ + "start", + ["pitch.constant.numeric","D"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","D"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","F"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","D"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","E"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","E"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","F"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","E"], + ["text"," "], + ["pitch.constant.numeric","D"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator",":|"] +],[ + "start", + ["pitch.constant.numeric","D"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["text"," "], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","D"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["text"," "], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","D"], + ["barline.keyword.operator","|[1"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","E"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","E"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["text","["], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","G"], + ["text","] "], + ["pitch.constant.numeric","F"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","E"], + ["text"," "], + ["pitch.constant.numeric","D"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator",":|"], + ["text","\\ "], + ["comment.line.percentage","% no line-break in score"] +],[ + "start", + ["information.keyword","M:"], + ["information.argument.string.unquoted","12/8 "], + ["comment.line.percentage","% change of meter"] +],[ + "start", + ["barline.keyword.operator","[2"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","E"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","E"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","E"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["text","\\ "], + ["comment.line.percentage","% no line-break in score"] +],[ + "start", + ["information.keyword","M:"], + ["information.argument.string.unquoted","9/8 "], + ["comment.line.percentage","% change of meter"] +],[ + "start", + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","F"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","E"], + ["text"," "], + ["pitch.constant.numeric","D"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator","|]"] +],[ + "start" +],[ + "start", + ["information.keyword","X:"], + ["information.argument.string.unquoted","3"] +],[ + "start", + ["information.keyword","T:"], + ["information.argument.string.unquoted","William and Nancy"] +],[ + "start", + ["information.keyword","T:"], + ["information.argument.string.unquoted","New Mown Hay"] +],[ + "start", + ["information.keyword","T:"], + ["information.argument.string.unquoted","Legacy, The"] +],[ + "start", + ["information.keyword","C:"], + ["information.argument.string.unquoted","Trad."] +],[ + "start", + ["information.keyword","O:"], + ["information.argument.string.unquoted","England; Gloucs; Bledington "], + ["comment.line.percentage","% place of origin"] +],[ + "start", + ["information.keyword","B:"], + ["information.argument.string.unquoted","Sussex Tune Book "], + ["comment.line.percentage","% can be found in these books"] +],[ + "start", + ["information.keyword","B:"], + ["information.argument.string.unquoted","Mally's Cotswold Morris vol.1 2"] +],[ + "start", + ["information.keyword","D:"], + ["information.argument.string.unquoted","Morris On "], + ["comment.line.percentage","% can be heard on this record"] +],[ + "start", + ["information.keyword","P:"], + ["information.argument.string.unquoted","(AB)2(AC)2A "], + ["comment.line.percentage","% play the parts in this order"] +],[ + "start", + ["information.keyword","M:"], + ["information.argument.string.unquoted","6/8"] +],[ + "start", + ["information.keyword","K:"], + ["information.argument.string.unquoted","G "] +],[ + "start", + ["information.keyword.embedded","[P:"], + ["information.argument.string.unquoted","A]"], + ["text"," "], + ["pitch.constant.numeric","D"], + ["barline.keyword.operator","|"], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["string.quoted","\"C\""], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","e"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["string.quoted","\"D7\""], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","d"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["string.quoted","\"C\""], + ["pitch.constant.numeric","E"], + ["duration.constant.numeric","2"], + ["string.quoted","\"D7\""], + ["pitch.constant.numeric","F"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator",":|"] +],[ + "start", + ["information.keyword.embedded","[P:"], + ["information.argument.string.unquoted","B]"], + ["text"," "], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","d"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["string.quoted","\"C\""], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["pitch.constant.numeric","e"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","d"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["string.quoted","\"C\""], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["pitch.constant.numeric","e"], + ["text"," "], + ["string.quoted","\"D7\""], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","c"], + ["barline.keyword.operator","|"] +],[ + "start", + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","B"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["string.quoted","\"C\""], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","e"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["string.quoted","\"D7\""], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","d"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["string.quoted","\"C\""], + ["pitch.constant.numeric","E"], + ["duration.constant.numeric","2"], + ["string.quoted","\"D7\""], + ["pitch.constant.numeric","F"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator",":|"] +],[ + "start", + ["comment.line.percentage","% changes of meter, using inline fields"] +],[ + "start", + ["information.keyword.embedded","[T:"], + ["information.argument.string.unquoted","Slows]"], + ["information.keyword.embedded","[M:"], + ["information.argument.string.unquoted","4/4]"], + ["information.keyword.embedded","[L:"], + ["information.argument.string.unquoted","1/4]"], + ["information.keyword.embedded","[P:"], + ["information.argument.string.unquoted","C]"], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator","|"], + ["string.quoted","\"C\""], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","2"], + ["text"," "], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator","|"], + ["string.quoted","\"Em\""], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["text"," "], + ["string.quoted","\"A7\""], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator","|"], + ["string.quoted","\"D7\""], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator","|"], + ["text","\\"] +],[ + "start", + ["text"," "], + ["string.quoted","\"C\""], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator","|"], + ["information.keyword.embedded","[M:"], + ["information.argument.string.unquoted","3/8]"], + ["information.keyword.embedded","[L:"], + ["information.argument.string.unquoted","1/8]"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","2"], + ["text"," "], + ["pitch.constant.numeric","d"], + ["text"," "], + ["barline.keyword.operator","|"], + ["information.keyword.embedded","[M:"], + ["information.argument.string.unquoted","6/8]"], + ["text"," "], + ["string.quoted","\"C\""], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["pitch.constant.numeric","e"], + ["text"," "], + ["string.quoted","\"D7\""], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","c"], + ["barline.keyword.operator","|"] +],[ + "start", + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","B"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["string.quoted","\"C\""], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","e"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["string.quoted","\"D7\""], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","d"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["string.quoted","\"C\""], + ["pitch.constant.numeric","E"], + ["duration.constant.numeric","2"], + ["string.quoted","\"D7\""], + ["pitch.constant.numeric","F"], + ["text"," "], + ["string.quoted","\"G\""], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator",":|"] +],[ + "start" +],[ + "start", + ["information.keyword","X:"], + ["information.argument.string.unquoted","4"] +],[ + "start", + ["information.keyword","T:"], + ["information.argument.string.unquoted","South Downs Jig"] +],[ + "start", + ["information.keyword","R:"], + ["information.argument.string.unquoted","jig"] +],[ + "start", + ["information.keyword","S:"], + ["information.argument.string.unquoted","Robert Harbron"] +],[ + "start", + ["information.keyword","M:"], + ["information.argument.string.unquoted","6/8"] +],[ + "start", + ["information.keyword","L:"], + ["information.argument.string.unquoted","1/8"] +],[ + "start", + ["information.keyword","K:"], + ["information.argument.string.unquoted","G"] +],[ + "start", + ["barline.keyword.operator","|:"], + ["text"," "], + ["pitch.constant.numeric","d"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text"," "], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","3"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","E"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text"," "], + ["pitch.constant.numeric","D"], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text"," "], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","e"], + ["text"," "], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","d"], + ["text"," "], + ["barline.keyword.operator","|"] +],[ + "start", + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","3"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","E"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text"," "], + ["pitch.constant.numeric","D"], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text"," "], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","F"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","2"], + ["text"," "], + ["barline.keyword.operator",":|"] +],[ + "start", + ["pitch.constant.numeric","B"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["text"," "], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","c"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text"," "], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","B"], + ["text"," "], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["text"," "], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","c"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text"," "], + ["information.keyword.embedded","[M:"], + ["information.argument.string.unquoted","9/8]"], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","B"], + ["text"," "], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","B"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","3"], + ["text"," "], + ["barline.keyword.operator","|"] +],[ + "start", + ["information.keyword.embedded","[M:"], + ["information.argument.string.unquoted","6/8]"], + ["pitch.constant.numeric","D"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","F"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["duration.constant.numeric","3"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text"," "], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","D"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text"," "], + ["pitch.constant.numeric","D"], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["text"," "], + ["barline.keyword.operator","|1"], + ["text"," "], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","F"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","2"], + ["text"," "], + ["barline.keyword.operator",":|2"], + ["text"," "], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","F"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","3"], + ["text"," "], + ["barline.keyword.operator","|]"] +],[ + "start" +],[ + "start", + ["information.keyword","X:"], + ["information.argument.string.unquoted","5"] +],[ + "start", + ["information.keyword","T:"], + ["information.argument.string.unquoted","Atholl Brose"] +],[ + "start", + ["comment.line.percentage","% in this example, which reproduces Highland Bagpipe gracing,"] +],[ + "start", + ["comment.line.percentage","% the large number of grace notes mean that it is more convenient to be specific about"] +],[ + "start", + ["comment.line.percentage","% score line-breaks (using the $ symbol), rather than using code line breaks to indicate them"] +],[ + "start", + ["information.keyword","I:"], + ["information.argument.string.unquoted","linebreak $"] +],[ + "start", + ["information.keyword","K:"], + ["information.argument.string.unquoted","D"] +],[ + "start", + ["text","{"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["text","}"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","<"], + ["text","{"], + ["pitch.constant.numeric","e"], + ["text","}"], + ["pitch.constant.numeric","A"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["text","}"], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","2"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","A"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["text","}"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"] +],[ + "start", + ["text","{"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["text","}"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","<"], + ["text","{"], + ["pitch.constant.numeric","e"], + ["text","}"], + ["pitch.constant.numeric","A"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["text","}"], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","a"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","f"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"] +],[ + "start", + ["text","{"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["text","}"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","<"], + ["text","{"], + ["pitch.constant.numeric","e"], + ["text","}"], + ["pitch.constant.numeric","A"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["text","}"], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","2"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","A"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["text","}"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"] +],[ + "start", + ["text","{"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","/"], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","/"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric",">"], + ["text","{"], + ["pitch.constant.numeric","d"], + ["text","}"], + ["pitch.constant.numeric","B"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","G"], + ["text"," {"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","c"], + ["text","}"], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","B"], + ["barline.keyword.operator",":|"], + ["text","$"] +],[ + "start", + ["text","{"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","<"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","a"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","e"], + ["barline.keyword.operator","|"] +],[ + "start", + ["text","{"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","<"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","a"], + ["duration.constant.numeric","2"], + ["text"," {"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","G"], + ["text","}"], + ["pitch.constant.numeric","a"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"] +],[ + "start", + ["text","{"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","<"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","a"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","f"], + ["barline.keyword.operator","|"] +],[ + "start", + ["text","{"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","d"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","d"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","d"], + ["text","}"], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","<"], + ["text","{"], + ["pitch.constant.numeric","e"], + ["text","}"], + ["pitch.constant.numeric","G"], + ["text"," {"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","c"], + ["text","}"], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","B"], + ["barline.keyword.operator","|"] +],[ + "start", + ["text","{"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","<"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","a"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","e"], + ["barline.keyword.operator","|"] +],[ + "start", + ["text","{"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","<"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","a"], + ["duration.constant.numeric","2"], + ["text"," {"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","G"], + ["text","}"], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"] +],[ + "start", + ["text","{"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","<"], + ["text","{"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","G"], + ["text","}"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","a"], + ["text"," {"], + ["pitch.constant.numeric","f"], + ["text","}"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","e"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","f"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"] +],[ + "start", + ["text","{"], + ["pitch.constant.numeric","g"], + ["text","}"], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","/"], + ["pitch.constant.numeric","f"], + ["duration.constant.numeric","/"], + ["pitch.constant.numeric","g"], + ["text"," {"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","c"], + ["text","}"], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","c"], + ["text"," {"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","d"], + ["text","}"], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","<"], + ["text","{"], + ["pitch.constant.numeric","e"], + ["text","}"], + ["pitch.constant.numeric","G"], + ["text"," {"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","c"], + ["text","}"], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator","|]"] +],[ + "start" +],[ + "start", + ["information.keyword","X:"], + ["information.argument.string.unquoted","6"] +],[ + "start", + ["information.keyword","T:"], + ["information.argument.string.unquoted","Untitled Reel"] +],[ + "start", + ["information.keyword","C:"], + ["information.argument.string.unquoted","Trad."] +],[ + "start", + ["information.keyword","K:"], + ["information.argument.string.unquoted","D"] +],[ + "start", + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","g"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","a"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","b"], + ["text"," "], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","g"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","b"], + ["pitch.constant.numeric","g"], + ["text"," "], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","f"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric","2"], + ["text"," "], + ["pitch.constant.numeric","f"], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","g"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","f"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["text"," "], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator",":|"], + ["text","\\"] +],[ + "start", + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","2"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator",":|"] +],[ + "start", + ["information.keyword","K:"], + ["information.argument.string.unquoted","G"] +],[ + "start", + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","c"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","B"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","F"], + ["text"," "], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","E"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","c"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","B"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","2"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator",":|"] +],[ + "start" +],[ + "start", + ["information.keyword","X:"], + ["information.argument.string.unquoted","7"] +],[ + "start", + ["information.keyword","T:"], + ["information.argument.string.unquoted","Kitchen Girl"] +],[ + "start", + ["information.keyword","C:"], + ["information.argument.string.unquoted","Trad."] +],[ + "start", + ["information.keyword","K:"], + ["information.argument.string.unquoted","D"] +],[ + "start", + ["text","["], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","4"], + ["pitch.constant.numeric","a"], + ["duration.constant.numeric","4"], + ["text","] ["], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","4"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric","4"], + ["text","]"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","f"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","d"], + ["text"," "], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","f"], + ["duration.constant.numeric","2"], + ["text"," "], + ["pitch.constant.numeric","g"], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","b"], + ["pitch.constant.numeric","a"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["text"," "], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","f"], + ["pitch.constant.numeric","g"], + ["barline.keyword.operator","|"] +],[ + "start", + ["pitch.constant.numeric","a"], + ["duration.constant.numeric","4"], + ["text"," "], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric","4"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","f"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","d"], + ["text"," "], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","f"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["text"," "], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","f"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","2"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","4"], + ["barline.keyword.operator",":|"] +],[ + "start", + ["information.keyword","K:"], + ["information.argument.string.unquoted","G"] +],[ + "start", + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","B"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","D"], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["text"," "], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","3"], + ["pitch.constant.numeric","f"], + ["text"," "], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","B"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","B"], + ["barline.keyword.operator","|"] +],[ + "start", + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["text"," "], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","c"], + ["text"," "], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","4"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","4"], + ["barline.keyword.operator",":|"] +],[ + "start" +],[ + "start", + ["comment.line.percentage","%abc-2.1"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","pagewidth 21cm"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","pageheight 29.7cm"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","topspace 0.5cm"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","topmargin 1cm"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","botmargin 0cm"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","leftmargin 1cm"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","rightmargin 1cm"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","titlespace 0cm"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","titlefont Times-Bold 32"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","subtitlefont Times-Bold 24"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","composerfont Times 16"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","vocalfont Times-Roman 14"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","staffsep 60pt"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","sysstaffsep 20pt"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","musicspace 1cm"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","vocalspace 5pt"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","measurenb 0"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","barsperstaff 5"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","scale 0.7"] +],[ + "start", + ["information.keyword","X:"], + ["information.argument.string.unquoted"," 1"] +],[ + "start", + ["information.keyword","T:"], + ["information.argument.string.unquoted"," Canzonetta a tre voci"] +],[ + "start", + ["information.keyword","C:"], + ["information.argument.string.unquoted"," Claudio Monteverdi (1567-1643)"] +],[ + "start", + ["information.keyword","M:"], + ["information.argument.string.unquoted"," C"] +],[ + "start", + ["information.keyword","L:"], + ["information.argument.string.unquoted"," 1/4"] +],[ + "start", + ["information.keyword","Q:"], + ["information.argument.string.unquoted"," \"Andante mosso\" 1/4 = 110"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","score [1 2 3]"] +],[ + "start", + ["information.keyword","V:"], + ["information.argument.string.unquoted"," 1 clef=treble name=\"Soprano\"sname=\"A\""] +],[ + "start", + ["information.keyword","V:"], + ["information.argument.string.unquoted"," 2 clef=treble name=\"Alto\" sname=\"T\""] +],[ + "start", + ["information.keyword","V:"], + ["information.argument.string.unquoted"," 3 clef=bass middle=d name=\"Tenor\" sname=\"B\""] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","MIDI program 1 75 % recorder"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","MIDI program 2 75"] +],[ + "start", + ["information.comment.line.percentage","%%"], + ["information.keyword.embedded","MIDI program 3 75"] +],[ + "start", + ["information.keyword","K:"], + ["information.argument.string.unquoted"," Eb"] +],[ + "start", + ["comment.line.percentage","% 1 - 4"] +],[ + "start", + ["information.keyword.embedded","[V:"], + ["information.argument.string.unquoted"," 1]"], + ["text"," "], + ["barline.keyword.operator","|:"], + ["pitch.constant.numeric","z"], + ["duration.constant.numeric","4"], + ["text"," "], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","z"], + ["duration.constant.numeric","4"], + ["text"," "], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","f"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","c"], + ["text"," "], + ["barline.keyword.operator","|"], + ["accent.constant.language","_"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","c"], + ["text"," "], + ["barline.keyword.operator","|"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," Son que-sti~i cre-spi cri-ni~e"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," Que-sti son gli~oc-chi che mi-"] +],[ + "start", + ["information.keyword.embedded","[V:"], + ["information.argument.string.unquoted"," 2]"], + ["text"," "], + ["barline.keyword.operator","|:"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","G"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","c"], + ["barline.keyword.operator","|"], + ["text","("], + ["pitch.constant.numeric","F"], + ["duration.constant.numeric","/"], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","/"], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","/"], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","/"], + ["text",")"], + ["pitch.constant.numeric","c"], + ["accent.constant.language","="], + ["pitch.constant.numeric","A"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["barline.keyword.operator","|"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," Son que-sti~i cre-spi cri-ni~e que - - - - sto~il vi-so e"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," Que-sti son~gli oc-chi che mi-ran - - - - do fi-so mi-"] +],[ + "start", + ["information.keyword.embedded","[V:"], + ["information.argument.string.unquoted"," 3]"], + ["text"," "], + ["barline.keyword.operator","|:"], + ["pitch.constant.numeric","z"], + ["duration.constant.numeric","4"], + ["text"," "], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","f"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","c"], + ["barline.keyword.operator","|"], + ["accent.constant.language","_"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","f"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text","("], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","/"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","/"], + ["accent.constant.language","_"], + ["pitch.constant.numeric","d"], + ["duration.constant.numeric","/"], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","/"], + ["text",")"], + ["pitch.constant.numeric","f"], + ["pitch.constant.numeric","f"], + ["barline.keyword.operator","|"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," Son que-sti~i cre-spi cri-ni~e que - - - - sto~il"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," Que-sti son~gli oc-chi che mi-ran - - - - do"] +],[ + "start", + ["comment.line.percentage","% 5 - 9"] +],[ + "start", + ["information.keyword.embedded","[V:"], + ["information.argument.string.unquoted"," 1]"], + ["text"," "], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","2"], + ["text"," "], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","3"], + ["pitch.constant.numeric","B"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","2"], + ["string.quoted","!fermata!"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","z"], + ["text"," "], + ["barline.keyword.operator","::"], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","4"], + ["barline.keyword.operator","|"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," que-sto~il vi-so ond' io ri-man-go~uc-ci-so. Deh,"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," ran-do fi-so, tut-to re-stai con-qui-so."] +],[ + "start", + ["information.keyword.embedded","[V:"], + ["information.argument.string.unquoted"," 2]"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","2"], + ["text"," "], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","F"], + ["text"," "], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","3"], + ["pitch.constant.numeric","F"], + ["barline.keyword.operator","|"], + ["accent.constant.language","="], + ["pitch.constant.numeric","E"], + ["duration.constant.numeric","2"], + ["string.quoted","!fermata!"], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","z"], + ["barline.keyword.operator","::"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","4"], + ["barline.keyword.operator","|"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," que-sto~il vi-so ond' io ri-man-go~uc-ci-so. Deh,"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," ran-do fi-so tut-to re-stai con-qui-so."] +],[ + "start", + ["information.keyword.embedded","[V:"], + ["information.argument.string.unquoted"," 3]"], + ["text"," ("], + ["pitch.constant.numeric","a"], + ["pitch.constant.numeric","g"], + ["duration.constant.numeric","/"], + ["pitch.constant.numeric","f"], + ["duration.constant.numeric","/"], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["text",")"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","A"], + ["accent.constant.language","_"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","3"], + ["pitch.constant.numeric","B"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","2"], + ["string.quoted","!fermata!"], + ["pitch.constant.numeric","c"], + ["pitch.constant.numeric","z"], + ["text"," "], + ["barline.keyword.operator","::"], + ["pitch.constant.numeric","A"], + ["duration.constant.numeric","4"], + ["barline.keyword.operator","|"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," vi - - - so ond' io ti-man-go~uc-ci-so. Deh,"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," fi - - - so tut-to re-stai con-qui-so."] +],[ + "start", + ["comment.line.percentage","% 10 - 15"] +],[ + "start", + ["information.keyword.embedded","[V:"], + ["information.argument.string.unquoted"," 1]"], + ["text"," "], + ["pitch.constant.numeric","f"], + ["accent.constant.language","_"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","e"], + ["pitch.constant.numeric","c"], + ["text"," "], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","B"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","z"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","F"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text","\\"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," dim-me-lo ben mi-o, che que-sto"], + ["text","\\"] +],[ + "start", + ["accent.constant.language","="], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","2"], + ["text"," "], + ["barline.keyword.operator","|1"], + ["pitch.constant.numeric","F"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","z"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator",":|2"], + ["pitch.constant.numeric","F"], + ["duration.constant.numeric","8"], + ["barline.keyword.operator","|]"], + ["text"," "], + ["comment.line.percentage","% more notes"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," sol de-si-o_. "], + ["comment.line.percentage","% more lyrics"] +],[ + "start", + ["information.keyword.embedded","[V:"], + ["information.argument.string.unquoted"," 2]"], + ["text"," "], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","A"], + ["text"," "], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","G"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","A"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","F"], + ["accent.constant.language","="], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["text"," "], + ["barline.keyword.operator","|"], + ["text","("], + ["pitch.constant.numeric","G"], + ["pitch.constant.numeric","F"], + ["duration.constant.numeric","3/2"], + ["accent.constant.language","="], + ["pitch.constant.numeric","E"], + ["duration.constant.numeric","//"], + ["pitch.constant.numeric","D"], + ["duration.constant.numeric","//"], + ["pitch.constant.numeric","E"], + ["text",")"], + ["barline.keyword.operator","|1"], + ["pitch.constant.numeric","F"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","z"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator",":|2"], + ["pitch.constant.numeric","F"], + ["duration.constant.numeric","8"], + ["barline.keyword.operator","|]"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," dim-me-lo ben mi-o, che que-sto sol de-si - - - - o_."] +],[ + "start", + ["information.keyword.embedded","[V:"], + ["information.argument.string.unquoted"," 3]"], + ["text"," "], + ["accent.constant.language","_"], + ["pitch.constant.numeric","d"], + ["pitch.constant.numeric","B"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric",">"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","e"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","A"], + ["pitch.constant.numeric","F"], + ["barline.keyword.operator","|"], + ["accent.constant.language","="], + ["pitch.constant.numeric","E"], + ["pitch.constant.numeric","F"], + ["pitch.constant.numeric","c"], + ["accent.constant.language","_"], + ["pitch.constant.numeric","d"], + ["barline.keyword.operator","|"], + ["pitch.constant.numeric","c"], + ["duration.constant.numeric","4"], + ["text"," "], + ["barline.keyword.operator","|1"], + ["pitch.constant.numeric","F"], + ["duration.constant.numeric","2"], + ["pitch.constant.numeric","z"], + ["duration.constant.numeric","2"], + ["barline.keyword.operator",":|2"], + ["pitch.constant.numeric","F"], + ["duration.constant.numeric","8"], + ["barline.keyword.operator","|]"] +],[ + "start", + ["information.keyword","w:"], + ["information.argument.string.unquoted"," dim-me-lo ben mi-o, che que-sto sol de-si-o_."] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_actionscript.json b/lib/ace/mode/_test/tokens_actionscript.json new file mode 100644 index 00000000..e3fad38f --- /dev/null +++ b/lib/ace/mode/_test/tokens_actionscript.json @@ -0,0 +1,263 @@ +[[ + "start", + ["text","package code"] +],[ + "start", + ["text","{"] +],[ + "punctuation.definition.comment.actionscript.2", + ["text"," "], + ["punctuation.definition.comment.actionscript.2","/*"], + ["comment.block.actionscript.2","****************************************"] +],[ + "punctuation.definition.comment.actionscript.2", + ["comment.block.actionscript.2","\t * based on textmate actionscript bundle"] +],[ + "start", + ["comment.block.actionscript.2","\t ***************************************"], + ["punctuation.definition.comment.actionscript.2","*/"] +],[ + "start", + ["text","\t "] +],[ + "start", + ["text","\t"], + ["keyword.control.actionscript.2","import"], + ["text"," fl.events.SliderEvent;"] +],[ + "start", + ["text","\t"] +],[ + "start", + ["text","\t"], + ["keyword.control.actionscript.2","public"], + ["text"," "], + ["storage.type.class.actionscript.2","class"], + ["meta.class.actionscript.2"," "], + ["entity.name.type.class.actionscript.2","Foo"], + ["meta.class.actionscript.2"," "], + ["storage.modifier.extends.actionscript.2","extends"], + ["meta.class.actionscript.2"," "], + ["entity.other.inherited-class.actionscript.2","MovieClip"] +],[ + "start", + ["text","\t{"] +],[ + "start", + ["text","\t\t"], + ["punctuation.definition.comment.actionscript.2","//*************************"] +],[ + "start", + ["text","\t\t"], + ["punctuation.definition.comment.actionscript.2","// Properties:"] +],[ + "start", + ["text","\t\t"] +],[ + "start", + ["text","\t\t"], + ["keyword.control.actionscript.2","public"], + ["text"," "], + ["keyword.control.actionscript.2","var"], + ["text"," activeSwatch"], + ["keyword.operator.symbolic.actionscript.2",":"], + ["support.class.actionscript.2","MovieClip"], + ["text",";"] +],[ + "start", + ["text","\t\t"] +],[ + "start", + ["text","\t\t"], + ["punctuation.definition.comment.actionscript.2","// Color offsets"] +],[ + "start", + ["text","\t\t"], + ["keyword.control.actionscript.2","public"], + ["text"," "], + ["keyword.control.actionscript.2","var"], + ["text"," c1"], + ["keyword.operator.symbolic.actionscript.2",":"], + ["storage.type.actionscript.2","Number"], + ["text"," "], + ["keyword.operator.symbolic.actionscript.2","="], + ["text"," "], + ["constant.numeric.actionscript.2","0"], + ["text",";\t"], + ["punctuation.definition.comment.actionscript.2","// R"] +],[ + "start", + ["text","\t\t"] +],[ + "start", + ["text","\t\t"], + ["punctuation.definition.comment.actionscript.2","//*************************"] +],[ + "start", + ["text","\t\t"], + ["punctuation.definition.comment.actionscript.2","// Constructor:"] +],[ + "start", + ["text","\t\t"] +],[ + "start", + ["text","\t\t"], + ["keyword.control.actionscript.2","public"], + ["text"," "], + ["storage.type.function.actionscript.2","function"], + ["meta.function.actionscript.2"," "], + ["entity.name.function.actionscript.2","Foo"], + ["punctuation.definition.parameters.begin.actionscript.2","("], + ["punctuation.definition.parameters.end.actionscript.2",")"] +],[ + "start", + ["text","\t\t{"] +],[ + "start", + ["text","\t\t\t"], + ["punctuation.definition.comment.actionscript.2","// Respond to mouse events"] +],[ + "start", + ["text","\t\t\tswatch1_btn."], + ["support.function.actionscript.2","addEventListener"], + ["text","(MouseEvent.CLICK,swatchHandler,"], + ["constant.language.actionscript.2","false"], + ["text",","], + ["constant.numeric.actionscript.2","0"], + ["text",","], + ["constant.language.actionscript.2","false"], + ["text",");"] +],[ + "start", + ["text","\t\t\tpreviewBox_btn."], + ["support.function.actionscript.2","addEventListener"], + ["text","(MouseEvent.MOUSE_DOWN,dragPressHandler);"] +],[ + "start", + ["text","\t\t\t"] +],[ + "start", + ["text","\t\t\t"], + ["punctuation.definition.comment.actionscript.2","// Respond to drag events"] +],[ + "start", + ["text","\t\t\tred_slider."], + ["support.function.actionscript.2","addEventListener"], + ["text","(SliderEvent.THUMB_DRAG,sliderHandler);"] +],[ + "start", + ["text","\t\t\t"] +],[ + "start", + ["text","\t\t\t"], + ["punctuation.definition.comment.actionscript.2","// Draw a frame later"] +],[ + "start", + ["text","\t\t\t"], + ["support.function.actionscript.2","addEventListener"], + ["text","(Event.ENTER_FRAME,"], + ["support.function.actionscript.2","draw"], + ["text",");"] +],[ + "start", + ["text","\t\t}"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text","\t\tprotected "], + ["storage.type.function.actionscript.2","function"], + ["meta.function.actionscript.2"," "], + ["entity.name.function.actionscript.2","clickHandler"], + ["punctuation.definition.parameters.begin.actionscript.2","("], + ["variable.parameter.function.actionscript.2","event:MouseEvent"], + ["punctuation.definition.parameters.end.actionscript.2",")"], + ["keyword.operator.symbolic.actionscript.2",":"], + ["support.function.actionscript.2","void"] +],[ + "start", + ["text","\t\t{"] +],[ + "start", + ["text","\t\t\tcar.transform.colorTransform "], + ["keyword.operator.symbolic.actionscript.2","="], + ["text"," "], + ["keyword.control.actionscript.2","new"], + ["text"," ColorTransform("], + ["constant.numeric.actionscript.2","0"], + ["text",","], + ["constant.numeric.actionscript.2","0"], + ["text",","], + ["constant.numeric.actionscript.2","0"], + ["text",","], + ["constant.numeric.actionscript.2","1"], + ["text",",c1,c2,c3);"] +],[ + "start", + ["text","\t\t}"] +],[ + "start", + ["text","\t\t"] +],[ + "start", + ["text","\t\tprotected "], + ["storage.type.function.actionscript.2","function"], + ["meta.function.actionscript.2"," "], + ["entity.name.function.actionscript.2","changeRGBHandler"], + ["punctuation.definition.parameters.begin.actionscript.2","("], + ["variable.parameter.function.actionscript.2","event:Event"], + ["punctuation.definition.parameters.end.actionscript.2",")"], + ["keyword.operator.symbolic.actionscript.2",":"], + ["support.function.actionscript.2","void"] +],[ + "start", + ["text","\t\t{"] +],[ + "start", + ["text","\t\t\tc1 "], + ["keyword.operator.symbolic.actionscript.2","="], + ["text"," "], + ["storage.type.actionscript.2","Number"], + ["text","(c1_txt."], + ["support.function.actionscript.2","text"], + ["text",");"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text","\t\t\t"], + ["keyword.control.actionscript.2","if"], + ["text","("], + ["keyword.operator.symbolic.actionscript.2","!"], + ["text","(c1>"], + ["keyword.operator.symbolic.actionscript.2","="], + ["constant.numeric.actionscript.2","0"], + ["text",")){"] +],[ + "start", + ["text","\t\t\t\tc1 "], + ["keyword.operator.symbolic.actionscript.2","="], + ["text"," "], + ["constant.numeric.actionscript.2","0"], + ["text",";"] +],[ + "start", + ["text","\t\t\t}\t\t\t"] +],[ + "start", + ["text","\t\t\t"] +],[ + "start", + ["text","\t\t\tupdateSliders();"] +],[ + "start", + ["text","\t\t}"] +],[ + "start", + ["text","\t}"] +],[ + "start", + ["text","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_ada.json b/lib/ace/mode/_test/tokens_ada.json new file mode 100644 index 00000000..bdef7256 --- /dev/null +++ b/lib/ace/mode/_test/tokens_ada.json @@ -0,0 +1,39 @@ +[[ + "start", + ["keyword","with"], + ["text"," "], + ["identifier","Ada"], + ["text","."], + ["identifier","Text_IO"], + ["text","; "], + ["keyword","use"], + ["text"," "], + ["identifier","Ada"], + ["text","."], + ["identifier","Text_IO"], + ["text",";"] +],[ + "start", + ["keyword","procedure"], + ["text"," "], + ["identifier","Hello"], + ["text"," "], + ["keyword","is"] +],[ + "start", + ["keyword","begin"] +],[ + "start", + ["text"," "], + ["identifier","Put_Line"], + ["paren.lparen","("], + ["string","\"Hello, world!\""], + ["paren.rparen",")"], + ["text",";"] +],[ + "start", + ["keyword","end"], + ["text"," "], + ["identifier","Hello"], + ["text",";"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_asciidoc.json b/lib/ace/mode/_test/tokens_asciidoc.json new file mode 100644 index 00000000..f54c355e --- /dev/null +++ b/lib/ace/mode/_test/tokens_asciidoc.json @@ -0,0 +1,422 @@ +[[ + "literalBlock", + ["support.function","------------------------------------"] +],[ + "dissallowDelimitedBlock", + ["support.function","-----------------------------------"] +],[ + "text", + ["string.italic","_ita_lic_"], + ["text",", "], + ["keyword.bold","*bo*ld*"], + ["text",", "], + ["support.function","+mo+no+"], + ["text",", normal. "] +],[ + "text", + ["keyword","``"], + ["text","double quoted"], + ["keyword","''"], + ["text",", `single quoted'."] +],[ + "text", + ["text"," normal, ^super^, "], + ["keyword","~sub~"], + ["text","."] +],[ + "start" +],[ + "text", + ["text","''''"] +],[ + "text", + ["text","Escaped:"] +],[ + "text", + ["constant.language.escape","\\_"], + ["text","italic_, "], + ["support.function","+++"], + ["text","_italic_"], + ["support.function","+++"], + ["text",","] +],[ + "smallPassthrough", + ["text","t"], + ["constant.language.escape","\\_"], + ["text","_e"], + ["string.italic","__st, +++t__"], + ["text","e__st"], + ["support.function","+++"], + ["text",","] +],[ + "smallPassthrough", + ["support.function","+++"], + ["text","bold"], + ["support.function","+++"], + ["text",", $$<"], + ["support.function","b"], + ["text",">"], + ["support.function","normal"], + ["text","$$"] +],[ + "smallPassthrough", + ["text","\\&#"], + ["support.function","182"], + ["text","; &#"], + ["support.function","182"], + ["text",";"] +],[ + "smallPassthrough", + ["text","\\`"], + ["support.function","not"], + ["text"," "], + ["support.function","single"], + ["text"," "], + ["support.function","quoted"], + ["text","'"] +],[ + "smallPassthrough", + ["text","\\`\\`"], + ["support.function","not"], + ["text"," "], + ["support.function","double"], + ["text"," "], + ["support.function","quoted"], + ["text","''"] +],[ + "dissallowDelimitedBlock" +],[ + "text" +],[ + "start", + ["string.regexp","[fffff]"] +],[ + "passthroughBlock", + ["string","+++++++++++++++++++++++++++++++++++++"] +],[ + "passthroughBlock", + ["support.function","(C) "], + ["constant.character","{ss}"], + ["support.function"," ss"] +],[ + "dissallowDelimitedBlock", + ["support.function","+++++++++++++++++++++++++++++++++++++"] +],[ + "text" +],[ + "listingBlock", + ["support.function","............."] +],[ + "listingBlock", + ["support.function","callout "], + ["constant.numeric","<1>"] +],[ + "dissallowDelimitedBlock", + ["support.function",".............."] +],[ + "text" +],[ + "text", + ["text","> 1"] +],[ + "text", + ["text","1> 2"] +],[ + "text", + ["text","<2> 3"] +],[ + "start" +],[ + "text", + ["text","Escaped:"] +],[ + "text", + ["constant.language.escape","\\_"], + ["text","italic_,"] +],[ + "text", + ["text","t"], + ["constant.language.escape","\\_"], + ["text","_e"], + ["string.italic","__st, o__"] +],[ + "start" +],[ + "start", + ["constant.numeric",".optional title"] +],[ + "listingBlock", + ["support.function","............."] +],[ + "listingBlock", + ["support.function","callout "], + ["constant.numeric","<1>"] +],[ + "dissallowDelimitedBlock", + ["support.function",".............."] +],[ + "text" +],[ + "start" +],[ + "text", + ["keyword",":macro:"], + ["text"," dddd"] +],[ + "start" +],[ + "start", + ["constant.numeric",".lists"] +],[ + "listText", + ["keyword",". "], + ["text","1"] +],[ + "listText", + ["keyword",".. "], + ["text","2"] +],[ + "listText", + ["keyword","... "], + ["text","d"] +],[ + "listText", + ["keyword","..... "], + ["text","big"] +],[ + "start", + ["keyword","+"] +],[ + "text", + ["text","continue"], + ["keyword"," +"] +],[ + "text", + ["text","next line"] +],[ + "text", + ["text","xi) no "], + ["support.function","++la+tin++"] +],[ + "start" +],[ + "listText", + ["keyword","xi) "], + ["text","la"], + ["support.function","++tin++"] +],[ + "listText", + ["keyword","2. "], + ["text","num"], + ["string.italic","__ber__"], + ["text"," [red]"], + ["keyword","#"], + ["text","red"], + ["keyword","#"] +],[ + "start", + ["keyword","--"] +],[ + "listText", + ["keyword"," 5. "], + ["text","f "], + ["keyword","<>"], + ["text"," "], + ["constant.character","{macro}"] +],[ + "start", + ["keyword","--"] +],[ + "text", + ["markup.list.macro","image::"], + ["keyword","path"], + ["string","[beauty]"], + ["text"," "], + ["constant.language.escape","->"], + ["text","--"], + ["constant.language.escape","<= --"], + ["text"," replacements"] +],[ + "start" +],[ + "indentedBlock", + ["support.function"," image::s"] +],[ + "indentedBlock", + ["support.function","sssss"] +],[ + "indentedBlock", + ["support.function","sss "] +],[ + "indentedBlock", + ["support.function","sssss"] +],[ + "start" +],[ + "start" +],[ + "start", + ["markup.heading","== 1"] +],[ + "indentedBlock", + ["support.function"," heading"] +],[ + "start", + ["markup.heading","=== not a heading"] +],[ + "start", + ["keyword","===================================="] +],[ + "start" +],[ + "start", + ["keyword","=================================="] +],[ + "text", + ["text","====4 "] +],[ + "text", + ["text","NOTE: above"] +],[ + "start" +],[ + "text", + ["keyword","NOTE:"], + ["text"," above"] +],[ + "start" +],[ + "start", + ["string.regexp","[[x6]]"] +],[ + "text", + ["keyword","WARNING:"], + ["text"," "] +],[ + "start" +],[ + "start", + ["string.regexp","[options[]]"] +],[ + "literalBlock", + ["support.function","---------------------------"] +],[ + "literalBlock", + ["support.function","literal"] +],[ + "dissallowDelimitedBlock", + ["support.function","---------------------------"] +],[ + "text" +],[ + "start" +],[ + "start", + ["markup.heading","= Tables"] +],[ + "tableBlock", + ["doc.comment","|===================================="] +],[ + "tableBlock", + ["doc.comment","|"], + ["text"," "], + ["string.italic","_italic_"], + ["text"," "], + ["doc.comment","|"], + ["text"," "], + ["keyword.bold","*bold*"], + ["text"," "], + ["doc.comment","|"], + ["text"," text "], + ["doc.comment","|"], + ["text"," "], + ["constant.language.escape","(R)"] +],[ + "tableBlock" +],[ + "dissallowDelimitedBlock", + ["doc.comment","|===================================="] +],[ + "text" +],[ + "start" +],[ + "start", + ["string.regexp","[more, options]"] +],[ + "commentBlock", + ["doc.comment","///////////"] +],[ + "commentBlock", + ["doc.comment","comment"] +],[ + "dissallowDelimitedBlock", + ["doc.comment","///////////"] +],[ + "text", + ["comment","// one line comment"] +],[ + "start" +],[ + "start" +],[ + "start" +],[ + "text", + ["text","[red]"], + ["keyword","#"], + ["text","red text"], + ["keyword","#"], + ["text"," [yellow-background]"], + ["keyword","#"], + ["text","on yellow"], + ["keyword","#"] +],[ + "text", + ["text","[big]"], + ["keyword","#"], + ["text","large"], + ["keyword","#"], + ["text"," [red yellow-background big]"], + ["keyword.bold","*all bold*"] +],[ + "start" +],[ + "start", + ["text","\t"] +],[ + "text", + ["markup.underline.list","https://site"], + ["text"," text <"], + ["markup.underline.list","mail@i.am"], + ["text","> "], + ["markup.underline.list","callto:ace"], + ["text"," "], + ["link","http://ace.ajaxorg.com"], + ["variable.language","[awesome]"] +],[ + "text", + ["text"," .still normal text"] +],[ + "start", + ["constant.numeric",".break out thoug should not"] +],[ + "literalBlock", + ["support.function","---------------------------"] +],[ + "literalBlock", + ["support.function","///////////////////////////"] +],[ + "dissallowDelimitedBlock", + ["support.function","---------------------------"] +],[ + "text" +],[ + "start" +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_assembly_x86.json b/lib/ace/mode/_test/tokens_assembly_x86.json new file mode 100644 index 00000000..5da0470e --- /dev/null +++ b/lib/ace/mode/_test/tokens_assembly_x86.json @@ -0,0 +1,114 @@ +[[ + "start", + ["support.function.directive.assembly","section"], + ["text","\t.text"] +],[ + "start", + ["text"," "], + ["support.function.directive.assembly","global"], + ["text"," "], + ["entity.name.function.assembly","main"], + ["text"," "], + ["comment.assembly",";must be declared for using gcc"] +],[ + "start" +],[ + "start", + ["entity.name.function.assembly","main:"], + ["text","\t "], + ["comment.assembly",";tell linker entry point"] +],[ + "start" +],[ + "start", + ["text","\t"], + ["keyword.control.assembly","mov"], + ["text","\t"], + ["variable.parameter.register.assembly","edx"], + ["text",", len\t "], + ["comment.assembly",";message length"] +],[ + "start", + ["text","\t"], + ["keyword.control.assembly","mov"], + ["text","\t"], + ["variable.parameter.register.assembly","ecx"], + ["text",", msg\t "], + ["comment.assembly",";message to write"] +],[ + "start", + ["text","\t"], + ["keyword.control.assembly","mov"], + ["text","\t"], + ["variable.parameter.register.assembly","ebx"], + ["text",", "], + ["constant.character.decimal.assembly","1"], + ["text","\t "], + ["comment.assembly",";file descriptor (stdout)"] +],[ + "start", + ["text","\t"], + ["keyword.control.assembly","mov"], + ["text","\t"], + ["variable.parameter.register.assembly","eax"], + ["text",", "], + ["constant.character.decimal.assembly","4"], + ["text","\t "], + ["comment.assembly",";system call number (sys_write)"] +],[ + "start", + ["text","\t"], + ["keyword.control.assembly","int"], + ["text","\t"], + ["constant.character.hexadecimal.assembly","0x80"], + ["text","\t "], + ["comment.assembly",";call kernel"] +],[ + "start" +],[ + "start", + ["text","\t"], + ["keyword.control.assembly","mov"], + ["text","\t"], + ["variable.parameter.register.assembly","eax"], + ["text",", "], + ["constant.character.decimal.assembly","1"], + ["text","\t "], + ["comment.assembly",";system call number (sys_exit)"] +],[ + "start", + ["text","\t"], + ["keyword.control.assembly","int"], + ["text","\t"], + ["constant.character.hexadecimal.assembly","0x80"], + ["text","\t "], + ["comment.assembly",";call kernel"] +],[ + "start" +],[ + "start", + ["support.function.directive.assembly","section"], + ["text","\t.data"] +],[ + "start" +],[ + "start", + ["entity.name.function.assembly","msg"], + ["text","\t"], + ["support.function.directive.assembly","db"], + ["text","\t"], + ["string.assembly","'Hello, world!'"], + ["text",","], + ["constant.character.hexadecimal.assembly","0xa"], + ["text","\t"], + ["comment.assembly",";our dear string"] +],[ + "start", + ["entity.name.function.assembly","len"], + ["text","\t"], + ["support.function.directive.assembly","equ"], + ["text","\t$ - msg\t\t\t"], + ["comment.assembly",";length of our dear string"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_autohotkey.json b/lib/ace/mode/_test/tokens_autohotkey.json new file mode 100644 index 00000000..374310fb --- /dev/null +++ b/lib/ace/mode/_test/tokens_autohotkey.json @@ -0,0 +1,261 @@ +[[ + "start", + ["punctuation.ahk","#"], + ["keyword.command.ahk","NoEnv"] +],[ + "start", + ["keyword.command.ahk","SetBatchLines"], + ["text"," "], + ["constant.numeric","-1"] +],[ + "start" +],[ + "start", + ["keyword.command.ahk","CoordMode"], + ["text"," "], + ["variable.parameter","Mouse"], + ["punctuation.ahk",","], + ["text"," "], + ["variable.parameter","Screen"] +],[ + "start", + ["keyword.command.ahk","OnExit"], + ["text"," "], + ["variable.parameter","GuiClose"] +],[ + "start" +],[ + "start", + ["text","zoom "], + ["keyword.operator.ahk",":="], + ["text"," 9"] +],[ + "start" +],[ + "start", + ["text","computeSize"], + ["punctuation.ahk","(){"] +],[ + "start", + ["text","\t"], + ["keyword.control.ahk","global"], + ["text"," as_x"] +],[ + "start", + ["text","\tas_x "], + ["keyword.operator.ahk",":="], + ["text"," "], + ["support.function.ahk","Round"], + ["punctuation.ahk","("], + ["text","ws_x"], + ["keyword.operator.ahk","/"], + ["text","zoom"], + ["keyword.operator.ahk","/"], + ["text","2 "], + ["keyword.operator.ahk","-"], + ["text"," 0.5"], + ["punctuation.ahk",")"] +],[ + "start", + ["text","\t"], + ["keyword.control.ahk","if"], + ["text"," "], + ["punctuation.ahk","("], + ["text","zoom"], + ["keyword.operator.ahk",">"], + ["text","1"], + ["punctuation.ahk",")"], + ["text"," "], + ["punctuation.ahk","{"] +],[ + "start", + ["text","\t\tpix "], + ["keyword.operator.ahk",":="], + ["text"," "], + ["support.function.ahk","Round"], + ["punctuation.ahk","("], + ["text","zoom"], + ["punctuation.ahk",")"] +],[ + "start", + ["text","\t"], + ["punctuation.ahk","}"], + ["text"," ele "], + ["punctuation.ahk","{"] +],[ + "start", + ["text","\t\tpix "], + ["keyword.operator.ahk",":="], + ["text"," 1"] +],[ + "start", + ["text","\t"], + ["punctuation.ahk","}"] +],[ + "start", + ["text"," "], + ["keyword.command.ahk","ToolTip"], + ["text"," Message "], + ["punctuation.ahk","%"], + ["text","as_x"], + ["punctuation.ahk","%"], + ["text"," "], + ["punctuation.ahk","%"], + ["text","zoom"], + ["punctuation.ahk","%"], + ["text"," "], + ["punctuation.ahk","%"], + ["text","ws_x"], + ["punctuation.ahk","%"], + ["text"," "], + ["punctuation.ahk","%"], + ["text","hws_x"], + ["punctuation.ahk","%"], + ["text"," "] +],[ + "start", + ["punctuation.ahk","}"] +],[ + "start" +],[ + "start", + ["text","hdc_frame "], + ["keyword.operator.ahk",":="], + ["text"," "], + ["support.function.ahk","DllCall"], + ["punctuation.ahk","("], + ["punctuation.quote.double","\""], + ["string.quoted.ahk","GetDC"], + ["punctuation.quote.double","\""], + ["punctuation.ahk",","], + ["text"," UInt"], + ["punctuation.ahk",","], + ["text"," MagnifierID"], + ["punctuation.ahk",")"] +],[ + "start" +],[ + "start", + ["comment.line.ahk","; comment"] +],[ + "start", + ["text","DrawCross"], + ["punctuation.ahk","("], + ["keyword.control.ahk","byRef"], + ["text"," x"], + ["keyword.operator.ahk","="], + ["punctuation.quote.double","\""], + ["punctuation.quote.double","\""], + ["punctuation.ahk",","], + ["text"," rX"], + ["punctuation.ahk",","], + ["text","rY"], + ["punctuation.ahk",","], + ["text","z"], + ["punctuation.ahk",","], + ["text"," dc"], + ["punctuation.ahk","){"] +],[ + "start", + ["text"," "], + ["comment.line.ahk"," ;specify the style, thickness and color of the cross lines"] +],[ + "start", + ["text"," h_pen "], + ["keyword.operator.ahk",":="], + ["text"," "], + ["support.function.ahk","DllCall"], + ["punctuation.ahk","("], + ["text"," "], + ["punctuation.quote.double","\""], + ["string.quoted.ahk","gdi32.dll\\CreatePen"], + ["punctuation.quote.double","\""], + ["punctuation.ahk",","], + ["text"," "], + ["constant.language","Int"], + ["punctuation.ahk",","], + ["text"," 0"], + ["punctuation.ahk",","], + ["text"," "], + ["constant.language","Int"], + ["punctuation.ahk",","], + ["text"," 1"], + ["punctuation.ahk",","], + ["text"," UInt"], + ["punctuation.ahk",","], + ["text"," 0x0000FF"], + ["punctuation.ahk",")"] +],[ + "start", + ["punctuation.ahk","}"] +],[ + "start" +],[ + "start", + ["comment.line.ahk",";Ctrl ^; Shift +; Win #; Alt !"] +],[ + "start", + ["text","^"], + ["support.constant.ahk","NumPadAdd"], + ["keyword.operator.ahk","::"] +],[ + "start", + ["text","^"], + ["support.constant.ahk","WheelUp"], + ["keyword.operator.ahk","::"], + ["text"," "] +],[ + "start", + ["text","^;"], + ["keyword.operator.ahk","::"], + ["text"," "], + ["comment.line.ahk"," ;comment"] +],[ + "start", + ["text"," "], + ["keyword.control.ahk","If"], + ["punctuation.ahk","("], + ["text","zoom "], + ["keyword.operator.ahk","<"], + ["text"," ws_x "], + ["variable.parameter","and"], + ["text"," "], + ["punctuation.ahk","("], + ["text"," "], + ["variable.predefined.ahk","A_ThisHotKey"], + ["text"," "], + ["keyword.operator.ahk","="], + ["text"," "], + ["punctuation.quote.double","\""], + ["string.quoted.ahk","^WheelUp"], + ["punctuation.quote.double","\""], + ["text"," "], + ["variable.parameter","or"], + ["text"," "], + ["variable.predefined.ahk","A_ThisHotKey"], + ["text"," "], + ["keyword.operator.ahk","="], + ["punctuation.quote.double","\""], + ["string.quoted.ahk","^NumPadAdd"], + ["punctuation.quote.double","\""], + ["punctuation.ahk",")"], + ["text"," "], + ["punctuation.ahk",")"] +],[ + "start", + ["text","\t\tzoom "], + ["keyword.operator.ahk","*="], + ["text"," 1.189207115 "], + ["comment.line.ahk"," ; sqrt(sqrt(2))"] +],[ + "start", + ["text","\t"], + ["keyword.command.ahk","Gosub"], + ["punctuation.ahk",","], + ["text","setZoom"] +],[ + "start", + ["keyword.control.ahk","return"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_batchfile.json b/lib/ace/mode/_test/tokens_batchfile.json new file mode 100644 index 00000000..0f1f138c --- /dev/null +++ b/lib/ace/mode/_test/tokens_batchfile.json @@ -0,0 +1,70 @@ +[[ + "start", + ["comment.line.colons.dosbatch",":: batch file highlighting in Ace!"] +],[ + "start", + ["text","@"], + ["keyword.command.dosbatch","echo"], + ["text"," off"] +],[ + "start" +],[ + "start", + ["keyword.control.statement.dosbatch","CALL"], + ["text"," "], + ["keyword.command.dosbatch","set"], + ["text"," var1="], + ["constant.numeric","%cd%"] +],[ + "start", + ["keyword.command.dosbatch","echo"], + ["text"," unhide everything in "], + ["constant.numeric","%var1%"], + ["text","!"] +],[ + "start" +],[ + "start", + ["comment.line.colons.dosbatch",":: FOR loop in bat is super strange!"] +],[ + "start", + ["keyword.control.repeat.dosbatch","FOR"], + ["text"," /f "], + ["punctuation.definition.string.begin.shell","\""], + ["string.quoted.double.dosbatch","tokens=*"], + ["punctuation.definition.string.end.shell","\""], + ["text"," "], + ["constant.numeric","%%G"], + ["text"," IN ('"], + ["keyword.command.dosbatch","dir"], + ["text"," /A:D /b') DO ("] +],[ + "start", + ["keyword.command.dosbatch","echo"], + ["text"," "], + ["constant.numeric","%var1%%%G"] +],[ + "start", + ["keyword.command.dosbatch","attrib"], + ["text"," -r -a -h -s "], + ["punctuation.definition.string.begin.shell","\""], + ["constant.numeric","%var1%%%G"], + ["punctuation.definition.string.end.shell","\""], + ["text"," /D /S"] +],[ + "start", + ["text",")"] +],[ + "start" +],[ + "start", + ["keyword.command.dosbatch","pause"] +],[ + "start" +],[ + "start", + ["doc.comment","REM"], + ["comment"," that's all"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_c9search.json b/lib/ace/mode/_test/tokens_c9search.json new file mode 100644 index 00000000..902d8dce --- /dev/null +++ b/lib/ace/mode/_test/tokens_c9search.json @@ -0,0 +1,131 @@ +[[ + ["start",{}], + ["text","Searching for '"], + ["text","var"], + ["text","' in"], + ["text"," /.c9/metadata/workspace/plugins "], + ["text","(regexp, case sensitive, whole word)"], + "Searching for \u0001var\u0001 in\u0001/.c9/metadata/workspace/plugins\u0001\u0001regexp, case sensitive, whole word\u0001" +],[ + ["start",{}] +],[ + ["start",{}], + ["string","configs/default.js"], + ["text",":"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric"," 1"], + ["c9searchresults.text",": "], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," fs = require(\"fs\");"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric","\t2"], + ["c9searchresults.text",": "], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," argv = require('optimist').argv;"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric","\t3"], + ["c9searchresults.text",": "], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," path = require(\"path\");"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric","\t5"], + ["c9searchresults.text",": "], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," clientExtensions = {};"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric","\t6"], + ["c9searchresults.text",": "], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," clientDirs = fs.readdirSync(__dirname + \"/../plugins-client\");"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric","\t7"], + ["c9searchresults.text",": "], + ["c9searchresults.text","for ("], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," i = 0; i < clientDirs.length; i++) {"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric","\t8"], + ["c9searchresults.text",": "], + ["c9searchresults.text"," "], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," dir = clientDirs[i];"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric","\t12"], + ["c9searchresults.text",": "], + ["c9searchresults.text"," "], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," name = dir.split(\".\")[1];"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric","\t16"], + ["c9searchresults.text",": "], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," projectDir = (argv.w && path.resolve(process.cwd(), argv.w)) || process.cwd();"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric","\t17"], + ["c9searchresults.text",": "], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," fsUrl = \"/workspace\";"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric","\t19"], + ["c9searchresults.text",": "], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," port = argv.p || process.env.PORT || 3131;"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric","\t20"], + ["c9searchresults.text",": "], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," host = argv.l || \"localhost\";"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric","\t22"], + ["c9searchresults.text",": "], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," config = {"] +],[ + ["start",{}] +],[ + ["start",{}], + ["string","configs/local.js"], + ["text",":"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric","\t2"], + ["c9searchresults.text",": "], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," config = require(\"./default\");"] +],[ + ["start",{}] +],[ + ["start",{}], + ["string","configs/packed.js"], + ["text",":"] +],[ + ["start",{}], + ["c9searchresults.constant.numeric","\t1"], + ["c9searchresults.text",": "], + ["c9searchresults.keyword","var"], + ["c9searchresults.text"," config = require(\"./default\");"] +],[ + ["start",{}] +],[ + ["start",{}] +],[ + ["start",{}], + ["text","Found "], + ["constant.numeric","15"], + ["text"," matches in "], + ["constant.numeric","3"], + ["text"," files"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_c_cpp.json b/lib/ace/mode/_test/tokens_c_cpp.json new file mode 100644 index 00000000..a8668b0b --- /dev/null +++ b/lib/ace/mode/_test/tokens_c_cpp.json @@ -0,0 +1,190 @@ +[[ + "start", + ["comment","// compound assignment operators"] +],[ + "start" +],[ + "start", + ["keyword","#include"], + ["constant.other"," "] +],[ + "start" +],[ + "directive", + ["keyword","#include"], + ["constant.other.multiline"," \\"] +],[ + "start", + ["constant.other"," "] +],[ + "start" +],[ + "directive", + ["keyword","#include"], + ["constant.other.multiline"," \\"] +],[ + "directive", + ["constant.other.multiline"," \\"] +],[ + "start", + ["constant.other"," "] +],[ + "start" +],[ + "directive", + ["keyword","#include"], + ["constant.other.multiline"," \\"] +],[ + "directive", + ["constant.other.multiline"," \\"] +],[ + "start", + ["constant.other"," \"iostream\""] +],[ + "start" +],[ + "start", + ["keyword","#include"], + ["constant.other"," "] +],[ + "start", + ["keyword","#include"], + ["constant.other"," \"boost/asio/io_service.hpp\""] +],[ + "start" +],[ + "directive", + ["keyword","#include"], + ["constant.other.multiline"," \\"] +],[ + "directive", + ["constant.other.multiline"," \\"] +],[ + "directive", + ["constant.other.multiline"," \"iostream\" \\"] +],[ + "directive", + ["constant.other.multiline"," \"string\" \\"] +],[ + "start", + ["constant.other"," "] +],[ + "start", + ["text"," "] +],[ + "start", + ["keyword.control","using"], + ["text"," "], + ["keyword.operator","namespace"], + ["text"," "], + ["identifier","std"], + ["punctuation.operator",";"] +],[ + "start" +],[ + "start", + ["storage.type","int"], + ["text"," "], + ["identifier","main"], + ["text"," "], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["storage.type","int"], + ["text"," "], + ["identifier","a"], + ["punctuation.operator",","], + ["text"," "], + ["identifier","b"], + ["keyword.operator","="], + ["constant.numeric","3"], + ["punctuation.operator",";"], + ["text"," "], + ["comment","/* foobar */"] +],[ + "start", + ["text"," "], + ["identifier","a"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","b"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["identifier","a"], + ["keyword.operator","+="], + ["constant.numeric","2"], + ["punctuation.operator",";"], + ["text"," "], + ["comment","// equivalent to a=a+2"] +],[ + "start", + ["text"," "], + ["identifier","cout"], + ["text"," "], + ["keyword.operator","<<"], + ["text"," "], + ["identifier","a"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword","#if"], + ["text"," "], + ["identifier","VERBOSE"], + ["text"," "], + ["keyword.operator",">="], + ["text"," "], + ["constant.numeric","2"] +],[ + "start", + ["text"," "], + ["identifier","prints"], + ["paren.lparen","("], + ["string","\"trace message\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword","#endif"] +],[ + "start", + ["text"," "], + ["keyword.control","return"], + ["text"," "], + ["constant.numeric","0"], + ["punctuation.operator",";"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["comment","/* Print an error message and get out */"] +],[ + "directive", + ["keyword","#define"], + ["constant.other.multiline"," ABORT \\"] +],[ + "directive", + ["constant.other.multiline"," do { \\"] +],[ + "directive", + ["constant.other.multiline"," print( \"Abort\\n\" ); \\"] +],[ + "directive", + ["constant.other.multiline"," exit(8); \\"] +],[ + "start", + ["constant.other","} while (0) "], + ["comment","/* Note: No semicolon */"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_cirru.json b/lib/ace/mode/_test/tokens_cirru.json new file mode 100644 index 00000000..de4852e6 --- /dev/null +++ b/lib/ace/mode/_test/tokens_cirru.json @@ -0,0 +1,267 @@ +[[ + "start", + ["comment.line.double-dash","-- https://github.com/Cirru/cirru-gopher/blob/master/code/scope.cr,"] +],[ + "start" +],[ + "line", + ["support.function","set"], + ["text"," "], + ["variable.parameter","a"], + ["text"," "], + ["storage.modifier","("], + ["support.function","int"], + ["text"," "], + ["constant.numeric","2"], + ["storage.modifier",")"] +],[ + "start" +],[ + "line", + ["support.function","print"], + ["text"," "], + ["storage.modifier","("], + ["support.function","self"], + ["storage.modifier",")"] +],[ + "start" +],[ + "line", + ["support.function","set"], + ["text"," "], + ["variable.parameter","c"], + ["text"," "], + ["storage.modifier","("], + ["support.function","child"], + ["storage.modifier",")"] +],[ + "start" +],[ + "line", + ["support.function","under"], + ["text"," "], + ["variable.parameter","c"] +],[ + "line", + ["markup.raw"," "], + ["support.function","under"], + ["text"," "], + ["variable.parameter","parent"] +],[ + "line", + ["markup.raw"," "], + ["support.function","print"], + ["text"," "], + ["variable.parameter","a"] +],[ + "start" +],[ + "line", + ["support.function","print"], + ["text"," "], + ["storage.modifier","$"], + ["text"," "], + ["support.function","get"], + ["text"," "], + ["variable.parameter","c"], + ["text"," "], + ["variable.parameter","a"] +],[ + "start" +],[ + "line", + ["support.function","set"], + ["text"," "], + ["variable.parameter","c"], + ["text"," "], + ["variable.parameter","x"], + ["text"," "], + ["storage.modifier","("], + ["support.function","int"], + ["text"," "], + ["constant.numeric","3"], + ["storage.modifier",")"] +],[ + "line", + ["support.function","print"], + ["text"," "], + ["storage.modifier","$"], + ["text"," "], + ["support.function","get"], + ["text"," "], + ["variable.parameter","c"], + ["text"," "], + ["variable.parameter","x"] +],[ + "start" +],[ + "line", + ["support.function","set"], + ["text"," "], + ["variable.parameter","just-print"], + ["text"," "], + ["storage.modifier","$"], + ["text"," "], + ["support.function","code"] +],[ + "line", + ["markup.raw"," "], + ["support.function","print"], + ["text"," "], + ["variable.parameter","a"] +],[ + "start" +],[ + "line", + ["support.function","print"], + ["text"," "], + ["variable.parameter","just-print"] +],[ + "start" +],[ + "line", + ["support.function","eval"], + ["text"," "], + ["storage.modifier","("], + ["support.function","self"], + ["storage.modifier",")"], + ["text"," "], + ["variable.parameter","just-print"] +],[ + "line", + ["support.function","eval"], + ["text"," "], + ["variable.parameter","just-print"] +],[ + "start" +],[ + "line", + ["support.function","print"], + ["text"," "], + ["storage.modifier","("], + ["support.function","string"], + ["text"," "], + ["string.quoted.double","\"string with space\""], + ["storage.modifier",")"] +],[ + "line", + ["support.function","print"], + ["text"," "], + ["storage.modifier","("], + ["support.function","string"], + ["text"," "], + ["string.quoted.double","\"escapes "], + ["constant.character.escape","\\n"], + ["string.quoted.double"," "], + ["constant.character.escape","\\\"\\\\"], + ["string.quoted.double","\""], + ["storage.modifier",")"] +],[ + "start" +],[ + "start", + ["support.function","brackets"], + ["text"," "], + ["storage.modifier","((((()))))"] +],[ + "start" +],[ + "line", + ["string.quoted.double","\"eval\""], + ["text"," "], + ["storage.modifier","$"], + ["text"," "], + ["support.function","string"], + ["text"," "], + ["string.quoted.double","\"eval\""] +],[ + "start" +],[ + "line", + ["support.function","print"], + ["text"," "], + ["storage.modifier","("], + ["support.function","add"], + ["text"," "], + ["storage.modifier","$"], + ["text"," "], + ["storage.modifier","("], + ["support.function","int"], + ["text"," "], + ["constant.numeric","1"], + ["storage.modifier",")"], + ["text"," "], + ["storage.modifier","("], + ["support.function","int"], + ["text"," "], + ["constant.numeric","2"], + ["storage.modifier","))"] +],[ + "start" +],[ + "start", + ["support.function","print"], + ["text"," "], + ["storage.modifier","$"], + ["text"," "], + ["support.function","unwrap"], + ["text"," "], + ["storage.modifier","$"] +],[ + "line", + ["text"," "], + ["support.function","map"], + ["text"," "], + ["storage.modifier","("], + ["support.function","a"], + ["text"," "], + ["storage.modifier","$"], + ["text"," "], + ["support.function","int"], + ["text"," "], + ["constant.numeric","1"], + ["storage.modifier",")"], + ["text"," "], + ["storage.modifier","("], + ["support.function","b"], + ["text"," "], + ["storage.modifier","$"], + ["text"," "], + ["support.function","int"], + ["text"," "], + ["constant.numeric","2"], + ["storage.modifier",")"] +],[ + "start" +],[ + "line", + ["support.function","print"], + ["text"," "], + ["variable.parameter","a"] +],[ + "line", + ["markup.raw"," "], + ["support.function","int"], + ["text"," "], + ["constant.numeric","1"] +],[ + "line", + ["markup.raw"," "], + ["storage.modifier",","], + ["text"," "], + ["variable.parameter","b"], + ["text"," "], + ["variable.parameter","c"] +],[ + "line", + ["markup.raw"," "], + ["support.function","int"], + ["text"," "], + ["constant.numeric","2"] +],[ + "line", + ["markup.raw"," "], + ["storage.modifier",","], + ["text"," "], + ["variable.parameter","d"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_clojure.json b/lib/ace/mode/_test/tokens_clojure.json new file mode 100644 index 00000000..824cba59 --- /dev/null +++ b/lib/ace/mode/_test/tokens_clojure.json @@ -0,0 +1,162 @@ +[[ + "start", + ["keyword","("], + ["support.function","defn"], + ["text"," "], + ["identifier","parting"] +],[ + "start", + ["text"," "], + ["string","\"returns a String parting in a given language\""] +],[ + "start", + ["text"," "], + ["keyword","([]"], + ["text"," "], + ["keyword","("], + ["identifier","parting"], + ["text"," "], + ["string","\"World\""], + ["keyword","))"] +],[ + "start", + ["text"," "], + ["keyword","(["], + ["support.function","name"], + ["keyword","]"], + ["text"," "], + ["keyword","("], + ["identifier","parting"], + ["text"," "], + ["support.function","name"], + ["text"," "], + ["string","\"en\""], + ["keyword","))"] +],[ + "start", + ["text"," "], + ["keyword","(["], + ["support.function","name"], + ["text"," "], + ["identifier","language"], + ["keyword","]"] +],[ + "start", + ["text"," "], + ["comment","; condp is similar to a case statement in other languages."] +],[ + "start", + ["text"," "], + ["comment","; It is described in more detail later."] +],[ + "start", + ["text"," "], + ["comment","; It is used here to take different actions based on whether the"] +],[ + "start", + ["text"," "], + ["comment","; parameter \"language\" is set to \"en\", \"es\" or something else."] +],[ + "start", + ["text"," "], + ["keyword","("], + ["support.function","condp"], + ["text"," "], + ["constant.language","="], + ["text"," "], + ["identifier","language"] +],[ + "start", + ["text"," "], + ["string","\"en\""], + ["text"," "], + ["keyword","("], + ["support.function","str"], + ["text"," "], + ["string","\"Goodbye, \""], + ["text"," "], + ["support.function","name"], + ["keyword",")"] +],[ + "start", + ["text"," "], + ["string","\"es\""], + ["text"," "], + ["keyword","("], + ["support.function","str"], + ["text"," "], + ["string","\"Adios, \""], + ["text"," "], + ["support.function","name"], + ["keyword",")"] +],[ + "start", + ["text"," "], + ["keyword","(throw"], + ["text"," "], + ["keyword","("], + ["identifier","IllegalArgumentException"], + ["text","."] +],[ + "start", + ["text"," "], + ["keyword","("], + ["support.function","str"], + ["text"," "], + ["string","\"unsupported language \""], + ["text"," "], + ["identifier","language"], + ["keyword","))))))"] +],[ + "start" +],[ + "start", + ["keyword","("], + ["support.function","println"], + ["text"," "], + ["keyword","("], + ["identifier","parting"], + ["keyword","))"], + ["text"," "], + ["comment","; -> Goodbye, World"] +],[ + "start", + ["keyword","("], + ["support.function","println"], + ["text"," "], + ["keyword","("], + ["identifier","parting"], + ["text"," "], + ["string","\"Mark\""], + ["keyword","))"], + ["text"," "], + ["comment","; -> Goodbye, Mark"] +],[ + "start", + ["keyword","("], + ["support.function","println"], + ["text"," "], + ["keyword","("], + ["identifier","parting"], + ["text"," "], + ["string","\"Mark\""], + ["text"," "], + ["string","\"es\""], + ["keyword","))"], + ["text"," "], + ["comment","; -> Adios, Mark"] +],[ + "start", + ["keyword","("], + ["support.function","println"], + ["text"," "], + ["keyword","("], + ["identifier","parting"], + ["text"," "], + ["string","\"Mark\""], + ["text",", "], + ["string","\"xy\""], + ["keyword","))"], + ["text"," "], + ["comment","; -> java.lang.IllegalArgumentException: unsupported language xy"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_cobol.json b/lib/ace/mode/_test/tokens_cobol.json new file mode 100644 index 00000000..9909eadd --- /dev/null +++ b/lib/ace/mode/_test/tokens_cobol.json @@ -0,0 +1,4 @@ +[[ + "start", + ["identifier","TODO"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_coffee.json b/lib/ace/mode/_test/tokens_coffee.json new file mode 100644 index 00000000..b0703b37 --- /dev/null +++ b/lib/ace/mode/_test/tokens_coffee.json @@ -0,0 +1,545 @@ +[[ + "start", + ["comment","#test: tokenize keyword"] +],[ + "start", + ["text"," "], + ["keyword","for"], + ["text"," "], + ["paren.lparen","("], + ["identifier","i"], + ["text"," "], + ["constant.numeric","1"], + ["punctuation.operator","."], + ["constant.numeric",".2"], + ["paren.rparen",")"] +],[ + "start", + ["comment","#test: tokenize regexp"] +],[ + "start", + ["string.regex","/\"[a]/"] +],[ + "start", + ["comment","#test: tokenize functions"] +],[ + "start", + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","{args}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","{a1, a2}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","{@a1, a2}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator",":"], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","{args}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","{args}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","{0abc}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["identifier","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["paren","{"], + ["keyword.operator","/"], + ["identifier","abc"], + ["paren","}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","=>"] +],[ + "start", + ["text"," "], + ["identifier","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["paren","{"], + ["identifier","abc"], + ["keyword.operator","/"], + ["paren","}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","{#abc}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","{abc#}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["identifier","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["paren","{"], + ["paren.rparen",")"], + ["identifier","abc"], + ["paren","}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["identifier","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["paren","{"], + ["identifier","abc"], + ["paren.rparen",")"], + ["paren","}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","{a{bc}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","{}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","{ }"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator",":"], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","{}"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","args"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","arg1, arg2"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","arg1 = 1, arg2 = 'name'"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","@arg1 = /abc/, arg2 = 'name'"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["comment","#test: tokenize function: invalid case:"] +],[ + "start", + ["text"," "], + ["identifier","foo"], + ["keyword.operator","="], + ["paren.lparen","("], + ["keyword.operator","/"], + ["identifier","args"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter"," "], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator",":"], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter"," "], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["variable.language","window"], + ["punctuation.operator","."], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","args"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["entity.name.function","foo"], + ["text"," "], + ["keyword.operator",":"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["comment","#test: tokenize callback function"] +],[ + "start", + ["text"," "], + ["identifier","foo"], + ["text"," "], + ["identifier","bar"], + ["keyword.operator",":"], + ["text"," "], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","args"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["text"," "], + ["identifier","foo"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["text"," "], + ["constant.numeric","2"], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter","x"], + ["paren.rparen",")"], + ["text"," "], + ["storage.type","->"] +],[ + "start", + ["comment","#test: tokenize class"] +],[ + "start", + ["keyword","class"], + ["text"," "], + ["language.support.class","Foo"] +],[ + "start", + ["keyword","class"], + ["text"," "], + ["language.support.class","Foo"], + ["text"," "], + ["keyword","extends"], + ["text"," "], + ["language.support.class","Bar"] +],[ + "start", + ["comment","#test: tokenize illegal name property"] +],[ + "start", + ["identifier","foo"], + ["punctuation.operator","."], + ["identifier","static"], + ["punctuation.operator","."], + ["identifier","function"] +],[ + "start", + ["comment","#!test tokenize string with interpolation"] +],[ + "start", + ["identifier","a"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string.start","\""], + ["paren.string","#{"], + ["text"," "], + ["constant.numeric","22"], + ["text"," "], + ["keyword.operator","/"], + ["text"," "], + ["constant.numeric","7"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["paren","{"], + ["identifier","x"], + ["keyword.operator",":"], + ["text"," "], + ["string.start","\""], + ["paren.string","#{"], + ["identifier","a"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["identifier","b"], + ["paren.string","}"], + ["string.end","\""], + ["paren","}"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","2"], + ["paren.string","}"], + ["string.end","\""] +],[ + "start", + ["string.start","\""], + ["string"," "], + ["paren.string","#{"], + ["text"," "], + ["string.start","\""], + ["string.end","\""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["paren","{}"], + ["text"," "], + ["paren.string","}"], + ["string"," )"], + ["string.end","\""], + ["text"," "] +],[ + "qqdoc", + ["string","\"\"\"heredoc"] +],[ + "start", + ["string"," \"\"\""] +],[ + "start", + ["keyword","do"], + ["text"," "], + ["storage.type","->"] +],[ + "comment", + ["text"," "], + ["comment","###"] +],[ + "comment", + ["comment"," herecomment"] +],[ + "start", + ["comment"," ###"] +],[ + "heregex", + ["text"," "], + ["identifier","re"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string.regex","/regex/imgy"], + ["punctuation.operator","."], + ["identifier","test"], + ["text"," "], + ["string.regex","///"] +],[ + "heregex", + ["comment.regex"," "], + ["string.regex","heregex"], + ["comment.regex"," # comment"] +],[ + "start", + ["string.regex"," ///imgy"] +],[ + "js", + ["text"," "], + ["keyword","this"], + ["text"," "], + ["keyword","isnt"], + ["keyword.operator",":"], + ["text"," "], + ["string","`just "] +],[ + "start", + ["string"," JavaScript`"] +],[ + "start", + ["text"," "], + ["constant.language","undefined"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_coldfusion.json b/lib/ace/mode/_test/tokens_coldfusion.json new file mode 100644 index 00000000..804e647d --- /dev/null +++ b/lib/ace/mode/_test/tokens_coldfusion.json @@ -0,0 +1,26 @@ +[[ + "start", + ["comment.xml",""] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","cfset"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","welcome"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"Hello World!\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","cfoutput"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","#welcome#"], + ["meta.tag.punctuation.end-tag-open.xml",""] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_csharp.json b/lib/ace/mode/_test/tokens_csharp.json new file mode 100644 index 00000000..dcc6d0e9 --- /dev/null +++ b/lib/ace/mode/_test/tokens_csharp.json @@ -0,0 +1,31 @@ +[[ + "start", + ["keyword","public"], + ["text"," "], + ["keyword","void"], + ["text"," "], + ["identifier","HelloWorld"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["comment","//Say Hello!"] +],[ + "start", + ["text"," "], + ["identifier","Console"], + ["punctuation.operator","."], + ["identifier","WriteLine"], + ["paren.lparen","("], + ["string.start","\""], + ["string","Hello World"], + ["string.end","\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["paren.rparen","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_css.json b/lib/ace/mode/_test/tokens_css.json new file mode 100644 index 00000000..e1a7ba05 --- /dev/null +++ b/lib/ace/mode/_test/tokens_css.json @@ -0,0 +1,148 @@ +[[ + "ruleset", + ["variable",".text-layer"], + ["text"," "], + ["paren.lparen","{"] +],[ + "ruleset", + ["text"," "], + ["support.type","font-family"], + ["text",": Monaco, "], + ["string","\"Courier New\""], + ["text",", "], + ["support.constant.fonts","monospace"], + ["text",";"] +],[ + "ruleset", + ["text"," "], + ["support.type","font-size"], + ["text",": "], + ["constant.numeric","12"], + ["keyword","pX"], + ["text",";"] +],[ + "ruleset", + ["text"," "], + ["support.type","cursor"], + ["text",": "], + ["support.constant","text"], + ["text",";"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "ruleset", + ["variable",".blinker"], + ["text"," "], + ["paren.lparen","{"] +],[ + "ruleset", + ["text"," "], + ["support.type","animation-duration"], + ["text",": "], + ["constant.numeric","1"], + ["keyword","s"], + ["text",";"] +],[ + "ruleset", + ["text"," "], + ["support.type","animation-name"], + ["text",": blink;"] +],[ + "ruleset", + ["text"," "], + ["support.type","animation-iteration-count"], + ["text",": infinite;"] +],[ + "ruleset", + ["text"," "], + ["support.type","animation-direction"], + ["text",": alternate;"] +],[ + "ruleset", + ["text"," "], + ["support.type","animation-timing-function"], + ["text",": "], + ["support.constant","linear"], + ["text",";"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "media", + ["string","@keyframes blink {"] +],[ + ["ruleset","media"], + ["text"," "], + ["constant","0"], + ["text","% "], + ["paren.lparen","{"] +],[ + ["ruleset","media"], + ["text"," "], + ["support.type","opacity"], + ["text",": "], + ["constant.numeric","0"], + ["text",";"] +],[ + "media", + ["text"," "], + ["paren.rparen","}"] +],[ + ["ruleset","media"], + ["text"," "], + ["constant","40"], + ["text","% "], + ["paren.lparen","{"] +],[ + ["ruleset","media"], + ["text"," "], + ["support.type","opacity"], + ["text",": "], + ["constant.numeric","0"], + ["text",";"] +],[ + "media", + ["text"," "], + ["paren.rparen","}"] +],[ + ["ruleset","media"], + ["text"," "], + ["constant","40"], + ["variable",".5"], + ["text","% "], + ["paren.lparen","{"] +],[ + ["ruleset","media"], + ["text"," "], + ["support.type","opacity"], + ["text",": "], + ["constant.numeric","1"] +],[ + "media", + ["text"," "], + ["paren.rparen","}"] +],[ + ["ruleset","media"], + ["text"," "], + ["constant","100"], + ["text","% "], + ["paren.lparen","{"] +],[ + ["ruleset","media"], + ["text"," "], + ["support.type","opacity"], + ["text",": "], + ["constant.numeric","1"] +],[ + "media", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["string","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_curly.json b/lib/ace/mode/_test/tokens_curly.json new file mode 100644 index 00000000..d87a627a --- /dev/null +++ b/lib/ace/mode/_test/tokens_curly.json @@ -0,0 +1,56 @@ +[[ + "start", + ["text.xml","tokenize Curly template"], + ["variable","{{"], + ["text","test"], + ["variable","}}"] +],[ + "start", + ["text.xml","tokenize embedded script"] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.script.tag-name.xml","script"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","a"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","'a'"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["storage.type","var"], + ["meta.tag.punctuation.end-tag-open.xml",""], + ["text.xml","'123'"] +],[ + "start", + ["text.xml","tokenize multiline attribute value with double quotes"] +],[ + ["string.attribute-value.xml0","tag_stuff"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.anchor.tag-name.xml","a"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"abc{{xyz}}"] +],[ + "start", + ["string.attribute-value.xml","def\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml","tokenize multiline attribute value with single quotes"] +],[ + ["string.attribute-value.xml","tag_stuff"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.anchor.tag-name.xml","a"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","'abc"] +],[ + "start", + ["string.attribute-value.xml","def\\\"'"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_d.json b/lib/ace/mode/_test/tokens_d.json new file mode 100644 index 00000000..85831cc3 --- /dev/null +++ b/lib/ace/mode/_test/tokens_d.json @@ -0,0 +1,111 @@ +[[ + "start", + ["comment.shebang","#!/usr/bin/env rdmd"] +],[ + "start", + ["comment","// Computes average line length for standard input."] +],[ + "start", + ["keyword","import"], + ["text"," "], + ["variable.module","std.stdio"], + ["punctuation.operator",";"] +],[ + "start" +],[ + "start", + ["keyword.type","void"], + ["text"," "], + ["identifier","main"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword.type","ulong"], + ["text"," "], + ["identifier","lines"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","0"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.type","double"], + ["text"," "], + ["identifier","sumLength"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","0"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.control","foreach"], + ["text"," "], + ["paren.lparen","("], + ["identifier","line"], + ["punctuation.operator",";"], + ["text"," "], + ["identifier","stdin"], + ["punctuation.operator","."], + ["identifier","byLine"], + ["paren.lparen","("], + ["paren.rparen","))"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword.operator","++"], + ["identifier","lines"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["identifier","sumLength"], + ["text"," "], + ["keyword.operator","+="], + ["text"," "], + ["identifier","line"], + ["punctuation.operator","."], + ["identifier","length"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["identifier","writeln"], + ["paren.lparen","("], + ["string","\"Average line length: \""], + ["punctuation.operator",","] +],[ + "start", + ["text"," "], + ["identifier","lines"], + ["text"," "], + ["keyword.operator","?"], + ["text"," "], + ["identifier","sumLength"], + ["text"," "], + ["keyword.operator","/"], + ["text"," "], + ["identifier","lines"], + ["text"," "], + ["punctuation.operator",":"], + ["text"," "], + ["constant.numeric","0"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["paren.rparen","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_dart.json b/lib/ace/mode/_test/tokens_dart.json new file mode 100644 index 00000000..37cdc323 --- /dev/null +++ b/lib/ace/mode/_test/tokens_dart.json @@ -0,0 +1,368 @@ +[[ + "start", + ["identifier","main"], + ["text","() {"] +],[ + "start", + ["text"," "], + ["identifier","print"], + ["text","("], + ["string","'Hello World!'"], + ["text",");"] +],[ + "start", + ["text","}"] +],[ + "start" +],[ + "start" +],[ + "start", + ["storage.type.primitive.dart","int"], + ["text"," "], + ["identifier","fib"], + ["text","("], + ["storage.type.primitive.dart","int"], + ["text"," "], + ["identifier","n"], + ["text",") "], + ["keyword.operator.assignment.dart","="], + ["keyword.operator.comparison.dart",">"], + ["text"," ("], + ["identifier","n"], + ["text"," "], + ["keyword.operator.comparison.dart",">"], + ["text"," "], + ["constant.numeric","1"], + ["text",") "], + ["keyword.control.ternary.dart","?"], + ["text"," ("], + ["identifier","fib"], + ["text","("], + ["identifier","n"], + ["text"," "], + ["keyword.operator.arithmetic.dart","-"], + ["text"," "], + ["constant.numeric","1"], + ["text",") "], + ["keyword.operator.arithmetic.dart","+"], + ["text"," "], + ["identifier","fib"], + ["text","("], + ["identifier","n"], + ["text"," "], + ["keyword.operator.arithmetic.dart","-"], + ["text"," "], + ["constant.numeric","2"], + ["text",")) "], + ["keyword.control.ternary.dart",":"], + ["text"," "], + ["identifier","n"], + ["text",";"] +],[ + "start", + ["identifier","main"], + ["text","() {"] +],[ + "start", + ["text"," "], + ["identifier","print"], + ["text","("], + ["string","'fib(20) = ${fib(20)}'"], + ["text",");"] +],[ + "start", + ["text","}"] +],[ + "comment", + ["comment","/*asd"] +],[ + "comment", + ["comment","asdad"] +],[ + "start", + ["comment","*/"] +],[ + "start", + ["constant.numeric","0.67"] +],[ + "start", + ["constant.numeric","77"] +],[ + "start", + ["text","."], + ["constant.numeric","86"] +],[ + "start" +],[ + "start", + ["keyword.other.import.dart","import"], + ["text","("], + ["string","\"http://dartwatch.com/myOtherLibrary.dart\""], + ["text",");"] +],[ + "start", + ["keyword.other.import.dart","import"], + ["text","("], + ["string","\"myOtherLibrary.dart\""], + ["text",", "], + ["keyword.other.import.dart","prefix"], + ["text",":"], + ["string","\"lib1\""], + ["text",");"] +],[ + "start" +],[ + "qqdoc", + ["string","\"\"\"asdasdads"] +],[ + "qqdoc", + ["string","asdadsadsasd"] +],[ + "start", + ["string","asdasdasdad\"\"\""] +],[ + "start", + ["text"," "] +],[ + "start", + ["string","'23424'"] +],[ + "start" +],[ + "start", + ["constant.numeric","0x234"] +],[ + "start" +],[ + "start", + ["identifier","foo"], + ["text"," "], + ["keyword.operator.dart","is"], + ["text"," "], + ["identifier","bar"] +],[ + "start" +],[ + "start", + ["storage.type.primitive.dart","int"], + ["text"," "], + ["identifier","x"], + ["text"," "], + ["keyword.operator.assignment.dart","="], + ["text"," "], + ["constant.numeric","4"], + ["text"," "], + ["keyword.operator.bitwise.dart","<<"], + ["text"," "], + ["constant.numeric","10"], + ["text"," "] +],[ + "start", + ["comment","// Create a class for Point."] +],[ + "start", + ["keyword.declaration.dart","class"], + ["text"," "], + ["identifier","Point"], + ["text"," {"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["comment","// Final variables cannot be changed once they are assigned."] +],[ + "start", + ["text"," "], + ["comment","// Create two instance variables."] +],[ + "start", + ["text"," "], + ["storage.modifier.dart","final"], + ["text"," "], + ["storage.type.primitive.dart","num"], + ["text"," "], + ["identifier","x"], + ["text",", "], + ["identifier","y"], + ["text",";"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["comment","// A constructor, with syntactic sugar for setting instance variables."] +],[ + "start", + ["text"," "], + ["identifier","Point"], + ["text","("], + ["variable.language.dart","this"], + ["text","."], + ["identifier","x"], + ["text",", "], + ["variable.language.dart","this"], + ["text","."], + ["identifier","y"], + ["text",");"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["comment","// A named constructor with an initializer list."] +],[ + "start", + ["text"," "], + ["identifier","Point"], + ["text","."], + ["identifier","origin"], + ["text","() "], + ["keyword.control.ternary.dart",":"], + ["text"," "], + ["identifier","x"], + ["text"," "], + ["keyword.operator.assignment.dart","="], + ["text"," "], + ["constant.numeric","0"], + ["text",", "], + ["identifier","y"], + ["text"," "], + ["keyword.operator.assignment.dart","="], + ["text"," "], + ["constant.numeric","0"], + ["text",";"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["comment","// A method."] +],[ + "start", + ["text"," "], + ["storage.type.primitive.dart","num"], + ["text"," "], + ["identifier","distanceTo"], + ["text","("], + ["identifier","Point"], + ["text"," "], + ["identifier","other"], + ["text",") {"] +],[ + "start", + ["text"," "], + ["storage.type.primitive.dart","var"], + ["text"," "], + ["identifier","dx"], + ["text"," "], + ["keyword.operator.assignment.dart","="], + ["text"," "], + ["identifier","x"], + ["text"," "], + ["keyword.operator.arithmetic.dart","-"], + ["text"," "], + ["identifier","other"], + ["text","."], + ["identifier","x"], + ["text",";"] +],[ + "start", + ["text"," "], + ["storage.type.primitive.dart","var"], + ["text"," "], + ["identifier","dy"], + ["text"," "], + ["keyword.operator.assignment.dart","="], + ["text"," "], + ["identifier","y"], + ["text"," "], + ["keyword.operator.arithmetic.dart","-"], + ["text"," "], + ["identifier","other"], + ["text","."], + ["identifier","y"], + ["text",";"] +],[ + "start", + ["text"," "], + ["keyword.control.dart","return"], + ["text"," "], + ["identifier","sqrt"], + ["text","("], + ["identifier","dx"], + ["text"," "], + ["keyword.operator.arithmetic.dart","*"], + ["text"," "], + ["identifier","dx"], + ["text"," "], + ["keyword.operator.arithmetic.dart","+"], + ["text"," "], + ["identifier","dy"], + ["text"," "], + ["keyword.operator.arithmetic.dart","*"], + ["text"," "], + ["identifier","dy"], + ["text",");"] +],[ + "start", + ["text"," }"] +],[ + "start", + ["text","}"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["comment","// Check for null."] +],[ + "start", + ["storage.type.primitive.dart","var"], + ["text"," "], + ["identifier","unicorn"], + ["text",";"] +],[ + "start", + ["keyword.control.dart","assert"], + ["text","("], + ["identifier","unicorn"], + ["text"," "], + ["keyword.operator.comparison.dart","=="], + ["text"," "], + ["constant.language.dart","null"], + ["text",");"] +],[ + "start" +],[ + "start", + ["comment","// Check for NaN."] +],[ + "start", + ["storage.type.primitive.dart","var"], + ["text"," "], + ["identifier","iMeantToDoThis"], + ["text"," "], + ["keyword.operator.assignment.dart","="], + ["text"," "], + ["constant.numeric","0"], + ["keyword.operator.arithmetic.dart","/"], + ["constant.numeric","0"], + ["text",";"] +],[ + "start", + ["keyword.control.dart","assert"], + ["text","("], + ["identifier","iMeantToDoThis"], + ["text","."], + ["identifier","isNaN"], + ["text","());"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_diff.json b/lib/ace/mode/_test/tokens_diff.json new file mode 100644 index 00000000..6c36f5fa --- /dev/null +++ b/lib/ace/mode/_test/tokens_diff.json @@ -0,0 +1,262 @@ +[[ + "start", + ["variable","diff"], + ["variable"," --git"], + ["keyword"," a/lib/ace/edit_session.js"], + ["variable"," b/lib/ace/edit_session.js"] +],[ + "start", + ["variable","index 23fc3fc..ed3b273 100644"] +],[ + "start", + ["constant.numeric","---"], + ["meta.tag"," a/lib/ace/edit_session.js"] +],[ + "start", + ["constant.numeric","+++"], + ["meta.tag"," b/lib/ace/edit_session.js"] +],[ + "start", + ["constant","@@"], + ["constant.numeric"," -51,6 +51,7 "], + ["constant","@@"], + ["comment.doc.tag"," var TextMode = require(\"./mode/text\").Mode;"] +],[ + "start", + ["invisible"," var Range = require(\"./range\").Range;"] +],[ + "start", + ["invisible"," var Document = require(\"./document\").Document;"] +],[ + "start", + ["invisible"," var BackgroundTokenizer = require(\"./background_tokenizer\").BackgroundTokenizer;"] +],[ + "start", + ["support.constant","+"], + ["text","var SearchHighlight = require(\"./search_highlight\").SearchHighlight;"] +],[ + "start", + ["text"," "] +],[ + "start", + ["invisible"," /**"] +],[ + "start", + ["invisible"," * class EditSession"] +],[ + "start", + ["constant","@@"], + ["constant.numeric"," -307,6 +308,13 "], + ["constant","@@"], + ["comment.doc.tag"," var EditSession = function(text, mode) {"] +],[ + "start", + ["invisible"," return token;"] +],[ + "start", + ["invisible"," };"] +],[ + "start", + ["text"," "] +],[ + "start", + ["support.constant","+"], + ["text"," this.highlight = function(re) {"] +],[ + "start", + ["support.constant","+"], + ["text"," if (!this.$searchHighlight) {"] +],[ + "start", + ["support.constant","+"], + ["text"," var highlight = new SearchHighlight(null, \"ace_selected-word\", \"text\");"] +],[ + "start", + ["support.constant","+"], + ["text"," this.$searchHighlight = this.addDynamicMarker(highlight);"] +],[ + "start", + ["support.constant","+"], + ["text"," }"] +],[ + "start", + ["support.constant","+"], + ["text"," this.$searchHighlight.setRegexp(re);"] +],[ + "start", + ["support.constant","+"], + ["text"," }"] +],[ + "start", + ["invisible"," /**"] +],[ + "start", + ["invisible"," * EditSession.setUndoManager(undoManager)"] +],[ + "start", + ["invisible"," * - undoManager (UndoManager): The new undo manager"] +],[ + "start", + ["constant","@@"], + ["constant.numeric"," -556,7 +564,8 "], + ["constant","@@"], + ["comment.doc.tag"," var EditSession = function(text, mode) {"] +],[ + "start", + ["invisible"," type : type || \"line\","] +],[ + "start", + ["invisible"," renderer: typeof type == \"function\" ? type : null,"] +],[ + "start", + ["invisible"," clazz : clazz,"] +],[ + "start", + ["support.function","-"], + ["string"," inFront: !!inFront"] +],[ + "start", + ["support.constant","+"], + ["text"," inFront: !!inFront,"] +],[ + "start", + ["support.constant","+"], + ["text"," id: id"] +],[ + "start", + ["invisible"," }"] +],[ + "start", + ["text"," "] +],[ + "start", + ["invisible"," if (inFront) {"] +],[ + "start", + ["variable","diff"], + ["variable"," --git"], + ["keyword"," a/lib/ace/editor.js"], + ["variable"," b/lib/ace/editor.js"] +],[ + "start", + ["variable","index 834e603..b27ec73 100644"] +],[ + "start", + ["constant.numeric","---"], + ["meta.tag"," a/lib/ace/editor.js"] +],[ + "start", + ["constant.numeric","+++"], + ["meta.tag"," b/lib/ace/editor.js"] +],[ + "start", + ["constant","@@"], + ["constant.numeric"," -494,7 +494,7 "], + ["constant","@@"], + ["comment.doc.tag"," var Editor = function(renderer, session) {"] +],[ + "start", + ["invisible"," * Emitted when a selection has changed."] +],[ + "start", + ["invisible"," **/"] +],[ + "start", + ["invisible"," this.onSelectionChange = function(e) {"] +],[ + "start", + ["support.function","-"], + ["string"," var session = this.getSession();"] +],[ + "start", + ["support.constant","+"], + ["text"," var session = this.session;"] +],[ + "start", + ["text"," "] +],[ + "start", + ["invisible"," if (session.$selectionMarker) {"] +],[ + "start", + ["invisible"," session.removeMarker(session.$selectionMarker);"] +],[ + "start", + ["constant","@@"], + ["constant.numeric"," -509,12 +509,40 "], + ["constant","@@"], + ["comment.doc.tag"," var Editor = function(renderer, session) {"] +],[ + "start", + ["invisible"," this.$updateHighlightActiveLine();"] +],[ + "start", + ["invisible"," }"] +],[ + "start", + ["text"," "] +],[ + "start", + ["support.function","-"], + ["string"," var self = this;"] +],[ + "start", + ["support.function","-"], + ["string"," if (this.$highlightSelectedWord && !this.$wordHighlightTimer)"] +],[ + "start", + ["support.function","-"], + ["string"," this.$wordHighlightTimer = setTimeout(function() {"] +],[ + "start", + ["support.function","-"], + ["string"," self.session.$mode.highlightSelection(self);"] +],[ + "start", + ["support.function","-"], + ["string"," self.$wordHighlightTimer = null;"] +],[ + "start", + ["support.function","-"], + ["string"," }, 30, this);"] +],[ + "start", + ["support.constant","+"], + ["text"," var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp()"] +],[ + "start", + ["invisible"," };"] +],[ + "start", + ["variable","diff"], + ["variable"," --git"], + ["keyword"," a/lib/ace/search_highlight.js"], + ["variable"," b/lib/ace/search_highlight.js"] +],[ + "start", + ["invisible","new file mode 100644"] +],[ + "start", + ["variable","index 0000000..b2df779"] +],[ + "start", + ["constant.numeric","---"], + ["meta.tag"," /dev/null"] +],[ + "start", + ["constant.numeric","+++"], + ["meta.tag"," b/lib/ace/search_highlight.js"] +],[ + "start", + ["constant","@@"], + ["constant.numeric"," -0,0 +1,3 "], + ["constant","@@"] +],[ + "start", + ["support.constant","+"], + ["text","new"] +],[ + "start", + ["support.constant","+"], + ["text","empty file"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_dot.json b/lib/ace/mode/_test/tokens_dot.json new file mode 100644 index 00000000..fec8b969 --- /dev/null +++ b/lib/ace/mode/_test/tokens_dot.json @@ -0,0 +1,2254 @@ +[[ + "start", + ["comment","// Original source: http://www.graphviz.org/content/lion_share"] +],[ + "start", + ["comment","##\"A few people in the field of genetics are using dot to draw \"marriage node diagram\" pedigree drawings. Here is one I have done of a test pedigree from the FTREE pedigree drawing package (Lion Share was a racehorse).\" Contributed by David Duffy."] +],[ + "start" +],[ + "start", + ["comment","##Command to get the layout: \"dot -Tpng thisfile > thisfile.png\""] +],[ + "start" +],[ + "start", + ["keyword","digraph"], + ["text"," Ped_Lion_Share "], + ["paren.lparen","{"] +],[ + "start", + ["comment","# page = \"8.2677165,11.692913\" ;"] +],[ + "start", + ["variable","ratio"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string","\"auto\""], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["text","mincross "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","2.0"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["variable","label"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string","\"Pedigree Lion_Share\""], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start" +],[ + "start", + ["string","\"001\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","box "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"002\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","box "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"003\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"004\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","box "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"005\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","box "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"006\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"007\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"009\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"014\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"015\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"016\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"ZZ01\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"ZZ02\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"017\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"012\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"008\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","box "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"011\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","box "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"013\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","box "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"010\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","box "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"023\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"020\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"021\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"018\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"025\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"019\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","box "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"022\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","box "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"024\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","box "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"027\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","circle "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"026\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","box "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","white "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"028\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","box "], + ["punctuation.operator",","], + ["text"," "], + ["variable","regular"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","fillcolor"], + ["keyword.operator","="], + ["text","grey "], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0001\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"001\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0001\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"007\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0001\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0001\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"017\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0002\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"001\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0002\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"ZZ02\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0002\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0002\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"012\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0003\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"002\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0003\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"003\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0003\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0003\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"008\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0004\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"002\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0004\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"006\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0004\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0004\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"011\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0005\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"002\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0005\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"ZZ01\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0005\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0005\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"013\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0006\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"004\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0006\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"009\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0006\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0006\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"010\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0007\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"005\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0007\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"015\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0007\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0007\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"023\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0008\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"005\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0008\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"016\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0008\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0008\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"020\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0009\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"005\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0009\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"012\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0009\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0009\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"021\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0010\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"008\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0010\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"017\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0010\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0010\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"018\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0011\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"011\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0011\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"023\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0011\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0011\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"025\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0012\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"013\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0012\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"014\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0012\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0012\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"019\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0013\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"010\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0013\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"021\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0013\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0013\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"022\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0014\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"019\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0014\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"020\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0014\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0014\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"024\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0015\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"022\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0015\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"025\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0015\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0015\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"027\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0016\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"024\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0016\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"018\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0016\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0016\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"026\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0017\""], + ["text"," "], + ["paren.lparen","["], + ["variable","shape"], + ["keyword.operator","="], + ["text","diamond"], + ["punctuation.operator",","], + ["variable","style"], + ["keyword.operator","="], + ["text","filled"], + ["punctuation.operator",","], + ["variable","label"], + ["keyword.operator","="], + ["string","\"\""], + ["punctuation.operator",","], + ["variable","height"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["variable","width"], + ["keyword.operator","="], + ["text","."], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"026\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0017\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"027\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"marr0017\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["string","\"marr0017\""], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["string","\"028\""], + ["text"," "], + ["paren.lparen","["], + ["variable","dir"], + ["keyword.operator","="], + ["text","none"], + ["punctuation.operator",","], + ["text"," "], + ["variable","weight"], + ["keyword.operator","="], + ["constant.numeric","2"], + ["paren.rparen","]"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_eiffel.json b/lib/ace/mode/_test/tokens_eiffel.json new file mode 100644 index 00000000..344dbc62 --- /dev/null +++ b/lib/ace/mode/_test/tokens_eiffel.json @@ -0,0 +1,141 @@ +[[ + "start", + ["keyword","note"] +],[ + "start", + ["text","\t"], + ["identifier","description"], + ["keyword.operator",":"], + ["text"," "], + ["string.quoted.double","\"Represents a person.\""] +],[ + "start" +],[ + "start", + ["keyword","class"] +],[ + "start", + ["text","\t"], + ["entity.name.type","PERSON"] +],[ + "start" +],[ + "start", + ["keyword","create"] +],[ + "start", + ["text","\t"], + ["identifier","make"], + ["keyword.operator",","], + ["text"," "], + ["identifier","make_unknown"] +],[ + "start" +],[ + "start", + ["keyword","feature"], + ["text"," "], + ["paren.lparen","{"], + ["entity.name.type","NONE"], + ["paren.rparen","}"], + ["text"," "], + ["comment.line.double-dash","-- Creation"] +],[ + "start" +],[ + "start", + ["text","\t"], + ["identifier","make"], + ["text"," "], + ["paren.lparen","("], + ["identifier","a_name"], + ["keyword.operator",":"], + ["text"," "], + ["keyword","like"], + ["text"," "], + ["identifier","name"], + ["paren.rparen",")"] +],[ + "start", + ["text","\t\t\t"], + ["comment.line.double-dash","-- Create a person with `a_name' as `name'."] +],[ + "start", + ["text","\t\t"], + ["keyword","do"] +],[ + "start", + ["text","\t\t\t"], + ["identifier","name"], + ["text"," "], + ["keyword.operator",":="], + ["text"," "], + ["identifier","a_name"] +],[ + "start", + ["text","\t\t"], + ["keyword","ensure"] +],[ + "start", + ["text","\t\t\t"], + ["identifier","name"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","a_name"] +],[ + "start", + ["text","\t\t"], + ["keyword","end"] +],[ + "start" +],[ + "start", + ["text","\t"], + ["identifier","make_unknown"] +],[ + "start", + ["text","\t\t"], + ["keyword","do"], + ["text"," "], + ["keyword","ensure"] +],[ + "start", + ["text","\t\t\t"], + ["identifier","name"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.language","Void"] +],[ + "start", + ["text","\t\t"], + ["keyword","end"] +],[ + "start" +],[ + "start", + ["keyword","feature"], + ["text"," "], + ["comment.line.double-dash","-- Access"] +],[ + "start" +],[ + "start", + ["text","\t"], + ["identifier","name"], + ["keyword.operator",":"], + ["text"," "], + ["keyword","detachable"], + ["text"," "], + ["entity.name.type","STRING"] +],[ + "start", + ["text","\t\t\t"], + ["comment.line.double-dash","-- Full name or Void if unknown."] +],[ + "start" +],[ + "start", + ["keyword","end"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_ejs.json b/lib/ace/mode/_test/tokens_ejs.json new file mode 100644 index 00000000..7e54af91 --- /dev/null +++ b/lib/ace/mode/_test/tokens_ejs.json @@ -0,0 +1,296 @@ +[[ + "start", + ["xml-pe.doctype.xml",""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","html"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","head"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","title"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Cloud9 Rocks!"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","body"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start" +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","table"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","class"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"table\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","tr"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","th"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Name"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","th"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Size"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["markup.list.meta.tag","<%"], + ["text"," "], + ["keyword","if"], + ["text"," "], + ["paren.lparen","("], + ["keyword.operator","!"], + ["identifier","isRoot"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"], + ["text"," "], + ["markup.list.meta.tag","%>"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","tr"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","td"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.anchor.tag-name.xml","a"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"..\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml",".."], + ["meta.tag.punctuation.end-tag-open.xml",""], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","td"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.end-tag-open.xml",""], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["markup.list.meta.tag","<%"], + ["text"," "], + ["paren.rparen","}"], + ["text"," "], + ["markup.list.meta.tag","%>"] +],[ + "start", + ["text.xml"," "], + ["markup.list.meta.tag","<%"], + ["text"," "], + ["identifier","entries"], + ["punctuation.operator","."], + ["identifier","forEach"], + ["paren.lparen","("], + ["storage.type","function"], + ["paren.lparen","("], + ["identifier","entry"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"], + ["text"," "], + ["markup.list.meta.tag","%>"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","tr"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","td"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","span"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","class"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"glyphicon "], + ["markup.list.meta.tag","<%="], + ["text"," "], + ["identifier","entry"], + ["punctuation.operator","."], + ["identifier","mime"], + ["text"," "], + ["keyword.operator","=="], + ["text"," "], + ["string","'directory'"], + ["text"," "], + ["punctuation.operator","?"], + ["text"," "], + ["string","'folder'"], + ["punctuation.operator",":"], + ["text"," "], + ["string","'file'"], + ["markup.list.meta.tag","%>"], + ["string.attribute-value.xml","\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.anchor.tag-name.xml","a"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\""], + ["markup.list.meta.tag","<%="], + ["text"," "], + ["identifier","entry"], + ["punctuation.operator","."], + ["identifier","name"], + ["text"," "], + ["markup.list.meta.tag","%>"], + ["string.attribute-value.xml","\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["markup.list.meta.tag","<%="], + ["text"," "], + ["identifier","entry"], + ["punctuation.operator","."], + ["identifier","name"], + ["text"," "], + ["markup.list.meta.tag","%>"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","td"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["markup.list.meta.tag","<%="], + ["text"," "], + ["identifier","entry"], + ["punctuation.operator","."], + ["identifier","size"], + ["text"," "], + ["markup.list.meta.tag","%>"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["markup.list.meta.tag","<%"], + ["text"," "], + ["paren.rparen","})"], + ["text"," "], + ["markup.list.meta.tag","%>"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_elixir.json b/lib/ace/mode/_test/tokens_elixir.json new file mode 100644 index 00000000..cbbe1fee --- /dev/null +++ b/lib/ace/mode/_test/tokens_elixir.json @@ -0,0 +1,196 @@ +[[ + "start", + ["keyword.control.module.elixir","defmodule"], + ["meta.module.elixir"," "], + ["entity.name.type.module.elixir","HelloModule"], + ["text"," "], + ["keyword.control.elixir","do"] +],[ + "comment.documentation.heredoc", + ["text"," "], + ["comment.documentation.heredoc","@moduledoc \"\"\""] +],[ + "comment.documentation.heredoc", + ["comment.documentation.heredoc"," This is supposed to be `markdown`."] +],[ + "comment.documentation.heredoc", + ["comment.documentation.heredoc"," __Yes__ this is [mark](http://down.format)"] +],[ + "comment.documentation.heredoc" +],[ + "comment.documentation.heredoc", + ["comment.documentation.heredoc"," # Truly"] +],[ + "comment.documentation.heredoc" +],[ + "comment.documentation.heredoc", + ["comment.documentation.heredoc"," ## marked"] +],[ + "comment.documentation.heredoc" +],[ + "comment.documentation.heredoc", + ["comment.documentation.heredoc"," * with lists"] +],[ + "comment.documentation.heredoc", + ["comment.documentation.heredoc"," * more"] +],[ + "comment.documentation.heredoc", + ["comment.documentation.heredoc"," * and more"] +],[ + "comment.documentation.heredoc" +],[ + "comment.documentation.heredoc", + ["comment.documentation.heredoc"," Even.with(code)"] +],[ + "comment.documentation.heredoc", + ["comment.documentation.heredoc"," blocks |> with |> samples"] +],[ + "comment.documentation.heredoc" +],[ + "comment.documentation.heredoc", + ["comment.documentation.heredoc"," _Docs are first class citizens in Elixir_ (Jose Valim)"] +],[ + "start", + ["comment.documentation.heredoc"," \"\"\""] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["punctuation.definition.comment.elixir","#"], + ["comment.line.number-sign.elixir"," A \"Hello world\" function"] +],[ + "start", + ["text"," "], + ["keyword.control.elixir","def"], + ["text"," some_fun "], + ["keyword.control.elixir","do"] +],[ + "start", + ["text"," "], + ["variable.other.constant.elixir","IO"], + ["punctuation.separator.method.elixir","."], + ["text","puts "], + ["punctuation.definition.string.begin.elixir","\""], + ["string.quoted.double.elixir","Juhu Kinners!"], + ["punctuation.definition.string.end.elixir","\""] +],[ + "start", + ["text"," "], + ["keyword.control.elixir","end"] +],[ + "start", + ["text"," "], + ["punctuation.definition.comment.elixir","#"], + ["comment.line.number-sign.elixir"," A private function"] +],[ + "start", + ["text"," "], + ["keyword.control.elixir","defp"], + ["text"," priv "], + ["keyword.control.elixir","do"] +],[ + "punctuation.definition.string.begin.elixir7", + ["text"," is_regex "], + ["punctuation.definition.string.begin.elixir","~r\"\"\""] +],[ + "punctuation.definition.string.begin.elixir7", + ["string.quoted.double.heredoc.elixir"," This is a regex"] +],[ + "punctuation.definition.string.begin.elixir7", + ["string.quoted.double.heredoc.elixir"," spanning several"] +],[ + "punctuation.definition.string.begin.elixir7", + ["string.quoted.double.heredoc.elixir"," lines."] +],[ + "start", + ["punctuation.definition.string.end.elixir"," \"\"\""] +],[ + "start", + ["text"," x "], + ["keyword.operator.assignment.elixir","="], + ["text"," elem"], + ["punctuation.section.function.elixir","("], + ["punctuation.section.scope.elixir","{"], + ["text"," "], + ["punctuation.definition.constant.elixir",":"], + ["constant.other.symbol.elixir","a"], + ["punctuation.separator.object.elixir",","], + ["text"," "], + ["punctuation.definition.constant.elixir",":"], + ["constant.other.symbol.elixir","b"], + ["punctuation.separator.object.elixir",","], + ["text"," "], + ["punctuation.definition.constant.elixir",":"], + ["constant.other.symbol.elixir","c"], + ["text"," "], + ["punctuation.section.scope.elixir","}"], + ["punctuation.separator.object.elixir",","], + ["text"," "], + ["constant.numeric.elixir","0"], + ["punctuation.section.function.elixir",")"], + ["text"," "], + ["punctuation.definition.comment.elixir","#"], + ["comment.line.number-sign.elixir","=> :a"] +],[ + "start", + ["text"," "], + ["keyword.control.elixir","end"] +],[ + "start", + ["keyword.control.elixir","end"] +],[ + "start" +],[ + "start", + ["text","test_fun "], + ["keyword.operator.assignment.elixir","="], + ["text"," "], + ["keyword.control.elixir","fn"], + ["punctuation.section.function.elixir","("], + ["text","x"], + ["punctuation.section.function.elixir",")"], + ["text"," "], + ["keyword.operator.arithmetic.elixir","-"], + ["keyword.operator.comparison.elixir",">"] +],[ + "start", + ["text"," "], + ["keyword.control.elixir","cond"], + ["text"," "], + ["keyword.control.elixir","do"] +],[ + "start", + ["text"," x "], + ["keyword.operator.comparison.elixir",">"], + ["text"," "], + ["constant.numeric.elixir","10"], + ["text"," "], + ["keyword.operator.arithmetic.elixir","-"], + ["keyword.operator.comparison.elixir",">"] +],[ + "start", + ["text"," "], + ["punctuation.definition.constant.elixir",":"], + ["constant.other.symbol.elixir","greater_than_ten"] +],[ + "start", + ["text"," "], + ["constant.language.elixir","true"], + ["text"," "], + ["keyword.operator.arithmetic.elixir","-"], + ["keyword.operator.comparison.elixir",">"] +],[ + "start", + ["text"," "], + ["punctuation.definition.constant.elixir",":"], + ["constant.other.symbol.elixir","maybe_ten"] +],[ + "start", + ["text"," "], + ["keyword.control.elixir","end"] +],[ + "start", + ["keyword.control.elixir","end"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_elm.json b/lib/ace/mode/_test/tokens_elm.json new file mode 100644 index 00000000..b39de92f --- /dev/null +++ b/lib/ace/mode/_test/tokens_elm.json @@ -0,0 +1,198 @@ +[[ + "start", + ["comment.start","{-"], + ["comment"," Ace "], + ["comment.start","{-"], + ["comment"," 4 "], + ["comment.end","-}"], + ["comment"," Elm "], + ["comment.end","-}"] +],[ + "start", + ["constant.language","main"], + ["text"," "], + ["keyword","="], + ["text"," "], + ["identifier","lift"], + ["text"," "], + ["identifier","clock"], + ["text"," "], + ["paren.lparen","("], + ["identifier","every"], + ["text"," "], + ["identifier","second"], + ["paren.rparen",")"] +],[ + "start" +],[ + "start", + ["constant.language","clock"], + ["text"," "], + ["identifier","t"], + ["text"," "], + ["keyword","="], + ["text"," "], + ["identifier","collage"], + ["text"," "], + ["constant.numeric","400"], + ["text"," "], + ["constant.numeric","400"], + ["text"," "], + ["paren.lparen","["], + ["text"," "], + ["identifier","filled"], + ["text"," "], + ["identifier","lightGrey"], + ["text"," "], + ["paren.lparen","("], + ["identifier","ngon"], + ["text"," "], + ["constant.numeric","12"], + ["text"," "], + ["constant.numeric","110"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["operator.punctuation",","], + ["text"," "], + ["identifier","outlined"], + ["text"," "], + ["paren.lparen","("], + ["identifier","solid"], + ["text"," "], + ["identifier","grey"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","("], + ["identifier","ngon"], + ["text"," "], + ["constant.numeric","12"], + ["text"," "], + ["constant.numeric","110"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["operator.punctuation",","], + ["text"," "], + ["identifier","hand"], + ["text"," "], + ["identifier","orange"], + ["text"," "], + ["constant.numeric","100"], + ["text"," "], + ["identifier","t"] +],[ + "start", + ["text"," "], + ["operator.punctuation",","], + ["text"," "], + ["identifier","hand"], + ["text"," "], + ["identifier","charcoal"], + ["text"," "], + ["constant.numeric","100"], + ["text"," "], + ["paren.lparen","("], + ["identifier","t"], + ["keyword.operator","/"], + ["constant.numeric","60"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["operator.punctuation",","], + ["text"," "], + ["identifier","hand"], + ["text"," "], + ["identifier","charcoal"], + ["text"," "], + ["constant.numeric","60"], + ["text"," "], + ["paren.lparen","("], + ["identifier","t"], + ["keyword.operator","/"], + ["constant.numeric","720"], + ["paren.rparen",")"], + ["text"," "], + ["paren.rparen","]"] +],[ + "start" +],[ + "start", + ["constant.language","hand"], + ["text"," "], + ["identifier","clr"], + ["text"," "], + ["identifier","len"], + ["text"," "], + ["identifier","time"], + ["text"," "], + ["keyword","="] +],[ + "start", + ["text"," "], + ["keyword","let"], + ["text"," "], + ["identifier","angle"], + ["text"," "], + ["keyword","="], + ["text"," "], + ["identifier","degrees"], + ["text"," "], + ["paren.lparen","("], + ["constant.numeric","90"], + ["text"," "], + ["keyword.operator","-"], + ["text"," "], + ["constant.numeric","6"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "], + ["identifier","inSeconds"], + ["text"," "], + ["identifier","time"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["keyword","in"], + ["text"," "], + ["identifier","traced"], + ["text"," "], + ["paren.lparen","("], + ["identifier","solid"], + ["text"," "], + ["identifier","clr"], + ["paren.rparen",")"], + ["text"," "], + ["keyword.operator","<|"], + ["text"," "], + ["identifier","segment"], + ["text"," "], + ["paren.lparen","("], + ["constant.numeric","0"], + ["operator.punctuation",","], + ["constant.numeric","0"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","("], + ["identifier","len"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "], + ["identifier","cos"], + ["text"," "], + ["identifier","angle"], + ["operator.punctuation",","], + ["text"," "], + ["identifier","len"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "], + ["identifier","sin"], + ["text"," "], + ["identifier","angle"], + ["paren.rparen",")"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_erlang.json b/lib/ace/mode/_test/tokens_erlang.json new file mode 100644 index 00000000..8a828976 --- /dev/null +++ b/lib/ace/mode/_test/tokens_erlang.json @@ -0,0 +1,166 @@ +[[ + "start", + ["text"," "], + ["punctuation.definition.comment.erlang","%% A process whose only job is to keep a counter."] +],[ + "start", + ["text"," "], + ["punctuation.definition.comment.erlang","%% First version"] +],[ + "start", + ["meta.directive.module.erlang"," "], + ["punctuation.section.directive.begin.erlang","-"], + ["keyword.control.directive.module.erlang","module"], + ["punctuation.definition.parameters.begin.erlang","("], + ["entity.name.type.class.module.definition.erlang","counter"], + ["punctuation.definition.parameters.end.erlang",")"], + ["punctuation.section.directive.end.erlang","."] +],[ + "start", + ["meta.directive.export.erlang"," "], + ["punctuation.section.directive.begin.erlang","-"], + ["keyword.control.directive.export.erlang","export"], + ["punctuation.definition.parameters.begin.erlang","("], + ["punctuation.definition.list.begin.erlang","["], + ["entity.name.function.erlang","start"], + ["punctuation.separator.function-arity.erlang","/"], + ["constant.numeric.integer.decimal.erlang","0"], + ["punctuation.separator.list.erlang",","], + ["meta.structure.list.function.erlang"," "], + ["entity.name.function.erlang","codeswitch"], + ["punctuation.separator.function-arity.erlang","/"], + ["constant.numeric.integer.decimal.erlang","1"], + ["punctuation.definition.list.end.erlang","]"], + ["punctuation.definition.parameters.end.erlang",")"], + ["punctuation.section.directive.end.erlang","."] +],[ + "start", + ["text"," "] +],[ + "start", + ["meta.function.erlang"," "], + ["entity.name.function.definition.erlang","start"], + ["punctuation.section.expression.begin.erlang","("], + ["punctuation.section.expression.end.erlang",")"], + ["text"," "], + ["keyword.operator.symbolic.erlang","->"], + ["text"," "], + ["entity.name.function.erlang","loop"], + ["punctuation.definition.parameters.begin.erlang","("], + ["constant.numeric.integer.decimal.erlang","0"], + ["punctuation.definition.parameters.end.erlang",")"], + ["punctuation.terminator.function.erlang","."] +],[ + "start", + ["text"," "] +],[ + ["text6","meta.function.erlang"], + ["meta.function.erlang"," "], + ["entity.name.function.definition.erlang","loop"], + ["punctuation.section.expression.begin.erlang","("], + ["variable.other.erlang","Sum"], + ["punctuation.section.expression.end.erlang",")"], + ["text"," "], + ["keyword.operator.symbolic.erlang","->"] +],[ + ["keyword.control.receive.erlang","text6","text6","meta.function.erlang"], + ["text"," "], + ["keyword.control.receive.erlang","receive"] +],[ + ["keyword.control.receive.erlang","text6","text6","meta.function.erlang"], + ["meta.expression.receive.erlang"," "], + ["punctuation.definition.tuple.begin.erlang","{"], + ["constant.other.symbol.unquoted.erlang","increment"], + ["punctuation.separator.tuple.erlang",","], + ["meta.structure.tuple.erlang"," "], + ["variable.other.erlang","Count"], + ["punctuation.definition.tuple.end.erlang","}"], + ["meta.expression.receive.erlang"," "], + ["punctuation.separator.clause-head-body.erlang","->"] +],[ + ["keyword.control.receive.erlang","text6","text6","meta.function.erlang"], + ["meta.expression.receive.erlang"," "], + ["entity.name.function.erlang","loop"], + ["punctuation.definition.parameters.begin.erlang","("], + ["variable.other.erlang","Sum"], + ["keyword.operator.symbolic.erlang","+"], + ["variable.other.erlang","Count"], + ["punctuation.definition.parameters.end.erlang",")"], + ["punctuation.separator.clauses.erlang",";"] +],[ + ["keyword.control.receive.erlang","text6","text6","meta.function.erlang"], + ["meta.expression.receive.erlang"," "], + ["punctuation.definition.tuple.begin.erlang","{"], + ["constant.other.symbol.unquoted.erlang","counter"], + ["punctuation.separator.tuple.erlang",","], + ["meta.structure.tuple.erlang"," "], + ["variable.other.erlang","Pid"], + ["punctuation.definition.tuple.end.erlang","}"], + ["meta.expression.receive.erlang"," "], + ["punctuation.separator.clause-head-body.erlang","->"] +],[ + ["keyword.control.receive.erlang","text6","text6","meta.function.erlang"], + ["meta.expression.receive.erlang"," "], + ["variable.other.erlang","Pid"], + ["meta.expression.receive.erlang"," "], + ["keyword.operator.symbolic.erlang","!"], + ["meta.expression.receive.erlang"," "], + ["punctuation.definition.tuple.begin.erlang","{"], + ["constant.other.symbol.unquoted.erlang","counter"], + ["punctuation.separator.tuple.erlang",","], + ["meta.structure.tuple.erlang"," "], + ["variable.other.erlang","Sum"], + ["punctuation.definition.tuple.end.erlang","}"], + ["punctuation.separator.expressions.erlang",","] +],[ + ["keyword.control.receive.erlang","text6","text6","meta.function.erlang"], + ["meta.expression.receive.erlang"," "], + ["entity.name.function.erlang","loop"], + ["punctuation.definition.parameters.begin.erlang","("], + ["variable.other.erlang","Sum"], + ["punctuation.definition.parameters.end.erlang",")"], + ["punctuation.separator.clauses.erlang",";"] +],[ + ["keyword.control.receive.erlang","text6","text6","meta.function.erlang"], + ["meta.expression.receive.erlang"," "], + ["constant.other.symbol.unquoted.erlang","code_switch"], + ["meta.expression.receive.erlang"," "], + ["punctuation.separator.clause-head-body.erlang","->"] +],[ + ["keyword.control.receive.erlang","text6","text6","meta.function.erlang"], + ["meta.expression.receive.erlang"," "], + ["keyword.operator.macro.erlang","?"], + ["entity.name.function.macro.erlang","MODULE"], + ["meta.expression.receive.erlang",":"], + ["entity.name.function.erlang","codeswitch"], + ["punctuation.definition.parameters.begin.erlang","("], + ["variable.other.erlang","Sum"], + ["punctuation.definition.parameters.end.erlang",")"] +],[ + ["keyword.control.receive.erlang","text6","text6","meta.function.erlang"], + ["meta.expression.receive.erlang"," "], + ["punctuation.definition.comment.erlang","% Force the use of 'codeswitch/1' from the latest MODULE version"] +],[ + "start", + ["meta.expression.receive.erlang"," "], + ["keyword.control.end.erlang","end"], + ["punctuation.terminator.function.erlang","."] +],[ + "start", + ["text"," "] +],[ + "start", + ["meta.function.erlang"," "], + ["entity.name.function.definition.erlang","codeswitch"], + ["punctuation.section.expression.begin.erlang","("], + ["variable.other.erlang","Sum"], + ["punctuation.section.expression.end.erlang",")"], + ["text"," "], + ["keyword.operator.symbolic.erlang","->"], + ["text"," "], + ["entity.name.function.erlang","loop"], + ["punctuation.definition.parameters.begin.erlang","("], + ["variable.other.erlang","Sum"], + ["punctuation.definition.parameters.end.erlang",")"], + ["punctuation.terminator.function.erlang","."] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_forth.json b/lib/ace/mode/_test/tokens_forth.json new file mode 100644 index 00000000..8c8a007e --- /dev/null +++ b/lib/ace/mode/_test/tokens_forth.json @@ -0,0 +1,219 @@ +[[ + "start", + ["keyword.other.compile-only.forth",":"], + ["meta.block.forth"," "], + ["entity.name.function.forth","HELLO"], + ["meta.block.forth"," "], + ["comment.line.parentheses.forth"," ( -- )"], + ["meta.block.forth"," CR "], + ["string.quoted.double.forth",".\" Hello, world!\""], + ["meta.block.forth"," "], + ["keyword.other.compile-only.forth",";"], + ["text"," "] +],[ + "start" +],[ + "start", + ["text","HELLO "] +],[ + "start", + ["text","Hello, world!"] +],[ + "start" +],[ + "start", + ["keyword.other.compile-only.forth",":"], + ["meta.block.forth"," "], + ["entity.name.function.forth","[CHAR]"], + ["meta.block.forth"," "], + ["keyword.other.non-immediate.forth"," CHAR"], + ["meta.block.forth"," "], + ["keyword.other.compile-only.forth"," POSTPONE"], + ["meta.block.forth"," LITERAL "], + ["keyword.other.compile-only.forth",";"], + ["keyword.other.immediate.forth"," IMMEDIATE"] +],[ + "start" +],[ + "start", + ["constant.numeric.forth","0"], + ["storage.type.forth"," value"], + ["text"," ii "], + ["constant.numeric.forth"," 0"], + ["storage.type.forth"," value"], + ["text"," jj"] +],[ + "start", + ["constant.numeric.forth","0"], + ["storage.type.forth"," value"], + ["text"," KeyAddr "], + ["constant.numeric.forth"," 0"], + ["storage.type.forth"," value"], + ["text"," KeyLen"] +],[ + "start", + ["storage.type.forth","create"], + ["text"," SArray "], + ["constant.numeric.forth"," 256"], + ["text"," allot "], + ["comment.line.backslash.forth"," \\ state array of 256 bytes"] +],[ + "start", + ["keyword.other.compile-only.forth",":"], + ["meta.block.forth"," "], + ["entity.name.function.forth","KeyArray"], + ["meta.block.forth"," KeyLen mod KeyAddr "], + ["keyword.other.compile-only.forth",";"] +],[ + "start" +],[ + "start", + ["keyword.other.compile-only.forth",":"], + ["meta.block.forth"," "], + ["entity.name.function.forth","get_byte"], + ["meta.block.forth"," + c@ "], + ["keyword.other.compile-only.forth",";"] +],[ + "start", + ["keyword.other.compile-only.forth",":"], + ["meta.block.forth"," "], + ["entity.name.function.forth","set_byte"], + ["meta.block.forth"," + c! "], + ["keyword.other.compile-only.forth",";"] +],[ + "start", + ["keyword.other.compile-only.forth",":"], + ["meta.block.forth"," "], + ["entity.name.function.forth","as_byte"], + ["meta.block.forth"," "], + ["constant.numeric.forth"," 255"], + ["meta.block.forth"," and "], + ["keyword.other.compile-only.forth",";"] +],[ + "start", + ["keyword.other.compile-only.forth",":"], + ["meta.block.forth"," "], + ["entity.name.function.forth","reset_ij"], + ["meta.block.forth"," "], + ["constant.numeric.forth"," 0"], + ["keyword.other.immediate.forth"," TO"], + ["meta.block.forth"," ii "], + ["constant.numeric.forth"," 0"], + ["keyword.other.immediate.forth"," TO"], + ["meta.block.forth"," jj "], + ["keyword.other.compile-only.forth",";"] +],[ + "start", + ["keyword.other.compile-only.forth",":"], + ["meta.block.forth"," "], + ["entity.name.function.forth","i_update"], + ["meta.block.forth"," "], + ["constant.numeric.forth"," 1"], + ["meta.block.forth"," + as_byte"], + ["keyword.other.immediate.forth"," TO"], + ["meta.block.forth"," ii "], + ["keyword.other.compile-only.forth",";"] +],[ + "start", + ["keyword.other.compile-only.forth",":"], + ["meta.block.forth"," "], + ["entity.name.function.forth","j_update"], + ["meta.block.forth"," ii SArray get_byte + as_byte"], + ["keyword.other.immediate.forth"," TO"], + ["meta.block.forth"," jj "], + ["keyword.other.compile-only.forth",";"] +],[ + "keyword.other.compile-only.forth", + ["keyword.other.compile-only.forth",":"], + ["meta.block.forth"," "], + ["entity.name.function.forth","swap_s_ij"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," jj SArray get_byte"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," ii SArray get_byte jj SArray set_byte"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," ii SArray set_byte"] +],[ + "start", + ["keyword.other.compile-only.forth",";"] +],[ + "start" +],[ + "keyword.other.compile-only.forth", + ["keyword.other.compile-only.forth",":"], + ["meta.block.forth"," "], + ["entity.name.function.forth","rc4_init"], + ["comment.line.parentheses.forth"," ( KeyAddr KeyLen -- )"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," "], + ["constant.numeric.forth"," 256"], + ["meta.block.forth"," min"], + ["keyword.other.immediate.forth"," TO"], + ["meta.block.forth"," KeyLen "], + ["keyword.other.immediate.forth"," TO"], + ["meta.block.forth"," KeyAddr"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," "], + ["constant.numeric.forth"," 256 0"], + ["keyword.control.compile-only.forth"," DO"], + ["meta.block.forth"," "], + ["variable.language.forth","i"], + ["meta.block.forth"," "], + ["variable.language.forth","i"], + ["meta.block.forth"," SArray set_byte "], + ["keyword.control.compile-only.forth"," LOOP"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," reset_ij"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," "], + ["keyword.control.compile-only.forth"," BEGIN"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," ii KeyArray get_byte jj + j_update"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," swap_s_ij"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," ii"], + ["constant.numeric.forth"," 255"], + ["meta.block.forth"," <"], + ["keyword.control.compile-only.forth"," WHILE"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," ii i_update"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," "], + ["keyword.control.compile-only.forth"," REPEAT"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," reset_ij"] +],[ + "start", + ["keyword.other.compile-only.forth",";"] +],[ + "keyword.other.compile-only.forth", + ["keyword.other.compile-only.forth",":"], + ["meta.block.forth"," "], + ["entity.name.function.forth","rc4_byte"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," ii i_update jj j_update"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," swap_s_ij"] +],[ + "keyword.other.compile-only.forth", + ["meta.block.forth"," ii SArray get_byte jj SArray get_byte + as_byte SArray get_byte xor"] +],[ + "start", + ["keyword.other.compile-only.forth",";"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_ftl.json b/lib/ace/mode/_test/tokens_ftl.json new file mode 100644 index 00000000..75e7a6f1 --- /dev/null +++ b/lib/ace/mode/_test/tokens_ftl.json @@ -0,0 +1,341 @@ +[[ + "start", + ["keyword.function","<#ftl"], + ["text"," "], + ["entity.other.attribute-name","encoding"], + ["keyword.operator","="], + ["string","\"utf-8\""], + ["text"," "], + ["keyword","/>"] +],[ + "start", + ["keyword.function","<#setting"], + ["text"," "], + ["entity.other.attribute-name","locale"], + ["keyword.operator","="], + ["string","\"en_US\""], + ["text"," "], + ["keyword","/>"] +],[ + "start", + ["keyword.function","<#import"], + ["text"," "], + ["string","\"library\""], + ["text"," "], + ["keyword.operator","as"], + ["text"," "], + ["variable","lib"], + ["text"," "], + ["keyword","/>"] +],[ + "ftl-dcomment", + ["comment","<#--"] +],[ + "ftl-dcomment", + ["comment"," FreeMarker comment"] +],[ + "ftl-dcomment", + ["comment"," ${abc} <#assign a=12 />"] +],[ + "start", + ["comment","-->"] +],[ + "start" +],[ + "start", + ["xml-pe.doctype.xml",""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","html"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","lang"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"en-us\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","head"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","meta"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","charset"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"utf-8\""], + ["text.tag-whitespace.xml"," "], + ["meta.tag.punctuation.tag-close.xml","/>"] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","title"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["string.interpolated","${"], + ["variable","title"], + ["keyword.operator","!"], + ["string","\"FreeMarker\""], + ["string.interpolated","}"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","title"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","body"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","h1"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Hello "], + ["string.interpolated","${"], + ["variable","name"], + ["keyword.operator","!"], + ["string","\"\""], + ["string.interpolated","}"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","p"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Today is: "], + ["string.interpolated","${"], + ["language.variable",".now"], + ["support.function","?date"], + ["string.interpolated","}"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["text.xml"," "], + ["keyword.function","<#assign"], + ["text"," "], + ["variable","x"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","13"], + ["keyword",">"] +],[ + "start", + ["text.xml"," "], + ["keyword.function","<#if"], + ["text"," "], + ["variable","x"], + ["text"," "], + ["constant.character.entity",">"], + ["text"," "], + ["constant.numeric","12"], + ["text"," "], + ["keyword.operator","&&"], + ["text"," "], + ["variable","x"], + ["text"," "], + ["keyword.operator","lt"], + ["text"," "], + ["constant.numeric","14"], + ["keyword",">"], + ["text.xml","x equals 13: "], + ["string.interpolated","${"], + ["variable","x"], + ["string.interpolated","}"], + ["keyword.function",""] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","ul"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["keyword.function","<#list"], + ["text"," "], + ["variable","items"], + ["text"," "], + ["keyword.operator","as"], + ["text"," "], + ["variable","item"], + ["keyword",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","li"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["string.interpolated","${"], + ["variable","item_index"], + ["string.interpolated","}"], + ["text.xml",": "], + ["string.interpolated","${"], + ["variable","item.name"], + ["keyword.operator","!"], + ["support.function","?split"], + ["paren.lparen","("], + ["string","\""], + ["constant.character.escape","\\n"], + ["string","\""], + ["paren.rparen",")"], + ["paren.lparen","["], + ["constant.numeric","0"], + ["paren.rparen","]"], + ["string.interpolated","}"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["keyword.function",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["text.xml"," User directive: "], + ["keyword.other","<@lib.function"], + ["text"," "], + ["variable","attr1"], + ["keyword.operator","="], + ["constant.language","true"], + ["text"," "], + ["variable","attr2"], + ["keyword.operator","="], + ["string","'value'"], + ["text"," "], + ["variable","attr3"], + ["keyword.operator","="], + ["constant.numeric","-42.12"], + ["keyword",">"], + ["text.xml","Test"], + ["keyword.other",""] +],[ + "start", + ["text.xml"," "], + ["keyword.other","<@anotherOne"], + ["text"," "], + ["keyword","/>"] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["text.xml"," "], + ["keyword.function","<#if"], + ["text"," "], + ["variable","variable"], + ["support.function.deprecated","?exists"], + ["keyword",">"] +],[ + "start", + ["text.xml"," Deprecated"] +],[ + "start", + ["text.xml"," "], + ["keyword.function","<#elseif"], + ["text"," "], + ["variable","variable"], + ["support.function","??"], + ["keyword",">"] +],[ + "start", + ["text.xml"," Better"] +],[ + "start", + ["text.xml"," "], + ["keyword.function","<#else"], + ["keyword",">"] +],[ + "start", + ["text.xml"," Default"] +],[ + "start", + ["text.xml"," "], + ["keyword.function",""] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.image.tag-name.xml","img"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","src"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"images/"], + ["string.interpolated","${"], + ["variable","user.id"], + ["string.interpolated","}"], + ["string.attribute-value.xml",".png\""], + ["text.tag-whitespace.xml"," "], + ["meta.tag.punctuation.tag-close.xml","/>"] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_gcode.json b/lib/ace/mode/_test/tokens_gcode.json new file mode 100644 index 00000000..d6227473 --- /dev/null +++ b/lib/ace/mode/_test/tokens_gcode.json @@ -0,0 +1,296 @@ +[[ + "start", + ["identifier","O"], + ["constant.numeric","003"], + ["text"," "], + ["comment","(DIAMOND SQUARE)"] +],[ + "start", + ["comment","N2"], + ["text"," "], + ["string","G54"], + ["text"," "], + ["string","G90"], + ["text"," "], + ["string","G49"], + ["text"," "], + ["string","G80"] +],[ + "start", + ["comment","N3"], + ["text"," "], + ["string","M6"], + ["text"," "], + ["identifier","T"], + ["constant.numeric","1"], + ["text"," "], + ["comment","(1.ENDMILL)"] +],[ + "start", + ["comment","N4"], + ["text"," "], + ["string","M3"], + ["text"," "], + ["identifier","S"], + ["constant.numeric","1800"] +],[ + "start", + ["comment","N5"], + ["text"," "], + ["string","G0"], + ["text"," "], + ["identifier","X"], + ["constant.numeric","-.6"], + ["text"," "], + ["identifier","Y"], + ["constant.numeric","2.050"] +],[ + "start", + ["comment","N6"], + ["text"," "], + ["string","G43"], + ["text"," "], + ["identifier","H"], + ["constant.numeric","1"], + ["text"," "], + ["identifier","Z"], + ["constant.numeric",".1"] +],[ + "start", + ["comment","N7"], + ["text"," "], + ["string","G1"], + ["text"," "], + ["identifier","Z"], + ["constant.numeric","-.3"], + ["text"," "], + ["identifier","F"], + ["constant.numeric","50."] +],[ + "start", + ["comment","N8"], + ["text"," "], + ["string","G41"], + ["text"," "], + ["identifier","D"], + ["constant.numeric","1"], + ["text"," "], + ["identifier","Y"], + ["constant.numeric","1.45"] +],[ + "start", + ["comment","N9"], + ["text"," "], + ["string","G1"], + ["text"," "], + ["identifier","X"], + ["constant.numeric","0"], + ["text"," "], + ["identifier","F"], + ["constant.numeric","20."] +],[ + "start", + ["comment","N10"], + ["text"," "], + ["string","G2"], + ["text"," "], + ["identifier","J"], + ["constant.numeric","-1.45"] +],[ + "start", + ["comment","(CUTTER COMP CANCEL)"] +],[ + "start", + ["comment","N11"], + ["text"," "], + ["string","G1"], + ["text"," "], + ["identifier","Z"], + ["constant.numeric","-.2"], + ["text"," "], + ["identifier","F"], + ["constant.numeric","50."] +],[ + "start", + ["comment","N12"], + ["text"," "], + ["identifier","Y"], + ["constant.numeric","-.990"] +],[ + "start", + ["comment","N13"], + ["text"," "], + ["string","G40"] +],[ + "start", + ["comment","N14"], + ["text"," "], + ["string","G0"], + ["text"," "], + ["identifier","X"], + ["constant.numeric","-.6"], + ["text"," "], + ["identifier","Y"], + ["constant.numeric","1.590"] +],[ + "start", + ["comment","N15"], + ["text"," "], + ["string","G0"], + ["text"," "], + ["identifier","Z"], + ["constant.numeric",".1"] +],[ + "start", + ["comment","N16"], + ["text"," "], + ["string","M5"], + ["text"," "], + ["string","G49"], + ["text"," "], + ["string","G28"], + ["text"," "], + ["string","G91"], + ["text"," "], + ["identifier","Z"], + ["constant.numeric","0"] +],[ + "start", + ["comment","N17"], + ["text"," "], + ["identifier","CALL"], + ["text"," "], + ["identifier","O"], + ["constant.numeric","9456"] +],[ + "start", + ["comment","N18"], + ["text"," #"], + ["constant.numeric","500"], + ["text","="], + ["constant.numeric","0.004"] +],[ + "start", + ["comment","N19"], + ["text"," #"], + ["constant.numeric","503"], + ["text","="], + ["paren.lparen","["], + ["text","#"], + ["constant.numeric","500"], + ["text","+#"], + ["constant.numeric","501"], + ["paren.rparen","]"] +],[ + "start", + ["comment","N20"], + ["text"," "], + ["identifier","VC"], + ["constant.numeric","45"], + ["text","="], + ["constant.numeric","0.0006"] +],[ + "start", + ["identifier","VS"], + ["constant.numeric","4"], + ["text","="], + ["constant.numeric","0.0007"] +],[ + "start", + ["comment","N21"], + ["text"," "], + ["string","G90"], + ["text"," "], + ["string","G10"], + ["text"," "], + ["identifier","L"], + ["constant.numeric","20"], + ["text"," "], + ["identifier","P"], + ["constant.numeric","3"], + ["text"," "], + ["identifier","X"], + ["constant.numeric","5."], + ["identifier","Y"], + ["constant.numeric","4."], + ["text"," "], + ["identifier","Z"], + ["constant.numeric","6.567"] +],[ + "start", + ["comment","N22"], + ["text"," "], + ["string","G0"], + ["text"," "], + ["identifier","X"], + ["constant.numeric","5000"] +],[ + "start", + ["comment","N23"], + ["text"," "], + ["identifier","IF"], + ["text"," "], + ["paren.lparen","["], + ["text","#"], + ["constant.numeric","1"], + ["text"," "], + ["identifier","LT"], + ["text"," "], + ["constant.numeric","0.370"], + ["paren.rparen","]"], + ["text"," "], + ["identifier","GOTO"], + ["text"," "], + ["constant.numeric","49"] +],[ + "start", + ["comment","N24"], + ["text"," "], + ["identifier","X"], + ["constant.numeric","-0.678"], + ["text"," "], + ["identifier","Y"], + ["constant.numeric","+.990"] +],[ + "start", + ["comment","N25"], + ["text"," "], + ["string","G84.3"], + ["text"," "], + ["identifier","X"], + ["constant.numeric","-0.1"] +],[ + "start", + ["comment","N26"], + ["text"," #"], + ["constant.numeric","4"], + ["text","=#"], + ["constant.numeric","5"], + ["text","*"], + ["identifier","COS"], + ["paren.lparen","["], + ["constant.numeric","45"], + ["paren.rparen","]"] +],[ + "start", + ["comment","N27"], + ["text"," #"], + ["constant.numeric","4"], + ["text","=#"], + ["constant.numeric","5"], + ["text","*"], + ["identifier","SIN"], + ["paren.lparen","["], + ["constant.numeric","45"], + ["paren.rparen","]"] +],[ + "start", + ["comment","N28"], + ["text"," "], + ["identifier","VZOFZ"], + ["text","="], + ["constant.numeric","652.9658"] +],[ + "start", + ["text","%"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_gherkin.json b/lib/ace/mode/_test/tokens_gherkin.json new file mode 100644 index 00000000..173d9798 --- /dev/null +++ b/lib/ace/mode/_test/tokens_gherkin.json @@ -0,0 +1,142 @@ +[[ + "start", + ["comment","@these"], + ["text"," "], + ["comment","@are"], + ["text"," "], + ["comment","@tags"] +],[ + "start", + ["keyword","Feature:"], + ["text"," Serve coffee"] +],[ + "start", + ["text"," Coffee should not be served until paid for"] +],[ + "start", + ["text"," Coffee should not be served until the button has been pressed"] +],[ + "start", + ["text"," If there is no coffee left then money should be refunded"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["keyword","Scenario Outline:"], + ["text"," Eating"] +],[ + "start", + ["text"," "], + ["keyword","Given"], + ["text"," there are "], + ["comment",""], + ["text"," cucumbers"] +],[ + "start", + ["text"," "], + ["keyword","When"], + ["text"," I eat "], + ["comment",""], + ["text"," cucumbers"] +],[ + "start", + ["text"," "], + ["keyword","Then"], + ["text"," I should have "], + ["comment",""], + ["text"," cucumbers"] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword","Examples:"] +],[ + "start", + ["text"," "], + ["comment","|"], + ["string"," start "], + ["comment","|"], + ["string"," eat "], + ["comment","|"], + ["string"," left "], + ["comment","|"] +],[ + "start", + ["text"," "], + ["comment","|"], + ["string"," 12 "], + ["comment","|"], + ["string"," 5 "], + ["comment","|"], + ["string"," 7 "], + ["comment","|"] +],[ + "start", + ["text"," "], + ["comment","|"], + ["string"," 20 "], + ["comment","|"], + ["string"," 5 "], + ["comment","|"], + ["string"," 15 "], + ["comment","|"], + ["string"," "] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword","Scenario:"], + ["text"," Buy last coffee"] +],[ + "start", + ["text"," "], + ["keyword","Given"], + ["text"," there are "], + ["constant.numeric","1"], + ["text"," coffees left in the machine"] +],[ + "start", + ["text"," "], + ["keyword","And"], + ["text"," I have deposited "], + ["constant.numeric","1"], + ["text","$ "] +],[ + "start", + ["text"," "], + ["keyword","When"], + ["text"," I press the coffee button"] +],[ + "start", + ["text"," "], + ["keyword","Then"], + ["text"," I should be served a "], + ["string","\"coffee\""] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["comment","# this a comment"] +],[ + "start", + ["text"," "] +],[ + "qqstring3", + ["text"," "], + ["string","\"\"\""] +],[ + "qqstring3", + ["string"," this is a "] +],[ + "qqstring3", + ["string"," pystring"] +],[ + "start", + ["string"," \"\"\""] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_gitignore.json b/lib/ace/mode/_test/tokens_gitignore.json new file mode 100644 index 00000000..8689a724 --- /dev/null +++ b/lib/ace/mode/_test/tokens_gitignore.json @@ -0,0 +1,33 @@ +[[ + "start", + ["comment","# A sample .gitignore file."] +],[ + "start" +],[ + "start", + ["text",".buildlog"] +],[ + "start", + ["text",".DS_Store"] +],[ + "start", + ["text",".svn"] +],[ + "start" +],[ + "start", + ["comment","# Negated patterns:"] +],[ + "start", + ["keyword","!foo.bar"] +],[ + "start" +],[ + "start", + ["comment","# Also ignore user settings..."] +],[ + "start", + ["text","/.settings"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_glsl.json b/lib/ace/mode/_test/tokens_glsl.json new file mode 100644 index 00000000..ce8a4d16 --- /dev/null +++ b/lib/ace/mode/_test/tokens_glsl.json @@ -0,0 +1,127 @@ +[[ + "start", + ["keyword","uniform"], + ["text"," "], + ["keyword","float"], + ["text"," "], + ["identifier","amplitude"], + ["punctuation.operator",";"] +],[ + "start", + ["keyword","attribute"], + ["text"," "], + ["keyword","float"], + ["text"," "], + ["identifier","displacement"], + ["punctuation.operator",";"] +],[ + "start", + ["keyword","varying"], + ["text"," "], + ["keyword","vec3"], + ["text"," "], + ["identifier","vNormal"], + ["punctuation.operator",";"] +],[ + "start" +],[ + "start", + ["keyword","void"], + ["text"," "], + ["identifier","main"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start" +],[ + "start", + ["text"," "], + ["identifier","vNormal"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","normal"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["comment","// multiply our displacement by the"] +],[ + "start", + ["text"," "], + ["comment","// amplitude. The amp will get animated"] +],[ + "start", + ["text"," "], + ["comment","// so we'll have animated displacement"] +],[ + "start", + ["text"," "], + ["keyword","vec3"], + ["text"," "], + ["identifier","newPosition"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","position"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "] +],[ + "start", + ["text"," "], + ["identifier","normal"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "] +],[ + "start", + ["text"," "], + ["keyword","vec3"], + ["paren.lparen","("], + ["identifier","displacement"], + ["text"," "], + ["keyword.operator","*"] +],[ + "start", + ["text"," "], + ["identifier","amplitude"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["constant.language","gl_Position"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","projectionMatrix"], + ["text"," "], + ["keyword.operator","*"] +],[ + "start", + ["text"," "], + ["identifier","modelViewMatrix"], + ["text"," "], + ["keyword.operator","*"] +],[ + "start", + ["text"," "], + ["keyword","vec4"], + ["paren.lparen","("], + ["identifier","newPosition"], + ["punctuation.operator",","], + ["constant.numeric","1.0"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["paren.rparen","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_golang.json b/lib/ace/mode/_test/tokens_golang.json new file mode 100644 index 00000000..070c0a17 --- /dev/null +++ b/lib/ace/mode/_test/tokens_golang.json @@ -0,0 +1,256 @@ +[[ + "start", + ["comment","// Concurrent computation of pi."] +],[ + "start", + ["comment","// See http://goo.gl/ZuTZM."] +],[ + "start", + ["comment","//"] +],[ + "start", + ["comment","// This demonstrates Go's ability to handle"] +],[ + "start", + ["comment","// large numbers of concurrent processes."] +],[ + "start", + ["comment","// It is an unreasonable way to calculate pi."] +],[ + "start", + ["keyword","package"], + ["text"," "], + ["identifier","main"] +],[ + "start" +],[ + "start", + ["keyword","import"], + ["text"," "], + ["paren.lparen","("] +],[ + "start", + ["text"," "], + ["string","\"fmt\""] +],[ + "start", + ["text"," "], + ["string","\"math\""] +],[ + "start", + ["paren.rparen",")"] +],[ + "start" +],[ + "start", + ["keyword","func"], + ["text"," "], + ["identifier","main"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["identifier","fmt"], + ["punctuation.operator","."], + ["identifier","Println"], + ["paren.lparen","("], + ["identifier","pi"], + ["paren.lparen","("], + ["constant.numeric","5000"], + ["paren.rparen","))"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["comment","// pi launches n goroutines to compute an"] +],[ + "start", + ["comment","// approximation of pi."] +],[ + "start", + ["keyword","func"], + ["text"," "], + ["identifier","pi"], + ["paren.lparen","("], + ["identifier","n"], + ["text"," "], + ["support.type","int"], + ["paren.rparen",")"], + ["text"," "], + ["support.type","float64"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["identifier","ch"], + ["text"," "], + ["punctuation.operator",":"], + ["keyword.operator","="], + ["text"," "], + ["support.function","make"], + ["paren.lparen","("], + ["keyword","chan"], + ["text"," "], + ["support.type","float64"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["keyword","for"], + ["text"," "], + ["identifier","k"], + ["text"," "], + ["punctuation.operator",":"], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","0"], + ["punctuation.operator",";"], + ["text"," "], + ["identifier","k"], + ["text"," "], + ["keyword.operator","<="], + ["text"," "], + ["identifier","n"], + ["punctuation.operator",";"], + ["text"," "], + ["identifier","k"], + ["keyword.operator","++"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","go"], + ["text"," "], + ["identifier","term"], + ["paren.lparen","("], + ["identifier","ch"], + ["punctuation.operator",","], + ["text"," "], + ["support.type","float64"], + ["paren.lparen","("], + ["identifier","k"], + ["paren.rparen","))"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["identifier","f"], + ["text"," "], + ["punctuation.operator",":"], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","0.0"] +],[ + "start", + ["text"," "], + ["keyword","for"], + ["text"," "], + ["identifier","k"], + ["text"," "], + ["punctuation.operator",":"], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","0"], + ["punctuation.operator",";"], + ["text"," "], + ["identifier","k"], + ["text"," "], + ["keyword.operator","<="], + ["text"," "], + ["identifier","n"], + ["punctuation.operator",";"], + ["text"," "], + ["identifier","k"], + ["keyword.operator","++"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["identifier","f"], + ["text"," "], + ["keyword.operator","+="], + ["text"," "], + ["keyword.operator","<-"], + ["identifier","ch"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["keyword","return"], + ["text"," "], + ["identifier","f"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["keyword","func"], + ["text"," "], + ["identifier","term"], + ["paren.lparen","("], + ["identifier","ch"], + ["text"," "], + ["keyword","chan"], + ["text"," "], + ["support.type","float64"], + ["punctuation.operator",","], + ["text"," "], + ["identifier","k"], + ["text"," "], + ["support.type","float64"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["identifier","ch"], + ["text"," "], + ["keyword.operator","<-"], + ["text"," "], + ["constant.numeric","4"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "], + ["identifier","math"], + ["punctuation.operator","."], + ["identifier","Pow"], + ["paren.lparen","("], + ["constant.numeric","-1"], + ["punctuation.operator",","], + ["text"," "], + ["identifier","k"], + ["paren.rparen",")"], + ["text"," / "], + ["paren.lparen","("], + ["constant.numeric","2"], + ["keyword.operator","*"], + ["identifier","k"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","1"], + ["paren.rparen",")"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_groovy.json b/lib/ace/mode/_test/tokens_groovy.json new file mode 100644 index 00000000..c7dae6b1 --- /dev/null +++ b/lib/ace/mode/_test/tokens_groovy.json @@ -0,0 +1,410 @@ +[[ + "start", + ["comment","//http://groovy.codehaus.org/Martin+Fowler%27s+closure+examples+in+Groovy"] +],[ + "start" +],[ + "start", + ["keyword","class"], + ["text"," "], + ["identifier","Employee"], + ["text"," "], + ["lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","def"], + ["text"," "], + ["identifier","name"], + ["text",", "], + ["identifier","salary"] +],[ + "start", + ["text"," "], + ["keyword","boolean"], + ["text"," "], + ["identifier","manager"] +],[ + "start", + ["text"," "], + ["support.function","String"], + ["text"," "], + ["identifier","toString"], + ["lparen","("], + ["rparen",")"], + ["text"," "], + ["lparen","{"], + ["text"," "], + ["keyword","return"], + ["text"," "], + ["identifier","name"], + ["text"," "], + ["rparen","}"] +],[ + "start", + ["rparen","}"] +],[ + "start" +],[ + "start", + ["keyword","def"], + ["text"," "], + ["identifier","emps"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["lparen","["], + ["keyword","new"], + ["text"," "], + ["identifier","Employee"], + ["lparen","("], + ["identifier","name"], + ["text",":"], + ["string","'Guillaume'"], + ["text",", "], + ["identifier","manager"], + ["text",":"], + ["constant.language.boolean","true"], + ["text",", "], + ["identifier","salary"], + ["text",":"], + ["constant.numeric","200"], + ["rparen",")"], + ["text",","] +],[ + "start", + ["text"," "], + ["keyword","new"], + ["text"," "], + ["identifier","Employee"], + ["lparen","("], + ["identifier","name"], + ["text",":"], + ["string","'Graeme'"], + ["text",", "], + ["identifier","manager"], + ["text",":"], + ["constant.language.boolean","true"], + ["text",", "], + ["identifier","salary"], + ["text",":"], + ["constant.numeric","200"], + ["rparen",")"], + ["text",","] +],[ + "start", + ["text"," "], + ["keyword","new"], + ["text"," "], + ["identifier","Employee"], + ["lparen","("], + ["identifier","name"], + ["text",":"], + ["string","'Dierk'"], + ["text",", "], + ["identifier","manager"], + ["text",":"], + ["constant.language.boolean","false"], + ["text",", "], + ["identifier","salary"], + ["text",":"], + ["constant.numeric","151"], + ["rparen",")"], + ["text",","] +],[ + "start", + ["text"," "], + ["keyword","new"], + ["text"," "], + ["identifier","Employee"], + ["lparen","("], + ["identifier","name"], + ["text",":"], + ["string","'Bernd'"], + ["text",", "], + ["identifier","manager"], + ["text",":"], + ["constant.language.boolean","false"], + ["text",", "], + ["identifier","salary"], + ["text",":"], + ["constant.numeric","50"], + ["rparen",")]"] +],[ + "start" +],[ + "start", + ["keyword","def"], + ["text"," "], + ["identifier","managers"], + ["lparen","("], + ["identifier","emps"], + ["rparen",")"], + ["text"," "], + ["lparen","{"] +],[ + "start", + ["text"," "], + ["identifier","emps"], + ["text","."], + ["identifier","findAll"], + ["text"," "], + ["lparen","{"], + ["text"," "], + ["identifier","e"], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["identifier","e"], + ["text","."], + ["identifier","isManager"], + ["lparen","("], + ["rparen",")"], + ["text"," "], + ["rparen","}"] +],[ + "start", + ["rparen","}"] +],[ + "start" +],[ + "start", + ["keyword","assert"], + ["text"," "], + ["identifier","emps"], + ["lparen","["], + ["constant.numeric","0"], + ["text",".."], + ["constant.numeric","1"], + ["rparen","]"], + ["text"," "], + ["keyword.operator","=="], + ["text"," "], + ["identifier","managers"], + ["lparen","("], + ["identifier","emps"], + ["rparen",")"], + ["text"," "], + ["comment","// [Guillaume, Graeme]"] +],[ + "start" +],[ + "start", + ["keyword","def"], + ["text"," "], + ["identifier","highPaid"], + ["lparen","("], + ["identifier","emps"], + ["rparen",")"], + ["text"," "], + ["lparen","{"] +],[ + "start", + ["text"," "], + ["identifier","threshold"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","150"] +],[ + "start", + ["text"," "], + ["identifier","emps"], + ["text","."], + ["identifier","findAll"], + ["text"," "], + ["lparen","{"], + ["text"," "], + ["identifier","e"], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["identifier","e"], + ["text","."], + ["identifier","salary"], + ["text"," "], + ["keyword.operator",">"], + ["text"," "], + ["identifier","threshold"], + ["text"," "], + ["rparen","}"] +],[ + "start", + ["rparen","}"] +],[ + "start" +],[ + "start", + ["keyword","assert"], + ["text"," "], + ["identifier","emps"], + ["lparen","["], + ["constant.numeric","0"], + ["text",".."], + ["constant.numeric","2"], + ["rparen","]"], + ["text"," "], + ["keyword.operator","=="], + ["text"," "], + ["identifier","highPaid"], + ["lparen","("], + ["identifier","emps"], + ["rparen",")"], + ["text"," "], + ["comment","// [Guillaume, Graeme, Dierk]"] +],[ + "start" +],[ + "start", + ["keyword","def"], + ["text"," "], + ["identifier","paidMore"], + ["lparen","("], + ["identifier","amount"], + ["rparen",")"], + ["text"," "], + ["lparen","{"] +],[ + "start", + ["text"," "], + ["lparen","{"], + ["text"," "], + ["identifier","e"], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["identifier","e"], + ["text","."], + ["identifier","salary"], + ["text"," "], + ["keyword.operator",">"], + ["text"," "], + ["identifier","amount"], + ["rparen","}"] +],[ + "start", + ["rparen","}"] +],[ + "start", + ["keyword","def"], + ["text"," "], + ["identifier","highPaid"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","paidMore"], + ["lparen","("], + ["constant.numeric","150"], + ["rparen",")"] +],[ + "start" +],[ + "start", + ["keyword","assert"], + ["text"," "], + ["identifier","highPaid"], + ["lparen","("], + ["identifier","emps"], + ["lparen","["], + ["constant.numeric","0"], + ["rparen","])"], + ["text"," "], + ["comment","// true"] +],[ + "start", + ["keyword","assert"], + ["text"," "], + ["identifier","emps"], + ["lparen","["], + ["constant.numeric","0"], + ["text",".."], + ["constant.numeric","2"], + ["rparen","]"], + ["text"," "], + ["keyword.operator","=="], + ["text"," "], + ["identifier","emps"], + ["text","."], + ["identifier","findAll"], + ["lparen","("], + ["identifier","highPaid"], + ["rparen",")"] +],[ + "start" +],[ + "start", + ["keyword","def"], + ["text"," "], + ["identifier","filename"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string","'test.txt'"] +],[ + "start", + ["keyword","new"], + ["text"," "], + ["identifier","File"], + ["lparen","("], + ["identifier","filename"], + ["rparen",")"], + ["text","."], + ["identifier","withReader"], + ["lparen","{"], + ["text"," "], + ["identifier","reader"], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["identifier","doSomethingWith"], + ["lparen","("], + ["identifier","reader"], + ["rparen",")"], + ["text"," "], + ["rparen","}"] +],[ + "start" +],[ + "start", + ["keyword","def"], + ["text"," "], + ["identifier","readersText"] +],[ + "start", + ["keyword","def"], + ["text"," "], + ["identifier","doSomethingWith"], + ["lparen","("], + ["identifier","reader"], + ["rparen",")"], + ["text"," "], + ["lparen","{"], + ["text"," "], + ["identifier","readersText"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","reader"], + ["text","."], + ["identifier","text"], + ["text"," "], + ["rparen","}"] +],[ + "start" +],[ + "start", + ["keyword","assert"], + ["text"," "], + ["keyword","new"], + ["text"," "], + ["identifier","File"], + ["lparen","("], + ["identifier","filename"], + ["rparen",")"], + ["text","."], + ["identifier","text"], + ["text"," "], + ["keyword.operator","=="], + ["text"," "], + ["identifier","readersText"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_haml.json b/lib/ace/mode/_test/tokens_haml.json new file mode 100644 index 00000000..423c3bd5 --- /dev/null +++ b/lib/ace/mode/_test/tokens_haml.json @@ -0,0 +1,174 @@ +[[ + "start", + ["keyword.other.doctype","!!!5"] +],[ + "start" +],[ + "start", + ["punctuation.section.comment","# "] +],[ + "start", + ["punctuation.section.comment","# "] +],[ + "start", + ["punctuation.section.comment","# "] +],[ + "start", + ["punctuation.section.comment","# "] +],[ + "start" +],[ + "start" +],[ + "start", + ["punctuation.section.comment","/adasdasdad"] +],[ + "start", + ["entity.name.tag.haml","%div"], + ["punctuation.section","{"], + ["constant.other.symbol.ruby",":id"], + ["text"," => "], + ["string","\"#{@item.type}_#{@item.number}\""], + ["text",", "], + ["constant.other.symbol.ruby",":class"], + ["text"," => "], + ["string","'#{@item.type} #{@item.urgency}'"], + ["text",", "], + ["constant.other.symbol.ruby",":phoney"], + ["text"," => "], + ["string","`asdasdasd`"], + ["punctuation.section","}"] +],[ + "start", + ["punctuation.section.comment","/ file: app/views/movies/index.html.haml"] +],[ + "start", + ["meta.escape.haml","\\d"] +],[ + "start", + ["entity.name.tag.haml","%ads:"], + ["punctuation.section","{"], + ["constant.other.symbol.ruby",":bleh"], + ["text"," => "], + ["constant.numeric","33"], + ["punctuation.section","}"] +],[ + "embedded_ruby", + ["entity.name.tag.haml","%p"], + ["text","==ddd=="] +],[ + "start", + ["text"," Date/Time:"] +],[ + "embedded_ruby", + ["text"," - "], + ["identifier","now"], + ["text"," = "], + ["support.class","DateTime"], + ["text","."], + ["identifier","now"], + ["text"," "] +],[ + "start", + ["entity.name.tag.haml"," %strong"], + ["text","= now"] +],[ + "embedded_ruby", + ["text"," = "], + ["keyword","if"], + ["text"," "], + ["identifier","now"], + ["text"," "], + ["support.class","DateTime"], + ["text","."], + ["identifier","parse"], + ["text","(\""], + ["support.class","December"], + ["text"," "], + ["constant.numeric","31"], + ["text",", "], + ["constant.numeric","2006"], + ["text","\")"] +],[ + "embedded_ruby", + ["text"," = \""], + ["support.class","Happy"], + ["text"," "], + ["identifier","new"], + ["text"," \" + \""], + ["identifier","year"], + ["text","!\""] +],[ + "start", + ["entity.name.tag.haml","%sfd"], + ["entity.other.attribute-name.class.haml",".dfdfg"] +],[ + "start", + ["punctuation.section.comment","#content"] +],[ + "start", + ["text"," .title"] +],[ + "start", + ["entity.name.tag.haml"," %h1"], + ["text","= @title"] +],[ + "embedded_ruby", + ["text"," = "], + ["support.function","link_to"], + ["text"," '"], + ["support.class","Home"], + ["text","', "], + ["identifier","home_url"] +],[ + "start" +],[ + "start", + ["punctuation.section.comment"," #contents"] +],[ + "start", + ["entity.name.tag.haml","%div"], + ["entity.other.attribute-name.id.haml","#content"] +],[ + "start", + ["entity.name.tag.haml"," %div"], + ["entity.other.attribute-name.class.haml",".articles"] +],[ + "start", + ["entity.name.tag.haml"," %div"], + ["entity.other.attribute-name.class.haml",".article.title"], + ["text"," Blah"] +],[ + "start", + ["entity.name.tag.haml"," %div"], + ["entity.other.attribute-name.class.haml",".article.date"], + ["text"," "], + ["constant.numeric","2006-11-05"] +],[ + "start", + ["entity.name.tag.haml"," %div"], + ["entity.other.attribute-name.class.haml",".article.entry"] +],[ + "start", + ["text"," Neil Patrick Harris "] +],[ + "start" +],[ + "start", + ["entity.name.tag.haml","%div"], + ["text","[@user, "], + ["constant.other.symbol.ruby",":greeting"], + ["text","]"] +],[ + "start", + ["entity.name.tag.haml"," %bar"], + ["text","["], + ["constant.numeric","290"], + ["text","]/"] +],[ + "start", + ["text"," "], + ["string.quoted.double","==Hello!=="] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_handlebars.json b/lib/ace/mode/_test/tokens_handlebars.json new file mode 100644 index 00000000..1ec79139 --- /dev/null +++ b/lib/ace/mode/_test/tokens_handlebars.json @@ -0,0 +1,81 @@ +[[ + "start", + ["comment.start","{{!--"], + ["comment"," Ace + :-}} "], + ["comment.end","--}}"] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","div"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"comments\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["storage.type.start","{{#"], + ["variable.parameter","each"], + ["text"," "], + ["variable.parameter","comments"], + ["storage.type.end","}}"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","h2"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.anchor.tag-name.xml","a"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"/posts/"], + ["storage.type.start","{{"], + ["text","../"], + ["variable.parameter","permalink"], + ["storage.type.end","}}"], + ["string.attribute-value.xml","#"], + ["storage.type.start","{{"], + ["variable.parameter","id"], + ["storage.type.end","}}"], + ["string.attribute-value.xml","\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["storage.type.start","{{"], + ["variable.parameter","title"], + ["storage.type.end","}}"], + ["meta.tag.punctuation.end-tag-open.xml",""], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","div"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["support.function","{{{"], + ["variable.parameter","body"], + ["support.function","}}}"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["storage.type.start","{{/"], + ["variable.parameter","each"], + ["storage.type.end","}}"] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_haskell.json b/lib/ace/mode/_test/tokens_haskell.json new file mode 100644 index 00000000..8f9a2b38 --- /dev/null +++ b/lib/ace/mode/_test/tokens_haskell.json @@ -0,0 +1,156 @@ +[[ + "start", + ["punctuation.definition.comment.haskell","-- Type annotation (optional)"] +],[ + "start", + ["entity.name.function.haskell","fib"], + ["meta.function.type-declaration.haskell"," "], + ["keyword.other.double-colon.haskell","::"], + ["meta.function.type-declaration.haskell"," "], + ["support.type.prelude.haskell","Int"], + ["meta.function.type-declaration.haskell"," "], + ["keyword.other.arrow.haskell","->"], + ["meta.function.type-declaration.haskell"," "], + ["support.type.prelude.haskell","Integer"] +],[ + "start", + ["text"," "] +],[ + "start", + ["punctuation.definition.comment.haskell","-- With self-referencing data"] +],[ + "start", + ["text","fib n "], + ["keyword.operator.haskell","="], + ["text"," fibs "], + ["keyword.operator.haskell","!!"], + ["text"," n"] +],[ + "start", + ["text"," "], + ["keyword.other.haskell","where"], + ["text"," fibs "], + ["keyword.operator.haskell","="], + ["text"," "], + ["constant.numeric.haskell","0"], + ["text"," "], + ["keyword.operator.haskell",":"], + ["text"," "], + ["support.function.prelude.haskell","scanl"], + ["text"," "], + ["entity.name.function.infix.haskell","(+)"], + ["text"," "], + ["constant.numeric.haskell","1"], + ["text"," fibs"] +],[ + "start", + ["text"," "], + ["punctuation.definition.comment.haskell","-- 0,1,1,2,3,5,..."] +],[ + "start", + ["text"," "] +],[ + "start", + ["punctuation.definition.comment.haskell","-- Same, coded directly"] +],[ + "start", + ["text","fib n "], + ["keyword.operator.haskell","="], + ["text"," fibs "], + ["keyword.operator.haskell","!!"], + ["text"," n"] +],[ + "start", + ["text"," "], + ["keyword.other.haskell","where"], + ["text"," fibs "], + ["keyword.operator.haskell","="], + ["text"," "], + ["constant.numeric.haskell","0"], + ["text"," "], + ["keyword.operator.haskell",":"], + ["text"," "], + ["constant.numeric.haskell","1"], + ["text"," "], + ["keyword.operator.haskell",":"], + ["text"," next fibs"] +],[ + "start", + ["text"," next (a "], + ["keyword.operator.haskell",":"], + ["text"," t@(b"], + ["keyword.operator.haskell",":"], + ["text","_)) "], + ["keyword.operator.haskell","="], + ["text"," (a"], + ["keyword.operator.haskell","+"], + ["text","b) "], + ["keyword.operator.haskell",":"], + ["text"," next t"] +],[ + "start", + ["text"," "] +],[ + "start", + ["punctuation.definition.comment.haskell","-- Similar idea, using zipWith"] +],[ + "start", + ["text","fib n "], + ["keyword.operator.haskell","="], + ["text"," fibs "], + ["keyword.operator.haskell","!!"], + ["text"," n"] +],[ + "start", + ["text"," "], + ["keyword.other.haskell","where"], + ["text"," fibs "], + ["keyword.operator.haskell","="], + ["text"," "], + ["constant.numeric.haskell","0"], + ["text"," "], + ["keyword.operator.haskell",":"], + ["text"," "], + ["constant.numeric.haskell","1"], + ["text"," "], + ["keyword.operator.haskell",":"], + ["text"," "], + ["support.function.prelude.haskell","zipWith"], + ["text"," "], + ["entity.name.function.infix.haskell","(+)"], + ["text"," fibs ("], + ["support.function.prelude.haskell","tail"], + ["text"," fibs)"] +],[ + "start", + ["text"," "] +],[ + "start", + ["punctuation.definition.comment.haskell","-- Using a generator function"] +],[ + "start", + ["text","fib n "], + ["keyword.operator.haskell","="], + ["text"," fibs ("], + ["constant.numeric.haskell","0"], + ["punctuation.separator.comma.haskell",","], + ["constant.numeric.haskell","1"], + ["text",") "], + ["keyword.operator.haskell","!!"], + ["text"," n"] +],[ + "start", + ["text"," "], + ["keyword.other.haskell","where"], + ["text"," fibs (a"], + ["punctuation.separator.comma.haskell",","], + ["text","b) "], + ["keyword.operator.haskell","="], + ["text"," a "], + ["keyword.operator.haskell",":"], + ["text"," fibs (b"], + ["punctuation.separator.comma.haskell",","], + ["text","a"], + ["keyword.operator.haskell","+"], + ["text","b)"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_haxe.json b/lib/ace/mode/_test/tokens_haxe.json new file mode 100644 index 00000000..f0f79a48 --- /dev/null +++ b/lib/ace/mode/_test/tokens_haxe.json @@ -0,0 +1,143 @@ +[[ + "start", + ["keyword","class"], + ["text"," "], + ["identifier","Haxe"], + ["text"," "] +],[ + "start", + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","public"], + ["text"," "], + ["keyword","static"], + ["text"," "], + ["keyword","function"], + ["text"," "], + ["identifier","main"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "] +],[ + "start", + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["comment","// Say Hello!"] +],[ + "start", + ["text"," "], + ["keyword","var"], + ["text"," "], + ["identifier","greeting"], + ["punctuation.operator",":"], + ["keyword","String"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string","\"Hello World\""], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword","trace"], + ["paren.lparen","("], + ["identifier","greeting"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["keyword","var"], + ["text"," "], + ["identifier","targets"], + ["punctuation.operator",":"], + ["keyword","Array"], + ["keyword.operator","<"], + ["keyword","String"], + ["keyword.operator",">"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","["], + ["string","\"Flash\""], + ["punctuation.operator",","], + ["string","\"Javascript\""], + ["punctuation.operator",","], + ["string","\"PHP\""], + ["punctuation.operator",","], + ["string","\"Neko\""], + ["punctuation.operator",","], + ["string","\"C++\""], + ["punctuation.operator",","], + ["string","\"iOS\""], + ["punctuation.operator",","], + ["string","\"Android\""], + ["punctuation.operator",","], + ["string","\"webOS\""], + ["paren.rparen","]"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword","trace"], + ["paren.lparen","("], + ["string","\"Haxe is a great language that can target:\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword","for"], + ["text"," "], + ["paren.lparen","("], + ["identifier","target"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["identifier","targets"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","trace"], + ["text"," "], + ["paren.lparen","("], + ["string","\" - \""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["identifier","target"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["keyword","trace"], + ["paren.lparen","("], + ["string","\"And many more!\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_html.json b/lib/ace/mode/_test/tokens_html.json new file mode 100644 index 00000000..c5f75eff --- /dev/null +++ b/lib/ace/mode/_test/tokens_html.json @@ -0,0 +1,63 @@ +[[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","html"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","scripts"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.script.tag-name.xml","script"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","a"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","'a'"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["storage.type","var"], + ["text"," "], + ["string","\""], + ["meta.tag.punctuation.end-tag-open.xml",""], + ["text.xml","'123'"] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + ["string.attribute-value.xml0","tag_stuff"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.anchor.tag-name.xml","a"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"abc"] +],[ + "start", + ["string.attribute-value.xml"," def\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + ["string.attribute-value.xml","tag_stuff"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.anchor.tag-name.xml","a"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","'abc"] +],[ + "start", + ["string.attribute-value.xml","def\\'"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_html_ruby.json b/lib/ace/mode/_test/tokens_html_ruby.json new file mode 100644 index 00000000..8ff5f6ea --- /dev/null +++ b/lib/ace/mode/_test/tokens_html_ruby.json @@ -0,0 +1,257 @@ +[[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","h1"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Listing Books"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","table"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","tr"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","th"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Title"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","th"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Summary"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","th"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","th"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","th"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["support.ruby_tag","<%"], + ["text"," "], + ["variable.instance","@books"], + ["text","."], + ["identifier","each"], + ["text"," "], + ["keyword","do"], + ["text"," |"], + ["identifier","book"], + ["text","| "], + ["support.ruby_tag","%>"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","tr"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["comment.start.erb","<%#"], + ["comment"," comment "], + ["comment.end.erb","%>"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","td"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["support.ruby_tag","<%="], + ["text"," "], + ["identifier","book"], + ["text","."], + ["identifier","title"], + ["text"," "], + ["support.ruby_tag","%>"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","td"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["support.ruby_tag","<%="], + ["text"," "], + ["identifier","book"], + ["text","."], + ["identifier","content"], + ["text"," "], + ["support.ruby_tag","%>"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","td"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["support.ruby_tag","<%="], + ["text"," "], + ["support.function","link_to"], + ["text"," "], + ["string.start","'"], + ["string","Show"], + ["string.end","'"], + ["text",", "], + ["identifier","book"], + ["text"," "], + ["support.ruby_tag","%>"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","td"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["support.ruby_tag","<%="], + ["text"," "], + ["support.function","link_to"], + ["text"," "], + ["string.start","'"], + ["string","Edit"], + ["string.end","'"], + ["text",", "], + ["identifier","edit_book_path"], + ["paren.lparen","("], + ["identifier","book"], + ["paren.rparen",")"], + ["text"," "], + ["support.ruby_tag","%>"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","td"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["support.ruby_tag","<%="], + ["text"," "], + ["support.function","link_to"], + ["text"," "], + ["string.start","'"], + ["string","Remove"], + ["string.end","'"], + ["text",", "], + ["identifier","book"], + ["text",", "], + ["constant.other.symbol.ruby",":confirm"], + ["text"," "], + ["punctuation.separator.key-value","=>"], + ["text"," "], + ["string.start","'"], + ["string","Are you sure?"], + ["string.end","'"], + ["text",", "], + ["constant.other.symbol.ruby",":method"], + ["text"," "], + ["punctuation.separator.key-value","=>"], + ["text"," "], + ["constant.other.symbol.ruby",":delete"], + ["text"," "], + ["support.ruby_tag","%>"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["support.ruby_tag","<%"], + ["text"," "], + ["keyword","end"], + ["text"," "], + ["support.ruby_tag","%>"] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","br"], + ["text.tag-whitespace.xml"," "], + ["meta.tag.punctuation.tag-close.xml","/>"] +],[ + "start", + ["text.xml"," "] +],[ + "start", + ["support.ruby_tag","<%="], + ["text"," "], + ["support.function","link_to"], + ["text"," "], + ["string.start","'"], + ["string","New book"], + ["string.end","'"], + ["text",", "], + ["identifier","new_book_path"], + ["text"," "], + ["support.ruby_tag","%>"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_ini.json b/lib/ace/mode/_test/tokens_ini.json new file mode 100644 index 00000000..11d28017 --- /dev/null +++ b/lib/ace/mode/_test/tokens_ini.json @@ -0,0 +1,23 @@ +[[ + "start", + ["punctuation.definition.entity.ini","["], + ["constant.section.group-title.ini",".ShellClassInfo"], + ["punctuation.definition.entity.ini","]"] +],[ + "start", + ["keyword.other.definition.ini","IconResource"], + ["punctuation.separator.key-value.ini","="], + ["text","..\\logo.png"] +],[ + "start", + ["punctuation.definition.entity.ini","["], + ["constant.section.group-title.ini","ViewState"], + ["punctuation.definition.entity.ini","]"] +],[ + "start", + ["keyword.other.definition.ini","FolderType"], + ["punctuation.separator.key-value.ini","="], + ["text","Generic"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_io.json b/lib/ace/mode/_test/tokens_io.json new file mode 100644 index 00000000..b83a675a --- /dev/null +++ b/lib/ace/mode/_test/tokens_io.json @@ -0,0 +1,49 @@ +[[ + "start", + ["punctuation.definition.comment.io","//"], + ["comment.line.double-slash.io"," computes factorial of a number"] +],[ + "start", + ["text","factorial "], + ["keyword.operator.io",":="], + ["text"," "], + ["support.function.io","method"], + ["text","(n,"] +],[ + "start", + ["text"," "], + ["keyword.control.io","if"], + ["text","(n "], + ["keyword.operator.io","=="], + ["text"," "], + ["constant.numeric.io","0"], + ["text",", "], + ["keyword.control.io","return"], + ["text"," "], + ["constant.numeric.io","1"], + ["text",")"] +],[ + "start", + ["text"," res "], + ["keyword.operator.io",":="], + ["text"," "], + ["constant.numeric.io","1"] +],[ + "start", + ["text"," "], + ["support.class.io","Range"], + ["text"," "], + ["constant.numeric.io","1"], + ["text"," "], + ["support.function.io","to"], + ["text","(n) "], + ["keyword.control.io","foreach"], + ["text","(i, res "], + ["keyword.operator.io","="], + ["text"," res "], + ["keyword.operator.io","*"], + ["text"," i)"] +],[ + "start", + ["text",")"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_jack.json b/lib/ace/mode/_test/tokens_jack.json new file mode 100644 index 00000000..c3d694dd --- /dev/null +++ b/lib/ace/mode/_test/tokens_jack.json @@ -0,0 +1,1786 @@ +[[ + "start", + ["keyword","vars"], + ["text"," "], + ["variable","it"], + ["text",", "], + ["variable","p"] +],[ + "start" +],[ + "start", + ["variable","p"], + ["text"," = "], + ["paren.lparen","{"], + ["variable","label"], + ["text",", "], + ["variable","value"], + ["text","|"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["string","\""], + ["constant.language.escape","\\n"], + ["string","\""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["variable","label"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["language.builtin","inspect"], + ["paren.lparen","("], + ["variable","value"], + ["paren.rparen","))"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start", + ["comment","-- Create an array from 0 to 15"] +],[ + "start", + ["variable","p"], + ["paren.lparen","("], + ["string","\"range\""], + ["text",", "], + ["language.builtin","i-collect"], + ["paren.lparen","("], + ["language.builtin","range"], + ["paren.lparen","("], + ["constant.numeric","5"], + ["paren.rparen",")))"] +],[ + "start" +],[ + "start", + ["comment","-- Create an array from 0 to 15 and break up in chunks of 4"] +],[ + "start", + ["variable","p"], + ["paren.lparen","("], + ["string","\"chunked range\""], + ["text",", "], + ["language.builtin","i-collect"], + ["paren.lparen","("], + ["language.builtin","i-chunk"], + ["paren.lparen","("], + ["constant.numeric","4"], + ["text",", "], + ["language.builtin","range"], + ["paren.lparen","("], + ["constant.numeric","16"], + ["paren.rparen","))))"] +],[ + "start" +],[ + "start", + ["comment","-- Check if all or none items in stream pass test."] +],[ + "start", + ["variable","p"], + ["paren.lparen","("], + ["string","\"all < 60 in range(60)\""], + ["text",", "], + ["variable","i-all?"], + ["paren.lparen","({"], + ["variable","i"], + ["text","|"], + ["variable","i"], + ["keyword.operator","<"], + ["constant.numeric","60"], + ["paren.rparen","}"], + ["text",", "], + ["language.builtin","range"], + ["paren.lparen","("], + ["constant.numeric","60"], + ["paren.rparen",")))"] +],[ + "start", + ["variable","p"], + ["paren.lparen","("], + ["string","\"any < 60 in range(60)\""], + ["text",", "], + ["variable","i-any?"], + ["paren.lparen","({"], + ["variable","i"], + ["text","|"], + ["variable","i"], + ["keyword.operator",">"], + ["constant.numeric","60"], + ["paren.rparen","}"], + ["text",", "], + ["language.builtin","range"], + ["paren.lparen","("], + ["constant.numeric","60"], + ["paren.rparen",")))"] +],[ + "start", + ["variable","p"], + ["paren.lparen","("], + ["string","\"all < 60 in range(70)\""], + ["text",", "], + ["variable","i-all?"], + ["paren.lparen","({"], + ["variable","i"], + ["text","|"], + ["variable","i"], + ["keyword.operator","<"], + ["constant.numeric","60"], + ["paren.rparen","}"], + ["text",", "], + ["language.builtin","range"], + ["paren.lparen","("], + ["constant.numeric","70"], + ["paren.rparen",")))"] +],[ + "start", + ["variable","p"], + ["paren.lparen","("], + ["string","\"any < 60 in range(70)\""], + ["text",", "], + ["variable","i-any?"], + ["paren.lparen","({"], + ["variable","i"], + ["text","|"], + ["variable","i"], + ["keyword.operator",">"], + ["constant.numeric","60"], + ["paren.rparen","}"], + ["text",", "], + ["language.builtin","range"], + ["paren.lparen","("], + ["constant.numeric","70"], + ["paren.rparen",")))"] +],[ + "start" +],[ + "start", + ["comment","-- Zip three different collections together"] +],[ + "start", + ["variable","p"], + ["paren.lparen","("], + ["string","\"zipped\""], + ["text",", "], + ["language.builtin","i-collect"], + ["paren.lparen","("], + ["language.builtin","i-zip"], + ["paren.lparen","("] +],[ + "start", + ["text"," "], + ["language.builtin","range"], + ["paren.lparen","("], + ["constant.numeric","10"], + ["paren.rparen",")"], + ["text",","] +],[ + "start", + ["text"," "], + ["paren.lparen","["], + ["constant.numeric","1"], + ["text",","], + ["constant.numeric","2"], + ["text",","], + ["constant.numeric","3"], + ["text",","], + ["constant.numeric","4"], + ["text",","], + ["constant.numeric","5"], + ["paren.rparen","]"], + ["text",","] +],[ + "start", + ["text"," "], + ["language.builtin","i-map"], + ["paren.lparen","({"], + ["variable","i"], + ["text","|"], + ["variable","i"], + ["keyword.operator","*"], + ["variable","i"], + ["paren.rparen","}"], + ["text",", "], + ["language.builtin","range"], + ["paren.lparen","("], + ["constant.numeric","10"], + ["paren.rparen","))"] +],[ + "start", + ["paren.rparen",")))"] +],[ + "start" +],[ + "start", + ["keyword","vars"], + ["text"," "], + ["variable","names"], + ["text",", "], + ["variable","person"], + ["text",", "], + ["variable","i"], + ["text",", "], + ["variable","doubles"], + ["text",", "], + ["variable","lengths"], + ["text",", "], + ["variable","cubeRange"] +],[ + "start", + ["variable","names"], + ["text"," = "], + ["paren.lparen","["], + ["string","\"Thorin\""], + ["text",", "], + ["string","\"Dwalin\""], + ["text",", "], + ["string","\"Balin\""], + ["text",", "], + ["string","\"Bifur\""], + ["text",", "], + ["string","\"Bofur\""], + ["text",", "], + ["string","\"Bombur\""], + ["text",", "], + ["string","\"Oin\""], + ["text",","] +],[ + "start", + ["text"," "], + ["string","\"Gloin\""], + ["text",", "], + ["string","\"Ori\""], + ["text",", "], + ["string","\"Nori\""], + ["text",", "], + ["string","\"Dori\""], + ["text",", "], + ["string","\"Fili\""], + ["text",", "], + ["string","\"Kili\""], + ["text",", "], + ["string","\"Bilbo\""], + ["text",", "], + ["string","\"Gandalf\""], + ["paren.rparen","]"] +],[ + "start" +],[ + "start", + ["keyword","for"], + ["text"," "], + ["variable","name"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["variable","names"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","name"], + ["text"," "], + ["keyword.operator","!="], + ["text"," "], + ["string","\"Bilbo\""], + ["text"," "], + ["keyword.operator","&&"], + ["text"," "], + ["variable","name"], + ["text"," "], + ["keyword.operator","!="], + ["text"," "], + ["string","\"Gandalf\""], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["variable","name"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["variable","person"], + ["text"," = "], + ["paren.lparen","{"], + ["variable","name"], + ["text",": "], + ["string","\"Tim\""], + ["text",", "], + ["variable","age"], + ["text",": "], + ["constant.numeric","30"], + ["paren.rparen","}"] +],[ + "start", + ["keyword","for"], + ["text"," "], + ["variable","key"], + ["text",", "], + ["variable","value"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["variable","person"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["variable","key"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","\" = \""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["variable","value"], + ["paren.rparen",")"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["variable","i"], + ["text"," = "], + ["constant.numeric","0"] +],[ + "start", + ["keyword","while"], + ["text"," "], + ["variable","i"], + ["text"," "], + ["keyword.operator","<"], + ["text"," "], + ["constant.numeric","10"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","i"], + ["text"," = "], + ["variable","i"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","1"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["variable","i"], + ["paren.rparen",")"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["language.builtin","print"], + ["paren.lparen","("], + ["string","\"range\""], + ["paren.rparen",")"] +],[ + "start", + ["keyword","for"], + ["text"," "], + ["variable","i"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["language.builtin","range"], + ["paren.lparen","("], + ["constant.numeric","10"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["variable","i"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","1"], + ["paren.rparen",")"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start", + ["keyword","for"], + ["text"," "], + ["variable","i"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["language.builtin","range"], + ["paren.lparen","("], + ["constant.numeric","10"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["constant.numeric","10"], + ["text"," "], + ["keyword.operator","-"], + ["text"," "], + ["variable","i"], + ["paren.rparen",")"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["comment","-- Dynamic object that gives the first 10 doubles"] +],[ + "start", + ["variable","doubles"], + ["text"," = "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["storage.form","@len"], + ["text",": "], + ["paren.lparen","{"], + ["text","| "], + ["constant.numeric","10"], + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["storage.form","@get"], + ["text",": "], + ["paren.lparen","{"], + ["variable","key"], + ["text","|"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","key"], + ["text"," "], + ["keyword","is"], + ["text"," "], + ["storage.type","Integer"], + ["text"," "], + ["paren.lparen","{"], + ["text"," "], + ["variable","key"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "], + ["variable","key"], + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start", + ["language.builtin","print"], + ["paren.lparen","("], + ["string","\"#doubles\""], + ["text",", "], + ["keyword.operator","#"], + ["variable","doubles"], + ["paren.rparen",")"] +],[ + "start" +],[ + "start", + ["language.builtin","print"], + ["paren.lparen","("], + ["string","\"Doubles\""], + ["paren.rparen",")"] +],[ + "start", + ["keyword","for"], + ["text"," "], + ["variable","k"], + ["text",", "], + ["variable","v"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["variable","doubles"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","(["], + ["variable","k"], + ["text",", "], + ["variable","v"], + ["paren.rparen","])"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["comment","-- Dynamic object that has names list as keys and string lenth as values"] +],[ + "start", + ["variable","lengths"], + ["text"," = "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["storage.form","@keys"], + ["text",": "], + ["paren.lparen","{"], + ["text","| "], + ["variable","names"], + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["storage.form","@get"], + ["text",": "], + ["paren.lparen","{"], + ["variable","key"], + ["text","|"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","key"], + ["text"," "], + ["keyword","is"], + ["text"," "], + ["storage.type","String"], + ["text"," "], + ["paren.lparen","{"], + ["text"," "], + ["keyword.operator","#"], + ["variable","key"], + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["language.builtin","print"], + ["text"," "], + ["paren.lparen","("], + ["string","\"Lengths\""], + ["paren.rparen",")"] +],[ + "start", + ["keyword","for"], + ["text"," "], + ["variable","k"], + ["text",", "], + ["variable","v"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["variable","lengths"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","(["], + ["variable","k"], + ["text",", "], + ["variable","v"], + ["paren.rparen","])"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start" +],[ + "start", + ["variable","cubeRange"], + ["text"," = "], + ["paren.lparen","{"], + ["variable","n"], + ["text","|"] +],[ + "start", + ["text"," "], + ["keyword","vars"], + ["text"," "], + ["variable","i"], + ["text",", "], + ["variable","v"] +],[ + "start", + ["text"," "], + ["variable","i"], + ["text"," = "], + ["constant.numeric","0"] +],[ + "start", + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["storage.form","@call"], + ["text",": "], + ["paren.lparen","{"], + ["text","|"] +],[ + "start", + ["text"," "], + ["variable","v"], + ["text"," = "], + ["variable","i"] +],[ + "start", + ["text"," "], + ["variable","i"], + ["text"," = "], + ["variable","i"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","1"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","v"], + ["text"," "], + ["keyword.operator","<"], + ["text"," "], + ["variable","n"], + ["text"," "], + ["paren.lparen","{"], + ["text"," "], + ["variable","v"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "], + ["variable","v"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "], + ["variable","v"], + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["language.builtin","print"], + ["paren.lparen","("], + ["string","\"Cubes\""], + ["paren.rparen",")"] +],[ + "start", + ["keyword","for"], + ["text"," "], + ["variable","k"], + ["text",", "], + ["variable","v"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["variable","cubeRange"], + ["paren.lparen","("], + ["constant.numeric","5"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","(["], + ["variable","k"], + ["text",", "], + ["variable","v"], + ["paren.rparen","])"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start", + ["language.builtin","print"], + ["paren.lparen","("], + ["string","\"String\""], + ["paren.rparen",")"] +],[ + "start", + ["keyword","for"], + ["text"," "], + ["variable","k"], + ["text",", "], + ["variable","v"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["string","\"Hello World\""], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","(["], + ["variable","k"], + ["text",", "], + ["variable","v"], + ["paren.rparen","])"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start" +],[ + "start", + ["language.builtin","print"], + ["paren.lparen","(["], + ["variable","i"], + ["text"," "], + ["keyword","for"], + ["text"," "], + ["variable","i"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["language.builtin","range"], + ["paren.lparen","("], + ["constant.numeric","10"], + ["paren.rparen",")])"] +],[ + "start", + ["language.builtin","print"], + ["paren.lparen","(["], + ["variable","i"], + ["text"," "], + ["keyword","for"], + ["text"," "], + ["variable","i"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["language.builtin","range"], + ["paren.lparen","("], + ["constant.numeric","20"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","i"], + ["text"," "], + ["keyword.operator","%"], + ["text"," "], + ["constant.numeric","3"], + ["paren.rparen","])"] +],[ + "start" +],[ + "start" +],[ + "start" +],[ + "start", + ["comment","-- Example showing how to do parallel work using split..and"] +],[ + "start", + ["variable","base"], + ["text"," = "], + ["paren.lparen","{"], + ["variable","bootstrap"], + ["text",", "], + ["variable","target-dir"], + ["text","|"] +],[ + "start", + ["text"," "], + ["keyword","split"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","copy"], + ["paren.lparen","("], + ["string","\"res\""], + ["text",", "], + ["variable","target-dir"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"], + ["text"," "], + ["keyword","and"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","newer"], + ["paren.lparen","("], + ["string","\"src/*.less\""], + ["text",", "], + ["variable","target-dir"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","\"/style.css\""], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","lessc"], + ["paren.lparen","("], + ["string","\"src/\""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["variable","bootstrap"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","\".less\""], + ["text",", "], + ["variable","target-dir"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","\"/style.css\""], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"], + ["text"," "], + ["keyword","and"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","build"], + ["paren.lparen","("], + ["string","\"src/\""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["variable","bootstrap"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","\".js\""], + ["text",", "], + ["variable","target-dir"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","\"/app.js\""], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start" +],[ + "start", + ["keyword","vars"], + ["text"," "], + ["variable","Dragon"], + ["text",", "], + ["variable","pet"] +],[ + "start" +],[ + "start", + ["variable","Dragon"], + ["text"," = "], + ["paren.lparen","{"], + ["variable","name"], + ["text","|"] +],[ + "start", + ["text"," "], + ["keyword","vars"], + ["text"," "], + ["variable","asleep"], + ["text",", "], + ["variable","stuff-in-belly"], + ["text",", "], + ["variable","stuff-in-intestine"], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","feed"], + ["text",", "], + ["variable","walk"], + ["text",", "], + ["variable","put-to-bed"], + ["text",", "], + ["variable","toss"], + ["text",", "], + ["variable","rock"], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","hungry?"], + ["text",", "], + ["variable","poopy?"], + ["text",", "], + ["variable","passage-of-time"] +],[ + "start" +],[ + "start", + ["text"," "], + ["variable","asleep"], + ["text"," = "], + ["constant.language.boolean","false"] +],[ + "start", + ["text"," "], + ["variable","stuff-in-belly"], + ["text"," = "], + ["constant.numeric","10"], + ["text"," "], + ["comment","-- He's full."] +],[ + "start", + ["text"," "], + ["variable","stuff-in-intestine"], + ["text"," = "], + ["constant.numeric","0"], + ["text"," "], + ["comment","-- He doesn't need to go."] +],[ + "start" +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["variable","name"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","' is born.'"], + ["paren.rparen",")"] +],[ + "start" +],[ + "start", + ["text"," "], + ["variable","feed"], + ["text"," = "], + ["paren.lparen","{"], + ["text","|"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["string","'You feed '"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["variable","name"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","'.'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["variable","stuff-in-belly"], + ["text"," = "], + ["constant.numeric","10"] +],[ + "start", + ["text"," "], + ["variable","passage-of-time"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["variable","walk"], + ["text"," = "], + ["paren.lparen","{"], + ["text","|"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["string","'You walk '"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["variable","name"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","\".\""], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["variable","stuff-in-intestine"], + ["text"," = "], + ["constant.numeric","0"] +],[ + "start", + ["text"," "], + ["variable","passage-of-time"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["variable","put-to-bed"], + ["text"," = "], + ["paren.lparen","{"], + ["text","|"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["string","'You put '"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["variable","name"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","' to bed.'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["variable","asleep"], + ["text"," = "], + ["constant.language.boolean","true"] +],[ + "start", + ["text"," "], + ["keyword","for"], + ["text"," "], + ["variable","i"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["language.builtin","range"], + ["paren.lparen","("], + ["constant.numeric","3"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","asleep"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","passage-of-time"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","asleep"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["variable","name"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","' snores, filling the room with smoke.'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","asleep"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","asleep"], + ["text"," = "], + ["constant.language.boolean","false"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["variable","name"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","' wakes up slowly.'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["variable","toss"], + ["text"," = "], + ["paren.lparen","{"], + ["text","|"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["string","'You toss '"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["variable","name"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","' up into the air.'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["string","'He giggles, which singes your eyebrows.'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["variable","passage-of-time"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["variable","rock"], + ["text"," = "], + ["paren.lparen","{"], + ["text","|"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["string","'You rock '"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["variable","name"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","' gently.'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["variable","asleep"], + ["text"," = "], + ["constant.language.boolean","true"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["string","'He briefly dozes off...'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["variable","passage-of-time"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","asleep"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","asleep"], + ["text"," = "], + ["constant.language.boolean","false"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["string","'...but wakes when you stop.'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["variable","hungry?"], + ["text"," = "], + ["paren.lparen","{"], + ["text","|"] +],[ + "start", + ["text"," "], + ["variable","stuff-in-belly"], + ["text"," "], + ["keyword.operator","<="], + ["text"," "], + ["constant.numeric","2"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["variable","poopy?"], + ["text"," = "], + ["paren.lparen","{"], + ["text","|"] +],[ + "start", + ["text"," "], + ["variable","stuff-in-intestine"], + ["text"," "], + ["keyword.operator",">="], + ["text"," "], + ["constant.numeric","8"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["variable","passage-of-time"], + ["text"," = "], + ["paren.lparen","{"], + ["text","|"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","stuff-in-belly"], + ["text"," "], + ["keyword.operator",">"], + ["text"," "], + ["constant.numeric","0"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["comment","-- Move food from belly to intestine"] +],[ + "start", + ["text"," "], + ["variable","stuff-in-belly"], + ["text"," = "], + ["variable","stuff-in-belly"], + ["text"," "], + ["keyword.operator","-"], + ["text"," "], + ["constant.numeric","1"] +],[ + "start", + ["text"," "], + ["variable","stuff-in-intestine"], + ["text"," = "], + ["variable","stuff-in-intestine"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","1"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"], + ["text"," "], + ["keyword","else"], + ["text"," "], + ["paren.lparen","{"], + ["text"," "], + ["comment","-- Our dragon is starving!"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","asleep"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","asleep"], + ["text"," = "], + ["constant.language.boolean","false"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["string","'He wakes up suddenly!'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["variable","name"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","' is starving! In desperation, he ate YOU!'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["keyword","abort"], + ["text"," "], + ["string","\"died\""] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","stuff-in-intestine"], + ["text"," "], + ["keyword.operator",">="], + ["text"," "], + ["constant.numeric","10"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","stuff-in-intestine"], + ["text"," = "], + ["constant.numeric","0"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["string","'Whoops! '"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["variable","name"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","' had an accident...'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","hungry?"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","asleep"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","asleep"], + ["text"," = "], + ["constant.language.boolean","false"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["string","'He wakes up suddenly!'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["variable","name"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","\"'s stomach grumbles...\""], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","poopy?"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","asleep"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","asleep"], + ["text"," = "], + ["constant.language.boolean","false"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["string","'He wakes up suddenly!'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["language.builtin","print"], + ["paren.lparen","("], + ["variable","name"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","' does the potty dance...'"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["comment","-- Export the public interface to this closure object."] +],[ + "start", + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","feed"], + ["text",": "], + ["variable","feed"] +],[ + "start", + ["text"," "], + ["variable","walk"], + ["text",": "], + ["variable","walk"] +],[ + "start", + ["text"," "], + ["variable","put-to-bed"], + ["text",": "], + ["variable","put-to-bed"] +],[ + "start", + ["text"," "], + ["variable","toss"], + ["text",": "], + ["variable","toss"] +],[ + "start", + ["text"," "], + ["variable","rock"], + ["text",": "], + ["variable","rock"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["variable","pet"], + ["text"," = "], + ["variable","Dragon"], + ["paren.lparen","("], + ["string","'Norbert'"], + ["paren.rparen",")"] +],[ + "start", + ["variable","pet"], + ["text","."], + ["variable","feed"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["variable","pet"], + ["text","."], + ["variable","toss"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["variable","pet"], + ["text","."], + ["variable","walk"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["variable","pet"], + ["text","."], + ["variable","put-to-bed"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["variable","pet"], + ["text","."], + ["variable","rock"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["variable","pet"], + ["text","."], + ["variable","put-to-bed"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["variable","pet"], + ["text","."], + ["variable","put-to-bed"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["variable","pet"], + ["text","."], + ["variable","put-to-bed"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["variable","pet"], + ["text","."], + ["variable","put-to-bed"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_jade.json b/lib/ace/mode/_test/tokens_jade.json new file mode 100644 index 00000000..5bf45968 --- /dev/null +++ b/lib/ace/mode/_test/tokens_jade.json @@ -0,0 +1,188 @@ +[[ + "start", + ["keyword.other.doctype.jade","!!!doctype"] +],[ + "start", + ["keyword.other.doctype.jade","!!!5"] +],[ + "start", + ["keyword.other.doctype.jade","!!!"] +],[ + "start" +],[ + "start", + ["keyword.control.import.include.jade","include"], + ["text"," something"] +],[ + "start" +],[ + "start", + ["keyword.control.import.include.jade"," include"], + ["text"," another_thing"] +],[ + "start" +],[ + "start", + ["punctuation.section.comment"," // let's talk about it"] +],[ + "start" +],[ + ["comment_block",0,"start"], + ["comment","// "] +],[ + ["comment_block",0,"start"], + ["comment"," here it is. a block comment!"] +],[ + ["comment_block",0,"start"], + ["comment"," and another row!"] +],[ + "start", + ["meta.tag.any.jade","but"], + ["text"," not here."] +],[ + "start" +],[ + ["comment_block",5,"start"], + ["comment"," // "] +],[ + ["comment_block",5,"start"], + ["comment"," a far spaced"] +],[ + "start", + ["text"," should be lack of block"] +],[ + "start" +],[ + "start", + ["punctuation.section.comment"," // also not a comment"] +],[ + "start", + ["meta.tag.any.jade"," div"], + ["entity.other.attribute-name.class.jade",".attemptAtBlock"] +],[ + "start", + ["text"," "] +],[ + "start", + ["meta.tag.any.jade"," span"], + ["entity.other.attribute-name.id.jade","#myName"] +],[ + "start" +],[ + "start", + ["text"," "], + ["string.interpolated.jade","#{implicit}"] +],[ + "start", + ["text"," "], + ["string.interpolated.jade","!{more_explicit}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["suport.type.attribute.id.jade","#idDiv"] +],[ + "start" +],[ + "start", + ["text"," "], + ["suport.type.attribute.class.jade",".idDiv"] +],[ + "start" +],[ + "start", + ["meta.tag.any.jade"," test"], + ["punctuation","("], + ["entity.other.attribute-name.jade","id"], + ["text","="], + ["string","\"tag\""], + ["punctuation",")"] +],[ + "start", + ["meta.tag.any.jade"," header"], + ["punctuation","("], + ["entity.other.attribute-name.jade","id"], + ["text","="], + ["string","\"tag\""], + ["text",", "], + ["entity.other.attribute-name.jade","blah"], + ["text","="], + ["string","\"foo\""], + ["text",", "], + ["entity.other.attribute-name.jade","meh"], + ["text","="], + ["string","\"aads\""], + ["punctuation",")"] +],[ + "start", + ["storage.type.function.jade","mixin"], + ["entity.name.function.jade"," article"], + ["punctuation.definition.parameters.begin.jade","("], + ["variable.parameter.function.jade","obj, parents"], + ["punctuation.definition.parameters.end.jade",")"] +],[ + "start" +],[ + "start", + ["storage.type.function.jade"," mixin"], + ["entity.name.function.jade"," bleh"], + ["punctuation.definition.parameters.begin.jade","("], + ["punctuation.definition.parameters.end.jade",")"] +],[ + "start" +],[ + "start", + ["storage.type.function.jade"," mixin"], + ["entity.name.function.jade"," clever-name"] +],[ + "start" +],[ + "start", + ["source.js.embedded.jade"," -"], + ["storage.type","var"], + ["text"," "], + ["identifier","x"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string","\"0\""], + ["text",";"] +],[ + "start", + ["source.js.embedded.jade"," -"], + ["text"," "], + ["identifier","y"], + ["text"," "], + ["identifier","each"], + ["text"," z"] +],[ + "start" +],[ + "start", + ["source.js.embedded.jade"," -"], + ["text"," "], + ["storage.type","var"], + ["text"," "], + ["identifier","items"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","["], + ["string","\"one\""], + ["punctuation.operator",","], + ["text"," "], + ["string","\"two\""], + ["punctuation.operator",","], + ["text"," "], + ["string","\"three\""], + ["text","]"] +],[ + "start", + ["meta.tag.any.jade"," each"], + ["text"," item in items"] +],[ + "start", + ["meta.tag.any.jade"," li"], + ["text","= item"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_java.json b/lib/ace/mode/_test/tokens_java.json new file mode 100644 index 00000000..799ebdb5 --- /dev/null +++ b/lib/ace/mode/_test/tokens_java.json @@ -0,0 +1,95 @@ +[[ + "start", + ["keyword","public"], + ["text"," "], + ["keyword","class"], + ["text"," "], + ["identifier","InfiniteLoop"], + ["text"," "], + ["lparen","{"] +],[ + "start" +],[ + "comment", + ["text"," "], + ["comment","/*"] +],[ + "comment", + ["comment"," * This will cause the program to hang..."] +],[ + "comment", + ["comment"," *"] +],[ + "comment", + ["comment"," * Taken from:"] +],[ + "comment", + ["comment"," * http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/"] +],[ + "start", + ["comment"," */"] +],[ + "start", + ["text"," "], + ["keyword","public"], + ["text"," "], + ["keyword","static"], + ["text"," "], + ["keyword","void"], + ["text"," "], + ["identifier","main"], + ["lparen","("], + ["support.function","String"], + ["lparen","["], + ["rparen","]"], + ["text"," "], + ["identifier","args"], + ["rparen",")"], + ["text"," "], + ["lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","double"], + ["text"," "], + ["identifier","d"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["support.function","Double"], + ["text","."], + ["identifier","parseDouble"], + ["lparen","("], + ["string","\"2.2250738585072012e-308\""], + ["rparen",")"], + ["text",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["comment","// unreachable code"] +],[ + "start", + ["text"," "], + ["support.function","System"], + ["text","."], + ["identifier","out"], + ["text","."], + ["identifier","println"], + ["lparen","("], + ["string","\"Value: \""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["identifier","d"], + ["rparen",")"], + ["text",";"] +],[ + "start", + ["text"," "], + ["rparen","}"] +],[ + "start", + ["rparen","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_javascript.json b/lib/ace/mode/_test/tokens_javascript.json new file mode 100644 index 00000000..1be3f605 --- /dev/null +++ b/lib/ace/mode/_test/tokens_javascript.json @@ -0,0 +1,593 @@ +[[ + "start", + ["comment","//test: tokenize 'standard' functions"] +],[ + "no_regex", + ["identifier","string"], + ["punctuation.operator","."], + ["support.function","charCodeAt"], + ["paren.lparen","("], + ["constant.numeric","23"], + ["paren.rparen",")"], + ["punctuation.operator",";"], + ["text"," "], + ["variable.language","document"], + ["punctuation.operator","."], + ["support.function.dom","getElementById"], + ["paren.lparen","("], + ["string","'test'"], + ["paren.rparen",")"], + ["punctuation.operator",";"], + ["text"," "], + ["storage.type","console"], + ["punctuation.operator","."], + ["support.function.firebug","log"], + ["paren.lparen","("], + ["string","'Here it is'"], + ["paren.rparen",")"], + ["punctuation.operator",";"], + ["string","\";"] +],[ + "no_regex", + ["identifier","test"], + ["punctuation.operator",":"], + ["text"," "], + ["comment.doc","/**tokenize doc*/"], + ["text"," "], + ["identifier","comment"] +],[ + "no_regex", + ["comment.doc","/**tokenize doc comment with "], + ["comment.doc.tag","@tag"], + ["comment.doc"," {}*/"] +],[ + "no_regex", + ["comment","//test: tokenize parens"] +],[ + "start", + ["text"," "], + ["storage.type","var"], + ["text"," "], + ["identifier","line"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string","\"[{( )}]\""], + ["punctuation.operator",";"] +],[ + "start", + ["comment","//test tokenize arithmetic expression which looks like a regexp"] +],[ + "no_regex", + ["identifier","a"], + ["keyword.operator","/"], + ["identifier","b"], + ["keyword.operator","/"], + ["identifier","c"] +],[ + "no_regex", + ["identifier","a"], + ["keyword.operator","/="], + ["identifier","b"], + ["keyword.operator","/"], + ["identifier","c"] +],[ + "no_regex", + ["comment","//test tokenize reg exps"] +],[ + "no_regex", + ["identifier","a"], + ["keyword.operator","="], + ["string.regexp","/b/g"] +],[ + "no_regex", + ["identifier","a"], + ["keyword.operator","+"], + ["string.regexp","/b/g"] +],[ + "no_regex", + ["identifier","a"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","1"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string.regexp","/2 "], + ["constant.language.escape","+"], + ["string.regexp"," 1/gimyx"], + ["identifier","k"] +],[ + "no_regex", + ["identifier","a"], + ["keyword.operator","="], + ["string.regexp","/a/"], + ["text"," "], + ["keyword.operator","/"], + ["text"," "], + ["string.regexp","/a/"] +],[ + "no_regex", + ["keyword","case"], + ["text"," "], + ["string.regexp","/a/"], + ["punctuation.operator","."], + ["support.function","test"], + ["paren.lparen","("], + ["identifier","c"], + ["paren.rparen",")"] +],[ + "no_regex", + ["comment","//test tokenize multi-line comment containing a single line comment"] +],[ + "no_regex", + ["identifier","noRegex"] +],[ + "no_regex", + ["comment","/* foo // bar */"] +],[ + "start", + ["identifier","canBeRegex"], + ["punctuation.operator",";"] +],[ + "start", + ["comment","/* foo // bar */"] +],[ + "start", + ["comment","// test tokenize identifier with umlauts"] +],[ + "no_regex", + ["identifier","fu"], + ["punctuation.operator","?"], + ["identifier","e"] +],[ + "no_regex", + ["comment","// test // is not a regexp"] +],[ + "start", + ["paren.lparen","{"], + ["text"," "], + ["comment","// 123"] +],[ + "start", + ["comment","//test skipping escaped chars"] +],[ + "no_regex", + ["string","'Meh"], + ["constant.language.escape","\\\\"], + ["string","nNeh'"] +],[ + "no_regex", + ["storage.type","console"], + ["punctuation.operator","."], + ["support.function.firebug","log"], + ["paren.lparen","("], + ["string","'"], + ["constant.language.escape","\\\\"], + ["string","u1232Feh'"] +],[ + "qqstring", + ["string","\"test multiline\\"] +],[ + "no_regex", + ["string"," strings\""] +],[ + "no_regex", + ["identifier","a"], + ["keyword.operator","="], + ["text","'"] +],[ + "qqstring", + ["identifier","b"], + ["keyword.operator","="], + ["string","\"\\"] +],[ + "no_regex", + ["string","still a string"] +],[ + "no_regex", + ["text"," "] +],[ + "no_regex", + ["text"," "] +],[ + "start", + ["storage.type","function"], + ["text"," "], + ["entity.name.function","foo"], + ["paren.lparen","("], + ["variable.parameter","items"], + ["punctuation.operator",", "], + ["variable.parameter","nada"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","for"], + ["text"," "], + ["paren.lparen","("], + ["storage.type","var"], + ["text"," "], + ["identifier","i"], + ["keyword.operator","="], + ["constant.numeric","0"], + ["punctuation.operator",";"], + ["text"," "], + ["identifier","i"], + ["keyword.operator","<"], + ["identifier","items"], + ["punctuation.operator","."], + ["support.constant","length"], + ["punctuation.operator",";"], + ["text"," "], + ["identifier","i"], + ["keyword.operator","++"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["support.function","alert"], + ["paren.lparen","("], + ["identifier","items"], + ["paren.lparen","["], + ["identifier","i"], + ["paren.rparen","]"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","\"juhu"], + ["constant.language.escape","\\n"], + ["string","\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "no_regex", + ["text"," "], + ["paren.rparen","}"], + ["text","\t"], + ["comment","// Real Tab."] +],[ + "no_regex", + ["paren.rparen","}"] +],[ + "no_regex" +],[ + "no_regex", + ["identifier","regexp"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string.regexp","/p"], + ["constant.language.delimiter","|"], + ["string.regexp","p/"], + ["text"," "], + ["comment","// ends here"] +],[ + "no_regex" +],[ + "no_regex", + ["identifier","r"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string.regexp","/d"], + ["constant.language.escape","{1,2}?"], + ["string.regexp","f{e}"], + ["invalid","++"], + ["string.regexp","r"], + ["constant.language.escape","*?"], + ["regexp.keyword.operator","\\d"], + ["constant.language.escape","+?[]"], + ["string.regexp","r"], + ["constant.language.escape","[^"], + ["string.regexp.charachterclass","r"], + ["constant.language.escape","-"], + ["string.regexp.charachterclass","o"], + ["regexp.charclass.keyword.operator","\\f\\f"], + ["string.regexp.charachterclass","["], + ["regexp.charclass.keyword.operator","\\f"], + ["constant.language.escape","]?"], + ["string.regexp","r"], + ["invalid","{7}+"], + ["string.regexp","r"], + ["regexp.keyword.operator","\\{"], + ["string.regexp","7}"], + ["constant.language.escape","+"], + ["string.regexp","rr--rr"], + ["constant.language.escape","$^(?:"], + ["string.regexp","d"], + ["constant.language.delimiter","|"], + ["string.regexp","s"], + ["constant.language.escape",")(?="], + ["string.regexp","a"], + ["constant.language.delimiter","|"], + ["constant.language.escape",")(?!"], + ["string.regexp","y"], + ["constant.language.escape",")[]"], + ["constant.language.delimiter","|"], + ["invalid","$?"], + ["constant.language.delimiter","|"], + ["invalid","^*"], + ["string.regexp","/"], + ["text"," "], + ["identifier","o"] +],[ + "no_regex", + ["identifier","a"], + ["keyword.operator","="], + ["string.regexp","/a/"], + ["text"," "], + ["identifier","jk"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string.regexp","/ /"], + ["text"," "], + ["keyword.operator","/"], + ["text"," "], + ["string.regexp","/ /"] +],[ + "no_regex", + ["text"," "], + ["comment.doc","/************************************/"] +],[ + "no_regex", + ["comment.doc","/** total mess, tricky to highlight**/"] +],[ + "no_regex" +],[ + "start", + ["storage.type","function"], + ["text"," "], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "doc-start", + ["text","\t"], + ["comment.doc","/**"] +],[ + "doc-start", + ["comment.doc","\t * docComment"] +],[ + "no_regex", + ["comment.doc","\t **/"] +],[ + "no_regex", + ["text","\t"], + ["identifier","r"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string.regexp","/u"], + ["regexp.keyword.operator","\\t"], + ["constant.language.escape","*"], + ["string.regexp","/"] +],[ + "no_regex", + ["text","\t"], + ["identifier","g"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","1."], + ["text","00"], + ["identifier","E"], + ["keyword.operator","^"], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["text"," "], + ["identifier","y"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","1.2"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["punctuation.operator","."], + ["constant.numeric","2"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","052"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","0x25"] +],[ + "no_regex", + ["text","\t"], + ["identifier","t"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","["], + ["string","'d'"], + ["punctuation.operator",","], + ["text"," "], + ["string","''"], + ["paren.rparen","]"] +],[ + "no_regex", + ["paren.rparen","}"] +],[ + "start", + ["storage.type","function"], + ["text"," "], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text","\t"], + ["comment","/* eee */"] +],[ + "no_regex", + ["paren.rparen","}"] +],[ + "no_regex" +],[ + "qqstring", + ["string","\"s\\"] +],[ + "no_regex", + ["string","s"], + ["constant.language.escape","\\u7824"], + ["string","sss"], + ["constant.language.escape","\\u"], + ["string","1\""] +],[ + "no_regex" +],[ + "qstring", + ["string","'\\"] +],[ + "no_regex", + ["string","string'"] +],[ + "no_regex" +],[ + "no_regex", + ["text","'"] +],[ + "no_regex", + ["identifier","string"], + ["text","'"] +],[ + "no_regex" +],[ + "no_regex", + ["string","\"trailing space"], + ["constant.language.escape","\\ "], + ["string"," "] +],[ + "no_regex", + ["string","\" \""], + ["text"," "], + ["keyword.operator","/"], + ["identifier","not"], + ["text"," "], + ["identifier","a"], + ["text"," "], + ["identifier","regexp"], + ["keyword.operator","/"], + ["identifier","g"] +],[ + "no_regex" +],[ + "doc-start", + ["comment.doc","/**"] +],[ + "doc-start", + ["comment.doc"," *doc"] +],[ + "no_regex", + ["comment.doc"," */"] +],[ + "no_regex" +],[ + "start", + ["identifier","a"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text","\t"], + ["string","'a'"], + ["punctuation.operator",":"], + ["text"," "], + ["identifier","b"], + ["punctuation.operator",","] +],[ + "no_regex", + ["text","\t"], + ["string","'g'"], + ["text",":"], + ["text"," "], + ["storage.type","function"], + ["paren.lparen","("], + ["variable.parameter","t"], + ["paren.rparen",")"] +],[ + "no_regex", + ["text","\t"], + ["entity.name.function","gta"], + ["punctuation.operator",":"], + ["storage.type","function"], + ["paren.lparen","("], + ["variable.parameter","a"], + ["punctuation.operator",","], + ["variable.parameter","b"], + ["paren.rparen",")"] +],[ + "no_regex", + ["paren.rparen","}"] +],[ + "no_regex" +],[ + "no_regex" +],[ + "function_arguments", + ["identifier","foo"], + ["punctuation.operator","."], + ["storage.type","protoype"], + ["punctuation.operator","."], + ["entity.name.function","d"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["storage.type","function"], + ["paren.lparen","("], + ["variable.parameter","a"], + ["punctuation.operator",", "], + ["variable.parameter","b"], + ["punctuation.operator",","] +],[ + "no_regex", + ["punctuation.operator"," "], + ["variable.parameter","c"], + ["punctuation.operator",", "], + ["variable.parameter","d"], + ["paren.rparen",")"] +],[ + "no_regex", + ["storage.type","foo"], + ["punctuation.operator","."], + ["entity.name.function","d"], + ["text"," "], + ["keyword.operator","="], + ["storage.type","function"], + ["paren.lparen","("], + ["variable.parameter","a"], + ["punctuation.operator",", "], + ["variable.parameter","b"], + ["paren.rparen",")"] +],[ + "no_regex", + ["storage.type","foo"], + ["punctuation.operator","."], + ["entity.name.function","d"], + ["text"," "], + ["keyword.operator","="], + ["storage.type","function"], + ["paren.lparen","("], + ["variable.parameter","a"], + ["punctuation.operator",", "], + ["comment.doc","/*****/"], + ["text"," "], + ["identifier","d"], + ["string","\"string\""], + ["text"," "] +],[ + "no_regex" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_json.json b/lib/ace/mode/_test/tokens_json.json new file mode 100644 index 00000000..4420a740 --- /dev/null +++ b/lib/ace/mode/_test/tokens_json.json @@ -0,0 +1,412 @@ +[[ + "start", + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","\"query\""], + ["text",": "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","\"count\""], + ["text",": "], + ["constant.numeric","10"], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"created\""], + ["text",": "], + ["string","\"2011-06-21T08:10:46Z\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"lang\""], + ["text",": "], + ["string","\"en-US\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"results\""], + ["text",": "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","\"photo\""], + ["text",": "], + ["paren.lparen","["] +],[ + "start", + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","\"farm\""], + ["text",": "], + ["string","\"6\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"id\""], + ["text",": "], + ["string","\"5855620975\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"isfamily\""], + ["text",": "], + ["string","\"0\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"isfriend\""], + ["text",": "], + ["string","\"0\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"ispublic\""], + ["text",": "], + ["string","\"1\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"owner\""], + ["text",": "], + ["string","\"32021554@N04\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"secret\""], + ["text",": "], + ["string","\"f1f5e8515d\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"server\""], + ["text",": "], + ["string","\"5110\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"title\""], + ["text",": "], + ["string","\"7087 bandit cat\""] +],[ + "start", + ["text"," "], + ["paren.rparen","}"], + ["text",","] +],[ + "start", + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","\"farm\""], + ["text",": "], + ["string","\"4\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"id\""], + ["text",": "], + ["string","\"5856170534\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"isfamily\""], + ["text",": "], + ["string","\"0\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"isfriend\""], + ["text",": "], + ["string","\"0\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"ispublic\""], + ["text",": "], + ["string","\"1\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"owner\""], + ["text",": "], + ["string","\"32021554@N04\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"secret\""], + ["text",": "], + ["string","\"ff1efb2a6f\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"server\""], + ["text",": "], + ["string","\"3217\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"title\""], + ["text",": "], + ["string","\"6975 rusty cat\""] +],[ + "start", + ["text"," "], + ["paren.rparen","}"], + ["text",","] +],[ + "start", + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","\"farm\""], + ["text",": "], + ["string","\"6\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"id\""], + ["text",": "], + ["string","\"5856172972\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"isfamily\""], + ["text",": "], + ["string","\"0\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"isfriend\""], + ["text",": "], + ["string","\"0\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"ispublic\""], + ["text",": "], + ["string","\"1\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"owner\""], + ["text",": "], + ["string","\"51249875@N03\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"secret\""], + ["text",": "], + ["string","\"6c6887347c\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"server\""], + ["text",": "], + ["string","\"5192\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"title\""], + ["text",": "], + ["string","\"watermarked-cats\""] +],[ + "start", + ["text"," "], + ["paren.rparen","}"], + ["text",","] +],[ + "start", + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","\"farm\""], + ["text",": "], + ["string","\"6\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"id\""], + ["text",": "], + ["string","\"5856168328\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"isfamily\""], + ["text",": "], + ["string","\"0\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"isfriend\""], + ["text",": "], + ["string","\"0\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"ispublic\""], + ["text",": "], + ["string","\"1\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"owner\""], + ["text",": "], + ["string","\"32021554@N04\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"secret\""], + ["text",": "], + ["string","\"0c1cfdf64c\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"server\""], + ["text",": "], + ["string","\"5078\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"title\""], + ["text",": "], + ["string","\"7020 mandy cat\""] +],[ + "start", + ["text"," "], + ["paren.rparen","}"], + ["text",","] +],[ + "start", + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","\"farm\""], + ["text",": "], + ["string","\"3\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"id\""], + ["text",": "], + ["string","\"5856171774\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"isfamily\""], + ["text",": "], + ["string","\"0\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"isfriend\""], + ["text",": "], + ["string","\"0\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"ispublic\""], + ["text",": "], + ["string","\"1\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"owner\""], + ["text",": "], + ["string","\"32021554@N04\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"secret\""], + ["text",": "], + ["string","\"7f5a3180ab\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"server\""], + ["text",": "], + ["string","\"2696\""], + ["text",","] +],[ + "start", + ["text"," "], + ["variable","\"title\""], + ["text",": "], + ["string","\"7448 bobby cat\""] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","]"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_jsoniq.json b/lib/ace/mode/_test/tokens_jsoniq.json new file mode 100644 index 00000000..0f4ee6e9 --- /dev/null +++ b/lib/ace/mode/_test/tokens_jsoniq.json @@ -0,0 +1,4 @@ +[[ + "[\"start\"]", + ["support.function","TODO"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_jsp.json b/lib/ace/mode/_test/tokens_jsp.json new file mode 100644 index 00000000..25d3af4d --- /dev/null +++ b/lib/ace/mode/_test/tokens_jsp.json @@ -0,0 +1,435 @@ +[[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","html"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","body"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "js-start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.script.tag-name.xml","script"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "js-start", + ["text"," "], + ["storage.type","var"], + ["text"," "], + ["identifier","x"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string","\"abc\""], + ["punctuation.operator",";"] +],[ + "js-start", + ["text"," "], + ["storage.type","function"], + ["text"," "], + ["identifier","y"], + ["text"," "], + ["paren.lparen","{"] +],[ + "js-no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "css-start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.style.tag-name.xml","style"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + ["css-ruleset","css-start"], + ["text"," "], + ["variable",".class"], + ["text"," "], + ["paren.lparen","{"] +],[ + ["css-ruleset","css-start"], + ["text"," "], + ["support.type","background"], + ["text",": "], + ["constant.numeric","#124356"], + ["text",";"] +],[ + "css-start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","p"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," Today's date: "], + ["meta.tag","<%"], + ["keyword.operator","="], + ["text"," "], + ["lparen","("], + ["keyword","new"], + ["text"," "], + ["identifier","java"], + ["text","."], + ["identifier","util"], + ["text","."], + ["identifier","Date"], + ["lparen","("], + ["rparen","))"], + ["text","."], + ["identifier","toLocaleString"], + ["lparen","("], + ["rparen",")"], + ["meta.tag","%>"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag","<%"], + ["keyword.operator","!"], + ["text"," "], + ["keyword","int"], + ["text"," "], + ["identifier","i"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","0"], + ["text","; "], + ["meta.tag","%>"] +],[ + "jsp-start", + ["text.xml"," "], + ["meta.tag",""] +],[ + "jsp-start", + ["text"," "], + ["keyword","int"], + ["text"," "], + ["identifier","j"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","10"], + ["text",";"] +],[ + "start", + ["text"," "], + ["meta.tag",""] +],[ + "start" +],[ + "start", + ["text.xml"," "], + ["comment","<%-- This is JSP comment --%>"] +],[ + "start", + ["text.xml"," "], + ["meta.tag","<%@"], + ["text"," "], + ["identifier","directive"], + ["text"," "], + ["identifier","attribute"], + ["keyword.operator","="], + ["string","\"value\""], + ["text"," "], + ["meta.tag","%>"] +],[ + "start" +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","h2"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Select Languages:"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.form.tag-name.xml","form"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","ACTION"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"jspCheckBox.jsp\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.form.tag-name.xml","input"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","type"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"checkbox\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","name"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"id\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","value"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"Java\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml"," Java"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","BR"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.form.tag-name.xml","input"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","type"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"checkbox\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","name"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"id\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","value"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\".NET\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml"," .NET"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","BR"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.form.tag-name.xml","input"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","type"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"checkbox\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","name"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"id\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","value"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"PHP\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml"," PHP"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","BR"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.form.tag-name.xml","input"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","type"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"checkbox\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","name"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"id\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","value"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"C/C++\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml"," C/C++"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","BR"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.form.tag-name.xml","input"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","type"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"checkbox\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","name"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"id\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","value"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"PERL\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml"," PERL "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","BR"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.form.tag-name.xml","input"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","type"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"submit\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","value"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"Submit\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "jsp-start", + ["text.xml"," "], + ["meta.tag","<%"] +],[ + "jsp-start", + ["text"," "], + ["support.function","String"], + ["text"," "], + ["identifier","select"], + ["lparen","["], + ["rparen","]"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["variable.language","request"], + ["text","."], + ["identifier","getParameterValues"], + ["lparen","("], + ["string","\"id\""], + ["rparen",")"], + ["text","; "] +],[ + "jsp-start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["lparen","("], + ["identifier","select"], + ["text"," "], + ["keyword.operator","!="], + ["text"," "], + ["constant.language","null"], + ["text"," "], + ["keyword.operator","&&"], + ["text"," "], + ["identifier","select"], + ["text","."], + ["identifier","length"], + ["text"," "], + ["keyword.operator","!="], + ["text"," "], + ["constant.numeric","0"], + ["rparen",")"], + ["text"," "], + ["lparen","{"] +],[ + "jsp-start", + ["text"," "], + ["variable.language","out"], + ["text","."], + ["identifier","println"], + ["lparen","("], + ["string","\"You have selected: \""], + ["rparen",")"], + ["text",";"] +],[ + "jsp-start", + ["text"," "], + ["keyword","for"], + ["text"," "], + ["lparen","("], + ["keyword","int"], + ["text"," "], + ["identifier","i"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","0"], + ["text","; "], + ["identifier","i"], + ["text"," "], + ["keyword.operator","<"], + ["text"," "], + ["identifier","select"], + ["text","."], + ["identifier","length"], + ["text","; "], + ["identifier","i"], + ["keyword.operator","++"], + ["rparen",")"], + ["text"," "], + ["lparen","{"] +],[ + "jsp-start", + ["text"," "], + ["variable.language","out"], + ["text","."], + ["identifier","println"], + ["lparen","("], + ["identifier","select"], + ["lparen","["], + ["identifier","i"], + ["rparen","])"], + ["text","; "] +],[ + "jsp-start", + ["text"," "], + ["rparen","}"] +],[ + "jsp-start", + ["text"," "], + ["rparen","}"] +],[ + "start", + ["text"," "], + ["meta.tag","%>"] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_jsx.json b/lib/ace/mode/_test/tokens_jsx.json new file mode 100644 index 00000000..d1a740b0 --- /dev/null +++ b/lib/ace/mode/_test/tokens_jsx.json @@ -0,0 +1,51 @@ +[[ + "comment", + ["comment","/*EXPECTED"] +],[ + "comment", + ["comment","hello world!"] +],[ + "start", + ["comment","*/"] +],[ + "start", + ["keyword","class"], + ["text"," "], + ["language.support.class","Test"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","static"], + ["text"," "], + ["storage.type","function"], + ["text"," "], + ["entity.name.function","run"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["punctuation.operator",":"], + ["text"," "], + ["keyword","void"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["comment","// console.log(\"hello world!\");"] +],[ + "start", + ["text"," "], + ["keyword","log"], + ["text"," "], + ["string","\"hello world!\""], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_julia.json b/lib/ace/mode/_test/tokens_julia.json new file mode 100644 index 00000000..5aaef6f9 --- /dev/null +++ b/lib/ace/mode/_test/tokens_julia.json @@ -0,0 +1,111 @@ +[[ + "start", + ["keyword.control.julia","for"], + ["text"," op "], + ["keyword.operator.update.julia","="], + ["text"," ("], + ["keyword.operator.ternary.julia",":"], + ["keyword.operator.arithmetic.julia","+"], + ["text",", "], + ["keyword.operator.ternary.julia",":"], + ["keyword.operator.arithmetic.julia","*"], + ["text",", "], + ["keyword.operator.ternary.julia",":"], + ["keyword.operator.bitwise.julia","&"], + ["text",", "], + ["keyword.operator.ternary.julia",":"], + ["keyword.operator.bitwise.julia","|"], + ["text",", "], + ["keyword.operator.ternary.julia",":"], + ["keyword.operator.interpolation.julia","$"], + ["text",")"] +],[ + "start", + ["text"," "], + ["variable.macro.julia","@eval"], + ["text"," ("], + ["keyword.operator.interpolation.julia","$"], + ["text","op)(a,b,c) "], + ["keyword.operator.update.julia","="], + ["text"," ("], + ["keyword.operator.interpolation.julia","$"], + ["text","op)(("], + ["keyword.operator.interpolation.julia","$"], + ["text","op)(a,b),c)"] +],[ + "start", + ["keyword.control.julia","end"] +],[ + "start" +],[ + "start", + ["text","v "], + ["keyword.operator.update.julia","="], + ["text"," "], + ["variable","α"], + ["keyword.operator.transposed-variable.julia","'"], + ["text",";"] +],[ + "start", + ["keyword.other.julia","function"], + ["meta.function.julia"," "], + ["entity.name.function.julia","g"], + ["text","("], + ["text","x,y)"] +],[ + "start", + ["text"," "], + ["keyword.control.julia","return"], + ["text"," x "], + ["keyword.operator.arithmetic.julia","*"], + ["text"," y"] +],[ + "start", + ["text"," x "], + ["keyword.operator.arithmetic.julia","+"], + ["text"," y"] +],[ + "start", + ["keyword.control.julia","end"] +],[ + "start" +],[ + "start", + ["support.function.julia","cd"], + ["text","("], + ["punctuation.definition.string.begin.julia","\""], + ["string.quoted.double.julia","data"], + ["punctuation.definition.string.end.julia","\""], + ["text",") "], + ["keyword.control.julia","do"] +],[ + "start", + ["text"," "], + ["support.function.julia","open"], + ["text","("], + ["punctuation.definition.string.begin.julia","\""], + ["string.quoted.double.julia","outfile"], + ["punctuation.definition.string.end.julia","\""], + ["text",", "], + ["punctuation.definition.string.begin.julia","\""], + ["string.quoted.double.julia","w"], + ["punctuation.definition.string.end.julia","\""], + ["text",") "], + ["keyword.control.julia","do"], + ["text"," f"] +],[ + "start", + ["text"," "], + ["support.function.julia","write"], + ["text","("], + ["text","f, data)"] +],[ + "start", + ["text"," "], + ["keyword.control.julia","end"] +],[ + "start", + ["keyword.control.julia","end"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_latex.json b/lib/ace/mode/_test/tokens_latex.json new file mode 100644 index 00000000..52508e0d --- /dev/null +++ b/lib/ace/mode/_test/tokens_latex.json @@ -0,0 +1,127 @@ +[[ + "start", + ["keyword","\\usepackage"], + ["lparen","{"], + ["storage.type","amsmath"], + ["rparen","}"] +],[ + "start", + ["storage.type","\\title"], + ["lparen","{"], + ["storage.type","\\LaTeX"], + ["rparen","}"] +],[ + "start", + ["storage.type","\\date"], + ["lparen","{"], + ["rparen","}"] +],[ + "start", + ["storage.type","\\begin"], + ["lparen","{"], + ["variable.parameter","document"], + ["rparen","}"] +],[ + "start", + ["text"," "], + ["storage.type","\\maketitle"] +],[ + "start", + ["text"," "], + ["storage.type","\\LaTeX"], + ["lparen","{"], + ["rparen","}"], + ["text"," is a document preparation system for the "], + ["storage.type","\\TeX"], + ["lparen","{"], + ["rparen","}"] +],[ + "start", + ["text"," typesetting program. It offers programmable desktop publishing"] +],[ + "start", + ["text"," features and extensive facilities for automating most aspects of"] +],[ + "start", + ["text"," typesetting and desktop publishing, including numbering and"] +],[ + "start", + ["text"," cross-referencing, tables and figures, page layout, bibliographies,"] +],[ + "start", + ["text"," and much more. "], + ["storage.type","\\LaTeX"], + ["lparen","{"], + ["rparen","}"], + ["text"," was originally written in 1984 by Leslie"] +],[ + "start", + ["text"," Lamport and has become the dominant method for using "], + ["storage.type","\\TeX"], + ["text","; few"] +],[ + "start", + ["text"," people write in plain "], + ["storage.type","\\TeX"], + ["lparen","{"], + ["rparen","}"], + ["text"," anymore. The current version is"] +],[ + "start", + ["text"," "], + ["storage.type","\\LaTeXe"], + ["text","."] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["comment","% This is a comment; it will not be shown in the final output."] +],[ + "start", + ["text"," "], + ["comment","% The following shows a little of the typesetting power of LaTeX:"] +],[ + "start", + ["text"," "], + ["storage.type","\\begin"], + ["lparen","{"], + ["variable.parameter","align"], + ["rparen","}"] +],[ + "start", + ["text"," E &= mc^2 "], + ["constant.character.escape","\\\\"] +],[ + "start", + ["text"," m &= "], + ["storage.type","\\frac"], + ["lparen","{"], + ["text","m_0"], + ["rparen","}"], + ["lparen","{"], + ["storage.type","\\sqrt"], + ["lparen","{"], + ["text","1-"], + ["storage.type","\\frac"], + ["lparen","{"], + ["text","v^2"], + ["rparen","}"], + ["lparen","{"], + ["text","c^2"], + ["rparen","}}}"] +],[ + "start", + ["text"," "], + ["storage.type","\\end"], + ["lparen","{"], + ["variable.parameter","align"], + ["rparen","}"] +],[ + "start", + ["storage.type","\\end"], + ["lparen","{"], + ["variable.parameter","document"], + ["rparen","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_less.json b/lib/ace/mode/_test/tokens_less.json new file mode 100644 index 00000000..81fe0c20 --- /dev/null +++ b/lib/ace/mode/_test/tokens_less.json @@ -0,0 +1,204 @@ +[[ + "start", + ["comment","/* styles.less */"] +],[ + "start" +],[ + "start", + ["variable","@base"], + ["text",": "], + ["constant.numeric","#f938ab"], + ["text",";"] +],[ + "start" +],[ + "start", + ["variable.language",".box-shadow"], + ["paren.lparen","("], + ["variable","@style"], + ["text",", "], + ["variable","@c"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","when"], + ["text"," "], + ["paren.lparen","("], + ["support.function","iscolor"], + ["paren.lparen","("], + ["variable","@c"], + ["paren.rparen","))"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," box-shadow: "], + ["variable","@style"], + ["text"," "], + ["variable","@c"], + ["text",";"] +],[ + "start", + ["text"," -webkit-box-shadow: "], + ["variable","@style"], + ["text"," "], + ["variable","@c"], + ["text",";"] +],[ + "start", + ["text"," -moz-box-shadow: "], + ["variable","@style"], + ["text"," "], + ["variable","@c"], + ["text",";"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start", + ["variable.language",".box-shadow"], + ["paren.lparen","("], + ["variable","@style"], + ["text",", "], + ["variable","@alpha"], + ["text",": "], + ["constant.numeric","50%"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","when"], + ["text"," "], + ["paren.lparen","("], + ["support.function","isnumber"], + ["paren.lparen","("], + ["variable","@alpha"], + ["paren.rparen","))"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable.language",".box-shadow"], + ["paren.lparen","("], + ["variable","@style"], + ["text",", "], + ["support.function","rgba"], + ["paren.lparen","("], + ["constant.numeric","0"], + ["text",", "], + ["constant.numeric","0"], + ["text",", "], + ["constant.numeric","0"], + ["text",", "], + ["variable","@alpha"], + ["paren.rparen","))"], + ["text",";"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["comment","// Box styles"] +],[ + "start", + ["variable.language",".box"], + ["text"," "], + ["paren.lparen","{"], + ["text"," "] +],[ + "start", + ["text"," "], + ["support.type","color"], + ["text",": "], + ["support.function","saturate"], + ["paren.lparen","("], + ["variable","@base"], + ["text",", "], + ["constant.numeric","5%"], + ["paren.rparen",")"], + ["text",";"] +],[ + "start", + ["text"," "], + ["support.type","border-color"], + ["text",": "], + ["support.function","lighten"], + ["paren.lparen","("], + ["variable","@base"], + ["text",", "], + ["constant.numeric","30%"], + ["paren.rparen",")"], + ["text",";"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["variable.language","div"], + ["text"," "], + ["paren.lparen","{"], + ["text"," "], + ["variable.language",".box-shadow"], + ["paren.lparen","("], + ["constant.numeric","0"], + ["text"," "], + ["constant.numeric","0"], + ["text"," "], + ["constant.numeric","5px"], + ["text",", "], + ["constant.numeric","30%"], + ["paren.rparen",")"], + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["variable.language","a"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["support.type","color"], + ["text",": "], + ["variable","@base"], + ["text",";"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," &"], + ["variable.language",":hover"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["support.type","color"], + ["text",": "], + ["support.function","lighten"], + ["paren.lparen","("], + ["variable","@base"], + ["text",", "], + ["constant.numeric","50%"], + ["paren.rparen",")"], + ["text",";"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_liquid.json b/lib/ace/mode/_test/tokens_liquid.json new file mode 100644 index 00000000..30d003cb --- /dev/null +++ b/lib/ace/mode/_test/tokens_liquid.json @@ -0,0 +1,551 @@ +[[ + "start", + ["text.xml","The following examples can be found in full at http://liquidmarkup.org/"] +],[ + "start" +],[ + "start", + ["text.xml","Liquid is an extraction from the e-commerce system Shopify."] +],[ + "start", + ["text.xml","Shopify powers many thousands of e-commerce stores which all call for unique designs."] +],[ + "start", + ["text.xml","For this we developed Liquid which allows our customers complete design freedom while"] +],[ + "start", + ["text.xml","maintaining the integrity of our servers."] +],[ + "start" +],[ + "start", + ["text.xml","Liquid has been in production use since June 2006 and is now used by many other"] +],[ + "start", + ["text.xml","hosted web applications."] +],[ + "start" +],[ + "start", + ["text.xml","It was developed for usage in Ruby on Rails web applications and integrates seamlessly"] +],[ + "start", + ["text.xml","as a plugin but it also works excellently as a stand alone library."] +],[ + "start" +],[ + "start", + ["text.xml","Here's what it looks like:"] +],[ + "start" +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","ul"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"products\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","for"], + ["text"," "], + ["identifier","product"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["identifier","products"], + ["text"," "], + ["variable","%}"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","li"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","h2"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["variable","{{"], + ["text"," "], + ["identifier","product"], + ["text","."], + ["identifier","title"], + ["text"," "], + ["variable","}}"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," Only "], + ["variable","{{"], + ["text"," "], + ["identifier","product"], + ["text","."], + ["identifier","price"], + ["text"," | "], + ["identifier","format_as_money"], + ["text"," "], + ["variable","}}"] +],[ + "start" +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","p"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["variable","{{"], + ["text"," "], + ["identifier","product"], + ["text","."], + ["identifier","description"], + ["text"," | "], + ["identifier","prettyprint"], + ["text"," | "], + ["support.function","truncate"], + ["text",": "], + ["constant.numeric","200"], + ["text"," "], + ["variable","}}"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","endfor"], + ["text"," "], + ["variable","%}"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "start" +],[ + "start", + ["text.xml","Some more features include:"] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","h2"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Filters"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","p"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml"," The word \"tobi\" in uppercase: "], + ["variable","{{"], + ["text"," "], + ["string","'tobi'"], + ["text"," | "], + ["support.function","upcase"], + ["text"," "], + ["variable","}}"], + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","p"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","The word \"tobi\" has "], + ["variable","{{"], + ["text"," "], + ["string","'tobi'"], + ["text"," | "], + ["support.function","size"], + ["text"," "], + ["variable","}}"], + ["text.xml"," letters! "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","p"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Change \"Hello world\" to \"Hi world\": "], + ["variable","{{"], + ["text"," "], + ["string","'Hello world'"], + ["text"," | "], + ["support.function","replace"], + ["text",": "], + ["string","'Hello'"], + ["text",", "], + ["string","'Hi'"], + ["text"," "], + ["variable","}}"], + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","p"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","The date today is "], + ["variable","{{"], + ["text"," "], + ["string","'now'"], + ["text"," | "], + ["support.function","date"], + ["text",": "], + ["string","\"%Y %b %d\""], + ["text"," "], + ["variable","}}"], + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","h2"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","If"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","p"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","if"], + ["text"," "], + ["identifier","user"], + ["text","."], + ["identifier","name"], + ["text"," "], + ["keyword.operator","=="], + ["text"," "], + ["string","'tobi'"], + ["text"," "], + ["identifier","or"], + ["text"," "], + ["identifier","user"], + ["text","."], + ["identifier","name"], + ["text"," "], + ["keyword.operator","=="], + ["text"," "], + ["string","'marc'"], + ["text"," "], + ["variable","%}"], + ["text.xml"," "] +],[ + "start", + ["text.xml"," hi marc or tobi"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","endif"], + ["text"," "], + ["variable","%}"] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","h2"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Case"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","p"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","case"], + ["text"," "], + ["identifier","template"], + ["text"," "], + ["variable","%}"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","when"], + ["text"," "], + ["string","'index'"], + ["text"," "], + ["variable","%}"] +],[ + "start", + ["text.xml"," Welcome"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","when"], + ["text"," "], + ["string","'product'"], + ["text"," "], + ["variable","%}"] +],[ + "start", + ["text.xml"," "], + ["variable","{{"], + ["text"," "], + ["identifier","product"], + ["text","."], + ["identifier","vendor"], + ["text"," | "], + ["identifier","link_to_vendor"], + ["text"," "], + ["variable","}}"], + ["text.xml"," / "], + ["variable","{{"], + ["text"," "], + ["identifier","product"], + ["text","."], + ["identifier","title"], + ["text"," "], + ["variable","}}"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","else"], + ["text"," "], + ["variable","%}"] +],[ + "start", + ["text.xml"," "], + ["variable","{{"], + ["text"," "], + ["identifier","page_title"], + ["text"," "], + ["variable","}}"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","endcase"], + ["text"," "], + ["variable","%}"] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","h2"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","For Loops"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","p"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","for"], + ["text"," "], + ["identifier","item"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["identifier","array"], + ["text"," "], + ["variable","%}"], + ["text.xml"," "] +],[ + "start", + ["text.xml"," "], + ["variable","{{"], + ["text"," "], + ["identifier","item"], + ["text"," "], + ["variable","}}"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","endfor"], + ["text"," "], + ["variable","%}"] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","h2"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Tables"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","p"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","tablerow"], + ["text"," "], + ["identifier","item"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["identifier","items"], + ["text"," "], + ["identifier","cols"], + ["text",": "], + ["constant.numeric","3"], + ["text"," "], + ["variable","%}"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable.language","tablerowloop"], + ["text","."], + ["identifier","col_first"], + ["text"," "], + ["variable","%}"] +],[ + "start", + ["text.xml"," First column: "], + ["variable","{{"], + ["text"," "], + ["identifier","item"], + ["text","."], + ["identifier","variable"], + ["text"," "], + ["variable","}}"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","else"], + ["text"," "], + ["variable","%}"] +],[ + "start", + ["text.xml"," Different column: "], + ["variable","{{"], + ["text"," "], + ["identifier","item"], + ["text","."], + ["identifier","variable"], + ["text"," "], + ["variable","}}"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","endif"], + ["text"," "], + ["variable","%}"] +],[ + "start", + ["text.xml"," "], + ["variable","{%"], + ["text"," "], + ["keyword","endtablerow"], + ["text"," "], + ["variable","%}"] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_lisp.json b/lib/ace/mode/_test/tokens_lisp.json new file mode 100644 index 00000000..2e70a555 --- /dev/null +++ b/lib/ace/mode/_test/tokens_lisp.json @@ -0,0 +1,248 @@ +[[ + "start", + ["text","("], + ["storage.type.function-type.lisp","defun"], + ["text"," "], + ["entity.name.function.lisp","prompt-for-cd"], + ["text"," ()"] +],[ + "start", + ["text"," "], + ["string","\"Prompts"] +],[ + "start", + ["text"," "], + ["identifier","for"], + ["text"," "], + ["identifier","CD"], + ["text","\""] +],[ + "start", + ["text"," ("], + ["identifier","prompt"], + ["text","-"], + ["identifier","read"], + ["text"," "], + ["string","\"Title\""], + ["text"," "], + ["constant.numeric","1.53"], + ["text"," "], + ["constant.numeric","1"], + ["text"," "], + ["constant.numeric","2"], + ["text","/"], + ["constant.numeric","4"], + ["text"," "], + ["constant.numeric","1.7"], + ["text"," "], + ["constant.numeric","1.7e0"], + ["text"," "], + ["constant.numeric","2.9E-4"], + ["text"," "], + ["constant.numeric","+42"], + ["text"," "], + ["constant.numeric","-7"], + ["text"," "], + ["punctuation.definition.constant.character.lisp","#"], + ["constant.character.lisp","b001"], + ["text"," "], + ["punctuation.definition.constant.character.lisp","#"], + ["constant.character.lisp","b001/100"], + ["text"," "], + ["punctuation.definition.constant.character.lisp","#"], + ["constant.character.lisp","o777"], + ["text"," "], + ["punctuation.definition.constant.character.lisp","#"], + ["constant.character.lisp","O777"], + ["text"," "], + ["punctuation.definition.constant.character.lisp","#"], + ["constant.character.lisp","xabc55"], + ["text"," "], + ["punctuation.definition.constant.character.lisp","#"], + ["constant.character.lisp","c"], + ["text","("], + ["constant.numeric","0"], + ["text"," "], + ["constant.numeric","-5.6"], + ["text","))"] +],[ + "start", + ["text"," ("], + ["identifier","prompt"], + ["text","-"], + ["identifier","read"], + ["text"," "], + ["string","\"Artist\""], + ["text"," &"], + ["identifier","rest"], + ["text",")"] +],[ + "start", + ["text"," ("], + ["keyword.operator","or"], + ["text"," ("], + ["identifier","parse"], + ["text","-"], + ["identifier","integer"], + ["text"," ("], + ["identifier","prompt"], + ["text","-"], + ["identifier","read"], + ["text"," "], + ["string","\"Rating\""], + ["text",") :"], + ["identifier","junk"], + ["text","-"], + ["identifier","allowed"], + ["text"," "], + ["support.function","t"], + ["text",") "], + ["constant.numeric","0"], + ["text",")"] +],[ + "start", + ["text"," ("], + ["keyword.control","if"], + ["text"," "], + ["identifier","x"], + ["text"," ("], + ["support.function","format"], + ["text"," "], + ["support.function","t"], + ["text"," "], + ["string","\"yes\""], + ["text",") ("], + ["support.function","format"], + ["text"," "], + ["support.function","t"], + ["text"," "], + ["string","\"no\""], + ["text"," "], + ["constant.language","nil"], + ["text",") "], + ["comment",";and here comment"] +],[ + "start", + ["text"," ) "], + ["constant.numeric","0xFFLL"], + ["text"," "], + ["constant.numeric","-23ull"] +],[ + "start", + ["text"," "], + ["comment",";; second line comment"] +],[ + "start", + ["text"," '(+ "], + ["constant.numeric","1"], + ["text"," "], + ["constant.numeric","2"], + ["text",")"] +],[ + "start", + ["text"," ("], + ["identifier","defvar"], + ["text"," "], + ["punctuation.definition.variable.lisp","*"], + ["variable.other.global.lisp","lines"], + ["punctuation.definition.variable.lisp","*"], + ["text",") "], + ["comment","; list of all lines"] +],[ + "start", + ["text"," ("], + ["identifier","position"], + ["text","-"], + ["keyword.control","if"], + ["text","-"], + ["identifier","not"], + ["text"," "], + ["punctuation.definition.constant.character.lisp","#"], + ["constant.character.lisp","'sys::whitespacep"], + ["text"," "], + ["identifier","line"], + ["text"," :"], + ["identifier","start"], + ["text"," "], + ["identifier","beg"], + ["text","))"] +],[ + "start", + ["text"," ("], + ["support.function","quote"], + ["text"," ("], + ["identifier","privet"], + ["text"," "], + ["constant.numeric","1"], + ["text"," "], + ["constant.numeric","2"], + ["text"," "], + ["constant.numeric","3"], + ["text","))"] +],[ + "start", + ["text"," '("], + ["identifier","hello"], + ["text"," "], + ["identifier","world"], + ["text",")"] +],[ + "start", + ["text"," (* "], + ["constant.numeric","5"], + ["text"," "], + ["constant.numeric","7"], + ["text",")"] +],[ + "start", + ["text"," ("], + ["constant.numeric","1"], + ["text"," "], + ["constant.numeric","2"], + ["text"," "], + ["constant.numeric","34"], + ["text"," "], + ["constant.numeric","5"], + ["text",")"] +],[ + "start", + ["text"," (:"], + ["identifier","use"], + ["text"," "], + ["string","\"aaaa\""], + ["text",")"] +],[ + "start", + ["text"," ("], + ["keyword.control","let"], + ["text"," (("], + ["identifier","x"], + ["text"," "], + ["constant.numeric","10"], + ["text",") ("], + ["identifier","y"], + ["text"," "], + ["constant.numeric","20"], + ["text","))"] +],[ + "start", + ["text"," ("], + ["identifier","print"], + ["text"," (+ "], + ["identifier","x"], + ["text"," "], + ["identifier","y"], + ["text","))"] +],[ + "start", + ["text"," ) "], + ["support.function","LAmbDa"] +],[ + "start" +],[ + "start", + ["text"," "], + ["string","\"asdad"], + ["constant.character.escape.lisp","\\0"], + ["string","eqweqe\""] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_livescript.json b/lib/ace/mode/_test/tokens_livescript.json new file mode 100644 index 00000000..c2bd83df --- /dev/null +++ b/lib/ace/mode/_test/tokens_livescript.json @@ -0,0 +1,6 @@ +[[ + "start", + ["comment","# comment"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_logiql.json b/lib/ace/mode/_test/tokens_logiql.json new file mode 100644 index 00000000..5f7eda49 --- /dev/null +++ b/lib/ace/mode/_test/tokens_logiql.json @@ -0,0 +1,190 @@ +[[ + "start", + ["comment.single","// ancestors"] +],[ + "start", + ["entity.name","parentof"], + ["text","("], + ["string","\"douglas\""], + ["keyword.other",","], + ["text"," "], + ["string","\"john\""], + ["text",")"], + ["keyword.end","."] +],[ + "start", + ["entity.name","parentof"], + ["text","("], + ["string","\"john\""], + ["keyword.other",","], + ["text"," "], + ["string","\"bob\""], + ["text",")"], + ["keyword.end","."] +],[ + "start", + ["entity.name","parentof"], + ["text","("], + ["string","\"bob\""], + ["keyword.other",","], + ["text"," "], + ["string","\"ebbon\""], + ["text",")"], + ["keyword.end","."] +],[ + "start" +],[ + "start", + ["entity.name","parentof"], + ["text","("], + ["string","\"douglas\""], + ["keyword.other",","], + ["text"," "], + ["string","\"jane\""], + ["text",")"], + ["keyword.end","."] +],[ + "start", + ["entity.name","parentof"], + ["text","("], + ["string","\"jane\""], + ["keyword.other",","], + ["text"," "], + ["string","\"jan\""], + ["text",")"], + ["keyword.end","."] +],[ + "start" +],[ + "start", + ["entity.name","ancestorof"], + ["text","("], + ["variable.parameter","A"], + ["keyword.other",","], + ["text"," "], + ["variable.parameter","B"], + ["text",") "], + ["keyword.start","<-"], + ["text"," "], + ["entity.name","parentof"], + ["text","("], + ["variable.parameter","A"], + ["keyword.other",","], + ["text"," "], + ["variable.parameter","B"], + ["text",")"], + ["keyword.end","."] +],[ + "start", + ["entity.name","ancestorof"], + ["text","("], + ["variable.parameter","A"], + ["keyword.other",","], + ["text"," "], + ["variable.parameter","C"], + ["text",") "], + ["keyword.start","<-"], + ["text"," "], + ["entity.name","ancestorof"], + ["text","("], + ["variable.parameter","A"], + ["keyword.other",","], + ["text"," "], + ["variable.parameter","B"], + ["text",")"], + ["keyword.other",","], + ["text"," "], + ["entity.name","parentof"], + ["text","("], + ["variable.parameter","B"], + ["keyword.other",","], + ["variable.parameter","C"], + ["text",")"], + ["keyword.end","."] +],[ + "start" +],[ + "start", + ["entity.name","grandparentof"], + ["text","("], + ["variable.parameter","A"], + ["keyword.other",","], + ["text"," "], + ["variable.parameter","B"], + ["text",") "], + ["keyword.start","<-"], + ["text"," "], + ["entity.name","parentof"], + ["text","("], + ["variable.parameter","A"], + ["keyword.other",","], + ["text"," "], + ["variable.parameter","C"], + ["text",")"], + ["keyword.other",","], + ["text"," "], + ["entity.name","parentof"], + ["text","("], + ["variable.parameter","C"], + ["keyword.other",","], + ["text"," "], + ["variable.parameter","B"], + ["text",")"], + ["keyword.end","."] +],[ + "start" +],[ + "start", + ["entity.name","cousins"], + ["text","("], + ["variable.parameter","A"], + ["keyword.other",","], + ["variable.parameter","B"], + ["text",") "], + ["keyword.start","<-"], + ["text"," "], + ["entity.name","grandparentof"], + ["text","("], + ["variable.parameter","C"], + ["keyword.other",","], + ["variable.parameter","A"], + ["text",")"], + ["keyword.other",","], + ["text"," "], + ["entity.name","grandparentof"], + ["text","("], + ["variable.parameter","C"], + ["keyword.other",","], + ["variable.parameter","B"], + ["text",")"], + ["keyword.end","."] +],[ + "start" +],[ + "start", + ["entity.name","parentof"], + ["text","["], + ["entity.name.type.logicblox","`arg"], + ["text","]("], + ["variable.parameter","A"], + ["keyword.other",","], + ["text"," "], + ["variable.parameter","B"], + ["text",") "], + ["keyword.start","->"], + ["text"," "], + ["entity.name","int"], + ["text","["], + ["constant.numeric","32"], + ["text","]("], + ["variable.parameter","A"], + ["text",")"], + ["keyword.other",","], + ["text"," "], + ["keyword.other","!"], + ["entity.name","string"], + ["text","("], + ["variable.parameter","B"], + ["text",")"], + ["keyword.end","."] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_lsl.json b/lib/ace/mode/_test/tokens_lsl.json new file mode 100644 index 00000000..2248a607 --- /dev/null +++ b/lib/ace/mode/_test/tokens_lsl.json @@ -0,0 +1,503 @@ +[[ + "comment", + ["comment.block.begin.lsl","/*"] +],[ + "comment", + ["comment.block.lsl"," Testing syntax highlighting"] +],[ + "comment", + ["comment.block.lsl"," of Ace Editor"] +],[ + "comment", + ["comment.block.lsl"," for the Linden Scripting Language"] +],[ + "start", + ["comment.block.end.lsl","*/"] +],[ + "start" +],[ + "start", + ["storage.type.lsl","integer"], + ["text.lsl"," "], + ["identifier","someIntNormal"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["constant.numeric.lsl","3672"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["storage.type.lsl","integer"], + ["text.lsl"," "], + ["identifier","someIntHex"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["constant.numeric.lsl","0x00000000"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["storage.type.lsl","integer"], + ["text.lsl"," "], + ["identifier","someIntMath"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["constant.language.float.lsl","PI_BY_TWO"], + ["punctuation.operator.lsl",";"] +],[ + "start" +],[ + "start", + ["storage.type.lsl","integer"], + ["text.lsl"," "], + ["invalid.illegal.lsl","event"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["constant.numeric.lsl","5673"], + ["punctuation.operator.lsl",";"], + ["text.lsl"," "], + ["comment.line.double-slash.lsl","// invalid.illegal"] +],[ + "start" +],[ + "start", + ["storage.type.lsl","key"], + ["text.lsl"," "], + ["identifier","someKeyTexture"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["constant.language.string.lsl","TEXTURE_DEFAULT"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["storage.type.lsl","string"], + ["text.lsl"," "], + ["identifier","someStringSpecial"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["constant.language.string.lsl","EOF"], + ["punctuation.operator.lsl",";"] +],[ + "start" +],[ + "start", + ["identifier","some_user_defined_function_without_return_type"], + ["paren.lparen.lsl","("], + ["storage.type.lsl","string"], + ["text.lsl"," "], + ["identifier","inputAsString"], + ["paren.rparen.lsl",")"] +],[ + "start", + ["paren.lparen.lsl","{"] +],[ + "start", + ["text.lsl"," "], + ["support.function.lsl","llSay"], + ["paren.lparen.lsl","("], + ["constant.language.integer.lsl","PUBLIC_CHANNEL"], + ["punctuation.operator.lsl",","], + ["text.lsl"," "], + ["identifier","inputAsString"], + ["paren.rparen.lsl",")"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["paren.rparen.lsl","}"] +],[ + "start" +],[ + "start", + ["storage.type.lsl","string"], + ["text.lsl"," "], + ["identifier","user_defined_function_returning_a_string"], + ["paren.lparen.lsl","("], + ["storage.type.lsl","key"], + ["text.lsl"," "], + ["identifier","inputAsKey"], + ["paren.rparen.lsl",")"] +],[ + "start", + ["paren.lparen.lsl","{"] +],[ + "start", + ["text.lsl"," "], + ["keyword.control.lsl","return"], + ["text.lsl"," "], + ["paren.lparen.lsl","("], + ["storage.type.lsl","string"], + ["paren.rparen.lsl",")"], + ["identifier","inputAsKey"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["paren.rparen.lsl","}"] +],[ + "start" +],[ + "start", + ["entity.name.state.lsl","default"] +],[ + "start", + ["paren.lparen.lsl","{"] +],[ + "start", + ["text.lsl"," "], + ["support.function.event.lsl","state_entry"], + ["paren.lparen.lsl","("], + ["paren.rparen.lsl",")"] +],[ + "start", + ["text.lsl"," "], + ["paren.lparen.lsl","{"] +],[ + "start", + ["text.lsl"," "], + ["storage.type.lsl","key"], + ["text.lsl"," "], + ["identifier","someKey"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["constant.language.string.lsl","NULL_KEY"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["text.lsl"," "], + ["identifier","someKey"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["support.function.lsl","llGetOwner"], + ["paren.lparen.lsl","("], + ["paren.rparen.lsl",")"], + ["punctuation.operator.lsl",";"] +],[ + "start" +],[ + "start", + ["text.lsl"," "], + ["storage.type.lsl","string"], + ["text.lsl"," "], + ["identifier","someString"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["identifier","user_defined_function_returning_a_string"], + ["paren.lparen.lsl","("], + ["identifier","someKey"], + ["paren.rparen.lsl",")"], + ["punctuation.operator.lsl",";"] +],[ + "start" +],[ + "start", + ["text.lsl"," "], + ["identifier","some_user_defined_function_without_return_type"], + ["paren.lparen.lsl","("], + ["identifier","someString"], + ["paren.rparen.lsl",")"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["text.lsl"," "], + ["paren.rparen.lsl","}"] +],[ + "start" +],[ + "start", + ["text.lsl"," "], + ["support.function.event.lsl","touch_start"], + ["paren.lparen.lsl","("], + ["storage.type.lsl","integer"], + ["text.lsl"," "], + ["identifier","num_detected"], + ["paren.rparen.lsl",")"] +],[ + "start", + ["text.lsl"," "], + ["paren.lparen.lsl","{"] +],[ + "start", + ["text.lsl"," "], + ["storage.type.lsl","list"], + ["text.lsl"," "], + ["identifier","agentsInRegion"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["support.function.lsl","llGetAgentList"], + ["paren.lparen.lsl","("], + ["constant.language.integer.lsl","AGENT_LIST_REGION"], + ["punctuation.operator.lsl",","], + ["text.lsl"," "], + ["paren.lparen.lsl","["], + ["paren.rparen.lsl","])"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["text.lsl"," "], + ["storage.type.lsl","integer"], + ["text.lsl"," "], + ["identifier","numOfAgents"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["support.function.lsl","llGetListLength"], + ["paren.lparen.lsl","("], + ["identifier","agentsInRegion"], + ["paren.rparen.lsl",")"], + ["punctuation.operator.lsl",";"] +],[ + "start" +],[ + "start", + ["text.lsl"," "], + ["storage.type.lsl","integer"], + ["text.lsl"," "], + ["identifier","index"], + ["punctuation.operator.lsl",";"], + ["text.lsl"," "], + ["comment.line.double-slash.lsl","// defaults to 0"] +],[ + "start", + ["text.lsl"," "], + ["keyword.control.lsl","for"], + ["text.lsl"," "], + ["paren.lparen.lsl","("], + ["punctuation.operator.lsl",";"], + ["text.lsl"," "], + ["identifier","index"], + ["text.lsl"," "], + ["keyword.operator.lsl","<="], + ["text.lsl"," "], + ["identifier","numOfAgents"], + ["text.lsl"," "], + ["keyword.operator.lsl","-"], + ["text.lsl"," "], + ["constant.numeric.lsl","1"], + ["punctuation.operator.lsl",";"], + ["text.lsl"," "], + ["identifier","index"], + ["keyword.operator.lsl","++"], + ["paren.rparen.lsl",")"], + ["text.lsl"," "], + ["comment.line.double-slash.lsl","// for each agent in region"] +],[ + "start", + ["text.lsl"," "], + ["paren.lparen.lsl","{"] +],[ + "start", + ["text.lsl"," "], + ["support.function.lsl","llRegionSayTo"], + ["paren.lparen.lsl","("], + ["support.function.lsl","llList2Key"], + ["paren.lparen.lsl","("], + ["identifier","agentsInRegion"], + ["punctuation.operator.lsl",","], + ["text.lsl"," "], + ["identifier","index"], + ["paren.rparen.lsl",")"], + ["punctuation.operator.lsl",","], + ["text.lsl"," "], + ["constant.language.integer.lsl","PUBLIC_CHANNEL"], + ["punctuation.operator.lsl",","], + ["text.lsl"," "], + ["string.quoted.double.lsl.start","\""], + ["string.quoted.double.lsl","Hello, Avatar!"], + ["string.quoted.double.lsl.end","\""], + ["paren.rparen.lsl",")"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["text.lsl"," "], + ["paren.rparen.lsl","}"] +],[ + "start", + ["text.lsl"," "], + ["paren.rparen.lsl","}"] +],[ + "start" +],[ + "start", + ["text.lsl"," "], + ["support.function.event.lsl","touch_end"], + ["paren.lparen.lsl","("], + ["storage.type.lsl","integer"], + ["text.lsl"," "], + ["identifier","num_detected"], + ["paren.rparen.lsl",")"] +],[ + "start", + ["text.lsl"," "], + ["paren.lparen.lsl","{"] +],[ + "start", + ["text.lsl"," "], + ["identifier","someIntNormal"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["constant.numeric.lsl","3672"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["text.lsl"," "], + ["identifier","someIntHex"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["constant.numeric.lsl","0x00000000"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["text.lsl"," "], + ["identifier","someIntMath"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["constant.language.float.lsl","PI_BY_TWO"], + ["punctuation.operator.lsl",";"] +],[ + "start" +],[ + "start", + ["text.lsl"," "], + ["invalid.illegal.lsl","event"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["constant.numeric.lsl","5673"], + ["punctuation.operator.lsl",";"], + ["text.lsl"," "], + ["comment.line.double-slash.lsl","// invalid.illegal"] +],[ + "start" +],[ + "start", + ["text.lsl"," "], + ["identifier","someKeyTexture"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["constant.language.string.lsl","TEXTURE_DEFAULT"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["text.lsl"," "], + ["identifier","someStringSpecial"], + ["text.lsl"," "], + ["keyword.operator.lsl","="], + ["text.lsl"," "], + ["constant.language.string.lsl","EOF"], + ["punctuation.operator.lsl",";"] +],[ + "start" +],[ + "start", + ["text.lsl"," "], + ["reserved.godmode.lsl","llSetInventoryPermMask"], + ["paren.lparen.lsl","("], + ["string.quoted.double.lsl.start","\""], + ["string.quoted.double.lsl","some item"], + ["string.quoted.double.lsl.end","\""], + ["punctuation.operator.lsl",","], + ["text.lsl"," "], + ["constant.language.integer.lsl","MASK_NEXT"], + ["punctuation.operator.lsl",","], + ["text.lsl"," "], + ["constant.language.integer.lsl","PERM_ALL"], + ["paren.rparen.lsl",")"], + ["punctuation.operator.lsl",";"], + ["text.lsl"," "], + ["comment.line.double-slash.lsl","// reserved.godmode"] +],[ + "start" +],[ + "start", + ["text.lsl"," "], + ["support.function.lsl","llWhisper"], + ["paren.lparen.lsl","("], + ["constant.language.integer.lsl","PUBLIC_CHANNEL"], + ["punctuation.operator.lsl",","], + ["text.lsl"," "], + ["string.quoted.double.lsl.start","\""], + ["string.quoted.double.lsl","Leaving "], + ["constant.character.escape.lsl","\\\""], + ["string.quoted.double.lsl","default"], + ["constant.character.escape.lsl","\\\""], + ["string.quoted.double.lsl"," now..."], + ["string.quoted.double.lsl.end","\""], + ["paren.rparen.lsl",")"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["text.lsl"," "], + ["entity.name.state.lsl","state other"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["text.lsl"," "], + ["paren.rparen.lsl","}"] +],[ + "start", + ["paren.rparen.lsl","}"] +],[ + "start" +],[ + "start", + ["entity.name.state.lsl","state other"] +],[ + "start", + ["paren.lparen.lsl","{"] +],[ + "start", + ["text.lsl"," "], + ["support.function.event.lsl","state_entry"], + ["paren.lparen.lsl","("], + ["paren.rparen.lsl",")"] +],[ + "start", + ["text.lsl"," "], + ["paren.lparen.lsl","{"] +],[ + "start", + ["text.lsl"," "], + ["support.function.lsl","llWhisper"], + ["paren.lparen.lsl","("], + ["constant.language.integer.lsl","PUBLIC_CHANNEL"], + ["punctuation.operator.lsl",","], + ["text.lsl"," "], + ["string.quoted.double.lsl.start","\""], + ["string.quoted.double.lsl","Entered "], + ["constant.character.escape.lsl","\\\""], + ["string.quoted.double.lsl","state other"], + ["constant.character.escape.lsl","\\\""], + ["string.quoted.double.lsl",", returning to "], + ["constant.character.escape.lsl","\\\""], + ["string.quoted.double.lsl","default"], + ["constant.character.escape.lsl","\\\""], + ["string.quoted.double.lsl"," again..."], + ["string.quoted.double.lsl.end","\""], + ["paren.rparen.lsl",")"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["text.lsl"," "], + ["entity.name.state.lsl","state default"], + ["punctuation.operator.lsl",";"] +],[ + "start", + ["text.lsl"," "], + ["paren.rparen.lsl","}"] +],[ + "start", + ["paren.rparen.lsl","}"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_lua.json b/lib/ace/mode/_test/tokens_lua.json new file mode 100644 index 00000000..b60c7cb1 --- /dev/null +++ b/lib/ace/mode/_test/tokens_lua.json @@ -0,0 +1,348 @@ +[[ + ["bracketedComment",2,"start"], + ["comment","--[[--"] +],[ + ["bracketedComment",2,"start"], + ["comment","num_args takes in 5.1 byte code and extracts the number of arguments"] +],[ + ["bracketedComment",2,"start"], + ["comment","from its function header."] +],[ + "start", + ["comment","--]]--"] +],[ + "start" +],[ + "start", + ["keyword","function"], + ["text"," "], + ["identifier","int"], + ["paren.lparen","("], + ["identifier","t"], + ["paren.rparen",")"] +],[ + "start", + ["text","\t"], + ["keyword","return"], + ["text"," "], + ["identifier","t"], + ["keyword.operator",":"], + ["support.function","byte"], + ["paren.lparen","("], + ["constant.numeric","1"], + ["paren.rparen",")"], + ["keyword.operator","+"], + ["identifier","t"], + ["keyword.operator",":"], + ["support.function","byte"], + ["paren.lparen","("], + ["constant.numeric","2"], + ["paren.rparen",")"], + ["keyword.operator","*"], + ["constant.numeric","0x100"], + ["keyword.operator","+"], + ["identifier","t"], + ["keyword.operator",":"], + ["support.function","byte"], + ["paren.lparen","("], + ["constant.numeric","3"], + ["paren.rparen",")"], + ["keyword.operator","*"], + ["constant.numeric","0x10000"], + ["keyword.operator","+"], + ["identifier","t"], + ["keyword.operator",":"], + ["support.function","byte"], + ["paren.lparen","("], + ["constant.numeric","4"], + ["paren.rparen",")"], + ["keyword.operator","*"], + ["constant.numeric","0x1000000"] +],[ + "start", + ["keyword","end"] +],[ + "start" +],[ + "start", + ["keyword","function"], + ["text"," "], + ["identifier","num_args"], + ["paren.lparen","("], + ["identifier","func"], + ["paren.rparen",")"] +],[ + "start", + ["text","\t"], + ["keyword","local"], + ["text"," "], + ["support.function","dump"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.library","string"], + ["text","."], + ["support.function","dump"], + ["paren.lparen","("], + ["identifier","func"], + ["paren.rparen",")"] +],[ + "start", + ["text","\t"], + ["keyword","local"], + ["text"," "], + ["identifier","offset"], + ["text",", "], + ["identifier","cursor"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","int"], + ["paren.lparen","("], + ["support.function","dump"], + ["keyword.operator",":"], + ["support.function","sub"], + ["paren.lparen","("], + ["constant.numeric","13"], + ["paren.rparen","))"], + ["text",", "], + ["identifier","offset"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","26"] +],[ + "start", + ["text","\t"], + ["comment","--Get the params and var flag (whether there's a ... in the param)"] +],[ + "start", + ["text","\t"], + ["keyword","return"], + ["text"," "], + ["support.function","dump"], + ["keyword.operator",":"], + ["support.function","sub"], + ["paren.lparen","("], + ["identifier","cursor"], + ["paren.rparen",")"], + ["keyword.operator",":"], + ["support.function","byte"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text",", "], + ["support.function","dump"], + ["keyword.operator",":"], + ["support.function","sub"], + ["paren.lparen","("], + ["identifier","cursor"], + ["keyword.operator","+"], + ["constant.numeric","1"], + ["paren.rparen",")"], + ["keyword.operator",":"], + ["support.function","byte"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["keyword","end"] +],[ + "start" +],[ + "start", + ["comment","-- Usage:"] +],[ + "start", + ["identifier","num_args"], + ["paren.lparen","("], + ["keyword","function"], + ["paren.lparen","("], + ["identifier","a"], + ["text",","], + ["identifier","b"], + ["text",","], + ["identifier","c"], + ["text",","], + ["identifier","d"], + ["text",", "], + ["keyword.operator","..."], + ["paren.rparen",")"], + ["text"," "], + ["keyword","end"], + ["paren.rparen",")"], + ["text"," "], + ["comment","-- return 4, 7"] +],[ + "start" +],[ + "start", + ["comment","-- Python styled string format operator"] +],[ + "start", + ["keyword","local"], + ["text"," "], + ["identifier","gm"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.library","debug"], + ["text","."], + ["support.function","getmetatable"], + ["paren.lparen","("], + ["string","\"\""], + ["paren.rparen",")"] +],[ + "start" +],[ + "start", + ["identifier","gm"], + ["text","."], + ["support.function","__mod"], + ["keyword.operator","="], + ["keyword","function"], + ["paren.lparen","("], + ["variable.language","self"], + ["text",", "], + ["identifier","other"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["support.function","type"], + ["paren.lparen","("], + ["identifier","other"], + ["paren.rparen",")"], + ["text"," "], + ["keyword.operator","~="], + ["text"," "], + ["string","\"table\""], + ["text"," "], + ["keyword","then"], + ["text"," "], + ["identifier","other"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","{"], + ["identifier","other"], + ["paren.rparen","}"], + ["text"," "], + ["keyword","end"] +],[ + "start", + ["text"," "], + ["keyword","for"], + ["text"," "], + ["identifier","i"], + ["text",","], + ["identifier","v"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["support.function","ipairs"], + ["paren.lparen","("], + ["identifier","other"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","do"], + ["text"," "], + ["identifier","other"], + ["paren.lparen","["], + ["identifier","i"], + ["paren.rparen","]"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["support.function","tostring"], + ["paren.lparen","("], + ["identifier","v"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","end"] +],[ + "start", + ["text"," "], + ["keyword","return"], + ["text"," "], + ["variable.language","self"], + ["keyword.operator",":"], + ["support.function","format"], + ["paren.lparen","("], + ["support.function","unpack"], + ["paren.lparen","("], + ["identifier","other"], + ["paren.rparen","))"] +],[ + "start", + ["keyword","end"] +],[ + "start" +],[ + ["bracketedString",5,"start"], + ["support.function","print"], + ["paren.lparen","("], + ["comment","[===["] +],[ + ["bracketedString",5,"start"], + ["comment"," blah blah %s, (%d %d)"] +],[ + "start", + ["comment","]===]"], + ["keyword.operator","%"], + ["paren.lparen","{"], + ["string","\"blah\""], + ["text",", "], + ["identifier","num_args"], + ["paren.lparen","("], + ["identifier","int"], + ["paren.rparen",")})"] +],[ + "start" +],[ + ["bracketedComment",3,"start"], + ["comment","--[=[--"] +],[ + ["bracketedComment",3,"start"], + ["comment","table.maxn is deprecated, use # instead."] +],[ + "start", + ["comment","--]=]--"] +],[ + "start", + ["support.function","print"], + ["paren.lparen","("], + ["constant.library","table"], + ["text","."], + ["invalid.deprecated","maxn"], + ["paren.lparen","{"], + ["constant.numeric","1"], + ["text",","], + ["constant.numeric","2"], + ["text",","], + ["paren.lparen","["], + ["constant.numeric","4"], + ["paren.rparen","]"], + ["keyword.operator","="], + ["constant.numeric","4"], + ["text",","], + ["paren.lparen","["], + ["constant.numeric","8"], + ["paren.rparen","]"], + ["keyword.operator","="], + ["constant.numeric","8"], + ["paren.rparen",")"], + ["text"," "], + ["comment","-- outputs 8 instead of 2"] +],[ + "start" +],[ + "start", + ["support.function","print"], + ["paren.lparen","("], + ["constant.numeric","5"], + ["text"," "], + ["comment","--[[ blah ]]"], + ["paren.rparen",")"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_luapage.json b/lib/ace/mode/_test/tokens_luapage.json new file mode 100644 index 00000000..1fa765dd --- /dev/null +++ b/lib/ace/mode/_test/tokens_luapage.json @@ -0,0 +1,633 @@ +[[ + "doctype", + ["text.xml",""], + ["xml-pe.doctype.xml",""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","html"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + ["lua-bracketedComment",2,"lua-start"], + ["keyword","<%"], + ["text"," "], + ["comment","--[[--"] +],[ + ["lua-bracketedComment",2,"lua-start"], + ["comment"," index.lp from the Kepler Project's LuaDoc HTML doclet."] +],[ + ["lua-bracketedComment",2,"lua-start"], + ["comment"," http://keplerproject.github.com/luadoc/"] +],[ + "start", + ["comment","--]]"], + ["text"," "], + ["keyword","%>"] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","head"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","title"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Reference"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","link"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","rel"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"stylesheet\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\""], + ["keyword","<%="], + ["identifier","luadoc"], + ["text","."], + ["identifier","doclet"], + ["text","."], + ["identifier","html"], + ["text","."], + ["identifier","link"], + ["paren.lparen","("], + ["string","\"luadoc.css\""], + ["paren.rparen",")"], + ["keyword","%>"], + ["string.attribute-value.xml","\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","type"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"text/css\""], + ["text.tag-whitespace.xml"," "], + ["meta.tag.punctuation.tag-close.xml","/>"] +],[ + "start", + ["text.xml","\t"], + ["comment.xml",""] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","body"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","div"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"container\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","div"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"product\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml","\t"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","div"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"product_logo\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml","\t"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","div"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"product_name\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","big"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","b"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.end-tag-open.xml",""], + ["meta.tag.punctuation.end-tag-open.xml",""], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml","\t"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","div"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"product_description\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""], + ["text.xml"," "], + ["comment.xml",""] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","div"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"main\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","div"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"navigation\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["keyword","<%="], + ["identifier","luadoc"], + ["text","."], + ["identifier","doclet"], + ["text","."], + ["identifier","html"], + ["text","."], + ["identifier","include"], + ["paren.lparen","("], + ["string","\"menu.lp\""], + ["text",", "], + ["paren.lparen","{"], + ["text"," "], + ["identifier","doc"], + ["keyword.operator","="], + ["identifier","doc"], + ["text"," "], + ["paren.rparen","})"], + ["keyword","%>"] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""], + ["text.xml"," "], + ["comment.xml",""] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","div"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"content\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start" +],[ + "start" +],[ + "start", + ["keyword","<%if"], + ["text"," "], + ["keyword","not"], + ["text"," "], + ["identifier","options"], + ["text","."], + ["identifier","nomodules"], + ["text"," "], + ["keyword","and"], + ["text"," "], + ["keyword.operator","#"], + ["identifier","doc"], + ["text","."], + ["identifier","modules"], + ["text"," "], + ["keyword.operator",">"], + ["text"," "], + ["constant.numeric","0"], + ["text"," "], + ["keyword","then%>"] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","h2"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Modules"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","table"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","class"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"module_list\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["comment.xml",""] +],[ + "start", + ["keyword","<%for"], + ["text"," "], + ["identifier","_"], + ["text",", "], + ["identifier","modulename"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["support.function","ipairs"], + ["paren.lparen","("], + ["identifier","doc"], + ["text","."], + ["identifier","modules"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","do%>"] +],[ + "start", + ["text.xml","\t"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","tr"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml","\t\t"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","td"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","class"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"name\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.anchor.tag-name.xml","a"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\""], + ["keyword","<%="], + ["identifier","luadoc"], + ["text","."], + ["identifier","doclet"], + ["text","."], + ["identifier","html"], + ["text","."], + ["identifier","module_link"], + ["paren.lparen","("], + ["identifier","modulename"], + ["text",", "], + ["identifier","doc"], + ["paren.rparen",")"], + ["keyword","%>"], + ["string.attribute-value.xml","\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["keyword","<%="], + ["identifier","modulename"], + ["keyword","%>"], + ["meta.tag.punctuation.end-tag-open.xml",""], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml","\t\t"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","td"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","class"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"summary\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["keyword","<%="], + ["identifier","doc"], + ["text","."], + ["identifier","modules"], + ["paren.lparen","["], + ["identifier","modulename"], + ["paren.rparen","]"], + ["text","."], + ["identifier","summary"], + ["keyword","%>"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml","\t"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["keyword","<%end%>"] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["keyword","<%end%>"] +],[ + "start" +],[ + "start" +],[ + "start" +],[ + "start", + ["keyword","<%if"], + ["text"," "], + ["keyword","not"], + ["text"," "], + ["identifier","options"], + ["text","."], + ["identifier","nofiles"], + ["text"," "], + ["keyword","and"], + ["text"," "], + ["keyword.operator","#"], + ["identifier","doc"], + ["text","."], + ["identifier","files"], + ["text"," "], + ["keyword.operator",">"], + ["text"," "], + ["constant.numeric","0"], + ["text"," "], + ["keyword","then%>"] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","h2"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Files"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","table"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","class"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"file_list\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["comment.xml",""] +],[ + "start", + ["keyword","<%for"], + ["text"," "], + ["identifier","_"], + ["text",", "], + ["identifier","filepath"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["support.function","ipairs"], + ["paren.lparen","("], + ["identifier","doc"], + ["text","."], + ["identifier","files"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","do%>"] +],[ + "start", + ["text.xml","\t"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","tr"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml","\t\t"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","td"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","class"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"name\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.anchor.tag-name.xml","a"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\""], + ["keyword","<%="], + ["identifier","luadoc"], + ["text","."], + ["identifier","doclet"], + ["text","."], + ["identifier","html"], + ["text","."], + ["identifier","file_link"], + ["paren.lparen","("], + ["identifier","filepath"], + ["paren.rparen",")"], + ["keyword","%>"], + ["string.attribute-value.xml","\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["keyword","<%="], + ["identifier","filepath"], + ["keyword","%>"], + ["meta.tag.punctuation.end-tag-open.xml",""], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml","\t\t"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.table.tag-name.xml","td"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","class"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"summary\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml","\t"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["keyword","<%end%>"] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["keyword","<%end%>"] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""], + ["text.xml"," "], + ["comment.xml",""] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""], + ["text.xml"," "], + ["comment.xml",""] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","div"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"about\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml","\t"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","p"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.anchor.tag-name.xml","a"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"http://validator.w3.org/check?uri=referer\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.image.tag-name.xml","img"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","src"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"http://www.w3.org/Icons/valid-xhtml10\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","alt"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"Valid XHTML 1.0!\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","height"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"31\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","width"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"88\""], + ["text.tag-whitespace.xml"," "], + ["meta.tag.punctuation.tag-close.xml","/>"], + ["meta.tag.punctuation.end-tag-open.xml",""], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""], + ["text.xml"," "], + ["comment.xml",""] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""], + ["text.xml"," "], + ["comment.xml",""], + ["text.xml","\t"] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_lucene.json b/lib/ace/mode/_test/tokens_lucene.json new file mode 100644 index 00000000..1f6d2985 --- /dev/null +++ b/lib/ace/mode/_test/tokens_lucene.json @@ -0,0 +1,92 @@ +[[ + "start", + ["keyword","test:"], + ["text"," recognises "], + ["keyword.operator","AND"], + ["text"," as keyword"] +],[ + "start", + ["keyword","test:"], + ["text"," recognises "], + ["keyword.operator","OR"], + ["text"," as keyword"] +],[ + "start", + ["keyword","test:"], + ["text"," recognises "], + ["keyword.operator","NOT"], + ["text"," as keyword"] +],[ + "start", + ["keyword","test:"], + ["text"," recognises "], + ["string","\"hello this is dog\""], + ["text"," as string"] +],[ + "start", + ["keyword","test:"], + ["text"," recognises "], + ["constant.character.negation","-"], + ["string","\"hello this is dog\""], + ["text"," as negation with string"] +],[ + "start", + ["keyword","test:"], + ["text"," recognises "], + ["constant.character.proximity","~100"], + ["text"," as text with proximity"] +],[ + "start", + ["keyword","test:"], + ["text"," recognises "], + ["string","\"hello this is dog\""], + ["constant.character.proximity","~100"], + ["text"," as string with proximity"] +],[ + "start", + ["keyword","test:"], + ["text"," recognises "], + ["keyword","raw:"], + ["string","\"hello this is dog\""], + ["text"," as keyword"] +],[ + "start", + ["keyword","test:"], + ["text"," recognises "], + ["keyword","raw:"], + ["text","foo as\"keyword'"] +],[ + "start", + ["keyword","test:"], + ["text"," recognises "], + ["string","\"(\""], + ["text"," as opening parenthesis"] +],[ + "start", + ["keyword","test:"], + ["text"," recognises "], + ["string","\")\""], + ["text"," as closing parenthesis"] +],[ + "start", + ["keyword","test:"], + ["text"," recognises foo"], + ["constant.character.asterisk","*"], + ["text"," as text with asterisk"] +],[ + "start", + ["keyword","test:"], + ["text"," recognises foo"], + ["constant.character.interro","?"], + ["text"," as text with interro"] +],[ + "start", + ["keyword","test:"], + ["text"," recognises single word as text"] +],[ + "start", + ["text"," foo"] +],[ + "start", + ["text"," "] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_markdown.json b/lib/ace/mode/_test/tokens_markdown.json new file mode 100644 index 00000000..29e878b2 --- /dev/null +++ b/lib/ace/mode/_test/tokens_markdown.json @@ -0,0 +1,114 @@ +[[ + "start", + ["text.xml","test: header 1 "] +],[ + "start", + ["markup.heading.1","#"], + ["heading","f"] +],[ + "start", + ["text.xml","test: header 2"] +],[ + "start", + ["markup.heading.2","##"], + ["heading"," foo"] +],[ + "start", + ["text.xml","test: header ends with ' #'"] +],[ + "start", + ["markup.heading.1","#"], + ["heading"," # # "] +],[ + "start", + ["text.xml","test: header ends with '#'"] +],[ + "start", + ["markup.heading.1","#"], + ["heading","foo# "] +],[ + "start", + ["text.xml","test: 6+ #s is not a valid header"] +],[ + "start", + ["text.xml","####### foo"] +],[ + "start", + ["text.xml","test: # followed be only space is not a valid header"] +],[ + "start", + ["text.xml","# "] +],[ + "start", + ["text.xml","test: only space between #s is not a valid header"] +],[ + "start", + ["text.xml","# #"] +],[ + "allowBlock" +],[ + "start", + ["markup.heading.1","#"], + ["heading"," test links "], + ["text","["], + ["string","Cloud9 IDE"], + ["text","]("], + ["markup.underline","http://www.c9.io/"], + ["text",")"], + ["heading"," #"] +],[ + "listblock", + ["markup.list","* "], + ["text","["], + ["string","demo"], + ["text","]("], + ["markup.underline","http://ajaxorg.github.com/ace/"], + ["text",")"], + ["list"," "], + ["text","["], + ["string","+"], + ["text","]("], + ["markup.underline","escape(\\) "], + ["text",")"], + ["list"," "], + ["text","["], + ["string","+"], + ["text","]("], + ["markup.underline","a"], + ["string"," \"title\""], + ["text",")"], + ["list"," "], + ["text","["], + ["string","+"], + ["text","]("], + ["markup.underline","a"], + ["string"," \"space\" "], + ["text",")"] +],[ + "listblock", + ["markup.list","* "], + ["list","usually "], + ["string.emphasis","*work*"], + ["list"," fine ("], + ["string.emphasis","_em_"], + ["list",")"] +],[ + "listblock", + ["list","in lists"] +],[ + "start" +],[ + "start", + ["text.xml","in plain text "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","b"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","http://ace.ajaxorg.com"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","b"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "allowBlock" +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_mask.json b/lib/ace/mode/_test/tokens_mask.json new file mode 100644 index 00000000..5f2b9762 --- /dev/null +++ b/lib/ace/mode/_test/tokens_mask.json @@ -0,0 +1,302 @@ +[[ + "start", + ["comment","/* Mask Syntax Demo */"] +],[ + "start" +],[ + "start", + ["keyword.support.constant.language","div"], + ["text"," "], + ["paren.lparen",">"], + ["text"," "], + ["string.start","'"], + ["string"," Test "], + ["paren.lparen.markup.italic","~["], + ["identifier","name"], + ["paren.rparen.markup.italic","]"], + ["string.end","'"], + ["paren.rparen",";"] +],[ + "start" +],[ + "start", + ["keyword","define"], + ["text"," :"], + ["support.variable.class","userProfile"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text","\t"], + ["keyword.support.constant.language","header"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text","\t\t"], + ["keyword.support.constant.language","h4"], + ["text"," "], + ["paren.lparen",">"], + ["text"," "], + ["support.function.markup.bold","@title"], + ["paren.lparen",";"] +],[ + "start", + ["text","\t\t"], + ["keyword.support.constant.language","button"], + ["support.variable.class",".close"], + ["paren.lparen",";"] +],[ + "start", + ["text","\t"], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["support.function.markup.bold",":userProfile"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text","\t"], + ["support.function.markup.bold","@title"], + ["text"," "], + ["paren.lparen",">"], + ["text"," "], + ["string.start","'"], + ["string"," Hello "], + ["paren.lparen.markup.italic","~["], + ["keyword.control.markup.italic",":"], + ["text"," "], + ["identifier","username"], + ["punctuation.operator","."], + ["support.function","toUpperCase"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["paren.rparen.markup.italic","]"], + ["string.end","'"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + ["paren.lparen52","constant.language40"], + ["constant.language","style"], + ["text"," "], + ["paren.lparen","{"] +],[ + ["css-block-ruleset","paren.lparen52","paren.lparen52","constant.language40"], + ["text"," "], + ["constant","html"], + ["text",", "], + ["constant","body"], + ["text"," "], + ["paren.lparen","{"] +],[ + ["css-block-ruleset","paren.lparen52","paren.lparen52","constant.language40"], + ["text"," "], + ["support.type","background"], + ["text",": "], + ["support.function","url("], + ["string","'name.png'"], + ["support.function",")"], + ["text"," "], + ["constant.numeric","0"], + ["text"," "], + ["constant.numeric","0"], + ["text"," "], + ["support.constant","no-repeat"], + ["text",";"] +],[ + ["paren.lparen52","constant.language40"], + ["text"," "], + ["paren.rparen","}"] +],[ + ["#tmp","css-block-end","paren.lparen52","constant.language40"], + ["paren.rparen","}"] +],[ + ["#tmp","start","paren.lparen52","constant.language40"] +],[ + ["#tmp","start","paren.lparen52","constant.language40"], + ["keyword.support.constant.language","button"], + ["text"," "], + ["paren.lparen","{"] +],[ + ["paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["text","\t"], + ["constant.language","event"], + ["text"," "], + ["support.variable.class","click"], + ["text"," "], + ["paren.lparen","("], + ["identifier","e"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + ["#tmp","js-block-start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["text","\t "], + ["variable.language","this"], + ["punctuation.operator","."], + ["identifier","textContent"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string.quasi.start","`"], + ["string.quasi","name "], + ["paren.quasi.start","${"], + ["identifier","e"], + ["punctuation.operator","."], + ["identifier","clientX"], + ["paren.quasi.end","}"], + ["string.quasi"," !"], + ["string.quasi.end","`"], + ["punctuation.operator",";"] +],[ + ["#tmp","js-block-end","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["text","\t"], + ["paren.rparen","}"] +],[ + ["#tmp","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["paren.rparen","}"] +],[ + ["#tmp","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"] +],[ + ["paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["constant.language","md"], + ["text"," "], + ["paren.lparen",">"], + ["text"," "], + ["paren.lparen","\"\"\""] +],[ + ["#tmp","md-multiline-allowBlock","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"] +],[ + ["#tmp","md-multiline-listblock","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["markup.list","- "], + ["list","div"] +],[ + ["#tmp","md-multiline-listblock","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["markup.list","- "], + ["list","span"] +],[ + ["#tmp","md-multiline-listblock","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["list"," "] +],[ + ["#tmp","md-multiline-listblock","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["list","Hello"] +],[ + ["#tmp","md-multiline-start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"] +],[ + ["#tmp","md-multiline-start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["text","["], + ["string","one"], + ["text","]("], + ["markup.underline","http://google.com"], + ["text",")"] +],[ + ["#tmp","md-multiline-allowBlock","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"] +],[ + ["#tmp","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["paren.rparen","\"\"\";"] +],[ + ["#tmp","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"] +],[ + ["#tmp","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"] +],[ + ["#tmp","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["keyword.support.constant.language","header"], + ["text"," "], + ["support.variable.class",".foo"], + ["text"," "], + ["paren.lparen",">"], + ["text"," "], + ["string.start","'"], + ["string","Heading"], + ["string.end","'"] +],[ + ["#tmp","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"] +],[ + ["string.start2","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["keyword.support.constant.language","button"], + ["text"," "], + ["support.variable.class",".baz"], + ["text"," "], + ["support.variable.class.markup.bold","x-signal"], + ["keyword.operator","="], + ["string.start","'"], + ["string","click: test"], + ["string.end","'"], + ["text"," "], + ["support.variable.class","disabled"], + ["text"," "], + ["paren.lparen",">"], + ["text"," "], + ["string.start","\""] +],[ + ["string.start2","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["string","\tHello,"] +],[ + ["string.start2","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["string","\tworld "] +],[ + ["string.start2","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["string","\t"], + ["string.escape","\\\""], + ["string","Buddy"], + ["string.escape","\\\""] +],[ + ["#tmp","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["string.end","\""] +],[ + ["#tmp","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"] +],[ + ["#tmp","js-statement-start","start","js-statement-no_regex","constant.language53","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["constant.language","var"], + ["text"," "], + ["identifier","a"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren","{"] +],[ + ["#tmp","js-statement-no_regex","start","js-statement-no_regex","constant.language53","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["text"," "], + ["identifier","name"], + ["punctuation.operator",":"], + ["text"," "], + ["string.quasi.start","`"], + ["string.quasi","name "], + ["paren.quasi.start","${"], + ["variable.language","window"], + ["punctuation.operator","."], + ["support.constant","innerWidth"], + ["paren.rparen","}"], + ["string.quasi.end","`"] +],[ + ["#tmp","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["paren.rparen","};"] +],[ + ["#tmp","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"] +],[ + ["#tmp","start","paren.lparen13","constant.language","constant.language","start","paren.lparen39","constant.language27","constant.language27","start","paren.lparen52","constant.language40"], + ["keyword.support.constant.language","span"], + ["text"," "], + ["support.variable.class",".foo"], + ["text"," "], + ["paren.lparen",">"], + ["text"," "], + ["string.start","\""], + ["paren.lparen.markup.italic","~["], + ["keyword.control.markup.italic","bind:"], + ["text"," "], + ["identifier","a"], + ["punctuation.operator","."], + ["identifier","name"], + ["paren.rparen.markup.italic","]"], + ["string.end","\""] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_matlab.json b/lib/ace/mode/_test/tokens_matlab.json new file mode 100644 index 00000000..6b4a8567 --- /dev/null +++ b/lib/ace/mode/_test/tokens_matlab.json @@ -0,0 +1,90 @@ +[[ + ["blockComment","noQstring"], + ["comment.start","%{"] +],[ + ["blockComment","blockComment","blockComment","noQstring"], + ["comment.start"," %{"] +],[ + ["blockComment","blockComment","blockComment","noQstring"], + ["comment"," Ace Matlab demo"] +],[ + ["blockComment","noQstring"], + ["comment.end"," %}"] +],[ + "noQstring", + ["comment.end","%}"] +],[ + "start" +],[ + "start", + ["keyword","classdef"], + ["text"," "], + ["identifier","hello"] +],[ + "start", + ["text"," "], + ["support.function","methods"] +],[ + "start", + ["text"," "], + ["keyword","function"], + ["text"," "], + ["identifier","greet"], + ["paren.lparen","("], + ["identifier","this"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["support.function","disp"], + ["paren.lparen","("], + ["string","'Hello!'"], + ["paren.rparen",")"], + ["text"," "], + ["comment","% say hi"] +],[ + "start", + ["text"," "], + ["keyword","end"] +],[ + "start", + ["text"," "], + ["keyword","end"] +],[ + "start", + ["keyword","end"] +],[ + "noQstring" +],[ + "start", + ["comment","% transpose "] +],[ + "qqstring", + ["identifier","a"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","["], + ["text"," "], + ["string","'x"], + ["constant.language.escape","''"], + ["string","y'"], + ["punctuation.operator",","], + ["text"," "], + ["string","\"x"], + ["constant.language.escape","\\n"], + ["string","\\"] +],[ + "start", + ["string"," y\""], + ["punctuation.operator",","], + ["text"," "], + ["constant.numeric","1"], + ["text","' "], + ["paren.rparen","]"], + ["text","' "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","2"], + ["text","'"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_mel.json b/lib/ace/mode/_test/tokens_mel.json new file mode 100644 index 00000000..a2d618a9 --- /dev/null +++ b/lib/ace/mode/_test/tokens_mel.json @@ -0,0 +1,257 @@ +[[ + "start", + ["comment.line.double-slash.mel","//"], + ["punctuation.definition.comment.mel"," animated duplicates, instances script"] +],[ + "start", + ["meta.function.mel","proc"], + ["keyword.other.mel"," "], + ["storage.type.mel","animatedDuplication"], + ["entity.name.function.mel"," ("], + ["punctuation.section.function.mel","("], + ["meta.function.mel","int $rangeStart, int $rangeEnd, int $numOfDuplicates, int $duplicateOrInstance"], + ["punctuation.section.function.mel",")"], + "proc animatedDuplication (int $rangeStart, int $rangeEnd, int $numOfDuplicates, int $duplicateOrInstance)" +],[ + "start", + ["text","{"] +],[ + "start", + ["text"," "], + ["storage.type.mel","int"], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","range_start"], + ["text"," "], + ["keyword.operator.symbolic.mel","="], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","rangeStart"], + ["text",";"] +],[ + "start", + ["text"," "], + ["storage.type.mel","int"], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","range_end"], + ["text"," "], + ["keyword.operator.symbolic.mel","="], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","rangeEnd"], + ["text",";"] +],[ + "start", + ["text"," "], + ["storage.type.mel","int"], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","num_of_duplicates"], + ["text"," "], + ["keyword.operator.symbolic.mel","="], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","numOfDuplicates"], + ["text",";"] +],[ + "start", + ["text"," "], + ["storage.type.mel","int"], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","step_size"], + ["text"," "], + ["keyword.operator.symbolic.mel","="], + ["text"," ("], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","range_end"], + ["text"," "], + ["keyword.operator.symbolic.mel","-"], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","range_start"], + ["text",") "], + ["keyword.operator.symbolic.mel","/"], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","num_of_duplicates"], + ["text",";"] +],[ + "start", + ["text"," "], + ["storage.type.mel","int"], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","i"], + ["text"," "], + ["keyword.operator.symbolic.mel","="], + ["text"," "], + ["constant.numeric.mel","0"], + ["text",";"] +],[ + "start", + ["text"," "], + ["storage.type.mel","int"], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","temp"], + ["text",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["support.function.mel","currentTime"], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","range_start"], + ["text","; "], + ["comment.line.double-slash.mel","//"], + ["punctuation.definition.comment.mel"," set to range start"] +],[ + "start" +],[ + "start", + ["text"," "], + ["storage.type.mel","string"], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","selectedObjects"], + ["text","[]; "], + ["comment.line.double-slash.mel","//"], + ["punctuation.definition.comment.mel"," to store selected objects"] +],[ + "start", + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","selectedObjects"], + ["text"," "], + ["keyword.operator.symbolic.mel","="], + ["text"," `"], + ["support.function.mel","ls"], + ["text"," "], + ["keyword.operator.symbolic.mel","-"], + ["text","sl`; "], + ["comment.line.double-slash.mel","//"], + ["punctuation.definition.comment.mel"," store selected objects"] +],[ + "start", + ["text"," "], + ["support.function.mel","select"], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","selectedObjects"], + ["text",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword.control.mel","while"], + ["text"," ("], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","i"], + ["text"," <"], + ["keyword.operator.symbolic.mel","="], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","num_of_duplicates"], + ["text",")"] +],[ + "start", + ["text"," {"] +],[ + "start", + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","temp"], + ["text"," "], + ["keyword.operator.symbolic.mel","="], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","range_start"], + ["text"," "], + ["keyword.operator.symbolic.mel","+"], + ["text"," ("], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","step_size"], + ["text"," "], + ["keyword.operator.symbolic.mel","*"], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","i"], + ["text",");"] +],[ + "start", + ["text"," "], + ["support.function.mel","currentTime"], + ["text"," ("], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","temp"], + ["text",");"] +],[ + "start", + ["text"," "], + ["comment.line.double-slash.mel","//"], + ["punctuation.definition.comment.mel"," seleced the objects to duplicate or instance"] +],[ + "start", + ["text"," "], + ["support.function.mel","select"], + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","selectedObjects"], + ["text",";"] +],[ + "start", + ["text"," "], + ["keyword.control.mel","if"], + ["text","("], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","duplicateOrInstance"], + ["text"," "], + ["keyword.operator.symbolic.mel","=="], + ["text"," "], + ["constant.numeric.mel","0"], + ["text",")"] +],[ + "start", + ["text"," {"] +],[ + "start", + ["text"," "], + ["support.function.mel","duplicate"], + ["text",";"] +],[ + "start", + ["text"," }"] +],[ + "start", + ["text"," "], + ["keyword.control.mel","else"] +],[ + "start", + ["text"," {"] +],[ + "start", + ["text"," "], + ["support.function.mel","instance"], + ["text",";"] +],[ + "start", + ["text"," }"] +],[ + "start", + ["text"," "], + ["variable.other.mel","$"], + ["punctuation.definition.variable.mel","i"], + ["keyword.operator.symbolic.mel","++"], + ["text",";"] +],[ + "start", + ["text"," }"] +],[ + "start", + ["text","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_mushcode.json b/lib/ace/mode/_test/tokens_mushcode.json new file mode 100644 index 00000000..9f8e7cc2 --- /dev/null +++ b/lib/ace/mode/_test/tokens_mushcode.json @@ -0,0 +1,790 @@ +[[ + "start", + ["text","@"], + ["support.function","create"], + ["text"," "], + ["identifier","phone"] +],[ + "start", + ["text","&"], + ["identifier","pickup"], + ["text"," "], + ["identifier","phone"], + ["keyword.operator","="], + ["identifier","$pick"], + ["text"," "], + ["identifier","up"], + ["text",":@"], + ["support.function","ifelse"], + ["text"," "], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","is"], + ["text",","], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","mode"], + ["paren.rparen",")"], + ["text",","], + ["identifier","ICC"], + ["paren.rparen",")]"], + ["keyword.operator","="], + ["paren.lparen","{"], + ["text","@"], + ["support.function","pemit"], + ["text"," "], + ["keyword.operator","%#="], + ["identifier","You"], + ["text"," "], + ["support.function","pick"], + ["text"," "], + ["identifier","up"], + ["text"," "], + ["identifier","the"], + ["text"," "], + ["paren.lparen","["], + ["support.function","fullname"], + ["paren.lparen","("], + ["identifier","me"], + ["paren.rparen",")]"], + ["text","."], + ["paren.lparen","["], + ["support.function","set"], + ["paren.lparen","("], + ["identifier","me"], + ["text",","], + ["identifier","PHONER"], + ["text",":"], + ["keyword.operator","%#"], + ["paren.rparen",")]"], + ["paren.lparen","["], + ["support.function","set"], + ["paren.lparen","("], + ["identifier","me"], + ["text",","], + ["identifier","MODE"], + ["text",":"], + ["identifier","CIP"], + ["paren.rparen",")]"], + ["paren.lparen","["], + ["support.function","set"], + ["paren.lparen","(["], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","INCOMING"], + ["paren.rparen",")]"], + ["text",","], + ["identifier","CONNECTED"], + ["text",":"], + ["paren.lparen","["], + ["support.function","num"], + ["paren.lparen","("], + ["identifier","me"], + ["paren.rparen",")])]"], + ["paren.lparen","["], + ["support.function","set"], + ["paren.lparen","("], + ["identifier","me"], + ["text",","], + ["identifier","CONNECTED"], + ["text",":"], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","INCOMING"], + ["paren.rparen",")])]"], + ["variable","%r"], + ["paren.lparen","["], + ["support.function","showpicture"], + ["paren.lparen","("], + ["identifier","PICPICKUP"], + ["paren.rparen",")]"], + ["variable","%r"], + ["identifier","Use"], + ["text"," '"], + ["paren.lparen","["], + ["identifier","color"], + ["paren.lparen","("], + ["identifier","green"], + ["text",","], + ["identifier","black"], + ["text",","], + ["identifier","psay"], + ["text"," "], + ["keyword.operator","<"], + ["identifier","message"], + ["keyword.operator",">"], + ["paren.rparen",")]"], + ["text","' "], + ["paren.lparen","("], + ["support.function","or"], + ["text"," '"], + ["paren.lparen","["], + ["identifier","color"], + ["paren.lparen","("], + ["identifier","green"], + ["text",","], + ["identifier","black"], + ["text",","], + ["identifier","p"], + ["text"," "], + ["keyword.operator","<"], + ["identifier","message"], + ["keyword.operator",">"], + ["paren.rparen",")]"], + ["text","'"], + ["paren.rparen",")"], + ["text"," "], + ["identifier","to"], + ["text"," "], + ["identifier","talk"], + ["text"," "], + ["identifier","into"], + ["text"," "], + ["identifier","the"], + ["text"," "], + ["identifier","phone"], + ["text",".;@"], + ["support.function","oemit"], + ["text"," "], + ["keyword.operator","%#="], + ["variable","%N"], + ["text"," "], + ["identifier","picks"], + ["text"," "], + ["identifier","up"], + ["text"," "], + ["identifier","the"], + ["text"," "], + ["paren.lparen","["], + ["support.function","fullname"], + ["paren.lparen","("], + ["identifier","me"], + ["paren.rparen",")]"], + ["text","."], + ["paren.rparen","}"], + ["text",","], + ["paren.lparen","{"], + ["text","@"], + ["support.function","pemit"], + ["text"," "], + ["keyword.operator","%#="], + ["identifier","You"], + ["text"," "], + ["support.function","pick"], + ["text"," "], + ["identifier","up"], + ["text"," "], + ["identifier","the"], + ["text"," "], + ["identifier","phone"], + ["text"," "], + ["identifier","but"], + ["text"," "], + ["identifier","no"], + ["text"," "], + ["identifier","one"], + ["text"," "], + ["identifier","is"], + ["text"," "], + ["identifier","there"], + ["text",". "], + ["identifier","You"], + ["text"," "], + ["identifier","hear"], + ["text"," "], + ["identifier","a"], + ["text"," "], + ["identifier","dialtone"], + ["text"," "], + ["support.function","and"], + ["text"," "], + ["identifier","then"], + ["text"," "], + ["identifier","hang"], + ["text"," "], + ["identifier","up"], + ["text",". "], + ["paren.lparen","["], + ["support.function","play"], + ["paren.lparen","("], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","DIALTONE"], + ["paren.rparen","))]"], + ["text",";@"], + ["support.function","oemit"], + ["text"," "], + ["keyword.operator","%#="], + ["variable","%N"], + ["text"," "], + ["identifier","picks"], + ["text"," "], + ["identifier","up"], + ["text"," "], + ["identifier","the"], + ["text"," "], + ["identifier","phone"], + ["text",", "], + ["identifier","but"], + ["text"," "], + ["identifier","no"], + ["text"," "], + ["identifier","one"], + ["text"," "], + ["identifier","is"], + ["text"," "], + ["identifier","on"], + ["text"," "], + ["identifier","the"], + ["text"," "], + ["identifier","other"], + ["text"," "], + ["identifier","end"], + ["text","."], + ["paren.rparen","}"] +],[ + "start", + ["text","&"], + ["identifier","ringfun"], + ["text"," "], + ["identifier","phone"], + ["keyword.operator","="], + ["paren.lparen","["], + ["support.function","ifelse"], + ["paren.lparen","("], + ["support.function","eq"], + ["paren.lparen","("], + ["support.function","comp"], + ["paren.lparen","(["], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%0"], + ["keyword.operator","/"], + ["identifier","ringtone"], + ["paren.rparen",")]"], + ["text",","], + ["identifier","off"], + ["paren.rparen",")"], + ["text",","], + ["constant.numeric","0"], + ["paren.rparen",")"], + ["text",","], + ["paren.lparen","["], + ["identifier","color"], + ["paren.lparen","("], + ["identifier","black"], + ["text",","], + ["identifier","cyan"], + ["text",","], + ["identifier","INCOMING"], + ["text"," "], + ["identifier","CALL"], + ["text"," "], + ["identifier","FROM"], + ["text"," "], + ["variable","%1"], + ["paren.rparen",")]"], + ["text",","], + ["paren.lparen","["], + ["support.function","play"], + ["paren.lparen","(["], + ["support.function","switch"], + ["paren.lparen","(["], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%0"], + ["keyword.operator","/"], + ["identifier","ringtone"], + ["paren.rparen",")]"], + ["text",","], + ["constant.numeric","1"], + ["text",","], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%0"], + ["keyword.operator","/"], + ["identifier","ringtone1"], + ["paren.rparen",")]"], + ["text",","], + ["constant.numeric","2"], + ["text",","], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%0"], + ["keyword.operator","/"], + ["identifier","ringtone2"], + ["paren.rparen",")]"], + ["text",","], + ["constant.numeric","3"], + ["text",","], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%0"], + ["keyword.operator","/"], + ["identifier","ringtone3"], + ["paren.rparen",")]"], + ["text",","], + ["constant.numeric","4"], + ["text",","], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%0"], + ["keyword.operator","/"], + ["identifier","ringtone4"], + ["paren.rparen",")]"], + ["text",","], + ["constant.numeric","5"], + ["text",","], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%0"], + ["keyword.operator","/"], + ["identifier","ringtone5"], + ["paren.rparen",")]"], + ["text",","], + ["constant.numeric","6"], + ["text",","], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%0"], + ["keyword.operator","/"], + ["identifier","ringtone6"], + ["paren.rparen",")]"], + ["text",","], + ["constant.numeric","7"], + ["text",","], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%0"], + ["keyword.operator","/"], + ["identifier","ringtone7"], + ["paren.rparen",")]"], + ["text",","], + ["constant.numeric","8"], + ["text",","], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%0"], + ["keyword.operator","/"], + ["identifier","ringtone8"], + ["paren.rparen",")]"], + ["text",","], + ["constant.numeric","9"], + ["text",","], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%0"], + ["keyword.operator","/"], + ["identifier","ringtone9"], + ["paren.rparen",")]"], + ["text",","], + ["identifier","custom"], + ["text",","], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%0"], + ["keyword.operator","/"], + ["identifier","customtone"], + ["paren.rparen",")]"], + ["text",","], + ["identifier","vibrate"], + ["text",","], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%0"], + ["keyword.operator","/"], + ["identifier","vibrate"], + ["paren.rparen",")])])]"] +],[ + "start", + ["text","&"], + ["identifier","ringloop"], + ["text"," "], + ["identifier","phone"], + ["keyword.operator","="], + ["text","@"], + ["support.function","switch"], + ["text"," "], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","ringstate"], + ["paren.rparen",")]"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["text",","], + ["paren.lparen","{"], + ["text","@"], + ["support.function","emit"], + ["text"," "], + ["paren.lparen","["], + ["support.function","setq"], + ["paren.lparen","("], + ["identifier","q"], + ["text",","], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","connecting"], + ["paren.rparen",")])]"], + ["paren.lparen","["], + ["support.function","set"], + ["paren.lparen","("], + ["variable","%qq"], + ["text",","], + ["identifier","rangs"], + ["text",":"], + ["constant.numeric","0"], + ["paren.rparen",")]"], + ["paren.lparen","["], + ["support.function","set"], + ["paren.lparen","("], + ["variable","%qq"], + ["text",","], + ["identifier","mode"], + ["text",":"], + ["identifier","WFC"], + ["paren.rparen",")]"], + ["paren.lparen","["], + ["support.function","set"], + ["paren.lparen","("], + ["variable","%qq"], + ["text",","], + ["identifier","INCOMING"], + ["text",":"], + ["paren.rparen",")]"], + ["text",";@"], + ["support.function","ifelse"], + ["text"," "], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%qq"], + ["keyword.operator","/"], + ["identifier","HASVMB"], + ["paren.rparen",")]"], + ["keyword.operator","="], + ["paren.lparen","{"], + ["text","@"], + ["support.function","tr"], + ["text"," "], + ["identifier","me"], + ["keyword.operator","/"], + ["identifier","ROUTEVMB"], + ["keyword.operator","="], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","connecting"], + ["paren.rparen",")]"], + ["text",";"], + ["paren.rparen","}"], + ["text",","], + ["paren.lparen","{"], + ["text","@"], + ["support.function","pemit"], + ["text"," "], + ["keyword.operator","%#="], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","MSGCNC"], + ["paren.rparen",")]"], + ["text",";"], + ["paren.rparen","}}"], + ["text",","], + ["constant.numeric","2"], + ["text",","], + ["paren.lparen","{"], + ["text","@"], + ["support.function","pemit"], + ["text"," "], + ["keyword.operator","%#="], + ["identifier","The"], + ["text"," "], + ["identifier","call"], + ["text"," "], + ["identifier","is"], + ["text"," "], + ["identifier","connected"], + ["text","."], + ["paren.lparen","["], + ["support.function","setq"], + ["paren.lparen","("], + ["identifier","q"], + ["text",","], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","CONNECTING"], + ["paren.rparen",")])]"], + ["paren.lparen","["], + ["support.function","set"], + ["paren.lparen","("], + ["identifier","me"], + ["text",","], + ["identifier","CONNECTED"], + ["text",":"], + ["variable","%qq"], + ["paren.rparen",")]"], + ["paren.lparen","["], + ["support.function","set"], + ["paren.lparen","("], + ["variable","%qq"], + ["text",","], + ["identifier","CONNECTED"], + ["text",":"], + ["paren.lparen","["], + ["support.function","num"], + ["paren.lparen","("], + ["identifier","me"], + ["paren.rparen",")])]"], + ["paren.lparen","["], + ["support.function","set"], + ["paren.lparen","("], + ["variable","%qq"], + ["text",","], + ["identifier","MODE"], + ["text",":"], + ["identifier","CIP"], + ["paren.rparen",")]"], + ["text",";@"], + ["support.function","tr"], + ["text"," "], + ["identifier","me"], + ["keyword.operator","/"], + ["identifier","ciploop"], + ["text",";@"], + ["support.function","tr"], + ["text"," "], + ["variable","%qq"], + ["keyword.operator","/"], + ["identifier","ciploop"], + ["text",";"], + ["paren.rparen","}"], + ["text",","], + ["constant.numeric","3"], + ["text",","], + ["paren.lparen","{"], + ["text","@"], + ["support.function","emit"], + ["text"," "], + ["identifier","On"], + ["text"," "], + ["paren.lparen","["], + ["support.function","fullname"], + ["paren.lparen","("], + ["identifier","me"], + ["paren.rparen",")]"], + ["text","'"], + ["support.function","s"], + ["text"," "], + ["identifier","earpiece"], + ["text"," "], + ["identifier","you"], + ["text"," "], + ["identifier","hear"], + ["text"," "], + ["identifier","a"], + ["text"," "], + ["identifier","ringing"], + ["text"," "], + ["identifier","sound"], + ["text","."], + ["paren.lparen","["], + ["support.function","play"], + ["paren.lparen","("], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","LINETONE"], + ["paren.rparen","))]"], + ["text",";@"], + ["support.function","tr"], + ["text"," "], + ["identifier","me"], + ["keyword.operator","/"], + ["identifier","ringhere"], + ["text",";@"], + ["identifier","increment"], + ["text"," "], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","connecting"], + ["paren.rparen",")]"], + ["keyword.operator","/"], + ["identifier","RANGS"], + ["text",";@"], + ["identifier","wait"], + ["text"," "], + ["constant.numeric","5"], + ["keyword.operator","="], + ["paren.lparen","{"], + ["text","@"], + ["support.function","tr"], + ["text"," "], + ["identifier","me"], + ["keyword.operator","/"], + ["identifier","ringloop"], + ["paren.rparen","}"], + ["text",";"], + ["paren.rparen","}"], + ["text",","], + ["constant.numeric","4"], + ["text",","], + ["paren.lparen","{"], + ["paren.rparen","}"] +],[ + "start", + ["text","&"], + ["identifier","ringstate"], + ["text"," "], + ["identifier","phone"], + ["keyword.operator","="], + ["paren.lparen","["], + ["support.function","setq"], + ["paren.lparen","("], + ["identifier","q"], + ["text",","], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","connecting"], + ["paren.rparen","))]"], + ["paren.lparen","["], + ["support.function","setq"], + ["paren.lparen","("], + ["constant.numeric","1"], + ["text",","], + ["paren.lparen","["], + ["support.function","gt"], + ["paren.lparen","("], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%qq"], + ["keyword.operator","/"], + ["identifier","rangs"], + ["paren.rparen",")"], + ["text",","], + ["support.function","sub"], + ["paren.lparen","("], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%qq"], + ["keyword.operator","/"], + ["identifier","rings"], + ["paren.rparen",")"], + ["text",","], + ["constant.numeric","1"], + ["paren.rparen","))])]"], + ["paren.lparen","["], + ["support.function","setq"], + ["paren.lparen","("], + ["constant.numeric","2"], + ["text",","], + ["paren.lparen","["], + ["support.function","and"], + ["paren.lparen","("], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","is"], + ["text",","], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%qq"], + ["keyword.operator","/"], + ["identifier","MODE"], + ["paren.rparen",")"], + ["text",","], + ["identifier","CIP"], + ["paren.rparen",")"], + ["text",","], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","is"], + ["text",","], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%qq"], + ["keyword.operator","/"], + ["identifier","INCOMING"], + ["paren.rparen",")"], + ["text",","], + ["paren.lparen","["], + ["support.function","num"], + ["paren.lparen","("], + ["identifier","me"], + ["paren.rparen",")]))]"], + ["paren.lparen","["], + ["support.function","setq"], + ["paren.lparen","("], + ["constant.numeric","3"], + ["text",","], + ["paren.lparen","["], + ["support.function","u"], + ["paren.lparen","("], + ["identifier","is"], + ["text",","], + ["support.function","u"], + ["paren.lparen","("], + ["variable","%qq"], + ["keyword.operator","/"], + ["identifier","MODE"], + ["paren.rparen",")"], + ["text",","], + ["identifier","ICC"], + ["paren.rparen",")])]"], + ["paren.lparen","["], + ["support.function","ifelse"], + ["paren.lparen","("], + ["variable","%q1"], + ["text",","], + ["constant.numeric","1"], + ["text",","], + ["support.function","ifelse"], + ["paren.lparen","("], + ["variable","%q2"], + ["text",","], + ["constant.numeric","2"], + ["text",","], + ["support.function","ifelse"], + ["paren.lparen","("], + ["variable","%q3"], + ["text",","], + ["constant.numeric","3"], + ["text",","], + ["constant.numeric","4"], + ["paren.rparen",")))]"] +],[ + "start", + ["text",";"], + ["identifier","comment"] +],[ + "start", + ["text","@@"], + ["paren.lparen","("], + ["identifier","comment"], + ["paren.rparen",")"] +],[ + "start", + ["keyword","say"], + ["text"," "], + ["paren.lparen","["], + ["support.function","time"], + ["paren.lparen","("], + ["paren.rparen",")]"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_mysql.json b/lib/ace/mode/_test/tokens_mysql.json new file mode 100644 index 00000000..9909eadd --- /dev/null +++ b/lib/ace/mode/_test/tokens_mysql.json @@ -0,0 +1,4 @@ +[[ + "start", + ["identifier","TODO"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_nix.json b/lib/ace/mode/_test/tokens_nix.json new file mode 100644 index 00000000..b9424456 --- /dev/null +++ b/lib/ace/mode/_test/tokens_nix.json @@ -0,0 +1,360 @@ +[[ + "start", + ["text","{"] +],[ + "start", + ["text"," "], + ["comment","# Name of our deployment"] +],[ + "start", + ["text"," "], + ["identifier","network"], + ["text","."], + ["identifier","description"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," "], + ["string","\"HelloWorld\""], + ["text",";"] +],[ + "start", + ["text"," "], + ["comment","# Enable rolling back to previous versions of our infrastructure"] +],[ + "start", + ["text"," "], + ["identifier","network"], + ["text","."], + ["identifier","enableRollback"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," "], + ["constant.language.nix","true"], + ["text",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["comment","# It consists of a single server named 'helloserver'"] +],[ + "start", + ["text"," "], + ["identifier","helloserver"], + ["text"," "], + ["keyword.operator.assignment.nix","="] +],[ + "start", + ["text"," "], + ["comment","# Every server gets passed a few arguments, including a reference"] +],[ + "start", + ["text"," "], + ["comment","# to nixpkgs (pkgs)"] +],[ + "start", + ["text"," { "], + ["identifier","config"], + ["text",", "], + ["identifier","pkgs"], + ["text",", ... }:"] +],[ + "start", + ["text"," "], + ["keyword.declaration.nix","let"] +],[ + "start", + ["text"," "], + ["comment","# We import our custom packages from ./default passing pkgs as argument"] +],[ + "start", + ["text"," "], + ["identifier","packages"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," "], + ["keyword.control.nix","import"], + ["text"," ./"], + ["identifier","default"], + ["text","."], + ["identifier","nix"], + ["text"," { "], + ["identifier","pkgs"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," "], + ["identifier","pkgs"], + ["text","; };"] +],[ + "start", + ["text"," "], + ["comment","# This is the nodejs version specified in default.nix"] +],[ + "start", + ["text"," "], + ["identifier","nodejs"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," "], + ["identifier","packages"], + ["text","."], + ["identifier","nodejs"], + ["text",";"] +],[ + "start", + ["text"," "], + ["comment","# And this is the application we'd like to deploy"] +],[ + "start", + ["text"," "], + ["identifier","app"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," "], + ["identifier","packages"], + ["text","."], + ["identifier","app"], + ["text",";"] +],[ + "start", + ["text"," "], + ["keyword.declaration.nix","in"] +],[ + "start", + ["text"," {"] +],[ + "start", + ["text"," "], + ["comment","# We'll be running our application on port 8080, because a regular"] +],[ + "start", + ["text"," "], + ["comment","# user cannot bind to port 80"] +],[ + "start", + ["text"," "], + ["comment","# Then, using some iptables magic we'll forward traffic designated to port 80 to 8080"] +],[ + "start", + ["text"," "], + ["identifier","networking"], + ["text","."], + ["identifier","firewall"], + ["text","."], + ["identifier","enable"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," "], + ["constant.language.nix","true"], + ["text",";"] +],[ + "start", + ["text"," "], + ["comment","# We will open up port 22 (SSH) as well otherwise we're locking ourselves out"] +],[ + "start", + ["text"," "], + ["identifier","networking"], + ["text","."], + ["identifier","firewall"], + ["text","."], + ["identifier","allowedTCPPorts"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," [ "], + ["constant.numeric","80"], + ["text"," "], + ["constant.numeric","8080"], + ["text"," "], + ["constant.numeric","22"], + ["text"," ];"] +],[ + "start", + ["text"," "], + ["identifier","networking"], + ["text","."], + ["identifier","firewall"], + ["text","."], + ["identifier","allowPing"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," "], + ["constant.language.nix","true"], + ["text",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["comment","# Port forwarding using iptables"] +],[ + "qqdoc", + ["text"," "], + ["identifier","networking"], + ["text","."], + ["identifier","firewall"], + ["text","."], + ["identifier","extraCommands"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," "], + ["string","''"] +],[ + "qqdoc", + ["string"," iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080"] +],[ + "start", + ["string"," ''"], + ["text",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["comment","# To run our node.js program we're going to use a systemd service"] +],[ + "start", + ["text"," "], + ["comment","# We can configure the service to automatically start on boot and to restart"] +],[ + "start", + ["text"," "], + ["comment","# the process in case it crashes"] +],[ + "start", + ["text"," "], + ["identifier","systemd"], + ["text","."], + ["identifier","services"], + ["text","."], + ["identifier","helloserver"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," {"] +],[ + "start", + ["text"," "], + ["identifier","description"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," "], + ["string","\"Hello world application\""], + ["text",";"] +],[ + "start", + ["text"," "], + ["comment","# Start the service after the network is available"] +],[ + "start", + ["text"," "], + ["identifier","after"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," [ "], + ["string","\"network.target\""], + ["text"," ];"] +],[ + "start", + ["text"," "], + ["comment","# We're going to run it on port 8080 in production"] +],[ + "start", + ["text"," "], + ["identifier","environment"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," { "], + ["identifier","PORT"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," "], + ["string","\"8080\""], + ["text","; };"] +],[ + "start", + ["text"," "], + ["identifier","serviceConfig"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," {"] +],[ + "start", + ["text"," "], + ["comment","# The actual command to run"] +],[ + "start", + ["text"," "], + ["identifier","ExecStart"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," "], + ["string","\""], + ["constant.language.escape","${"], + ["identifier","nodejs"], + ["constant.language.escape","}"], + ["string","/bin/node "], + ["constant.language.escape","${"], + ["identifier","app"], + ["constant.language.escape","}"], + ["string","/server.js\""], + ["text",";"] +],[ + "start", + ["text"," "], + ["comment","# For security reasons we'll run this process as a special 'nodejs' user"] +],[ + "start", + ["text"," "], + ["identifier","User"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," "], + ["string","\"nodejs\""], + ["text",";"] +],[ + "start", + ["text"," "], + ["identifier","Restart"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," "], + ["string","\"always\""], + ["text",";"] +],[ + "start", + ["text"," };"] +],[ + "start", + ["text"," };"] +],[ + "start" +],[ + "start", + ["text"," "], + ["comment","# And lastly we ensure the user we run our application as is created"] +],[ + "start", + ["text"," "], + ["identifier","users"], + ["text","."], + ["identifier","extraUsers"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," {"] +],[ + "start", + ["text"," "], + ["identifier","nodejs"], + ["text"," "], + ["keyword.operator.assignment.nix","="], + ["text"," { };"] +],[ + "start", + ["text"," };"] +],[ + "start", + ["text"," };"] +],[ + "start", + ["text","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_objectivec.json b/lib/ace/mode/_test/tokens_objectivec.json new file mode 100644 index 00000000..cdfd1196 --- /dev/null +++ b/lib/ace/mode/_test/tokens_objectivec.json @@ -0,0 +1,793 @@ +[[ + "start", + ["storage.type.objc","@"], + ["punctuation.definition.storage.type.objc","protocol"], + ["entity.name.type.objc"," Printing"], + ["text",": "], + ["entity.other.inherited-class.objc","someParent"] +],[ + "start", + ["meta.function.objc","-"], + ["paren.lparen","("], + ["storage.type","void"], + ["paren.rparen",")"], + ["text"," "], + ["identifier","print"], + ["punctuation.operator",";"] +],[ + "start", + ["storage.type.objc","@end"] +],[ + "start" +],[ + "start", + ["storage.type.objc","@"], + ["punctuation.definition.storage.type.objc","interface"], + ["entity.name.type.objc"," Fraction"], + ["text",": "], + ["entity.other.inherited-class.objc","NSObject"], + ["text"," "], + ["keyword.operator","<"], + ["identifier","Printing"], + ["punctuation.operator",","], + ["text"," "], + ["support.class.cocoa","NSCopying"], + ["keyword.operator",">"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["storage.type","int"], + ["text"," "], + ["identifier","numerator"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["storage.type","int"], + ["text"," "], + ["identifier","denominator"], + ["punctuation.operator",";"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start", + ["storage.type.objc","@end"] +],[ + "start" +],[ + "start", + ["string.begin.objc","@\""], + ["string","blah"], + ["invalid.illegal.unknown-escape.objc","\\8"], + ["punctuation.definition.string.end","\""], + ["text"," "], + ["string.begin.objc","@\""], + ["string","a"], + ["constant.character.escape.objc","\\222"], + ["string","sd"], + ["invalid.illegal.unknown-escape.objc","\\d"], + ["punctuation.definition.string.end","\""], + ["text"," "], + ["string.begin.objc","@\""], + ["constant.character.escape.objc","\\f"], + ["string","aw"], + ["constant.character.escape.objc","\\\"\\?"], + ["string"," "], + ["constant.character.escape.objc","\\'"], + ["string"," "], + ["constant.character.escape.objc","\\4"], + ["string"," n"], + ["constant.character.escape.objc","\\\\"], + ["punctuation.definition.string.end","\""], + ["text"," "], + ["string.begin.objc","@\""], + ["constant.character.escape.objc","\\56"], + ["punctuation.definition.string.end","\""] +],[ + "start", + ["string.begin.objc","@\""], + ["constant.character.escape.objc","\\xSF42"], + ["punctuation.definition.string.end","\""] +],[ + "start" +],[ + "start", + ["meta.function.objc","-"], + ["paren.lparen","("], + ["support.class.cocoa","NSDecimalNumber"], + ["keyword.operator","*"], + ["paren.rparen",")"], + ["identifier","addCount"], + ["punctuation.operator",":"], + ["paren.lparen","("], + ["storage.type.id.objc","id"], + ["paren.rparen",")"], + ["identifier","addObject"], + ["paren.lparen","{"] +],[ + "start" +],[ + "start", + ["keyword.control","return"], + ["text"," "], + ["punctuation.section.scope.begin.objc","["], + ["identifier","count"], + ["text"," "], + ["support.function.any-method.objc","decimalNumberByAdding:"], + ["identifier","addObject"], + ["punctuation.operator","."], + ["identifier","count"], + ["paren.rparen","]"], + ["punctuation.operator",";"] +],[ + "start" +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword.control.macro.objc","NS_DURING"], + ["text"," "], + ["keyword.control.macro.objc","NS_HANDLER"], + ["text"," "], + ["keyword.control.macro.objc","NS_ENDHANDLER"] +],[ + "start" +],[ + "start", + ["punctuation.definition.keyword.objc","@"], + ["keyword.control.exception.objc","try"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword.control","if"], + ["text"," "], + ["paren.lparen","("], + ["identifier","argc"], + ["text"," "], + ["keyword.operator",">"], + ["text"," "], + ["constant.numeric","1"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["punctuation.definition.keyword.objc","@"], + ["keyword.control.exception.objc","throw"], + ["text"," "], + ["punctuation.section.scope.begin.objc","["], + ["support.class.cocoa","NSException"], + ["text"," "], + ["support.function.any-method.objc","exceptionWithName:"], + ["string.begin.objc","@\""], + ["string","Throwing a test exception"], + ["punctuation.definition.string.end","\""], + ["text"," "], + ["identifier","reason"], + ["punctuation.operator",":"], + ["string.begin.objc","@\""], + ["string","Testing the @throw directive."], + ["punctuation.definition.string.end","\""], + ["text"," "], + ["identifier","userInfo"], + ["punctuation.operator",":"], + ["constant.language.objc","nil"], + ["paren.rparen","]"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"], + ["text"," "] +],[ + "start", + ["punctuation.definition.keyword.objc","@"], + ["keyword.control.exception.objc","catch"], + ["text"," "], + ["paren.lparen","("], + ["storage.type.id.objc","id"], + ["text"," "], + ["identifier","theException"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["support.function.cocoa","NSLog"], + ["paren.lparen","("], + ["string.begin.objc","@\""], + ["string","%@"], + ["punctuation.definition.string.end","\""], + ["punctuation.operator",","], + ["text"," "], + ["identifier","theException"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["identifier","result"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","1"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["paren.rparen","}"], + ["text"," "] +],[ + "start", + ["punctuation.definition.keyword.objc","@"], + ["keyword.control.exception.objc","finally"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["support.function.cocoa","NSLog"], + ["paren.lparen","("], + ["string.begin.objc","@\""], + ["string","This always happens."], + ["punctuation.definition.string.end","\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["identifier","result"], + ["text"," "], + ["keyword.operator","+="], + ["text"," "], + ["constant.numeric","2"], + ["text"," "], + ["punctuation.operator",";"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["punctuation.definition.storage.modifier.objc","@"], + ["storage.modifier.objc","synchronized"], + ["paren.lparen","("], + ["identifier","lock"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["support.function.cocoa","NSLog"], + ["paren.lparen","("], + ["string.begin.objc","@\""], + ["string","Hello World"], + ["punctuation.definition.string.end","\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["storage.type","struct"], + ["text"," "], + ["paren.lparen","{"], + ["text"," "], + ["punctuation.definition.keyword.objc","@"], + ["keyword.other.objc","defs"], + ["paren.lparen","("], + ["text"," "], + ["support.class.cocoa","NSObject"], + ["paren.rparen",")"], + ["text"," "], + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["storage.type","char"], + ["text"," "], + ["keyword.operator","*"], + ["identifier","enc1"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["punctuation.definition.keyword.objc","@"], + ["keyword.other.objc","encode"], + ["paren.lparen","("], + ["storage.type","int"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["storage.type.objc","IBOutlet"], + ["text","|"], + ["storage.type.objc","IBAction"], + ["text","|"], + ["storage.type.objc","BOOL"], + ["text","|"], + ["storage.type.objc","SEL"], + ["text","|"], + ["storage.type.id.objc","id"], + ["text","|"], + ["storage.type.objc","unichar"], + ["text","|"], + ["storage.type.objc","IMP"], + ["text","|"], + ["storage.type.objc","Class"], + ["text"," "] +],[ + "start" +],[ + "start" +],[ + "start", + ["text"," "], + ["punctuation.definition.storage.type.objc","@"], + ["storage.type.objc","class"], + ["text"," "], + ["punctuation.definition.storage.type.objc","@"], + ["storage.type.objc","protocol"] +],[ + "start" +],[ + "start", + ["punctuation.definition.storage.modifier.objc","@"], + ["storage.modifier.objc","public"] +],[ + "start", + ["text"," "], + ["comment","// instance variables"] +],[ + "start", + ["punctuation.definition.storage.modifier.objc","@"], + ["storage.modifier.objc","package"] +],[ + "start", + ["text"," "], + ["comment","// instance variables"] +],[ + "start", + ["punctuation.definition.storage.modifier.objc","@"], + ["storage.modifier.objc","protected"] +],[ + "start", + ["text"," "], + ["comment","// instance variables"] +],[ + "start", + ["punctuation.definition.storage.modifier.objc","@"], + ["storage.modifier.objc","private"] +],[ + "start", + ["text"," "], + ["comment","// instance variables"] +],[ + "start" +],[ + "start", + ["text"," "], + ["constant.language.objc","YES"], + ["text"," "], + ["constant.language.objc","NO"], + ["text"," "], + ["constant.language.objc","Nil"], + ["text"," "], + ["constant.language.objc","nil"] +],[ + "start", + ["support.variable.foundation","NSApp"], + ["paren.lparen","("], + ["paren.rparen",")"] +],[ + "start", + ["support.function.cocoa.leopard","NSRectToCGRect"], + ["text"," "], + ["paren.lparen","("], + ["identifier","Protocol"], + ["text"," "], + ["identifier","ProtocolFromString"], + ["punctuation.operator",":"], + ["string","\"NSTableViewDelegate\""], + ["paren.rparen","))"] +],[ + "start" +],[ + "start", + ["punctuation.section.scope.begin.objc","["], + ["identifier","SPPoint"], + ["text"," "], + ["support.function.any-method.objc","pointFromCGPoint:"], + ["identifier","self"], + ["punctuation.operator","."], + ["identifier","position"], + ["paren.rparen","]"] +],[ + "start" +],[ + "start", + ["support.function.cocoa","NSRoundDownToMultipleOfPageSize"] +],[ + "start" +],[ + "start", + ["keyword","#import"], + ["constant.other"," "] +],[ + "start" +],[ + "start", + ["storage.type","int"], + ["text"," "], + ["identifier","main"], + ["paren.lparen","("], + ["text"," "], + ["storage.type","int"], + ["text"," "], + ["identifier","argc"], + ["punctuation.operator",","], + ["text"," "], + ["storage.modifier","const"], + ["text"," "], + ["storage.type","char"], + ["text"," "], + ["keyword.operator","*"], + ["identifier","argv"], + ["punctuation.section.scope.begin.objc","["], + ["punctuation.section.scope.end.objc","]"], + ["text"," "], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["support.function.C99.c","printf"], + ["paren.lparen","("], + ["text"," "], + ["string","\"hello world\\n\""], + ["text"," "], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.control","return"], + ["text"," "], + ["constant.numeric","0"], + ["punctuation.operator",";"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["support.class.cocoa","NSChangeSpelling"] +],[ + "start" +],[ + "start", + ["string.begin.objc","@\""], + ["string","0 != SUBQUERY(image, $x, 0 != SUBQUERY($x.bookmarkItems, $y, $y.@count == 0).@count).@count"], + ["punctuation.definition.string.end","\""] +],[ + "start" +],[ + "start", + ["punctuation.definition.storage.type.objc","@selector"], + ["punctuation","("], + ["support.function.any-method.name-of-parameter.objc","lowercaseString"], + ["punctuation",")"], + ["text"," "], + ["punctuation.definition.storage.type.objc","@selector"], + ["punctuation","("], + ["support.function.any-method.name-of-parameter.objc","uppercaseString:"], + ["punctuation",")"] +],[ + "start" +],[ + "start", + ["identifier","NSFetchRequest"], + ["text"," "], + ["keyword.operator","*"], + ["identifier","localRequest"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["punctuation.section.scope.begin.objc","[["], + ["identifier","NSFetchRequest"], + ["text"," "], + ["support.function.any-method.objc","alloc"], + ["paren.rparen","]"], + ["text"," "], + ["identifier","init"], + ["paren.rparen","]"], + ["punctuation.operator",";"], + ["text"," "] +],[ + "start", + ["identifier","localRequest"], + ["punctuation.operator","."], + ["identifier","entity"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["punctuation.section.scope.begin.objc","["], + ["identifier","NSEntityDescription"], + ["text"," "], + ["support.function.any-method.objc","entityForName:"], + ["string.begin.objc","@\""], + ["string","VNSource"], + ["punctuation.definition.string.end","\""], + ["text"," "], + ["identifier","inManagedObjectContext"], + ["punctuation.operator",":"], + ["identifier","context"], + ["paren.rparen","]"], + ["punctuation.operator",";"], + ["text"," "] +],[ + "start", + ["identifier","localRequest"], + ["punctuation.operator","."], + ["identifier","sortDescriptors"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["punctuation.section.scope.begin.objc","["], + ["support.class.cocoa","NSArray"], + ["text"," "], + ["support.function.any-method.objc","arrayWithObject:"], + ["punctuation.section.scope.begin.objc","["], + ["support.class.cocoa","NSSortDescriptor"], + ["text"," "], + ["support.function.any-method.objc","sortDescriptorWithKey:"], + ["string.begin.objc","@\""], + ["string","resolution"], + ["punctuation.definition.string.end","\""], + ["text"," "], + ["identifier","ascending"], + ["punctuation.operator",":"], + ["constant.language.objc","YES"], + ["paren.rparen","]]"], + ["punctuation.operator",";"], + ["text"," "] +],[ + "start", + ["support.class.cocoa","NSPredicate"], + ["text"," "], + ["keyword.operator","*"], + ["identifier","predicate"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["punctuation.section.scope.begin.objc","["], + ["support.class.cocoa","NSPredicate"], + ["text"," "], + ["support.function.any-method.objc","predicateWithFormat:"], + ["string.begin.objc","@\""], + ["string","0 != SUBQUERY(image, $x, 0 != SUBQUERY($x.bookmarkItems, $y, $y.@count == 0).@count).@count"], + ["punctuation.definition.string.end","\""], + ["paren.rparen","]"], + ["punctuation.operator",";"] +],[ + "start", + ["punctuation.section.scope.begin.objc","["], + ["support.class.cocoa","NSPredicate"], + ["text"," "], + ["support.function.any-method.objc","predicateWithFormat:"], + ["paren.rparen","]"] +],[ + "start", + ["support.class.cocoa","NSString"], + ["text"," "], + ["keyword.operator","*"], + ["identifier","predicateString"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["punctuation.section.scope.begin.objc","["], + ["support.class.cocoa","NSString"], + ["text"," "], + ["support.function.any-method.objc","stringWithFormat:"], + ["string.begin.objc","@\""], + ["string","SELF beginsWith[cd] %@"], + ["punctuation.definition.string.end","\""], + ["punctuation.operator",","], + ["text"," "], + ["identifier","searchString"], + ["paren.rparen","]"], + ["punctuation.operator",";"] +],[ + "start", + ["support.class.cocoa","NSPredicate"], + ["text"," "], + ["keyword.operator","*"], + ["identifier","pred"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["punctuation.section.scope.begin.objc","["], + ["support.class.cocoa","NSPredicate"], + ["text"," "], + ["support.function.any-method.objc","predicateWithFormat:"], + ["identifier","predicateString"], + ["paren.rparen","]"], + ["punctuation.operator",";"] +],[ + "start", + ["support.class.cocoa","NSArray"], + ["text"," "], + ["keyword.operator","*"], + ["identifier","filteredKeys"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["punctuation.section.scope.begin.objc","[["], + ["identifier","myMutableDictionary"], + ["text"," "], + ["support.function.any-method.objc","allKeys"], + ["paren.rparen","]"], + ["text"," "], + ["identifier","filteredArrayUsingPredicate"], + ["punctuation.operator",":"], + ["identifier","pred"], + ["paren.rparen","]"], + ["punctuation.operator",";"], + ["text"," "] +],[ + "start" +],[ + "start", + ["identifier","localRequest"], + ["punctuation.operator","."], + ["identifier","predicate"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["punctuation.section.scope.begin.objc","["], + ["support.class.cocoa","NSPredicate"], + ["text"," "], + ["support.function.any-method.objc","predicateWithFormat:"], + ["string.begin.objc","@\""], + ["string","whichChart = %@"], + ["punctuation.definition.string.end","\""], + ["text"," "], + ["identifier","argumentArray"], + ["punctuation.operator",":"], + ["text"," "], + ["identifier","listChartToDownload"], + ["paren.rparen","]"], + ["punctuation.operator",";"] +],[ + "start", + ["identifier","localRequest"], + ["punctuation.operator","."], + ["identifier","fetchBatchSize"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","100"], + ["punctuation.operator",";"] +],[ + "start", + ["identifier","arrayRequest"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["punctuation.section.scope.begin.objc","["], + ["identifier","context"], + ["text"," "], + ["support.function.any-method.objc","executeFetchRequest:"], + ["identifier","localRequest"], + ["text"," "], + ["identifier","error"], + ["punctuation.operator",":"], + ["keyword.operator","&"], + ["identifier","error1"], + ["paren.rparen","]"], + ["punctuation.operator",";"] +],[ + "start" +],[ + "start", + ["punctuation.section.scope.begin.objc","["], + ["identifier","localRequest"], + ["text"," "], + ["support.function.any-method.objc","release"], + ["paren.rparen","]"], + ["punctuation.operator",";"] +],[ + "start" +],[ + "start", + ["keyword","#ifndef"], + ["text"," "], + ["constant.language.objc","Nil"] +],[ + "start", + ["keyword","#define"], + ["constant.other"," Nil __DARWIN_NULL "], + ["comment","/* id of Nil class */"] +],[ + "start", + ["keyword","#endif"] +],[ + "start" +],[ + "start", + ["storage.type.objc","@implementation"], + ["entity.name.type.objc"," MyObject"] +],[ + "start", + ["meta.function.objc","- "], + ["paren.lparen","("], + ["storage.type","unsigned"], + ["text"," "], + ["storage.type","int"], + ["paren.rparen",")"], + ["identifier","areaOfWidth"], + ["punctuation.operator",":"], + ["paren.lparen","("], + ["storage.type","unsigned"], + ["text"," "], + ["storage.type","int"], + ["paren.rparen",")"], + ["identifier","width"] +],[ + "start", + ["text"," "], + ["identifier","height"], + ["punctuation.operator",":"], + ["paren.lparen","("], + ["storage.type","unsigned"], + ["text"," "], + ["storage.type","int"], + ["paren.rparen",")"], + ["identifier","height"] +],[ + "start", + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword.control","return"], + ["text"," "], + ["identifier","width"], + ["keyword.operator","*"], + ["identifier","height"], + ["punctuation.operator",";"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start", + ["storage.type.objc","@end"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_ocaml.json b/lib/ace/mode/_test/tokens_ocaml.json new file mode 100644 index 00000000..73e3cfcd --- /dev/null +++ b/lib/ace/mode/_test/tokens_ocaml.json @@ -0,0 +1,200 @@ +[[ + "comment", + ["comment","(*"] +],[ + "comment", + ["comment"," * Example of early return implementation taken from"] +],[ + "comment", + ["comment"," * http://ocaml.janestreet.com/?q=node/91"] +],[ + "start", + ["comment"," *)"] +],[ + "start" +],[ + "start", + ["keyword","let"], + ["text"," "], + ["identifier","with_return"], + ["text"," "], + ["paren.lparen","("], + ["keyword","type"], + ["text"," "], + ["identifier","t"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","("], + ["identifier","f"], + ["text"," : "], + ["identifier","_"], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["identifier","t"], + ["paren.rparen",")"], + ["text"," "], + ["keyword.operator","="] +],[ + "start", + ["text"," "], + ["keyword","let"], + ["text"," "], + ["keyword","module"], + ["text"," "], + ["identifier","M"], + ["text"," "], + ["keyword.operator","="] +],[ + "start", + ["text"," "], + ["keyword","struct"], + ["text"," "], + ["keyword","exception"], + ["text"," "], + ["identifier","Return"], + ["text"," "], + ["keyword","of"], + ["text"," "], + ["identifier","t"], + ["text"," "], + ["keyword","end"] +],[ + "start", + ["text"," "], + ["keyword","in"] +],[ + "start", + ["text"," "], + ["keyword","let"], + ["text"," "], + ["identifier","return"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","{"], + ["text"," "], + ["identifier","return"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["keyword","fun"], + ["text"," "], + ["identifier","x"], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["support.function","raise"], + ["text"," "], + ["paren.lparen","("], + ["identifier","M"], + ["text","."], + ["identifier","Return"], + ["text"," "], + ["identifier","x"], + ["paren.rparen","))"], + ["text","; "], + ["paren.rparen","}"], + ["text"," "], + ["keyword","in"] +],[ + "start", + ["text"," "], + ["keyword","try"], + ["text"," "], + ["identifier","f"], + ["text"," "], + ["identifier","return"], + ["text"," "], + ["keyword","with"], + ["text"," "], + ["identifier","M"], + ["text","."], + ["identifier","Return"], + ["text"," "], + ["identifier","x"], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["identifier","x"] +],[ + "start" +],[ + "start" +],[ + "start", + ["comment","(* Function that uses the 'early return' functionality provided by `with_return` *)"] +],[ + "start", + ["keyword","let"], + ["text"," "], + ["identifier","sum_until_first_negative"], + ["text"," "], + ["support.function","list"], + ["text"," "], + ["keyword.operator","="] +],[ + "start", + ["text"," "], + ["identifier","with_return"], + ["text"," "], + ["paren.lparen","("], + ["keyword","fun"], + ["text"," "], + ["identifier","r"], + ["text"," "], + ["keyword.operator","->"] +],[ + "start", + ["text"," "], + ["support.function","List"], + ["text","."], + ["support.function","fold"], + ["text"," "], + ["support.function","list"], + ["text"," "], + ["keyword.operator","~"], + ["support.function","init"], + ["text",":"], + ["constant.numeric","0"], + ["text"," "], + ["keyword.operator","~"], + ["identifier","f"], + ["text",":"], + ["paren.lparen","("], + ["keyword","fun"], + ["text"," "], + ["identifier","acc"], + ["text"," "], + ["identifier","x"], + ["text"," "], + ["keyword.operator","->"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["identifier","x"], + ["text"," "], + ["keyword.operator",">="], + ["text"," "], + ["constant.numeric","0"], + ["text"," "], + ["keyword","then"], + ["text"," "], + ["identifier","acc"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["identifier","x"], + ["text"," "], + ["keyword","else"], + ["text"," "], + ["identifier","r"], + ["text","."], + ["identifier","return"], + ["text"," "], + ["identifier","acc"], + ["paren.rparen","))"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_pascal.json b/lib/ace/mode/_test/tokens_pascal.json new file mode 100644 index 00000000..22c1f0c4 --- /dev/null +++ b/lib/ace/mode/_test/tokens_pascal.json @@ -0,0 +1,297 @@ +[[ + "punctuation.definition.comment.pascal", + ["punctuation.definition.comment.pascal","(*"], + ["comment.block.pascal.one","****************************************************************************"] +],[ + "punctuation.definition.comment.pascal", + ["comment.block.pascal.one"," * A simple bubble sort program. Reads integers, one per line, and prints *"] +],[ + "punctuation.definition.comment.pascal", + ["comment.block.pascal.one"," * them out in sorted order. Blows up if there are more than 49. *"] +],[ + "start", + ["comment.block.pascal.one"," ****************************************************************************"], + ["punctuation.definition.comment.pascal","*)"] +],[ + "start", + ["keyword.control.pascal","PROGRAM"], + ["text"," Sort(input"], + ["keyword.operator",","], + ["text"," output)"], + ["keyword.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.control.pascal","CONST"] +],[ + "start", + ["text"," "], + ["punctuation.definition.comment.pascal","(*"], + ["comment.block.pascal.one"," Max array size. "], + ["punctuation.definition.comment.pascal","*)"] +],[ + "start", + ["text"," MaxElts "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric.pascal","50"], + ["keyword.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.control.pascal","TYPE"], + ["text"," "] +],[ + "start", + ["text"," "], + ["punctuation.definition.comment.pascal","(*"], + ["comment.block.pascal.one"," Type of the element array. "], + ["punctuation.definition.comment.pascal","*)"] +],[ + "start", + ["text"," IntArrType "], + ["keyword.operator","="], + ["text"," "], + ["keyword.control.pascal","ARRAY"], + ["text"," ["], + ["constant.numeric.pascal","1"], + ["text","..MaxElts] "], + ["keyword.control.pascal","OF"], + ["text"," Integer"], + ["keyword.operator",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword.control.pascal","VAR"] +],[ + "start", + ["text"," "], + ["punctuation.definition.comment.pascal","(*"], + ["comment.block.pascal.one"," Indexes, exchange temp, array size. "], + ["punctuation.definition.comment.pascal","*)"] +],[ + "start", + ["text"," i"], + ["keyword.operator",","], + ["text"," j"], + ["keyword.operator",","], + ["text"," tmp"], + ["keyword.operator",","], + ["text"," size: integer"], + ["keyword.operator",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["punctuation.definition.comment.pascal","(*"], + ["comment.block.pascal.one"," Array of ints "], + ["punctuation.definition.comment.pascal","*)"] +],[ + "start", + ["text"," arr: IntArrType"], + ["keyword.operator",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["punctuation.definition.comment.pascal","(*"], + ["comment.block.pascal.one"," Read in the integers. "], + ["punctuation.definition.comment.pascal","*)"] +],[ + "start", + ["text"," "], + ["variable.pascal","PROCEDURE"], + ["text"," "], + ["storage.type.function.pascal","ReadArr"], + ["text","("], + ["keyword.control.pascal","VAR"], + ["text"," size: Integer"], + ["keyword.operator",";"], + ["text"," "], + ["keyword.control.pascal","VAR"], + ["text"," a: IntArrType)"], + ["keyword.operator",";"], + ["text"," "] +],[ + "start", + ["text"," "], + ["keyword.control.pascal","BEGIN"] +],[ + "start", + ["text"," size "], + ["keyword.operator",":="], + ["text"," "], + ["constant.numeric.pascal","1"], + ["keyword.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.control.pascal","WHILE"], + ["text"," "], + ["keyword.control.pascal","NOT"], + ["text"," eof "], + ["keyword.control.pascal","DO"], + ["text"," "], + ["keyword.control.pascal","BEGIN"] +],[ + "start", + ["text"," readln(a[size])"], + ["keyword.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.control.pascal","IF"], + ["text"," "], + ["keyword.control.pascal","NOT"], + ["text"," eof "], + ["keyword.control.pascal","THEN"], + ["text"," "] +],[ + "start", + ["text"," size "], + ["keyword.operator",":="], + ["text"," size "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric.pascal","1"] +],[ + "start", + ["text"," "], + ["keyword.control.pascal","END"] +],[ + "start", + ["text"," "], + ["keyword.control.pascal","END"], + ["keyword.operator",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword.control.pascal","BEGIN"] +],[ + "start", + ["text"," "], + ["punctuation.definition.comment.pascal","(*"], + ["comment.block.pascal.one"," Read "], + ["punctuation.definition.comment.pascal","*)"] +],[ + "start", + ["text"," ReadArr(size"], + ["keyword.operator",","], + ["text"," arr)"], + ["keyword.operator",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["punctuation.definition.comment.pascal","(*"], + ["comment.block.pascal.one"," Sort using bubble sort. "], + ["punctuation.definition.comment.pascal","*)"] +],[ + "start", + ["text"," "], + ["keyword.control.pascal","FOR"], + ["text"," i "], + ["keyword.operator",":="], + ["text"," size "], + ["keyword.operator","-"], + ["text"," "], + ["constant.numeric.pascal","1"], + ["text"," DOWNTO "], + ["constant.numeric.pascal","1"], + ["text"," "], + ["keyword.control.pascal","DO"] +],[ + "start", + ["text"," "], + ["keyword.control.pascal","FOR"], + ["text"," j "], + ["keyword.operator",":="], + ["text"," "], + ["constant.numeric.pascal","1"], + ["text"," "], + ["keyword.control.pascal","TO"], + ["text"," i "], + ["keyword.control.pascal","DO"], + ["text"," "] +],[ + "start", + ["text"," "], + ["keyword.control.pascal","IF"], + ["text"," arr[j] > arr[j "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric.pascal","1"], + ["text","] "], + ["keyword.control.pascal","THEN"], + ["text"," "], + ["keyword.control.pascal","BEGIN"] +],[ + "start", + ["text"," tmp "], + ["keyword.operator",":="], + ["text"," arr[j]"], + ["keyword.operator",";"] +],[ + "start", + ["text"," arr[j] "], + ["keyword.operator",":="], + ["text"," arr[j "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric.pascal","1"], + ["text","]"], + ["keyword.operator",";"] +],[ + "start", + ["text"," arr[j "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric.pascal","1"], + ["text","] "], + ["keyword.operator",":="], + ["text"," tmp"], + ["keyword.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.control.pascal","END"], + ["keyword.operator",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["punctuation.definition.comment.pascal","(*"], + ["comment.block.pascal.one"," Print. "], + ["punctuation.definition.comment.pascal","*)"] +],[ + "start", + ["text"," "], + ["keyword.control.pascal","FOR"], + ["text"," i "], + ["keyword.operator",":="], + ["text"," "], + ["constant.numeric.pascal","1"], + ["text"," "], + ["keyword.control.pascal","TO"], + ["text"," size "], + ["keyword.control.pascal","DO"] +],[ + "start", + ["text"," writeln(arr[i])"] +],[ + "start", + ["text"," "], + ["keyword.control.pascal","END"], + ["text","."] +],[ + "start", + ["text"," "] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_perl.json b/lib/ace/mode/_test/tokens_perl.json new file mode 100644 index 00000000..30bb39c6 --- /dev/null +++ b/lib/ace/mode/_test/tokens_perl.json @@ -0,0 +1,227 @@ +[[ + "start", + ["comment","#!/usr/bin/perl"] +],[ + "block_comment", + ["comment.doc","=begin"] +],[ + "block_comment", + ["comment.doc"," perl example code for Ace"] +],[ + "start", + ["comment.doc","=cut"] +],[ + "start" +],[ + "start", + ["keyword","use"], + ["text"," "], + ["identifier","strict"], + ["text",";"] +],[ + "start", + ["keyword","use"], + ["text"," "], + ["identifier","warnings"], + ["text",";"] +],[ + "start", + ["keyword","my"], + ["text"," "], + ["identifier","$num_primes"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","0"], + ["text",";"] +],[ + "start", + ["keyword","my"], + ["text"," @"], + ["identifier","primes"], + ["text",";"] +],[ + "start" +],[ + "start", + ["comment","# Put 2 as the first prime so we won't have an empty array"] +],[ + "start", + ["identifier","$primes"], + ["lparen","["], + ["identifier","$num_primes"], + ["rparen","]"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","2"], + ["text",";"] +],[ + "start", + ["identifier","$num_primes"], + ["keyword.operator","++"], + ["text",";"] +],[ + "start" +],[ + "start", + ["identifier","MAIN_LOOP"], + ["text",":"] +],[ + "start", + ["keyword","for"], + ["text"," "], + ["keyword","my"], + ["text"," "], + ["identifier","$number_to_check"], + ["text"," "], + ["lparen","("], + ["constant.numeric","3"], + ["text"," "], + ["keyword.operator",".."], + ["text"," "], + ["constant.numeric","200"], + ["rparen",")"] +],[ + "start", + ["lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","for"], + ["text"," "], + ["keyword","my"], + ["text"," "], + ["identifier","$p"], + ["text"," "], + ["lparen","("], + ["constant.numeric","0"], + ["text"," "], + ["keyword.operator",".."], + ["text"," "], + ["lparen","("], + ["identifier","$num_primes"], + ["constant.numeric","-1"], + ["rparen","))"] +],[ + "start", + ["text"," "], + ["lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["lparen","("], + ["identifier","$number_to_check"], + ["text"," "], + ["keyword.operator","%"], + ["text"," "], + ["identifier","$primes"], + ["lparen","["], + ["identifier","$p"], + ["rparen","]"], + ["text"," "], + ["keyword.operator","=="], + ["text"," "], + ["constant.numeric","0"], + ["rparen",")"] +],[ + "start", + ["text"," "], + ["lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","next"], + ["text"," "], + ["identifier","MAIN_LOOP"], + ["text",";"] +],[ + "start", + ["text"," "], + ["rparen","}"] +],[ + "start", + ["text"," "], + ["rparen","}"] +],[ + "start" +],[ + "start", + ["text"," "], + ["comment","# If we reached this point it means $number_to_check is not"] +],[ + "start", + ["text"," "], + ["comment","# divisable by any prime number that came before it."] +],[ + "start", + ["text"," "], + ["identifier","$primes"], + ["lparen","["], + ["identifier","$num_primes"], + ["rparen","]"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","$number_to_check"], + ["text",";"] +],[ + "start", + ["text"," "], + ["identifier","$num_primes"], + ["keyword.operator","++"], + ["text",";"] +],[ + "start", + ["rparen","}"] +],[ + "start" +],[ + "start", + ["keyword","for"], + ["text"," "], + ["keyword","my"], + ["text"," "], + ["identifier","$p"], + ["text"," "], + ["lparen","("], + ["constant.numeric","0"], + ["text"," "], + ["keyword.operator",".."], + ["text"," "], + ["lparen","("], + ["identifier","$num_primes"], + ["constant.numeric","-1"], + ["rparen","))"] +],[ + "start", + ["lparen","{"] +],[ + "start", + ["text"," "], + ["support.function","print"], + ["text"," "], + ["identifier","$primes"], + ["lparen","["], + ["identifier","$p"], + ["rparen","]"], + ["keyword.operator",","], + ["text"," "], + ["string","\", \""], + ["text",";"] +],[ + "start", + ["rparen","}"] +],[ + "start", + ["support.function","print"], + ["text"," "], + ["string","\"\\n\""], + ["text",";"] +],[ + "start" +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_pgsql.json b/lib/ace/mode/_test/tokens_pgsql.json new file mode 100644 index 00000000..fef23fd2 --- /dev/null +++ b/lib/ace/mode/_test/tokens_pgsql.json @@ -0,0 +1,889 @@ +[[ + "start" +],[ + "start", + ["keyword.statementBegin","BEGIN"], + ["statementEnd",";"] +],[ + "start" +],[ + "doc-start", + ["comment.doc","/**"] +],[ + "doc-start", + ["comment.doc","* Samples from PostgreSQL src/tutorial/basics.source"] +],[ + "start", + ["comment.doc","*/"] +],[ + "statement", + ["keyword.statementBegin","CREATE"], + ["text"," "], + ["keyword","TABLE"], + ["text"," "], + ["identifier","weather"], + ["text"," "], + ["paren.lparen","("] +],[ + "statement", + ["text","\t"], + ["identifier","city"], + ["text","\t\t"], + ["keyword","varchar"], + ["paren.lparen","("], + ["constant.numeric","80"], + ["paren.rparen",")"], + ["text",","] +],[ + "statement", + ["text","\t"], + ["identifier","temp_lo"], + ["text","\t\t"], + ["keyword","int"], + ["text",",\t\t"], + ["comment","-- low temperature"] +],[ + "statement", + ["text","\t"], + ["identifier","temp_hi"], + ["text","\t\t"], + ["keyword","int"], + ["text",",\t\t"], + ["comment","-- high temperature"] +],[ + "statement", + ["text","\t"], + ["identifier","prcp"], + ["text","\t\t"], + ["keyword","real"], + ["text",",\t\t"], + ["comment","-- precipitation"] +],[ + "statement", + ["text","\t"], + ["variable.language","\"date\""], + ["text","\t\t"], + ["keyword","date"] +],[ + "start", + ["paren.rparen",")"], + ["statementEnd",";"] +],[ + "start" +],[ + "statement", + ["keyword.statementBegin","CREATE"], + ["text"," "], + ["keyword","TABLE"], + ["text"," "], + ["identifier","cities"], + ["text"," "], + ["paren.lparen","("] +],[ + "statement", + ["text","\t"], + ["keyword","name"], + ["text","\t\t"], + ["keyword","varchar"], + ["paren.lparen","("], + ["constant.numeric","80"], + ["paren.rparen",")"], + ["text",","] +],[ + "statement", + ["text","\t"], + ["keyword","location"], + ["text","\t"], + ["keyword","point"] +],[ + "start", + ["paren.rparen",")"], + ["statementEnd",";"] +],[ + "start" +],[ + "start" +],[ + "statement", + ["keyword.statementBegin","INSERT"], + ["text"," "], + ["keyword","INTO"], + ["text"," "], + ["identifier","weather"] +],[ + "start", + ["text"," "], + ["keyword","VALUES"], + ["text"," "], + ["paren.lparen","("], + ["string","'San Francisco'"], + ["text",", "], + ["constant.numeric","46"], + ["text",", "], + ["constant.numeric","50"], + ["text",", "], + ["constant.numeric","0.25"], + ["text",", "], + ["string","'1994-11-27'"], + ["paren.rparen",")"], + ["statementEnd",";"] +],[ + "start" +],[ + "statement", + ["keyword.statementBegin","INSERT"], + ["text"," "], + ["keyword","INTO"], + ["text"," "], + ["identifier","cities"] +],[ + "start", + ["text"," "], + ["keyword","VALUES"], + ["text"," "], + ["paren.lparen","("], + ["string","'San Francisco'"], + ["text",", "], + ["string","'(-194.0, 53.0)'"], + ["paren.rparen",")"], + ["statementEnd",";"] +],[ + "start" +],[ + "statement", + ["keyword.statementBegin","INSERT"], + ["text"," "], + ["keyword","INTO"], + ["text"," "], + ["identifier","weather"], + ["text"," "], + ["paren.lparen","("], + ["identifier","city"], + ["text",", "], + ["identifier","temp_lo"], + ["text",", "], + ["identifier","temp_hi"], + ["text",", "], + ["identifier","prcp"], + ["text",", "], + ["variable.language","\"date\""], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["keyword","VALUES"], + ["text"," "], + ["paren.lparen","("], + ["string","'San Francisco'"], + ["text",", "], + ["constant.numeric","43"], + ["text",", "], + ["constant.numeric","57"], + ["text",", "], + ["constant.numeric","0.0"], + ["text",", "], + ["string","'1994-11-29'"], + ["paren.rparen",")"], + ["statementEnd",";"] +],[ + "start" +],[ + "statement", + ["keyword.statementBegin","INSERT"], + ["text"," "], + ["keyword","INTO"], + ["text"," "], + ["identifier","weather"], + ["text"," "], + ["paren.lparen","("], + ["keyword","date"], + ["text",", "], + ["identifier","city"], + ["text",", "], + ["identifier","temp_hi"], + ["text",", "], + ["identifier","temp_lo"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["keyword","VALUES"], + ["text"," "], + ["paren.lparen","("], + ["string","'1994-11-29'"], + ["text",", "], + ["string","'Hayward'"], + ["text",", "], + ["constant.numeric","54"], + ["text",", "], + ["constant.numeric","37"], + ["paren.rparen",")"], + ["statementEnd",";"] +],[ + "start" +],[ + "start" +],[ + "start", + ["keyword.statementBegin","SELECT"], + ["text"," "], + ["identifier","city"], + ["text",", "], + ["paren.lparen","("], + ["identifier","temp_hi"], + ["keyword.operator","+"], + ["identifier","temp_lo"], + ["paren.rparen",")"], + ["keyword.operator","/"], + ["constant.numeric","2"], + ["text"," "], + ["keyword","AS"], + ["text"," "], + ["identifier","temp_avg"], + ["text",", "], + ["variable.language","\"date\""], + ["text"," "], + ["keyword","FROM"], + ["text"," "], + ["identifier","weather"], + ["statementEnd",";"] +],[ + "start" +],[ + "statement", + ["keyword.statementBegin","SELECT"], + ["text"," "], + ["identifier","city"], + ["text",", "], + ["identifier","temp_lo"], + ["text",", "], + ["identifier","temp_hi"], + ["text",", "], + ["identifier","prcp"], + ["text",", "], + ["variable.language","\"date\""], + ["text",", "], + ["keyword","location"] +],[ + "statement", + ["text"," "], + ["keyword","FROM"], + ["text"," "], + ["identifier","weather"], + ["text",", "], + ["identifier","cities"] +],[ + "start", + ["text"," "], + ["keyword","WHERE"], + ["text"," "], + ["identifier","city"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["keyword","name"], + ["statementEnd",";"] +],[ + "start" +],[ + "start" +],[ + "start" +],[ + "doc-start", + ["comment.doc","/**"] +],[ + "doc-start", + ["comment.doc","* Dollar quotes starting at the end of the line are colored as SQL unless"] +],[ + "doc-start", + ["comment.doc","* a special language tag is used. Dollar quote syntax coloring is implemented"] +],[ + "doc-start", + ["comment.doc","* for Perl, Python, JavaScript, and Json."] +],[ + "start", + ["comment.doc","*/"] +],[ + "statement", + ["keyword.statementBegin","create"], + ["text"," "], + ["keyword","or"], + ["text"," "], + ["keyword","replace"], + ["text"," "], + ["keyword","function"], + ["text"," "], + ["identifier","blob_content_chunked"], + ["paren.lparen","("] +],[ + "statement", + ["text"," "], + ["keyword","in"], + ["text"," "], + ["identifier","p_data"], + ["text"," "], + ["keyword","bytea"], + ["text",", "] +],[ + "statement", + ["text"," "], + ["keyword","in"], + ["text"," "], + ["identifier","p_chunk"], + ["text"," "], + ["keyword","integer"], + ["paren.rparen",")"] +],[ + "dollarSql", + ["keyword","returns"], + ["text"," "], + ["keyword","setof"], + ["text"," "], + ["keyword","bytea"], + ["text"," "], + ["keyword","as"], + ["text"," "], + ["string","$$"] +],[ + "dollarSql", + ["comment","-- Still SQL comments"] +],[ + "dollarSql", + ["keyword","declare"] +],[ + "dollarSql", + ["text","\t"], + ["identifier","v_size"], + ["text"," "], + ["keyword","integer"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["support.function","octet_length"], + ["paren.lparen","("], + ["identifier","p_data"], + ["paren.rparen",")"], + ["text",";"] +],[ + "dollarSql", + ["keyword","begin"] +],[ + "dollarSql", + ["text","\t"], + ["keyword","for"], + ["text"," "], + ["identifier","i"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["constant.numeric","1"], + ["text",".."], + ["identifier","v_size"], + ["text"," "], + ["keyword","by"], + ["text"," "], + ["identifier","p_chunk"], + ["text"," "], + ["identifier","loop"] +],[ + "dollarSql", + ["text","\t\t"], + ["identifier","return"], + ["text"," "], + ["keyword","next"], + ["text"," "], + ["keyword","substring"], + ["paren.lparen","("], + ["identifier","p_data"], + ["text"," "], + ["keyword","from"], + ["text"," "], + ["identifier","i"], + ["text"," "], + ["keyword","for"], + ["text"," "], + ["identifier","p_chunk"], + ["paren.rparen",")"], + ["text",";"] +],[ + "dollarSql", + ["text","\t"], + ["keyword","end"], + ["text"," "], + ["identifier","loop"], + ["text",";"] +],[ + "dollarSql", + ["keyword","end"], + ["text",";"] +],[ + "start", + ["string","$$"], + ["text"," "], + ["keyword","language"], + ["text"," "], + ["identifier","plpgsql"], + ["text"," "], + ["keyword","stable"], + ["statementEnd",";"] +],[ + "start" +],[ + "start" +],[ + "start", + ["comment","-- pl/perl"] +],[ + "perl-start", + ["keyword.statementBegin","CREATE"], + ["text"," "], + ["keyword","FUNCTION"], + ["text"," "], + ["identifier","perl_max"], + ["text"," "], + ["paren.lparen","("], + ["keyword","integer"], + ["text",", "], + ["keyword","integer"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","RETURNS"], + ["text"," "], + ["keyword","integer"], + ["text"," "], + ["keyword","AS"], + ["text"," "], + ["string","$perl$"] +],[ + "perl-start", + ["text"," "], + ["comment","# perl comment..."] +],[ + "perl-start", + ["text"," "], + ["keyword","my"], + ["text"," "], + ["lparen","("], + ["identifier","$x"], + ["keyword.operator",","], + ["identifier","$y"], + ["rparen",")"], + ["text"," "], + ["keyword.operator","="], + ["text"," @"], + ["identifier","_"], + ["text",";"] +],[ + "perl-start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["lparen","("], + ["keyword.operator","!"], + ["text"," "], + ["support.function","defined"], + ["text"," "], + ["identifier","$x"], + ["rparen",")"], + ["text"," "], + ["lparen","{"] +],[ + "perl-start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["lparen","("], + ["keyword.operator","!"], + ["text"," "], + ["support.function","defined"], + ["text"," "], + ["identifier","$y"], + ["rparen",")"], + ["text"," "], + ["lparen","{"], + ["text"," "], + ["support.function","return"], + ["text"," "], + ["support.function","undef"], + ["text","; "], + ["rparen","}"] +],[ + "perl-start", + ["text"," "], + ["support.function","return"], + ["text"," "], + ["identifier","$y"], + ["text",";"] +],[ + "perl-start", + ["text"," "], + ["rparen","}"] +],[ + "perl-start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["lparen","("], + ["keyword.operator","!"], + ["text"," "], + ["support.function","defined"], + ["text"," "], + ["identifier","$y"], + ["rparen",")"], + ["text"," "], + ["lparen","{"], + ["text"," "], + ["support.function","return"], + ["text"," "], + ["identifier","$x"], + ["text","; "], + ["rparen","}"] +],[ + "perl-start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["lparen","("], + ["identifier","$x"], + ["text"," "], + ["keyword.operator",">"], + ["text"," "], + ["identifier","$y"], + ["rparen",")"], + ["text"," "], + ["lparen","{"], + ["text"," "], + ["support.function","return"], + ["text"," "], + ["identifier","$x"], + ["text","; "], + ["rparen","}"] +],[ + "perl-start", + ["text"," "], + ["support.function","return"], + ["text"," "], + ["identifier","$y"], + ["text",";"] +],[ + "start", + ["string","$perl$"], + ["text"," "], + ["keyword","LANGUAGE"], + ["text"," "], + ["identifier","plperl"], + ["statementEnd",";"] +],[ + "start" +],[ + "start", + ["comment","-- pl/python"] +],[ + "python-start", + ["keyword.statementBegin","CREATE"], + ["text"," "], + ["keyword","FUNCTION"], + ["text"," "], + ["identifier","usesavedplan"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["keyword","RETURNS"], + ["text"," "], + ["keyword","trigger"], + ["text"," "], + ["keyword","AS"], + ["text"," "], + ["string","$python$"] +],[ + "python-start", + ["text"," "], + ["comment","# python comment..."] +],[ + "python-start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["identifier","SD"], + ["text","."], + ["identifier","has_key"], + ["paren.lparen","("], + ["string","\"plan\""], + ["paren.rparen",")"], + ["text",":"] +],[ + "python-start", + ["text"," "], + ["identifier","plan"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","SD"], + ["paren.lparen","["], + ["string","\"plan\""], + ["paren.rparen","]"] +],[ + "python-start", + ["text"," "], + ["keyword","else"], + ["text",":"] +],[ + "python-start", + ["text"," "], + ["identifier","plan"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","plpy"], + ["text","."], + ["identifier","prepare"], + ["paren.lparen","("], + ["string","\"SELECT 1\""], + ["paren.rparen",")"] +],[ + "python-start", + ["text"," "], + ["identifier","SD"], + ["paren.lparen","["], + ["string","\"plan\""], + ["paren.rparen","]"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","plan"] +],[ + "start", + ["string","$python$"], + ["text"," "], + ["keyword","LANGUAGE"], + ["text"," "], + ["identifier","plpythonu"], + ["statementEnd",";"] +],[ + "start" +],[ + "start", + ["comment","-- pl/v8 (javascript)"] +],[ + "javascript-start", + ["keyword.statementBegin","CREATE"], + ["text"," "], + ["keyword","FUNCTION"], + ["text"," "], + ["identifier","plv8_test"], + ["paren.lparen","("], + ["identifier","keys"], + ["text"," "], + ["keyword","text"], + ["text","[], "], + ["identifier","vals"], + ["text"," "], + ["keyword","text"], + ["text","[]"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","RETURNS"], + ["text"," "], + ["keyword","text"], + ["text"," "], + ["keyword","AS"], + ["text"," "], + ["string","$javascript$"] +],[ + "javascript-start", + ["storage.type","var"], + ["text"," "], + ["identifier","o"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","{"], + ["paren.rparen","}"], + ["punctuation.operator",";"] +],[ + "javascript-start", + ["keyword","for"], + ["paren.lparen","("], + ["storage.type","var"], + ["text"," "], + ["identifier","i"], + ["keyword.operator","="], + ["constant.numeric","0"], + ["punctuation.operator",";"], + ["text"," "], + ["identifier","i"], + ["keyword.operator","<"], + ["identifier","keys"], + ["punctuation.operator","."], + ["support.constant","length"], + ["punctuation.operator",";"], + ["text"," "], + ["identifier","i"], + ["keyword.operator","++"], + ["paren.rparen",")"], + ["paren.lparen","{"] +],[ + "javascript-start", + ["text"," "], + ["identifier","o"], + ["paren.lparen","["], + ["identifier","keys"], + ["paren.lparen","["], + ["identifier","i"], + ["paren.rparen","]]"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","vals"], + ["paren.lparen","["], + ["identifier","i"], + ["paren.rparen","]"], + ["punctuation.operator",";"] +],[ + "javascript-no_regex", + ["paren.rparen","}"] +],[ + "javascript-start", + ["keyword","return"], + ["text"," "], + ["variable.language","JSON"], + ["punctuation.operator","."], + ["identifier","stringify"], + ["paren.lparen","("], + ["identifier","o"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["string","$javascript$"], + ["text"," "], + ["keyword","LANGUAGE"], + ["text"," "], + ["identifier","plv8"], + ["text"," "], + ["keyword","IMMUTABLE"], + ["text"," "], + ["keyword","STRICT"], + ["statementEnd",";"] +],[ + "start" +],[ + "start", + ["comment","-- json"] +],[ + "json-start", + ["keyword.statementBegin","select"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "], + ["keyword","from"], + ["text"," "], + ["support.function","json_object_keys"], + ["paren.lparen","("], + ["string","$json$"] +],[ + "json-start", + ["paren.lparen","{"] +],[ + "json-start", + ["text"," "], + ["variable","\"f1\""], + ["text",": "], + ["constant.numeric","5"], + ["text",","] +],[ + "json-start", + ["text"," "], + ["variable","\"f2\""], + ["text",": "], + ["string","\"test\""], + ["text",","] +],[ + "json-start", + ["text"," "], + ["variable","\"f3\""], + ["text",": "], + ["paren.lparen","{"], + ["paren.rparen","}"] +],[ + "json-start", + ["paren.rparen","}"] +],[ + "start", + ["string","$json$"], + ["paren.rparen",")"], + ["statementEnd",";"] +],[ + "start" +],[ + "start" +],[ + "start", + ["comment","-- psql commands"] +],[ + "start", + ["support.buildin","\\df cash*"] +],[ + "start" +],[ + "start" +],[ + "start", + ["comment","-- Some string samples."] +],[ + "start", + ["keyword.statementBegin","select"], + ["text"," "], + ["string","'don''t do it now;'"], + ["text"," "], + ["keyword.operator","||"], + ["text"," "], + ["string","'maybe later'"], + ["statementEnd",";"] +],[ + "start", + ["keyword.statementBegin","select"], + ["text"," "], + ["identifier","E"], + ["string","'dont\\'t do it'"], + ["statementEnd",";"] +],[ + "start", + ["keyword.statementBegin","select"], + ["text"," "], + ["support.function","length"], + ["paren.lparen","("], + ["string","'some other''s stuff'"], + ["text"," "], + ["keyword.operator","||"], + ["text"," "], + ["string","$$cat in hat's stuff $$"], + ["paren.rparen",")"], + ["statementEnd",";"] +],[ + "start" +],[ + "dollarStatementString", + ["keyword.statementBegin","select"], + ["text"," "], + ["string","$$ strings"] +],[ + "dollarStatementString", + ["string","over multiple "] +],[ + "dollarStatementString", + ["string","lines - use dollar quotes"] +],[ + "start", + ["string","$$"], + ["statementEnd",";"] +],[ + "start" +],[ + "start", + ["keyword.statementBegin","END"], + ["statementEnd",";"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_php.json b/lib/ace/mode/_test/tokens_php.json new file mode 100644 index 00000000..2134dccb --- /dev/null +++ b/lib/ace/mode/_test/tokens_php.json @@ -0,0 +1,171 @@ +[[ + "php-start", + ["support.php_tag",""], + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.script.tag-name.xml","script"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text"," "], + ["support.php_tag",""] +],[ + "js-comment_regex_allowed", + ["comment","/*this is js "], + ["support.php_tag",""] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""], + ["text.xml"," not "], + ["constant.language.escape.reference.xml","&js;"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_powershell.json b/lib/ace/mode/_test/tokens_powershell.json new file mode 100644 index 00000000..43b77db4 --- /dev/null +++ b/lib/ace/mode/_test/tokens_powershell.json @@ -0,0 +1,184 @@ +[[ + "start", + ["comment","# This is a simple comment"] +],[ + "start", + ["keyword","function"], + ["text"," "], + ["identifier","Hello"], + ["lparen","("], + ["variable.instance","$name"], + ["rparen",")"], + ["text"," "], + ["lparen","{"] +],[ + "start", + ["text"," "], + ["identifier","Write-host"], + ["text"," "], + ["string","\"Hello $name\""] +],[ + "start", + ["rparen","}"] +],[ + "start" +],[ + "start", + ["keyword","function"], + ["text"," "], + ["identifier","add"], + ["lparen","("], + ["variable.instance","$left"], + ["text",", "], + ["variable.instance","$right"], + ["keyword.operator","="], + ["constant.numeric","4"], + ["rparen",")"], + ["text"," "], + ["lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["lparen","("], + ["variable.instance","$right"], + ["text"," "], + ["keyword.operator","-ne"], + ["text"," "], + ["constant.numeric","4"], + ["rparen",")"], + ["text"," "], + ["lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","return"], + ["text"," "], + ["variable.instance","$left"] +],[ + "start", + ["text"," "], + ["rparen","}"], + ["text"," "], + ["keyword","elseif"], + ["text"," "], + ["lparen","("], + ["variable.instance","$left"], + ["text"," "], + ["keyword.operator","-eq"], + ["text"," "], + ["constant.language","$null"], + ["text"," "], + ["keyword.operator","-and"], + ["text"," "], + ["variable.instance","$right"], + ["text"," "], + ["keyword.operator","-eq"], + ["text"," "], + ["constant.numeric","2"], + ["rparen",")"], + ["text"," "], + ["lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","return"], + ["text"," "], + ["constant.numeric","3"] +],[ + "start", + ["text"," "], + ["rparen","}"], + ["text"," "], + ["keyword","else"], + ["text"," "], + ["lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","return"], + ["text"," "], + ["constant.numeric","2"] +],[ + "start", + ["text"," "], + ["rparen","}"] +],[ + "start", + ["rparen","}"] +],[ + "start" +],[ + "start", + ["variable.instance","$number"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","1"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","2"], + ["text",";"] +],[ + "start", + ["variable.instance","$number"], + ["text"," "], + ["keyword.operator","+="], + ["text"," "], + ["constant.numeric","3"] +],[ + "start" +],[ + "start", + ["support.function","Write-Host"], + ["text"," "], + ["identifier","Hello"], + ["text"," "], + ["keyword.operator","-"], + ["identifier","name"], + ["text"," "], + ["string","\"World\""] +],[ + "start" +],[ + "start", + ["variable.instance","$an_array"], + ["text"," "], + ["keyword.operator","="], + ["text"," @"], + ["lparen","("], + ["constant.numeric","1"], + ["text",", "], + ["constant.numeric","2"], + ["text",", "], + ["constant.numeric","3"], + ["rparen",")"] +],[ + "start", + ["variable.instance","$a_hash"], + ["text"," "], + ["keyword.operator","="], + ["text"," @"], + ["lparen","{"], + ["string","\"something\""], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string","\"something else\""], + ["rparen","}"] +],[ + "start" +],[ + "start", + ["keyword.operator","&"], + ["text"," "], + ["identifier","notepad"], + ["text"," .\\"], + ["identifier","readme"], + ["text","."], + ["identifier","md"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_prolog.json b/lib/ace/mode/_test/tokens_prolog.json new file mode 100644 index 00000000..4c0f5c5c --- /dev/null +++ b/lib/ace/mode/_test/tokens_prolog.json @@ -0,0 +1,245 @@ +[[ + "start", + ["entity.name.function.fact.prolog","partition"], + ["punctuation.begin.fact.parameters.prolog","("], + ["punctuation.begin.list.prolog","["], + ["punctuation.end.list.prolog","]"], + ["punctuation.separator.parameters.prolog",","], + ["meta.fact.prolog"," "], + ["variable.language.anonymous.prolog","_"], + ["punctuation.separator.parameters.prolog",","], + ["meta.fact.prolog"," "], + ["punctuation.begin.list.prolog","["], + ["punctuation.end.list.prolog","]"], + ["punctuation.separator.parameters.prolog",","], + ["meta.fact.prolog"," "], + ["punctuation.begin.list.prolog","["], + ["punctuation.end.list.prolog","]"], + ["punctuation.end.fact.parameters.prolog",")"], + ["punctuation.end.fact.prolog","."] +],[ + ["keyword.operator.definition.prolog","meta.rule.prolog"], + ["entity.name.function.rule.prolog","partition"], + ["punctuation.rule.parameters.begin.prolog","("], + ["punctuation.begin.list.prolog","["], + ["variable.other.prolog","X"], + ["punctuation.concat.list.prolog","|"], + ["variable.other.prolog","Xs"], + ["punctuation.end.list.prolog","]"], + ["punctuation.separator.parameters.prolog",","], + ["meta.rule.parameters.prolog"," "], + ["variable.parameter.prolog","Pivot"], + ["punctuation.separator.parameters.prolog",","], + ["meta.rule.parameters.prolog"," "], + ["variable.parameter.prolog","Smalls"], + ["punctuation.separator.parameters.prolog",","], + ["meta.rule.parameters.prolog"," "], + ["variable.parameter.prolog","Bigs"], + ["punctuation.rule.parameters.end.prolog",")"], + ["meta.rule.signature.prolog"," "], + ["keyword.operator.definition.prolog",":-"] +],[ + ["meta.expression.prolog","keyword.operator.definition.prolog","keyword.operator.definition.prolog","meta.rule.prolog"], + ["meta.rule.definition.prolog"," "], + ["meta.expression.prolog","( "], + ["variable.other.prolog","X"], + ["meta.expression.prolog"," @"], + ["keyword.operator.prolog","<"], + ["meta.expression.prolog"," "], + ["variable.other.prolog","Pivot"], + ["meta.expression.prolog"," "], + ["keyword.operator.prolog","->"] +],[ + ["meta.expression.prolog","keyword.operator.definition.prolog","keyword.operator.definition.prolog","meta.rule.prolog"], + ["meta.expression.prolog"," "], + ["variable.other.prolog","Smalls"], + ["meta.expression.prolog"," "], + ["keyword.operator.prolog","="], + ["meta.expression.prolog"," "], + ["punctuation.begin.list.prolog","["], + ["variable.other.prolog","X"], + ["punctuation.concat.list.prolog","|"], + ["variable.other.prolog","Rest"], + ["punctuation.end.list.prolog","]"], + ["punctuation.control.and.prolog",","] +],[ + ["meta.expression.prolog","keyword.operator.definition.prolog","keyword.operator.definition.prolog","meta.rule.prolog"], + ["meta.expression.prolog"," "], + ["constant.other.atom.prolog","partition"], + ["punctuation.begin.statement.parameters.prolog","("], + ["variable.other.prolog","Xs"], + ["punctuation.separator.statement.prolog",","], + ["meta.statement.parameters.prolog"," "], + ["variable.other.prolog","Pivot"], + ["punctuation.separator.statement.prolog",","], + ["meta.statement.parameters.prolog"," "], + ["variable.other.prolog","Rest"], + ["punctuation.separator.statement.prolog",","], + ["meta.statement.parameters.prolog"," "], + ["variable.other.prolog","Bigs"], + ["punctuation.end.statement.parameters.prolog",")"] +],[ + ["meta.expression.prolog","keyword.operator.definition.prolog","keyword.operator.definition.prolog","meta.rule.prolog"], + ["meta.expression.prolog"," "], + ["punctuation.control.or.prolog",";"], + ["meta.expression.prolog"," "], + ["variable.other.prolog","Bigs"], + ["meta.expression.prolog"," "], + ["keyword.operator.prolog","="], + ["meta.expression.prolog"," "], + ["punctuation.begin.list.prolog","["], + ["variable.other.prolog","X"], + ["punctuation.concat.list.prolog","|"], + ["variable.other.prolog","Rest"], + ["punctuation.end.list.prolog","]"], + ["punctuation.control.and.prolog",","] +],[ + ["meta.expression.prolog","keyword.operator.definition.prolog","keyword.operator.definition.prolog","meta.rule.prolog"], + ["meta.expression.prolog"," "], + ["constant.other.atom.prolog","partition"], + ["punctuation.begin.statement.parameters.prolog","("], + ["variable.other.prolog","Xs"], + ["punctuation.separator.statement.prolog",","], + ["meta.statement.parameters.prolog"," "], + ["variable.other.prolog","Pivot"], + ["punctuation.separator.statement.prolog",","], + ["meta.statement.parameters.prolog"," "], + ["variable.other.prolog","Smalls"], + ["punctuation.separator.statement.prolog",","], + ["meta.statement.parameters.prolog"," "], + ["variable.other.prolog","Rest"], + ["punctuation.end.statement.parameters.prolog",")"] +],[ + "start", + ["meta.expression.prolog"," )"], + ["punctuation.rule.end.prolog","."] +],[ + "start", + ["text"," "] +],[ + "start", + ["entity.name.function.fact.prolog","quicksort"], + ["punctuation.begin.fact.parameters.prolog","("], + ["punctuation.begin.list.prolog","["], + ["punctuation.end.list.prolog","]"], + ["punctuation.end.fact.parameters.prolog",")"], + ["text"," --> []."] +],[ + "start", + ["entity.name.function.fact.prolog","quicksort"], + ["punctuation.begin.fact.parameters.prolog","("], + ["punctuation.begin.list.prolog","["], + ["variable.other.prolog","X"], + ["punctuation.concat.list.prolog","|"], + ["variable.other.prolog","Xs"], + ["punctuation.end.list.prolog","]"], + ["punctuation.end.fact.parameters.prolog",")"], + ["text"," -->"] +],[ + "start", + ["text"," { "], + ["entity.name.function.fact.prolog","partition"], + ["punctuation.begin.fact.parameters.prolog","("], + ["variable.parameter.prolog","Xs"], + ["punctuation.separator.parameters.prolog",","], + ["meta.fact.prolog"," "], + ["variable.parameter.prolog","X"], + ["punctuation.separator.parameters.prolog",","], + ["meta.fact.prolog"," "], + ["variable.parameter.prolog","Smaller"], + ["punctuation.separator.parameters.prolog",","], + ["meta.fact.prolog"," "], + ["variable.parameter.prolog","Bigger"], + ["punctuation.end.fact.parameters.prolog",")"], + ["text"," },"] +],[ + "start", + ["text"," "], + ["entity.name.function.fact.prolog","quicksort"], + ["punctuation.begin.fact.parameters.prolog","("], + ["variable.parameter.prolog","Smaller"], + ["punctuation.end.fact.parameters.prolog",")"], + ["text",", [X], "], + ["entity.name.function.fact.prolog","quicksort"], + ["punctuation.begin.fact.parameters.prolog","("], + ["variable.parameter.prolog","Bigger"], + ["punctuation.end.fact.parameters.prolog",")"], + ["punctuation.end.fact.prolog","."] +],[ + "start" +],[ + ["keyword.operator.definition.prolog","meta.rule.prolog"], + ["entity.name.function.rule.prolog","perfect"], + ["punctuation.rule.parameters.begin.prolog","("], + ["variable.parameter.prolog","N"], + ["punctuation.rule.parameters.end.prolog",")"], + ["meta.rule.signature.prolog"," "], + ["keyword.operator.definition.prolog",":-"] +],[ + ["keyword.operator.definition.prolog","meta.rule.prolog"], + ["meta.rule.definition.prolog"," "], + ["constant.other.atom.prolog","between"], + ["punctuation.begin.statement.parameters.prolog","("], + ["constant.numeric.prolog","1"], + ["punctuation.separator.statement.prolog",","], + ["meta.statement.parameters.prolog"," "], + ["constant.other.atom.prolog","inf"], + ["punctuation.separator.statement.prolog",","], + ["meta.statement.parameters.prolog"," "], + ["variable.other.prolog","N"], + ["punctuation.end.statement.parameters.prolog",")"], + ["punctuation.control.and.prolog",","], + ["meta.rule.definition.prolog"," "], + ["variable.other.prolog","U"], + ["meta.rule.definition.prolog"," "], + ["keyword.operator.prolog","is"], + ["meta.rule.definition.prolog"," "], + ["variable.other.prolog","N"], + ["meta.rule.definition.prolog"," // "], + ["constant.numeric.prolog","2"], + ["punctuation.control.and.prolog",","] +],[ + ["keyword.operator.definition.prolog","meta.rule.prolog"], + ["meta.rule.definition.prolog"," "], + ["constant.other.atom.prolog","findall"], + ["punctuation.begin.statement.parameters.prolog","("], + ["variable.other.prolog","D"], + ["punctuation.separator.statement.prolog",","], + ["meta.statement.parameters.prolog"," ("], + ["constant.other.atom.prolog","between"], + ["punctuation.begin.statement.parameters.prolog","("], + ["constant.numeric.prolog","1"], + ["punctuation.separator.statement.prolog",","], + ["variable.other.prolog","U"], + ["punctuation.separator.statement.prolog",","], + ["variable.other.prolog","D"], + ["punctuation.end.statement.parameters.prolog",")"], + ["punctuation.separator.statement.prolog",","], + ["meta.statement.parameters.prolog"," "], + ["variable.other.prolog","N"], + ["meta.statement.parameters.prolog"," "], + ["constant.other.atom.prolog","mod"], + ["meta.statement.parameters.prolog"," "], + ["variable.other.prolog","D"], + ["meta.statement.parameters.prolog"," "], + ["keyword.operator.prolog","=:="], + ["meta.statement.parameters.prolog"," "], + ["constant.numeric.prolog","0"], + ["punctuation.end.statement.parameters.prolog",")"], + ["punctuation.control.and.prolog",","], + ["meta.rule.definition.prolog"," "], + ["variable.other.prolog","Ds"], + ["meta.rule.definition.prolog",")"], + ["punctuation.control.and.prolog",","] +],[ + "start", + ["meta.rule.definition.prolog"," "], + ["constant.other.atom.prolog","sumlist"], + ["punctuation.begin.statement.parameters.prolog","("], + ["variable.other.prolog","Ds"], + ["punctuation.separator.statement.prolog",","], + ["meta.statement.parameters.prolog"," "], + ["variable.other.prolog","N"], + ["punctuation.end.statement.parameters.prolog",")"], + ["punctuation.rule.end.prolog","."] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_properties.json b/lib/ace/mode/_test/tokens_properties.json new file mode 100644 index 00000000..8831045e --- /dev/null +++ b/lib/ace/mode/_test/tokens_properties.json @@ -0,0 +1,68 @@ +[[ + "start", + ["comment","# You are reading the \".properties\" entry."] +],[ + "start", + ["comment","! The exclamation mark can also mark text as comments."] +],[ + "start", + ["comment","# The key and element characters #, !, =, and : are written with a preceding backslash to ensure that they are properly loaded."] +],[ + "start", + ["variable","website "], + ["keyword","="], + ["string"," http"], + ["constant.language.escape","\\"], + ["string","://en.wikipedia.org/"] +],[ + "start", + ["variable","language "], + ["keyword","="], + ["string"," English"] +],[ + "start", + ["comment","# The backslash below tells the application to continue reading"] +],[ + "start", + ["comment","# the value onto the next line."] +],[ + "value", + ["variable","message "], + ["keyword","="], + ["string"," Welcome to \\"] +],[ + "start", + ["string"," Wikipedia!"] +],[ + "start", + ["comment","# Add spaces to the key"] +],[ + "start", + ["variable","key"], + ["constant.language.escape","\\"], + ["variable"," with"], + ["constant.language.escape","\\"], + ["variable"," spaces "], + ["keyword","="], + ["string"," This is the value that could be looked up with the key \"key with spaces\"."] +],[ + "start", + ["comment","# Unicode"] +],[ + "start", + ["variable","tab "], + ["keyword",":"], + ["string"," "], + ["constant.language.escape","\\u0009"] +],[ + "start", + ["variable","empty-key"], + ["keyword","="] +],[ + "start", + ["variable","last.line"], + ["keyword","="], + ["string","value"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_protobuf.json b/lib/ace/mode/_test/tokens_protobuf.json new file mode 100644 index 00000000..469dba06 --- /dev/null +++ b/lib/ace/mode/_test/tokens_protobuf.json @@ -0,0 +1,136 @@ +[[ + "start", + ["keyword.declaration.protobuf","message"], + ["text"," "], + ["identifier","Point"], + ["text"," {"] +],[ + "start", + ["text"," "], + ["keyword.declaration.protobuf","required"], + ["text"," "], + ["support.type","int32"], + ["text"," "], + ["identifier","x"], + ["text"," "], + ["keyword.operator.assignment.protobuf","="], + ["text"," "], + ["constant.numeric","1"], + ["text",";"] +],[ + "start", + ["text"," "], + ["keyword.declaration.protobuf","required"], + ["text"," "], + ["support.type","int32"], + ["text"," "], + ["identifier","y"], + ["text"," "], + ["keyword.operator.assignment.protobuf","="], + ["text"," "], + ["constant.numeric","2"], + ["text",";"] +],[ + "start", + ["text"," "], + ["keyword.declaration.protobuf","optional"], + ["text"," "], + ["support.type","string"], + ["text"," "], + ["identifier","label"], + ["text"," "], + ["keyword.operator.assignment.protobuf","="], + ["text"," "], + ["constant.numeric","3"], + ["text",";"] +],[ + "start", + ["text","}"] +],[ + "start" +],[ + "start", + ["keyword.declaration.protobuf","message"], + ["text"," "], + ["identifier","Line"], + ["text"," {"] +],[ + "start", + ["text"," "], + ["keyword.declaration.protobuf","required"], + ["text"," "], + ["identifier","Point"], + ["text"," "], + ["identifier","start"], + ["text"," "], + ["keyword.operator.assignment.protobuf","="], + ["text"," "], + ["constant.numeric","1"], + ["text",";"] +],[ + "start", + ["text"," "], + ["keyword.declaration.protobuf","required"], + ["text"," "], + ["identifier","Point"], + ["text"," "], + ["identifier","end"], + ["text"," "], + ["keyword.operator.assignment.protobuf","="], + ["text"," "], + ["constant.numeric","2"], + ["text",";"] +],[ + "start", + ["text"," "], + ["keyword.declaration.protobuf","optional"], + ["text"," "], + ["support.type","string"], + ["text"," "], + ["identifier","label"], + ["text"," "], + ["keyword.operator.assignment.protobuf","="], + ["text"," "], + ["constant.numeric","3"], + ["text",";"] +],[ + "start", + ["text","}"] +],[ + "start" +],[ + "start", + ["keyword.declaration.protobuf","message"], + ["text"," "], + ["identifier","Polyline"], + ["text"," {"] +],[ + "start", + ["text"," "], + ["keyword.declaration.protobuf","repeated"], + ["text"," "], + ["identifier","Point"], + ["text"," "], + ["identifier","point"], + ["text"," "], + ["keyword.operator.assignment.protobuf","="], + ["text"," "], + ["constant.numeric","1"], + ["text",";"] +],[ + "start", + ["text"," "], + ["keyword.declaration.protobuf","optional"], + ["text"," "], + ["support.type","string"], + ["text"," "], + ["identifier","label"], + ["text"," "], + ["keyword.operator.assignment.protobuf","="], + ["text"," "], + ["constant.numeric","2"], + ["text",";"] +],[ + "start", + ["text","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_python.json b/lib/ace/mode/_test/tokens_python.json new file mode 100644 index 00000000..293c8ff2 --- /dev/null +++ b/lib/ace/mode/_test/tokens_python.json @@ -0,0 +1,152 @@ +[[ + "start", + ["comment","#!/usr/local/bin/python"] +],[ + "start" +],[ + "start", + ["keyword","import"], + ["text"," "], + ["identifier","string"], + ["text",", "], + ["identifier","sys"] +],[ + "start" +],[ + "start", + ["comment","# If no arguments were given, print a helpful message"] +],[ + "start", + ["keyword","if"], + ["text"," "], + ["support.function","len"], + ["paren.lparen","("], + ["identifier","sys"], + ["text","."], + ["identifier","argv"], + ["paren.rparen",")"], + ["keyword.operator","=="], + ["constant.numeric","1"], + ["text",":"] +],[ + "qstring3", + ["text"," "], + ["keyword","print"], + ["text"," "], + ["string","'''Usage:"] +],[ + "start", + ["string","celsius temp1 temp2 ...'''"] +],[ + "start", + ["text"," "], + ["identifier","sys"], + ["text","."], + ["identifier","exit"], + ["paren.lparen","("], + ["constant.numeric","0"], + ["paren.rparen",")"] +],[ + "start" +],[ + "start", + ["comment","# Loop over the arguments"] +],[ + "start", + ["keyword","for"], + ["text"," "], + ["identifier","i"], + ["text"," "], + ["keyword","in"], + ["text"," "], + ["identifier","sys"], + ["text","."], + ["identifier","argv"], + ["paren.lparen","["], + ["constant.numeric","1"], + ["text",":"], + ["paren.rparen","]"], + ["text",":"] +],[ + "start", + ["text"," "], + ["keyword","try"], + ["text",":"] +],[ + "start", + ["text"," "], + ["identifier","fahrenheit"], + ["keyword.operator","="], + ["support.function","float"], + ["paren.lparen","("], + ["identifier","string"], + ["text","."], + ["identifier","atoi"], + ["paren.lparen","("], + ["identifier","i"], + ["paren.rparen","))"] +],[ + "start", + ["text"," "], + ["keyword","except"], + ["text"," "], + ["identifier","string"], + ["text","."], + ["identifier","atoi_error"], + ["text",":"] +],[ + "start", + ["text"," "], + ["keyword","print"], + ["text"," "], + ["support.function","repr"], + ["paren.lparen","("], + ["identifier","i"], + ["paren.rparen",")"], + ["text",", "], + ["string","\"not a numeric value\""] +],[ + "start", + ["text"," "], + ["keyword","else"], + ["text",":"] +],[ + "start", + ["text"," "], + ["identifier","celsius"], + ["keyword.operator","="], + ["paren.lparen","("], + ["identifier","fahrenheit"], + ["keyword.operator","-"], + ["constant.numeric","32"], + ["paren.rparen",")"], + ["keyword.operator","*"], + ["constant.numeric","5.0"], + ["keyword.operator","/"], + ["constant.numeric","9.0"] +],[ + "start", + ["text"," "], + ["keyword","print"], + ["text"," "], + ["string","'%i"], + ["constant.language.escape","\\260"], + ["string","F = %i"], + ["constant.language.escape","\\260"], + ["string","C'"], + ["text"," "], + ["keyword.operator","%"], + ["text"," "], + ["paren.lparen","("], + ["support.function","int"], + ["paren.lparen","("], + ["identifier","fahrenheit"], + ["paren.rparen",")"], + ["text",", "], + ["support.function","int"], + ["paren.lparen","("], + ["identifier","celsius"], + ["keyword.operator","+"], + ["constant.numeric",".5"], + ["paren.rparen","))"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_r.json b/lib/ace/mode/_test/tokens_r.json new file mode 100644 index 00000000..2d446bce --- /dev/null +++ b/lib/ace/mode/_test/tokens_r.json @@ -0,0 +1,235 @@ +[[ + "start", + ["identifier","Call"], + ["keyword.operator",":"] +],[ + "start", + ["identifier","lm"], + ["paren.keyword.operator","("], + ["identifier","formula"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","y"], + ["text"," "], + ["keyword.operator","~"], + ["text"," "], + ["identifier","x"], + ["paren.keyword.operator",")"] +],[ + "start", + ["text"," "] +],[ + "start", + ["identifier","Residuals"], + ["keyword.operator",":"] +],[ + "start", + ["constant.numeric","1"], + ["text"," "], + ["constant.numeric","2"], + ["text"," "], + ["constant.numeric","3"], + ["text"," "], + ["constant.numeric","4"], + ["text"," "], + ["constant.numeric","5"], + ["text"," "], + ["constant.numeric","6"] +],[ + "start", + ["constant.numeric","3.3333"], + ["text"," "], + ["keyword.operator","-"], + ["constant.numeric","0.6667"], + ["text"," "], + ["keyword.operator","-"], + ["constant.numeric","2.6667"], + ["text"," "], + ["keyword.operator","-"], + ["constant.numeric","2.6667"], + ["text"," "], + ["keyword.operator","-"], + ["constant.numeric","0.6667"], + ["text"," "], + ["constant.numeric","3.3333"] +],[ + "start", + ["text"," "] +],[ + "start", + ["identifier","Coefficients"], + ["keyword.operator",":"] +],[ + "start", + ["text"," "], + ["identifier","Estimate"], + ["text"," "], + ["identifier","Std"], + ["text",". "], + ["identifier","Error"], + ["text"," "], + ["identifier","t"], + ["text"," "], + ["identifier","value"], + ["text"," "], + ["identifier","Pr"], + ["paren.keyword.operator","("], + ["keyword.operator",">|"], + ["identifier","t"], + ["keyword.operator","|"], + ["paren.keyword.operator",")"] +],[ + "start", + ["paren.keyword.operator","("], + ["identifier","Intercept"], + ["paren.keyword.operator",")"], + ["text"," "], + ["keyword.operator","-"], + ["constant.numeric","9.3333"], + ["text"," "], + ["constant.numeric","2.8441"], + ["text"," "], + ["keyword.operator","-"], + ["constant.numeric","3.282"], + ["text"," "], + ["constant.numeric","0.030453"], + ["text"," "], + ["keyword.operator","*"] +],[ + "start", + ["identifier","x"], + ["text"," "], + ["constant.numeric","7.0000"], + ["text"," "], + ["constant.numeric","0.7303"], + ["text"," "], + ["constant.numeric","9.585"], + ["text"," "], + ["constant.numeric","0.000662"], + ["text"," "], + ["keyword.operator","***"] +],[ + "start", + ["keyword.operator","---"] +],[ + "start", + ["identifier","Signif"], + ["text",". "], + ["identifier","codes"], + ["keyword.operator",":"], + ["text"," "], + ["constant.numeric","0"], + ["text"," ‘"], + ["keyword.operator","***"], + ["text","’ "], + ["constant.numeric","0.001"], + ["text"," ‘"], + ["keyword.operator","**"], + ["text","’ "], + ["constant.numeric","0.01"], + ["text"," ‘"], + ["keyword.operator","*"], + ["text","’ "], + ["constant.numeric","0.05"], + ["text"," ‘.’ "], + ["constant.numeric","0.1"], + ["text"," ‘ ’ "], + ["constant.numeric","1"] +],[ + "start", + ["text"," "] +],[ + "start", + ["identifier","Residual"], + ["text"," "], + ["identifier","standard"], + ["text"," "], + ["identifier","error"], + ["keyword.operator",":"], + ["text"," "], + ["constant.numeric","3.055"], + ["text"," "], + ["identifier","on"], + ["text"," "], + ["constant.numeric","4"], + ["text"," "], + ["identifier","degrees"], + ["text"," "], + ["identifier","of"], + ["text"," "], + ["identifier","freedom"] +],[ + "start", + ["identifier","Multiple"], + ["text"," "], + ["identifier","R"], + ["keyword.operator","-"], + ["identifier","squared"], + ["keyword.operator",":"], + ["text"," "], + ["constant.numeric","0.9583"], + ["text",", "], + ["identifier","Adjusted"], + ["text"," "], + ["identifier","R"], + ["keyword.operator","-"], + ["identifier","squared"], + ["keyword.operator",":"], + ["text"," "], + ["constant.numeric","0.9478"] +],[ + "start", + ["constant.language.boolean","F"], + ["keyword.operator","-"], + ["identifier","statistic"], + ["keyword.operator",":"], + ["text"," "], + ["constant.numeric","91.88"], + ["text"," "], + ["identifier","on"], + ["text"," "], + ["constant.numeric","1"], + ["text"," "], + ["identifier","and"], + ["text"," "], + ["constant.numeric","4"], + ["text"," "], + ["identifier","DF"], + ["text",", "], + ["identifier","p"], + ["keyword.operator","-"], + ["identifier","value"], + ["keyword.operator",":"], + ["text"," "], + ["constant.numeric","0.000662"] +],[ + "start", + ["text"," "] +],[ + "start", + ["keyword.operator",">"], + ["text"," "], + ["identifier","par"], + ["paren.keyword.operator","("], + ["identifier","mfrow"], + ["keyword.operator","="], + ["identifier","c"], + ["paren.keyword.operator","("], + ["constant.numeric","2"], + ["text",", "], + ["constant.numeric","2"], + ["paren.keyword.operator","))"], + ["text"," "], + ["comment","# Request 2x2 plot layout"] +],[ + "start", + ["keyword.operator",">"], + ["text"," "], + ["identifier","plot"], + ["paren.keyword.operator","("], + ["identifier","lm_1"], + ["paren.keyword.operator",")"], + ["text"," "], + ["comment","# Diagnostic plot of regression model"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_rdoc.json b/lib/ace/mode/_test/tokens_rdoc.json new file mode 100644 index 00000000..0c757438 --- /dev/null +++ b/lib/ace/mode/_test/tokens_rdoc.json @@ -0,0 +1,441 @@ +[[ + "start", + ["keyword","\\name"], + ["paren.keyword.operator","{"], + ["nospell.text","picker"], + ["paren.keyword.operator","}"] +],[ + "start", + ["keyword","\\alias"], + ["paren.keyword.operator","{"], + ["nospell.text","picker"], + ["paren.keyword.operator","}"] +],[ + "start", + ["keyword","\\title"], + ["paren.keyword.operator","{"], + ["text","Create a picker control"], + ["paren.keyword.operator","}"] +],[ + "start", + ["keyword","\\description"], + ["paren.keyword.operator","{"] +],[ + "start", + ["text"," Create a picker control to enable manipulation of plot variables based on a set of fixed choices."] +],[ + "start", + ["paren.keyword.operator","}"] +],[ + "start" +],[ + "nospell", + ["keyword","\\usage"], + ["paren.keyword.operator","{"] +],[ + "nospell", + ["nospell.text","picker"], + ["paren.keyword.operator","("], + ["text","...,"], + ["nospell.text"," initial "], + ["text","="], + ["nospell.text"," NULL"], + ["text",","], + ["nospell.text"," label "], + ["text","="], + ["nospell.text"," NULL"], + ["paren.keyword.operator",")"] +],[ + "start", + ["paren.keyword.operator","}"] +],[ + "start" +],[ + "start" +],[ + "start", + ["keyword","\\arguments"], + ["paren.keyword.operator","{"] +],[ + "start", + ["text"," "], + ["keyword","\\item"], + ["paren.keyword.operator","{"], + ["keyword","\\dots"], + ["paren.keyword.operator","}{"] +],[ + "start", + ["text"," Arguments containing objects to be presented as choices for the picker "], + ["paren.keyword.operator","("], + ["text","or a list containing the choices"], + ["paren.keyword.operator",")"], + ["text",". If an element is named then the name is used to display it within the picker. If an element is not named then it is displayed within the picker using "], + ["keyword","\\code"], + ["paren.keyword.operator","{"], + ["keyword","\\link"], + ["paren.keyword.operator","{"], + ["nospell.text","as"], + ["text","."], + ["nospell.text","character"], + ["paren.keyword.operator","}}"], + ["text",". "] +],[ + "start", + ["paren.keyword.operator","}"] +],[ + "start", + ["text"," "], + ["keyword","\\item"], + ["paren.keyword.operator","{"], + ["nospell.text","initial"], + ["paren.keyword.operator","}{"] +],[ + "start", + ["text"," Initial value for picker. Value must be present in the list of choices specified. If not specified defaults to the first choice."] +],[ + "start", + ["paren.keyword.operator","}"] +],[ + "start", + ["text"," "], + ["keyword","\\item"], + ["paren.keyword.operator","{"], + ["nospell.text","label"], + ["paren.keyword.operator","}{"] +],[ + "start", + ["text"," Display label for picker. Defaults to the variable name if not specified."] +],[ + "start", + ["paren.keyword.operator","}"] +],[ + "start", + ["paren.keyword.operator","}"] +],[ + "start" +],[ + "start", + ["keyword","\\value"], + ["paren.keyword.operator","{"] +],[ + "start", + ["text"," An object of class \"manipulator.picker\" which can be passed to the "], + ["keyword","\\code"], + ["paren.keyword.operator","{"], + ["keyword","\\link"], + ["paren.keyword.operator","{"], + ["nospell.text","manipulate"], + ["paren.keyword.operator","}}"], + ["text"," function."] +],[ + "start", + ["paren.keyword.operator","}"] +],[ + "start" +],[ + "start", + ["keyword","\\seealso"], + ["paren.keyword.operator","{"] +],[ + "start", + ["keyword","\\code"], + ["paren.keyword.operator","{"], + ["keyword","\\link"], + ["paren.keyword.operator","{"], + ["nospell.text","manipulate"], + ["paren.keyword.operator","}}"], + ["text",", "], + ["keyword","\\code"], + ["paren.keyword.operator","{"], + ["keyword","\\link"], + ["paren.keyword.operator","{"], + ["nospell.text","slider"], + ["paren.keyword.operator","}}"], + ["text",", "], + ["keyword","\\code"], + ["paren.keyword.operator","{"], + ["keyword","\\link"], + ["paren.keyword.operator","{"], + ["nospell.text","checkbox"], + ["paren.keyword.operator","}}"], + ["text",", "], + ["keyword","\\code"], + ["paren.keyword.operator","{"], + ["keyword","\\link"], + ["paren.keyword.operator","{"], + ["nospell.text","button"], + ["paren.keyword.operator","}}"] +],[ + "start", + ["paren.keyword.operator","}"] +],[ + "start" +],[ + "start" +],[ + "nospell", + ["keyword","\\examples"], + ["paren.keyword.operator","{"] +],[ + "nospell", + ["keyword","\\dontrun"], + ["paren.keyword.operator","{"] +],[ + "nospell" +],[ + "nospell", + ["text","##"], + ["nospell.text"," Filtering data with a picker"] +],[ + "nospell", + ["nospell.text","manipulate"], + ["paren.keyword.operator","("] +],[ + "nospell", + ["nospell.text"," barplot"], + ["paren.keyword.operator","("], + ["nospell.text","as"], + ["text","."], + ["nospell.text","matrix"], + ["paren.keyword.operator","("], + ["nospell.text","longley"], + ["paren.keyword.operator","["], + ["text",","], + ["nospell.text","factor"], + ["paren.keyword.operator","])"], + ["text",","], + ["nospell.text"," "] +],[ + "nospell", + ["nospell.text"," beside "], + ["text","="], + ["nospell.text"," TRUE"], + ["text",","], + ["nospell.text"," main "], + ["text","="], + ["nospell.text"," factor"], + ["paren.keyword.operator",")"], + ["text",","] +],[ + "nospell", + ["nospell.text"," factor "], + ["text","="], + ["nospell.text"," picker"], + ["paren.keyword.operator","("], + ["text","\""], + ["nospell.text","GNP"], + ["text","\","], + ["nospell.text"," "], + ["text","\""], + ["nospell.text","Unemployed"], + ["text","\","], + ["nospell.text"," "], + ["text","\""], + ["nospell.text","Employed"], + ["text","\""], + ["paren.keyword.operator","))"] +],[ + "nospell" +],[ + "nospell", + ["text","##"], + ["nospell.text"," Create a picker with labels"] +],[ + "nospell", + ["nospell.text","manipulate"], + ["paren.keyword.operator","("] +],[ + "nospell", + ["nospell.text"," plot"], + ["paren.keyword.operator","("], + ["nospell.text","pressure"], + ["text",","], + ["nospell.text"," type "], + ["text","="], + ["nospell.text"," type"], + ["paren.keyword.operator",")"], + ["text",","], + ["nospell.text"," "] +],[ + "nospell", + ["nospell.text"," type "], + ["text","="], + ["nospell.text"," picker"], + ["paren.keyword.operator","("], + ["text","\""], + ["nospell.text","points"], + ["text","\""], + ["nospell.text"," "], + ["text","="], + ["nospell.text"," "], + ["text","\""], + ["nospell.text","p"], + ["text","\","], + ["nospell.text"," "], + ["text","\""], + ["nospell.text","line"], + ["text","\""], + ["nospell.text"," "], + ["text","="], + ["nospell.text"," "], + ["text","\""], + ["nospell.text","l"], + ["text","\","], + ["nospell.text"," "], + ["text","\""], + ["nospell.text","step"], + ["text","\""], + ["nospell.text"," "], + ["text","="], + ["nospell.text"," "], + ["text","\""], + ["nospell.text","s"], + ["text","\""], + ["paren.keyword.operator","))"] +],[ + "nospell", + ["nospell.text"," "] +],[ + "nospell", + ["text","##"], + ["nospell.text"," Picker with groups"] +],[ + "nospell", + ["nospell.text","manipulate"], + ["paren.keyword.operator","("] +],[ + "nospell", + ["nospell.text"," barplot"], + ["paren.keyword.operator","("], + ["nospell.text","as"], + ["text","."], + ["nospell.text","matrix"], + ["paren.keyword.operator","("], + ["nospell.text","mtcars"], + ["paren.keyword.operator","["], + ["nospell.text","group"], + ["text",",\""], + ["nospell.text","mpg"], + ["text","\""], + ["paren.keyword.operator","])"], + ["text",","], + ["nospell.text"," beside"], + ["text","="], + ["nospell.text","TRUE"], + ["paren.keyword.operator",")"], + ["text",","] +],[ + "nospell", + ["nospell.text"," group "], + ["text","="], + ["nospell.text"," picker"], + ["paren.keyword.operator","("], + ["text","\""], + ["nospell.text","Group 1"], + ["text","\""], + ["nospell.text"," "], + ["text","="], + ["nospell.text"," 1"], + ["text",":"], + ["nospell.text","11"], + ["text",","], + ["nospell.text"," "] +],[ + "nospell", + ["nospell.text"," "], + ["text","\""], + ["nospell.text","Group 2"], + ["text","\""], + ["nospell.text"," "], + ["text","="], + ["nospell.text"," 12"], + ["text",":"], + ["nospell.text","22"], + ["text",","], + ["nospell.text"," "] +],[ + "nospell", + ["nospell.text"," "], + ["text","\""], + ["nospell.text","Group 3"], + ["text","\""], + ["nospell.text"," "], + ["text","="], + ["nospell.text"," 23"], + ["text",":"], + ["nospell.text","32"], + ["paren.keyword.operator","))"] +],[ + "nospell" +],[ + "nospell", + ["text","##"], + ["nospell.text"," Histogram w"], + ["text","/"], + ["nospell.text"," picker to select type"] +],[ + "nospell", + ["nospell.text","require"], + ["paren.keyword.operator","("], + ["nospell.text","lattice"], + ["paren.keyword.operator",")"] +],[ + "nospell", + ["nospell.text","require"], + ["paren.keyword.operator","("], + ["nospell.text","stats"], + ["paren.keyword.operator",")"] +],[ + "nospell", + ["nospell.text","manipulate"], + ["paren.keyword.operator","("] +],[ + "nospell", + ["nospell.text"," histogram"], + ["paren.keyword.operator","("], + ["text","~"], + ["nospell.text"," height "], + ["text","|"], + ["nospell.text"," voice"], + ["text","."], + ["nospell.text","part"], + ["text",","], + ["nospell.text"," "] +],[ + "nospell", + ["nospell.text"," data "], + ["text","="], + ["nospell.text"," singer"], + ["text",","], + ["nospell.text"," type "], + ["text","="], + ["nospell.text"," type"], + ["paren.keyword.operator",")"], + ["text",","] +],[ + "nospell", + ["nospell.text"," type "], + ["text","="], + ["nospell.text"," picker"], + ["paren.keyword.operator","("], + ["text","\""], + ["nospell.text","percent"], + ["text","\","], + ["nospell.text"," "], + ["text","\""], + ["nospell.text","count"], + ["text","\","], + ["nospell.text"," "], + ["text","\""], + ["nospell.text","density"], + ["text","\""], + ["paren.keyword.operator","))"] +],[ + "nospell" +],[ + "start", + ["paren.keyword.operator","}"] +],[ + "start", + ["paren.keyword.operator","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_rhtml.json b/lib/ace/mode/_test/tokens_rhtml.json new file mode 100644 index 00000000..a536f851 --- /dev/null +++ b/lib/ace/mode/_test/tokens_rhtml.json @@ -0,0 +1,106 @@ +[[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","html"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","head"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","title"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Title"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","body"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","p"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","This is an R HTML document. When you click the "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","b"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Knit HTML"], + ["meta.tag.punctuation.end-tag-open.xml",""], + ["text.xml"," button a web page will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "r-start", + ["support.function.codebegin",""] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","p"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","You can also embed plots, for example:"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "r-start", + ["support.function.codebegin",""] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_ruby.json b/lib/ace/mode/_test/tokens_ruby.json new file mode 100644 index 00000000..f9991e9c --- /dev/null +++ b/lib/ace/mode/_test/tokens_ruby.json @@ -0,0 +1,242 @@ +[[ + "start", + ["text"," "], + ["comment","#test: symbol tokenizer"] +],[ + "start", + ["text"," "], + ["paren.lparen","["], + ["constant.other.symbol.ruby",":@thing"], + ["text",", "], + ["constant.other.symbol.ruby",":$thing"], + ["text",", "], + ["constant.other.symbol.ruby",":_thing"], + ["text",", "], + ["constant.other.symbol.ruby",":thing"], + ["text",", "], + ["constant.other.symbol.ruby",":Thing"], + ["text",", "], + ["constant.other.symbol.ruby",":thing1"], + ["text",", "], + ["constant.other.symbol.ruby",":thing_a"], + ["text",","] +],[ + "start", + ["text"," "], + ["constant.other.symbol.ruby",":THING"], + ["text",", "], + ["constant.other.symbol.ruby",":thing!"], + ["text",", "], + ["constant.other.symbol.ruby",":thing="], + ["text",", "], + ["constant.other.symbol.ruby",":thing?"], + ["text",", "], + ["constant.other.symbol.ruby",":t?"], + ["text",","] +],[ + "start", + ["text"," :, :@, :"], + ["keyword.operator","$"], + ["text",", :"], + ["constant.numeric","1"], + ["text",", :1"], + ["identifier","thing"], + ["text",", "], + ["constant.other.symbol.ruby",":th?"], + ["identifier","ing"], + ["text",", "], + ["constant.other.symbol.ruby",":thi="], + ["identifier","ng"], + ["text",", :1"], + ["identifier","thing"], + ["text",","] +],[ + "start", + ["text"," "], + ["constant.other.symbol.ruby",":th!"], + ["identifier","ing"], + ["text",", "], + ["constant.other.symbol.ruby",":thing"], + ["comment","#"] +],[ + "start", + ["text"," "], + ["paren.rparen","]"] +],[ + "start" +],[ + "start", + ["text"," "], + ["comment","#test: namespaces aren't symbols\" : function() {"] +],[ + "start", + ["text"," "], + ["support.class","Namespaced"], + ["text","::"], + ["support.class","Class"] +],[ + "start", + ["text"," "], + ["comment","#test: hex tokenizer "] +],[ + "start", + ["text"," "], + ["constant.numeric","0x9a"], + ["text",", "], + ["constant.numeric","0XA1"], + ["text",", "], + ["constant.numeric","0x9_a"], + ["text",", 0"], + ["identifier","x"], + ["text",", 0"], + ["identifier","x_9a"], + ["text",", 0"], + ["identifier","x9a_"], + ["text",","] +],[ + "start", + ["text"," "], + ["comment","#test: float tokenizer"] +],[ + "start", + ["text"," "], + ["paren.lparen","["], + ["constant.numeric","1"], + ["text",", "], + ["constant.numeric","+1"], + ["text",", "], + ["constant.numeric","-1"], + ["text",", "], + ["constant.numeric","12_345"], + ["text",", "], + ["constant.numeric","0.000_1"], + ["text",","] +],[ + "start", + ["text"," "], + ["identifier","_"], + ["text",", "], + ["constant.numeric","3_1"], + ["text",", "], + ["constant.numeric","1_2"], + ["text",", 1"], + ["identifier","_"], + ["text","."], + ["constant.numeric","0"], + ["text",", "], + ["constant.numeric","0"], + ["text","."], + ["identifier","_1"], + ["paren.rparen","]"], + ["text",";"] +],[ + "start", + ["text"," "] +],[ + "start", + ["paren.lparen","{"], + ["constant.other.symbol.ruby",":id"], + ["text"," "], + ["punctuation.separator.key-value","=>"], + ["text"," "], + ["string.character","?\""], + ["text",", "], + ["constant.other.symbol.ruby",":key"], + ["text"," "], + ["punctuation.separator.key-value","=>"], + ["text"," "], + ["string.start","\""], + ["string","value"], + ["string.end","\""], + ["text",", "], + ["identifier","anotherKey"], + ["text",": "], + ["paren.lparen","["], + ["identifier","x"], + ["text",", "], + ["identifier","y"], + ["text","?"], + ["paren.rparen","]}"] +],[ + "start" +],[ + "comment", + ["comment","=begin"] +],[ + "start", + ["comment","=end"] +],[ + "start" +],[ + "comment", + ["comment","=begin x"] +],[ + "comment", + ["comment","=end-"] +],[ + "start", + ["comment","=end x"] +],[ + "start" +],[ + ["heredoc","FOO","heredoc","BAR","indentedHeredoc","BAZ","indentedHeredoc","EXEC"], + ["text"," "], + ["identifier","herDocs"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","["], + ["constant","<<"], + ["string","'"], + ["support.class","FOO"], + ["string","'"], + ["text",", "], + ["constant","<<"], + ["string",""], + ["support.class","BAR"], + ["string",""], + ["text",", "], + ["constant","<<-"], + ["string",""], + ["support.class","BAZ"], + ["string",""], + ["text",", "], + ["constant","<<-"], + ["string","`"], + ["support.class","EXEC"], + ["string","`"], + ["paren.rparen","]"], + ["text"," "], + ["comment","#comment"] +],[ + ["heredoc","FOO","heredoc","BAR","indentedHeredoc","BAZ","indentedHeredoc","EXEC"], + ["string"," FOO #{literal}"] +],[ + ["heredoc","BAR","indentedHeredoc","BAZ","indentedHeredoc","EXEC"], + ["support.class","FOO"] +],[ + ["heredoc","BAR","indentedHeredoc","BAZ","indentedHeredoc","EXEC"], + ["string"," BAR #{fact(10)}"] +],[ + ["indentedHeredoc","BAZ","indentedHeredoc","EXEC"], + ["support.class","BAR"] +],[ + ["indentedHeredoc","BAZ","indentedHeredoc","EXEC"], + ["string"," BAZ indented"] +],[ + ["indentedHeredoc","EXEC"], + ["string"," "], + ["support.class","BAZ"] +],[ + ["indentedHeredoc","EXEC"], + ["string"," echo hi"] +],[ + "start", + ["string"," "], + ["support.class","EXEC"] +],[ + "start", + ["support.function","puts"], + ["text"," "], + ["identifier","herDocs"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_rust.json b/lib/ace/mode/_test/tokens_rust.json new file mode 100644 index 00000000..8c59a3aa --- /dev/null +++ b/lib/ace/mode/_test/tokens_rust.json @@ -0,0 +1,139 @@ +[[ + "start", + ["keyword.source.rust","use"], + ["text"," "], + ["support.constant","core::rand::"], + ["text","RngUtil"], + ["keyword.operator",";"] +],[ + "start" +],[ + "start", + ["keyword.source.rust","fn"], + ["text"," "], + ["entity.name.function.source.rust","main"], + ["text","() {"] +],[ + "start", + ["text"," "], + ["keyword.source.rust","for"], + ["text"," ["], + ["string.quoted.double.source.rust","\"Alice\""], + ["keyword.operator",","], + ["text"," "], + ["string.quoted.double.source.rust","\"Bob\""], + ["keyword.operator",","], + ["text"," "], + ["string.quoted.double.source.rust","\"Carol\""], + ["text","].each |&name| {"] +],[ + "start", + ["text"," "], + ["keyword.source.rust","do"], + ["text"," spawn {"] +],[ + "start", + ["text"," "], + ["keyword.source.rust","let"], + ["text"," v "], + ["keyword.operator","="], + ["text"," "], + ["support.constant","rand::"], + ["text","Rng().shuffle(["], + ["constant.numeric.integer.source.rust","1"], + ["keyword.operator",","], + ["text"," "], + ["constant.numeric.integer.source.rust","2"], + ["keyword.operator",","], + ["text"," "], + ["constant.numeric.integer.source.rust","3"], + ["text","])"], + ["keyword.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.source.rust","for"], + ["text"," v.each |&num| {"] +],[ + "start", + ["text"," print(fmt"], + ["keyword.operator","!"], + ["text","("], + ["string.quoted.double.source.rust","\"%s says: '%d'"], + ["constant.character.escape.source.rust","\\n"], + ["string.quoted.double.source.rust","\""], + ["keyword.operator",","], + ["text"," name"], + ["keyword.operator",","], + ["text"," num "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric.integer.source.rust","1"], + ["text","))"] +],[ + "start", + ["text"," }"] +],[ + "start", + ["text"," }"] +],[ + "start", + ["text"," }"] +],[ + "start", + ["text","}"] +],[ + "start" +],[ + "start", + ["keyword.source.rust","fn"], + ["text"," "], + ["entity.name.function.source.rust","map"], + ["keyword.operator","<"], + ["text","T"], + ["keyword.operator",","], + ["text"," U"], + ["keyword.operator",">"], + ["text","(vector: &[T]"], + ["keyword.operator",","], + ["text"," function: &fn(v: &T) "], + ["keyword.operator","->"], + ["text"," U) "], + ["keyword.operator","->"], + ["text"," ~[U] {"] +],[ + "start", + ["text"," "], + ["keyword.source.rust","let"], + ["text"," "], + ["keyword.source.rust","mut"], + ["text"," accumulator "], + ["keyword.operator","="], + ["text"," ~[]"], + ["keyword.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.source.rust","for"], + ["text"," "], + ["support.constant","vec::"], + ["text","each(vector) |element| {"] +],[ + "start", + ["text"," accumulator.push(function(element))"], + ["keyword.operator",";"] +],[ + "start", + ["text"," }"] +],[ + "start", + ["text"," "], + ["keyword.source.rust","return"], + ["text"," accumulator"], + ["keyword.operator",";"] +],[ + "start", + ["text","}"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_sass.json b/lib/ace/mode/_test/tokens_sass.json new file mode 100644 index 00000000..c0b85682 --- /dev/null +++ b/lib/ace/mode/_test/tokens_sass.json @@ -0,0 +1,229 @@ +[[ + "start", + ["comment","// sass ace mode;"] +],[ + "start" +],[ + "start", + ["keyword","@import"], + ["text"," "], + ["support.function","url("], + ["string","http://fonts.googleapis.com/css?family=Ace:700"], + ["support.function",")"] +],[ + "start" +],[ + "start", + ["variable.language","html"], + ["text",", "], + ["variable.language","body"] +],[ + "start", + ["support.type"," :background-color "], + ["constant.numeric","#ace"] +],[ + "start", + ["text"," "], + ["support.type","text-align"], + ["text",": "], + ["constant.language","center"] +],[ + "start", + ["text"," "], + ["support.type","height"], + ["text",": "], + ["constant.numeric","100%"] +],[ + ["comment",-1,2,"start"], + ["comment"," /*;*********;"] +],[ + ["comment",3,2,"start"], + ["comment"," ;comment ;"] +],[ + ["comment",3,2,"start"], + ["comment"," ;*********;"] +],[ + "start" +],[ + "start", + ["variable.language",".toggle"] +],[ + "start", + ["text"," "], + ["variable","$size"], + ["text",": "], + ["constant.numeric","14px"] +],[ + "start" +],[ + "start", + ["support.type"," :background "], + ["support.function","url("], + ["string","http://subtlepatterns.com/patterns/dark_stripes.png"], + ["support.function",")"] +],[ + "start", + ["text"," "], + ["support.type","border-radius"], + ["text",": "], + ["constant.numeric","8px"] +],[ + "start", + ["text"," "], + ["support.type","height"], + ["text",": "], + ["variable","$size"] +],[ + "start" +],[ + "start", + ["text"," &"], + ["variable.language",":before"] +],[ + "start", + ["text"," "], + ["variable","$radius"], + ["text",": "], + ["variable","$size"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "], + ["constant.numeric","0.845"] +],[ + "start", + ["text"," "], + ["variable","$glow"], + ["text",": "], + ["variable","$size"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "], + ["constant.numeric","0.125"] +],[ + "start" +],[ + "start", + ["text"," "], + ["support.type","box-shadow"], + ["text",": "], + ["constant.numeric","0"], + ["text"," "], + ["constant.numeric","0"], + ["text"," "], + ["variable","$glow"], + ["text"," "], + ["variable","$glow"], + ["text"," / "], + ["constant.numeric","2"], + ["text"," "], + ["constant.numeric","#fff"] +],[ + "start", + ["text"," "], + ["support.type","border-radius"], + ["text",": "], + ["variable","$radius"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," &"], + ["variable.language",":active"] +],[ + "start", + ["text"," ~ "], + ["variable.language",".button"] +],[ + "start", + ["text"," "], + ["support.type","box-shadow"], + ["text",": "], + ["constant.numeric","0"], + ["text"," "], + ["constant.numeric","15px"], + ["text"," "], + ["constant.numeric","25px"], + ["text"," "], + ["constant.numeric","-4px"], + ["text"," "], + ["support.function","rgba"], + ["paren.lparen","("], + ["constant.numeric","0"], + ["text",","], + ["constant.numeric","0"], + ["text",","], + ["constant.numeric","0"], + ["text",","], + ["constant.numeric","0.4"], + ["paren.rparen",")"], + ["text"," "] +],[ + "start", + ["text"," ~ "], + ["variable.language",".label"] +],[ + "start", + ["text"," "], + ["support.type","font-size"], + ["text",": "], + ["constant.numeric","40px"] +],[ + "start", + ["text"," "], + ["support.type","color"], + ["text",": "], + ["support.function","rgba"], + ["paren.lparen","("], + ["constant.numeric","0"], + ["text",","], + ["constant.numeric","0"], + ["text",","], + ["constant.numeric","0"], + ["text",","], + ["constant.numeric","0.45"], + ["paren.rparen",")"] +],[ + "start" +],[ + "start", + ["text"," &"], + ["variable.language",":checked"], + ["text"," "] +],[ + "start", + ["text"," ~ "], + ["variable.language",".button"] +],[ + "start", + ["text"," "], + ["support.type","box-shadow"], + ["text",": "], + ["constant.numeric","0"], + ["text"," "], + ["constant.numeric","15px"], + ["text"," "], + ["constant.numeric","25px"], + ["text"," "], + ["constant.numeric","-4px"], + ["text"," "], + ["constant.numeric","#ace"] +],[ + "start", + ["text"," ~ "], + ["variable.language",".label"] +],[ + "start", + ["text"," "], + ["support.type","font-size"], + ["text",": "], + ["constant.numeric","40px"] +],[ + "start", + ["text"," "], + ["support.type","color"], + ["text",": "], + ["constant.numeric","#c9c9c9"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_scad.json b/lib/ace/mode/_test/tokens_scad.json new file mode 100644 index 00000000..8f0ff637 --- /dev/null +++ b/lib/ace/mode/_test/tokens_scad.json @@ -0,0 +1,194 @@ +[[ + "start", + ["comment","// ace can highlight scad!"] +],[ + "start", + ["keyword","module"], + ["text"," "], + ["identifier","Element"], + ["paren.lparen","("], + ["identifier","xpos"], + ["text",", "], + ["identifier","ypos"], + ["text",", "], + ["identifier","zpos"], + ["paren.rparen",")"], + ["paren.lparen","{"] +],[ + "start", + ["text","\t"], + ["identifier","translate"], + ["paren.lparen","(["], + ["identifier","xpos"], + ["text",","], + ["identifier","ypos"], + ["text",","], + ["identifier","zpos"], + ["paren.rparen","])"], + ["paren.lparen","{"] +],[ + "start", + ["text","\t\t"], + ["identifier","union"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["paren.lparen","{"] +],[ + "start", + ["text","\t\t\t"], + ["identifier","cube"], + ["paren.lparen","(["], + ["constant.numeric","10"], + ["text",","], + ["constant.numeric","10"], + ["text",","], + ["constant.numeric","4"], + ["paren.rparen","]"], + ["text",","], + ["identifier","true"], + ["paren.rparen",")"], + ["text",";"] +],[ + "start", + ["text","\t\t\t"], + ["identifier","cylinder"], + ["paren.lparen","("], + ["constant.numeric","10"], + ["text",","], + ["constant.numeric","15"], + ["text",","], + ["constant.numeric","5"], + ["paren.rparen",")"], + ["text",";"] +],[ + "start", + ["text","\t\t\t"], + ["identifier","translate"], + ["paren.lparen","(["], + ["constant.numeric","0"], + ["text",","], + ["constant.numeric","0"], + ["text",","], + ["constant.numeric","10"], + ["paren.rparen","])"], + ["identifier","sphere"], + ["paren.lparen","("], + ["constant.numeric","5"], + ["paren.rparen",")"], + ["text",";"] +],[ + "start", + ["text","\t\t"], + ["paren.rparen","}"] +],[ + "start", + ["text","\t"], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["identifier","union"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["paren.lparen","{"] +],[ + "start", + ["text","\t"], + ["keyword","for"], + ["paren.lparen","("], + ["identifier","i"], + ["keyword.operator","="], + ["paren.lparen","["], + ["constant.numeric","0"], + ["text",":"], + ["constant.numeric","30"], + ["paren.rparen","])"], + ["paren.lparen","{"] +],[ + "start", + ["text","\t\t# "], + ["identifier","Element"], + ["paren.lparen","("], + ["constant.numeric","0"], + ["text",","], + ["constant.numeric","0"], + ["text",","], + ["constant.numeric","0"], + ["paren.rparen",")"], + ["text",";"] +],[ + "start", + ["text","\t\t"], + ["identifier","Element"], + ["paren.lparen","("], + ["constant.numeric","15"], + ["keyword.operator","*"], + ["identifier","i"], + ["text",","], + ["constant.numeric","0"], + ["text",","], + ["constant.numeric","0"], + ["paren.rparen",")"], + ["text",";"] +],[ + "start", + ["text","\t"], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["keyword","for"], + ["text"," "], + ["paren.lparen","("], + ["identifier","i"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","["], + ["constant.numeric","3"], + ["text",", "], + ["constant.numeric","5"], + ["text",", "], + ["constant.numeric","7"], + ["text",", "], + ["constant.numeric","11"], + ["paren.rparen","])"], + ["paren.lparen","{"] +],[ + "start", + ["text","\t"], + ["identifier","rotate"], + ["paren.lparen","(["], + ["identifier","i"], + ["keyword.operator","*"], + ["constant.numeric","10"], + ["text",","], + ["constant.numeric","0"], + ["text",","], + ["constant.numeric","0"], + ["paren.rparen","])"], + ["identifier","scale"], + ["paren.lparen","(["], + ["constant.numeric","1"], + ["text",","], + ["constant.numeric","1"], + ["text",","], + ["identifier","i"], + ["paren.rparen","])"], + ["identifier","cube"], + ["paren.lparen","("], + ["constant.numeric","10"], + ["paren.rparen",")"], + ["text",";"] +],[ + "start", + ["paren.rparen","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_scala.json b/lib/ace/mode/_test/tokens_scala.json new file mode 100644 index 00000000..01dd3ce3 --- /dev/null +++ b/lib/ace/mode/_test/tokens_scala.json @@ -0,0 +1,542 @@ +[[ + "start", + ["comment","// http://www.scala-lang.org/node/54"] +],[ + "start" +],[ + "start", + ["keyword","package"], + ["text"," "], + ["identifier","examples"], + ["text","."], + ["identifier","actors"] +],[ + "start" +],[ + "start", + ["keyword","import"], + ["text"," "], + ["identifier","scala"], + ["text","."], + ["identifier","actors"], + ["text","."], + ["identifier","Actor"] +],[ + "start", + ["keyword","import"], + ["text"," "], + ["identifier","scala"], + ["text","."], + ["identifier","actors"], + ["text","."], + ["identifier","Actor"], + ["text","."], + ["identifier","_"] +],[ + "start" +],[ + "start", + ["keyword","abstract"], + ["text"," "], + ["keyword","class"], + ["text"," "], + ["identifier","PingMessage"] +],[ + "start", + ["keyword","case"], + ["text"," "], + ["keyword","object"], + ["text"," "], + ["identifier","Start"], + ["text"," "], + ["keyword","extends"], + ["text"," "], + ["identifier","PingMessage"] +],[ + "start", + ["keyword","case"], + ["text"," "], + ["keyword","object"], + ["text"," "], + ["identifier","SendPing"], + ["text"," "], + ["keyword","extends"], + ["text"," "], + ["identifier","PingMessage"] +],[ + "start", + ["keyword","case"], + ["text"," "], + ["keyword","object"], + ["text"," "], + ["identifier","Pong"], + ["text"," "], + ["keyword","extends"], + ["text"," "], + ["identifier","PingMessage"] +],[ + "start" +],[ + "start", + ["keyword","abstract"], + ["text"," "], + ["keyword","class"], + ["text"," "], + ["identifier","PongMessage"] +],[ + "start", + ["keyword","case"], + ["text"," "], + ["keyword","object"], + ["text"," "], + ["identifier","Ping"], + ["text"," "], + ["keyword","extends"], + ["text"," "], + ["identifier","PongMessage"] +],[ + "start", + ["keyword","case"], + ["text"," "], + ["keyword","object"], + ["text"," "], + ["identifier","Stop"], + ["text"," "], + ["keyword","extends"], + ["text"," "], + ["identifier","PongMessage"] +],[ + "start" +],[ + "start", + ["keyword","object"], + ["text"," "], + ["identifier","pingpong"], + ["text"," "], + ["keyword","extends"], + ["text"," "], + ["identifier","Application"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","val"], + ["text"," "], + ["identifier","pong"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["keyword","new"], + ["text"," "], + ["identifier","Pong"] +],[ + "start", + ["text"," "], + ["keyword","val"], + ["text"," "], + ["identifier","ping"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["keyword","new"], + ["text"," "], + ["identifier","Ping"], + ["paren.lparen","("], + ["constant.numeric","100000"], + ["text",", "], + ["identifier","pong"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["identifier","ping"], + ["text","."], + ["identifier","start"] +],[ + "start", + ["text"," "], + ["identifier","pong"], + ["text","."], + ["identifier","start"] +],[ + "start", + ["text"," "], + ["identifier","ping"], + ["text"," "], + ["keyword.operator","!"], + ["text"," "], + ["identifier","Start"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["keyword","class"], + ["text"," "], + ["identifier","Ping"], + ["paren.lparen","("], + ["identifier","count"], + ["text",": "], + ["support.function","Int"], + ["text",", "], + ["identifier","pong"], + ["text",": "], + ["identifier","Actor"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","extends"], + ["text"," "], + ["identifier","Actor"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","def"], + ["text"," "], + ["identifier","act"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["identifier","println"], + ["paren.lparen","("], + ["string","\"Ping: Initializing with count \""], + ["keyword.operator","+"], + ["identifier","count"], + ["keyword.operator","+"], + ["string","\": \""], + ["keyword.operator","+"], + ["identifier","pong"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["keyword","var"], + ["text"," "], + ["identifier","pingsLeft"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","count"] +],[ + "start", + ["text"," "], + ["identifier","loop"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["identifier","react"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","case"], + ["text"," "], + ["identifier","Start"], + ["text"," "], + ["keyword.operator","=>"] +],[ + "start", + ["text"," "], + ["identifier","println"], + ["paren.lparen","("], + ["string","\"Ping: starting.\""], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["identifier","pong"], + ["text"," "], + ["keyword.operator","!"], + ["text"," "], + ["identifier","Ping"] +],[ + "start", + ["text"," "], + ["identifier","pingsLeft"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","pingsLeft"], + ["text"," "], + ["keyword.operator","-"], + ["text"," "], + ["constant.numeric","1"] +],[ + "start", + ["text"," "], + ["keyword","case"], + ["text"," "], + ["identifier","SendPing"], + ["text"," "], + ["keyword.operator","=>"] +],[ + "start", + ["text"," "], + ["identifier","pong"], + ["text"," "], + ["keyword.operator","!"], + ["text"," "], + ["identifier","Ping"] +],[ + "start", + ["text"," "], + ["identifier","pingsLeft"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","pingsLeft"], + ["text"," "], + ["keyword.operator","-"], + ["text"," "], + ["constant.numeric","1"] +],[ + "start", + ["text"," "], + ["keyword","case"], + ["text"," "], + ["identifier","Pong"], + ["text"," "], + ["keyword.operator","=>"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["paren.lparen","("], + ["identifier","pingsLeft"], + ["text"," "], + ["keyword.operator","%"], + ["text"," "], + ["constant.numeric","1000"], + ["text"," "], + ["keyword.operator","=="], + ["text"," "], + ["constant.numeric","0"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["identifier","println"], + ["paren.lparen","("], + ["string","\"Ping: pong from: \""], + ["keyword.operator","+"], + ["identifier","sender"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["paren.lparen","("], + ["identifier","pingsLeft"], + ["text"," "], + ["keyword.operator",">"], + ["text"," "], + ["constant.numeric","0"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["identifier","self"], + ["text"," "], + ["keyword.operator","!"], + ["text"," "], + ["identifier","SendPing"] +],[ + "start", + ["text"," "], + ["keyword","else"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["identifier","println"], + ["paren.lparen","("], + ["string","\"Ping: Stop.\""], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["identifier","pong"], + ["text"," "], + ["keyword.operator","!"], + ["text"," "], + ["identifier","Stop"] +],[ + "start", + ["text"," "], + ["identifier","exit"], + ["paren.lparen","("], + ["symbol.constant","'stop"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["keyword","class"], + ["text"," "], + ["identifier","Pong"], + ["text"," "], + ["keyword","extends"], + ["text"," "], + ["identifier","Actor"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","def"], + ["text"," "], + ["identifier","act"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","var"], + ["text"," "], + ["identifier","pongCount"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","0"] +],[ + "start", + ["text"," "], + ["identifier","loop"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["identifier","react"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","case"], + ["text"," "], + ["identifier","Ping"], + ["text"," "], + ["keyword.operator","=>"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["paren.lparen","("], + ["identifier","pongCount"], + ["text"," "], + ["keyword.operator","%"], + ["text"," "], + ["constant.numeric","1000"], + ["text"," "], + ["keyword.operator","=="], + ["text"," "], + ["constant.numeric","0"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["identifier","println"], + ["paren.lparen","("], + ["string","\"Pong: ping \""], + ["keyword.operator","+"], + ["identifier","pongCount"], + ["keyword.operator","+"], + ["string","\" from \""], + ["keyword.operator","+"], + ["identifier","sender"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["identifier","sender"], + ["text"," "], + ["keyword.operator","!"], + ["text"," "], + ["identifier","Pong"] +],[ + "start", + ["text"," "], + ["identifier","pongCount"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","pongCount"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","1"] +],[ + "start", + ["text"," "], + ["keyword","case"], + ["text"," "], + ["identifier","Stop"], + ["text"," "], + ["keyword.operator","=>"] +],[ + "start", + ["text"," "], + ["identifier","println"], + ["paren.lparen","("], + ["string","\"Pong: Stop.\""], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["identifier","exit"], + ["paren.lparen","("], + ["symbol.constant","'stop"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_scheme.json b/lib/ace/mode/_test/tokens_scheme.json new file mode 100644 index 00000000..42f4aa65 --- /dev/null +++ b/lib/ace/mode/_test/tokens_scheme.json @@ -0,0 +1,216 @@ +[[ + "start", + ["text","("], + ["storage.type.function-type.scheme","define"], + ["text"," "], + ["text","("], + ["identifier","prompt-for-cd"], + ["text",")"] +],[ + "start", + ["text"," "], + ["string","\"Prompts"] +],[ + "start", + ["text"," "], + ["identifier","for"], + ["text"," "], + ["identifier","CD"], + ["text","\""] +],[ + "start", + ["text"," ("], + ["identifier","prompt-read"], + ["text"," "], + ["string","\"Title\""], + ["text"," "], + ["constant.numeric","1.53"], + ["text"," "], + ["constant.numeric","1"], + ["text"," "], + ["constant.numeric","2"], + ["text","/"], + ["constant.numeric","4"], + ["text"," "], + ["constant.numeric","1.7"], + ["text"," "], + ["constant.numeric","1.7e0"], + ["text"," "], + ["constant.numeric","2.9E-4"], + ["text"," "], + ["constant.numeric","+42"], + ["text"," "], + ["constant.numeric","-7"], + ["text"," "], + ["constant.numeric","#b001"], + ["text"," "], + ["constant.numeric","#b001"], + ["text","/"], + ["constant.numeric","100"], + ["text"," "], + ["constant.numeric","#o777"], + ["text"," "], + ["constant.numeric","#O777"], + ["text"," "], + ["constant.numeric","#xabc55"], + ["text"," "], + ["identifier","#c"], + ["text","("], + ["constant.numeric","0"], + ["text"," "], + ["constant.numeric","-5.6"], + ["text","))"] +],[ + "start", + ["text"," ("], + ["identifier","prompt-read"], + ["text"," "], + ["string","\"Artist\""], + ["text",")"] +],[ + "start", + ["text"," ("], + ["keyword.operator","or"], + ["text"," ("], + ["identifier","parse-integer"], + ["text"," ("], + ["identifier","prompt-read"], + ["text"," "], + ["string","\"Rating\""], + ["text",") "], + ["punctuation.definition.constant.character.scheme","#:junk-allowed"], + ["text"," "], + ["constant.language","#t"], + ["text",") "], + ["constant.numeric","0"], + ["text",")"] +],[ + "start", + ["text"," ("], + ["keyword.control","if"], + ["text"," "], + ["identifier","x"], + ["text"," ("], + ["support.function","format"], + ["text"," "], + ["constant.language","#t"], + ["text"," "], + ["string","\"yes\""], + ["text",") ("], + ["support.function","format"], + ["text"," "], + ["constant.language","#f"], + ["text"," "], + ["string","\"no\""], + ["text",") "], + ["comment",";and here comment"] +],[ + "start", + ["text"," ) "] +],[ + "start", + ["text"," "], + ["comment",";; second line comment"] +],[ + "start", + ["text"," '(+ "], + ["constant.numeric","1"], + ["text"," "], + ["constant.numeric","2"], + ["text",")"] +],[ + "start", + ["text"," ("], + ["identifier","position-if-not"], + ["text"," "], + ["identifier","char-set"], + ["text",":"], + ["identifier","whitespace"], + ["text"," "], + ["identifier","line"], + ["text"," "], + ["punctuation.definition.constant.character.scheme","#:start"], + ["text"," "], + ["identifier","beg"], + ["text","))"] +],[ + "start", + ["text"," ("], + ["support.function","quote"], + ["text"," ("], + ["identifier","privet"], + ["text"," "], + ["constant.numeric","1"], + ["text"," "], + ["constant.numeric","2"], + ["text"," "], + ["constant.numeric","3"], + ["text","))"] +],[ + "start", + ["text"," '("], + ["identifier","hello"], + ["text"," "], + ["identifier","world"], + ["text",")"] +],[ + "start", + ["text"," (* "], + ["constant.numeric","5"], + ["text"," "], + ["constant.numeric","7"], + ["text",")"] +],[ + "start", + ["text"," ("], + ["constant.numeric","1"], + ["text"," "], + ["constant.numeric","2"], + ["text"," "], + ["constant.numeric","34"], + ["text"," "], + ["constant.numeric","5"], + ["text",")"] +],[ + "start", + ["text"," ("], + ["punctuation.definition.constant.character.scheme","#:use"], + ["text"," "], + ["string","\"aaaa\""], + ["text",")"] +],[ + "start", + ["text"," ("], + ["keyword.control","let"], + ["text"," (("], + ["identifier","x"], + ["text"," "], + ["constant.numeric","10"], + ["text",") ("], + ["identifier","y"], + ["text"," "], + ["constant.numeric","20"], + ["text","))"] +],[ + "start", + ["text"," ("], + ["identifier","display"], + ["text"," (+ "], + ["identifier","x"], + ["text"," "], + ["identifier","y"], + ["text","))"] +],[ + "start", + ["text"," ) "] +],[ + "start" +],[ + "start", + ["text"," "], + ["string","\"asdad"], + ["constant.character.escape.scheme","\\0"], + ["string","eqweqe\""] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_scss.json b/lib/ace/mode/_test/tokens_scss.json new file mode 100644 index 00000000..7e92f153 --- /dev/null +++ b/lib/ace/mode/_test/tokens_scss.json @@ -0,0 +1,123 @@ +[[ + "start", + ["comment","/* style.scss */"] +],[ + "start" +],[ + "start", + ["variable.language","#navbar"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable","$navbar-width"], + ["text",": "], + ["constant.numeric","800px"], + ["text",";"] +],[ + "start", + ["text"," "], + ["variable","$items"], + ["text",": "], + ["constant.numeric","5"], + ["text",";"] +],[ + "start", + ["text"," "], + ["variable","$navbar-color"], + ["text",": "], + ["constant.numeric","#ce4dd6"], + ["text",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["support.type","width"], + ["text",": "], + ["variable","$navbar-width"], + ["text",";"] +],[ + "start", + ["text"," "], + ["support.type","border-bottom"], + ["text",": "], + ["constant.numeric","2px"], + ["text"," "], + ["constant.language","solid"], + ["text"," "], + ["variable","$navbar-color"], + ["text",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["variable.language","li"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["support.type","float"], + ["text",": "], + ["support.type","left"], + ["text",";"] +],[ + "start", + ["text"," "], + ["support.type","width"], + ["text",": "], + ["variable","$navbar-width"], + ["text","/"], + ["variable","$items"], + ["text"," "], + ["constant","-"], + ["text"," "], + ["constant.numeric","10px"], + ["text",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["support.type","background-color"], + ["text",": "], + ["support.function","lighten"], + ["paren.lparen","("], + ["variable","$navbar-color"], + ["text",", "], + ["constant.numeric","20%"], + ["paren.rparen",")"], + ["text",";"] +],[ + "start", + ["text"," &"], + ["variable.language",":hover"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["support.type","background-color"], + ["text",": "], + ["support.function","lighten"], + ["paren.lparen","("], + ["variable","$navbar-color"], + ["text",", "], + ["constant.numeric","10%"], + ["paren.rparen",")"], + ["text",";"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["paren.rparen","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_sh.json b/lib/ace/mode/_test/tokens_sh.json new file mode 100644 index 00000000..f2c6b276 --- /dev/null +++ b/lib/ace/mode/_test/tokens_sh.json @@ -0,0 +1,334 @@ +[[ + "start", + ["comment","#!/bin/sh"] +],[ + "start" +],[ + "start", + ["comment","# Script to open a browser to current branch"] +],[ + "start", + ["comment","# Repo formats:"] +],[ + "start", + ["comment","# ssh git@github.com:richo/gh_pr.git"] +],[ + "start", + ["comment","# http https://richoH@github.com/richo/gh_pr.git"] +],[ + "start", + ["comment","# git git://github.com/richo/gh_pr.git"] +],[ + "start" +],[ + "start", + ["variable","username="], + ["text","`"], + ["identifier","git"], + ["text"," "], + ["identifier","config"], + ["text"," "], + ["keyword.operator","--"], + ["identifier","get"], + ["text"," "], + ["identifier","github"], + ["text","."], + ["identifier","user"], + ["text","`"] +],[ + "start" +],[ + "start", + ["support.function","get_repo()"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["identifier","git"], + ["text"," "], + ["identifier","remote"], + ["text"," "], + ["keyword.operator","-"], + ["identifier","v"], + ["text"," | "], + ["identifier","grep"], + ["text"," $"], + ["paren.lparen","{"], + ["text","@:"], + ["keyword.operator","-"], + ["variable","$username"], + ["paren.rparen","}"], + ["text"," | "], + ["keyword","while"], + ["text"," "], + ["keyword","read"], + ["text"," "], + ["identifier","remote"], + ["text","; "], + ["keyword","do"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","repo="], + ["text","`"], + ["support.function.builtin","echo"], + ["text"," "], + ["variable","$remote"], + ["text"," | "], + ["identifier","grep"], + ["text"," "], + ["keyword.operator","-"], + ["identifier","E"], + ["text"," "], + ["keyword.operator","-"], + ["identifier","o"], + ["text"," "], + ["string","\"git@github.com:[^ ]*\""], + ["text","`; "], + ["keyword","then"] +],[ + "start", + ["text"," "], + ["support.function.builtin","echo"], + ["text"," "], + ["variable","$repo"], + ["text"," | "], + ["identifier","sed"], + ["text"," "], + ["keyword.operator","-"], + ["identifier","e"], + ["text"," "], + ["string","\"s/^git@github\\.com://\""], + ["text"," "], + ["keyword.operator","-"], + ["identifier","e"], + ["text"," "], + ["string","\"s/\\.git$//\""] +],[ + "start", + ["text"," "], + ["support.function.builtin","exit"], + ["text"," "], + ["constant.numeric","1"] +],[ + "start", + ["text"," "], + ["keyword","fi"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","repo="], + ["text","`"], + ["support.function.builtin","echo"], + ["text"," "], + ["variable","$remote"], + ["text"," | "], + ["identifier","grep"], + ["text"," "], + ["keyword.operator","-"], + ["identifier","E"], + ["text"," "], + ["keyword.operator","-"], + ["identifier","o"], + ["text"," "], + ["string","\"https?://([^@]*@)?github.com/[^ ]*\\.git\""], + ["text","`; "], + ["keyword","then"] +],[ + "start", + ["text"," "], + ["support.function.builtin","echo"], + ["text"," "], + ["variable","$repo"], + ["text"," | "], + ["identifier","sed"], + ["text"," "], + ["keyword.operator","-"], + ["identifier","e"], + ["text"," "], + ["string","\"s|^https?://||\""], + ["text"," "], + ["keyword.operator","-"], + ["identifier","e"], + ["text"," "], + ["string","\"s/^.*github\\.com\\///\""], + ["text"," "], + ["keyword.operator","-"], + ["identifier","e"], + ["text"," "], + ["string","\"s/\\.git$//\""] +],[ + "start", + ["text"," "], + ["support.function.builtin","exit"], + ["text"," "], + ["constant.numeric","1"] +],[ + "start", + ["text"," "], + ["keyword","fi"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["variable","repo="], + ["text","`"], + ["support.function.builtin","echo"], + ["text"," "], + ["variable","$remote"], + ["text"," | "], + ["identifier","grep"], + ["text"," "], + ["keyword.operator","-"], + ["identifier","E"], + ["text"," "], + ["keyword.operator","-"], + ["identifier","o"], + ["text"," "], + ["string","\"git://github.com/[^ ]*\\.git\""], + ["text","`; "], + ["keyword","then"] +],[ + "start", + ["text"," "], + ["support.function.builtin","echo"], + ["text"," "], + ["variable","$repo"], + ["text"," | "], + ["identifier","sed"], + ["text"," "], + ["keyword.operator","-"], + ["identifier","e"], + ["text"," "], + ["string","\"s|^git://github.com/||\""], + ["text"," "], + ["keyword.operator","-"], + ["identifier","e"], + ["text"," "], + ["string","\"s/\\.git$//\""] +],[ + "start", + ["text"," "], + ["support.function.builtin","exit"], + ["text"," "], + ["constant.numeric","1"] +],[ + "start", + ["text"," "], + ["keyword","fi"] +],[ + "start", + ["text"," "], + ["keyword","done"] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["paren.lparen","["], + ["text"," "], + ["variable.language","$?"], + ["text"," "], + ["keyword.operator","-"], + ["identifier","eq"], + ["text"," "], + ["constant.numeric","0"], + ["text"," "], + ["paren.rparen","]"], + ["text","; "], + ["keyword","then"] +],[ + "start", + ["text"," "], + ["support.function.builtin","echo"], + ["text"," "], + ["string","\"Couldn't find a valid remote\""], + ["text"," "], + ["keyword.operator",">"], + ["support.function","&2"] +],[ + "start", + ["text"," "], + ["support.function.builtin","exit"], + ["text"," "], + ["constant.numeric","1"] +],[ + "start", + ["text"," "], + ["keyword","fi"] +],[ + "start", + ["paren.rparen","}"] +],[ + "start" +],[ + "start", + ["support.function.builtin","echo"], + ["text"," $"], + ["paren.lparen","{"], + ["text","#"], + ["identifier","x"], + ["paren.lparen","["], + ["text","@"], + ["paren.rparen","]}"] +],[ + "start" +],[ + "start", + ["keyword","if"], + ["text"," "], + ["variable","repo="], + ["text","`"], + ["identifier","get_repo"], + ["text"," $@`; "], + ["keyword","then"] +],[ + "start", + ["text"," "], + ["variable","branch="], + ["text","`"], + ["identifier","git"], + ["text"," "], + ["identifier","symbolic"], + ["keyword.operator","-"], + ["identifier","ref"], + ["text"," "], + ["identifier","HEAD"], + ["text"," "], + ["constant.numeric","2"], + ["keyword.operator",">/"], + ["identifier","dev"], + ["keyword.operator","/"], + ["identifier","null"], + ["text","`"] +],[ + "start", + ["text"," "], + ["support.function.builtin","echo"], + ["text"," "], + ["string","\"http://github.com/"], + ["constant","$repo"], + ["string","/pull/new/${branch##refs/heads/}\""] +],[ + "start", + ["keyword","else"] +],[ + "start", + ["text"," "], + ["support.function.builtin","exit"], + ["text"," "], + ["constant.numeric","1"] +],[ + "start", + ["keyword","fi"] +],[ + "start" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_sjs.json b/lib/ace/mode/_test/tokens_sjs.json new file mode 100644 index 00000000..5cd96451 --- /dev/null +++ b/lib/ace/mode/_test/tokens_sjs.json @@ -0,0 +1,276 @@ +[[ + "start", + ["storage.type","var"], + ["text"," "], + ["paren.lparen","{"], + ["text"," "], + ["identifier","each"], + ["punctuation.operator",","], + ["text"," "], + ["identifier","map"], + ["text"," "], + ["paren.rparen","}"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","require"], + ["paren.lparen","("], + ["string","'sjs:sequence'"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["storage.type","var"], + ["text"," "], + ["paren.lparen","{"], + ["text"," "], + ["keyword","get"], + ["text"," "], + ["paren.rparen","}"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","require"], + ["paren.lparen","("], + ["string","'sjs:http'"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start" +],[ + "start", + ["storage.type","function"], + ["text"," "], + ["entity.name.function","foo"], + ["paren.lparen","("], + ["variable.parameter","items"], + ["punctuation.operator",", "], + ["variable.parameter","nada"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + ["no_regex"], + ["text"," "], + ["storage.type","var"], + ["text"," "], + ["identifier","component"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","{"], + ["text"," "], + ["identifier","name"], + ["punctuation.operator",":"], + ["text"," "], + ["string","\"Ace\""], + ["punctuation.operator",","], + ["text"," "], + ["identifier","role"], + ["punctuation.operator",":"], + ["text"," "], + ["string","\"Editor\""], + ["text"," "], + ["paren.rparen","}"], + ["punctuation.operator",";"] +],[ + ["qqstring","no_regex"], + ["text"," "], + ["storage.type","console"], + ["punctuation.operator","."], + ["support.function.firebug","log"], + ["paren.lparen","("], + ["string","\""] +],[ + ["qqstring","no_regex"], + ["string"," Welcome, "], + ["paren.lparen","#{"], + ["identifier","component"], + ["text","."], + ["identifier","name"], + ["paren.rparen","}"] +],[ + ["no_regex"], + ["string"," \""], + ["punctuation.operator","."], + ["identifier","trim"], + ["paren.lparen","("], + ["paren.rparen","))"], + ["punctuation.operator",";"] +],[ + ["no_regex"] +],[ + ["no_regex"], + ["text"," "], + ["identifier","logging"], + ["punctuation.operator","."], + ["identifier","debug"], + ["paren.lparen","("], + ["string","`Component added: "], + ["paren.lparen","$"], + ["identifier","String"], + ["paren.lparen","("], + ["identifier","component"], + ["paren.rparen",")"], + ["string"," ("], + ["paren.lparen","${"], + ["identifier","component"], + ["paren.rparen","}"], + ["string",")`"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + ["no_regex"] +],[ + ["bstring","no_regex"], + ["text"," "], + ["storage.type","console"], + ["punctuation.operator","."], + ["support.function.firebug","log"], + ["paren.lparen","("], + ["string","`"] +],[ + ["string_interp","string_interp","bstring","no_regex"], + ["string"," Welcome, {"], + ["paren.lparen","${"], + ["storage.type","function"], + ["text","() "], + ["paren.lparen","{"] +],[ + ["string_interp","string_interp","bstring","no_regex"], + ["text"," "], + ["keyword","return"], + ["text"," "], + ["paren.lparen","{"], + ["text"," "], + ["identifier","x"], + ["text",": "], + ["constant.numeric","1"], + ["text",", "], + ["identifier","y"], + ["text",": "], + ["string","\"why?}\""], + ["paren.rparen","}"], + ["text",";"] +],[ + ["bstring","no_regex"], + ["text"," "], + ["paren.rparen","}"], + ["text","()"], + ["paren.rparen","}"] +],[ + ["no_regex"], + ["string"," `"], + ["punctuation.operator","."], + ["identifier","trim"], + ["paren.lparen","("], + ["paren.rparen","))"], + ["punctuation.operator",";"] +],[ + ["no_regex"] +],[ + ["no_regex"], + ["text"," "], + ["keyword","waitfor"], + ["text"," "], + ["paren.lparen","{"] +],[ + ["no_regex"], + ["text"," "], + ["identifier","items"], + ["text"," "], + ["keyword.operator",".."], + ["text"," "], + ["identifier","each"], + ["punctuation.operator","."], + ["identifier","par"], + ["text"," "], + ["paren.lparen","{"], + ["text"," "], + ["paren.rparen","|"], + ["variable.parameter","item"], + ["paren.rparen","|"] +],[ + ["no_regex"], + ["text"," "], + ["keyword","get"], + ["paren.lparen","("], + ["identifier","item"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + ["no_regex"], + ["text"," "], + ["paren.rparen","}"] +],[ + ["no_regex"], + ["text"," "], + ["paren.rparen","}"], + ["text"," "], + ["keyword","and"], + ["text"," "], + ["paren.lparen","{"] +],[ + ["no_regex"], + ["text"," "], + ["storage.type","var"], + ["text"," "], + ["identifier","lengths"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","items"], + ["text"," "], + ["keyword.operator",".."], + ["text"," "], + ["identifier","map"], + ["paren.lparen","("], + ["identifier","i"], + ["text"," "], + ["keyword.operator","->"], + ["text"," "], + ["identifier","i"], + ["punctuation.operator","."], + ["support.constant","length"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + ["no_regex"], + ["text"," "], + ["paren.rparen","}"], + ["text"," "], + ["keyword","or"], + ["text"," "], + ["paren.lparen","{"] +],[ + ["no_regex"], + ["text"," "], + ["variable.language","hold"], + ["paren.lparen","("], + ["constant.numeric","1500"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + ["no_regex"], + ["text"," "], + ["keyword","throw"], + ["text"," "], + ["keyword","new"], + ["text"," "], + ["variable.language","Error"], + ["paren.lparen","("], + ["string","\"timed out\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + ["no_regex"], + ["text"," "], + ["paren.rparen","}"] +],[ + ["no_regex"], + ["paren.rparen","}"], + ["text","\t"], + ["comment","// Real Tab."] +],[ + ["no_regex"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_smarty.json b/lib/ace/mode/_test/tokens_smarty.json new file mode 100644 index 00000000..0f56985d --- /dev/null +++ b/lib/ace/mode/_test/tokens_smarty.json @@ -0,0 +1,98 @@ +[[ + "start", + ["punctuation.section.embedded.begin.smarty","{"], + ["keyword.control.smarty","foreach"], + ["source.smarty"," "], + ["punctuation.definition.variable.smarty","$"], + ["variable.other.smarty","foo"], + ["source.smarty"," as "], + ["punctuation.definition.variable.smarty","$"], + ["variable.other.smarty","bar"], + ["punctuation.section.embedded.end.smarty","}"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.anchor.tag-name.xml","a"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\""], + ["punctuation.section.embedded.begin.smarty","{"], + ["punctuation.definition.variable.smarty","$"], + ["variable.other.smarty","bar"], + ["source.smarty",".zig"], + ["punctuation.section.embedded.end.smarty","}"], + ["string.attribute-value.xml","\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["punctuation.section.embedded.begin.smarty","{"], + ["punctuation.definition.variable.smarty","$"], + ["variable.other.smarty","bar"], + ["source.smarty",".zag"], + ["punctuation.section.embedded.end.smarty","}"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.anchor.tag-name.xml","a"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\""], + ["punctuation.section.embedded.begin.smarty","{"], + ["punctuation.definition.variable.smarty","$"], + ["variable.other.smarty","bar"], + ["source.smarty",".zig2"], + ["punctuation.section.embedded.end.smarty","}"], + ["string.attribute-value.xml","\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["punctuation.section.embedded.begin.smarty","{"], + ["punctuation.definition.variable.smarty","$"], + ["variable.other.smarty","bar"], + ["source.smarty",".zag2"], + ["punctuation.section.embedded.end.smarty","}"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.anchor.tag-name.xml","a"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\""], + ["punctuation.section.embedded.begin.smarty","{"], + ["punctuation.definition.variable.smarty","$"], + ["variable.other.smarty","bar"], + ["source.smarty",".zig3"], + ["punctuation.section.embedded.end.smarty","}"], + ["string.attribute-value.xml","\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["punctuation.section.embedded.begin.smarty","{"], + ["punctuation.definition.variable.smarty","$"], + ["variable.other.smarty","bar"], + ["source.smarty",".zag3"], + ["punctuation.section.embedded.end.smarty","}"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["punctuation.section.embedded.begin.smarty","{"], + ["keyword.control.smarty","foreachelse"], + ["punctuation.section.embedded.end.smarty","}"] +],[ + "start", + ["text.xml"," There were no rows found."] +],[ + "start", + ["punctuation.section.embedded.begin.smarty","{"], + ["source.smarty","/"], + ["keyword.control.smarty","foreach"], + ["punctuation.section.embedded.end.smarty","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_snippets.json b/lib/ace/mode/_test/tokens_snippets.json new file mode 100644 index 00000000..308683b7 --- /dev/null +++ b/lib/ace/mode/_test/tokens_snippets.json @@ -0,0 +1,159 @@ +[[ + "start", + ["comment","# Function"] +],[ + "start", + ["constant.language.escape","snippet"], + ["text"," fun"] +],[ + "sn-start", + ["text","\tfunction "], + ["markup.list","${"], + ["constant.numeric","1"], + ["text","?:function_name"], + ["markup.list","}"], + ["text","("], + ["markup.list","${"], + ["constant.numeric","2"], + ["punctuation.operator",":"], + ["text","argument"], + ["markup.list","}"], + ["text",") {"] +],[ + "sn-start", + ["text","\t\t"], + ["markup.list","${"], + ["constant.numeric","3"], + ["punctuation.operator",":"], + ["text","// body..."], + ["markup.list","}"] +],[ + "sn-start", + ["text","\t}"] +],[ + "start", + ["comment","# Anonymous Function"] +],[ + "start", + ["constant.language.escape","regex "], + ["keyword","/"], + ["text","((=)\\s*|(:)\\s*|(\\()|\\b)"], + ["keyword","/"], + ["text","f"], + ["keyword","/"], + ["text","(\\))?"], + ["keyword","/"] +],[ + "start", + ["constant.language.escape","name"], + ["text"," f"] +],[ + "sn-start", + ["text","\tfunction"], + ["markup.list","${"], + ["variable","M1"], + ["text","?: "], + ["markup.list","${"], + ["constant.numeric","1"], + ["punctuation.operator",":"], + ["text","functionName"], + ["markup.list","}}"], + ["text","("], + ["variable","$2"], + ["text",") {"] +],[ + "sn-start", + ["text","\t\t"], + ["markup.list","${"], + ["constant.numeric","0"], + ["punctuation.operator",":"], + ["keyword","$TM_SELECTED_TEXT"], + ["markup.list","}"] +],[ + "sn-start", + ["text","\t}"], + ["markup.list","${"], + ["variable","M2"], + ["text","?;"], + ["markup.list","}${"], + ["variable","M3"], + ["text","?,"], + ["markup.list","}${"], + ["variable","M4"], + ["text","?)"], + ["markup.list","}"] +],[ + "start", + ["comment","# Immediate function"] +],[ + "start", + ["constant.language.escape","trigger"], + ["text"," \\(?f\\("] +],[ + "start", + ["constant.language.escape","endTrigger"], + ["text"," \\)?"] +],[ + "start", + ["constant.language.escape","snippet"], + ["text"," f("] +],[ + "sn-start", + ["text","\t(function("], + ["markup.list","${"], + ["constant.numeric","1"], + ["markup.list","}"], + ["text",") {"] +],[ + "sn-start", + ["text","\t\t"], + ["markup.list","${"], + ["constant.numeric","0"], + ["punctuation.operator",":"], + ["markup.list","${"], + ["keyword","TM_SELECTED_TEXT"], + ["punctuation.operator",":"], + ["text","/* code */"], + ["markup.list","}}"] +],[ + "sn-start", + ["text","\t}("], + ["markup.list","${"], + ["constant.numeric","1"], + ["markup.list","}"], + ["text","));"] +],[ + "start", + ["comment","# if"] +],[ + "start", + ["constant.language.escape","snippet"], + ["text"," if"] +],[ + "sn-start", + ["text","\tif ("], + ["markup.list","${"], + ["constant.numeric","1"], + ["punctuation.operator",":"], + ["text","true"], + ["markup.list","}"], + ["text",") {"] +],[ + "sn-start", + ["text","\t\t"], + ["markup.list","${"], + ["constant.numeric","0"], + ["markup.list","}"] +],[ + "sn-start", + ["text","\t}"] +],[ + "sn-start", + ["text","\t"] +],[ + "sn-start", + ["text","\t"] +],[ + "sn-start", + ["text","\t"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_soy_template.json b/lib/ace/mode/_test/tokens_soy_template.json new file mode 100644 index 00000000..9ae7c4ed --- /dev/null +++ b/lib/ace/mode/_test/tokens_soy_template.json @@ -0,0 +1,286 @@ +[[ + "punctuation.definition.comment.begin.soy1", + ["punctuation.definition.comment.begin.soy","/**"] +],[ + "punctuation.definition.comment.begin.soy1", + ["comment.block.documentation.soy"," * Greets a person using \"Hello\" by default."] +],[ + "punctuation.definition.comment.begin.soy1", + ["comment.block.documentation.soy"," * "], + ["support.type.soy","@param"], + ["text"," "], + ["variable.parameter.soy","name"], + ["comment.block.documentation.soy"," The name of the person."] +],[ + "punctuation.definition.comment.begin.soy1", + ["comment.block.documentation.soy"," * "], + ["support.type.soy","@param?"], + ["text"," "], + ["variable.parameter.soy","greetingWord"], + ["comment.block.documentation.soy"," Optional greeting word to use instead of \"Hello\"."] +],[ + "start", + ["comment.block.documentation.soy"," "], + ["punctuation.definition.comment.end.soy","*/"] +],[ + "start", + ["punctuation.definition.tag.begin.soy","{"], + ["entity.name.tag.soy","template"], + ["text"," "], + ["entity.name.function.soy",".helloName"], + ["meta.tag.template.soy"," #eee"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["text.xml"," "], + ["punctuation.definition.tag.begin.soy","{"], + ["entity.name.tag.soy","if"], + ["meta.tag.if.soy"," "], + ["keyword.operator.soy","not"], + ["meta.tag.if.soy"," "], + ["variable.other.soy","$greetingWord"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["text.xml"," Hello "], + ["punctuation.definition.tag.begin.soy","{"], + ["variable.other.soy","$name"], + ["punctuation.definition.tag.end.soy","}"], + ["text.xml","!"] +],[ + "start", + ["text.xml"," "], + ["punctuation.definition.tag.begin.soy","{"], + ["text","else"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["text.xml"," "], + ["punctuation.definition.tag.begin.soy","{"], + ["variable.other.soy","$greetingWord"], + ["punctuation.definition.tag.end.soy","}"], + ["text.xml"," "], + ["punctuation.definition.tag.begin.soy","{"], + ["variable.other.soy","$name"], + ["punctuation.definition.tag.end.soy","}"], + ["text.xml","!"] +],[ + "start", + ["text.xml"," "], + ["punctuation.definition.tag.begin.soy","{/"], + ["entity.name.tag.soy","if"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["punctuation.definition.tag.begin.soy","{/"], + ["meta.tag.template.soy","template"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start" +],[ + "punctuation.definition.comment.begin.soy1", + ["punctuation.definition.comment.begin.soy","/**"] +],[ + "punctuation.definition.comment.begin.soy1", + ["comment.block.documentation.soy"," * Greets a person and optionally a list of other people."] +],[ + "punctuation.definition.comment.begin.soy1", + ["comment.block.documentation.soy"," * "], + ["support.type.soy","@param"], + ["text"," "], + ["variable.parameter.soy","name"], + ["comment.block.documentation.soy"," The name of the person."] +],[ + "punctuation.definition.comment.begin.soy1", + ["comment.block.documentation.soy"," * "], + ["support.type.soy","@param"], + ["text"," "], + ["variable.parameter.soy","additionalNames"], + ["comment.block.documentation.soy"," The additional names to greet. May be an empty list."] +],[ + "start", + ["comment.block.documentation.soy"," "], + ["punctuation.definition.comment.end.soy","*/"] +],[ + "start", + ["punctuation.definition.tag.begin.soy","{"], + ["entity.name.tag.soy","template"], + ["text"," "], + ["entity.name.function.soy",".helloNames"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["comment.line.double-slash.soy"," "], + ["punctuation.definition.comment.soy","//"], + ["comment.line.double-slash.soy"," Greet the person."] +],[ + "start", + ["text.xml"," "], + ["punctuation.definition.tag.begin.soy","{"], + ["entity.name.tag.soy","call"], + ["variable.parameter.soy"," .helloName"], + ["meta.tag.call.soy"," "], + ["entity.other.attribute-name.soy","data"], + ["keyword.operator.soy","="], + ["string.quoted.double","\"all\""], + ["meta.tag.call.soy"," /"], + ["punctuation.definition.tag.end.soy","}"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","br"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["comment.line.double-slash.soy"," "], + ["punctuation.definition.comment.soy","//"], + ["comment.line.double-slash.soy"," Greet the additional people."] +],[ + "start", + ["text.xml"," "], + ["punctuation.definition.tag.begin.soy","{"], + ["entity.name.tag.soy","foreach"], + ["meta.tag.foreach.soy"," "], + ["variable.other.soy","$additionalName"], + ["meta.tag.foreach.soy"," "], + ["keyword.operator.soy","in"], + ["meta.tag.foreach.soy"," "], + ["variable.other.soy","$additionalNames"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["text.xml"," "], + ["punctuation.definition.tag.begin.soy","{"], + ["entity.name.tag.soy","call"], + ["variable.parameter.soy"," .helloName"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["text.xml"," "], + ["punctuation.definition.tag.begin.soy","{"], + ["entity.name.tag.soy","param"], + ["meta.tag.param.soy"," "], + ["entity.other.attribute-name.soy","name"], + ["keyword.operator.soy",":"], + ["meta.tag.param.soy"," "], + ["variable.other.soy","$additionalName"], + ["meta.tag.param.soy"," /"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["text.xml"," "], + ["punctuation.definition.tag.begin.soy","{/"], + ["meta.tag.call.soy","call"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["text.xml"," "], + ["punctuation.definition.tag.begin.soy","{"], + ["entity.name.tag.soy","if"], + ["meta.tag.if.soy"," "], + ["keyword.operator.soy","not"], + ["meta.tag.if.soy"," "], + ["support.function.soy","isLast"], + ["meta.tag.if.soy","("], + ["variable.other.soy","$additionalName"], + ["meta.tag.if.soy",")"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","br"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["comment.line.double-slash.soy"," "], + ["punctuation.definition.comment.soy","//"], + ["comment.line.double-slash.soy"," break after every line except the last"] +],[ + "start", + ["text.xml"," "], + ["punctuation.definition.tag.begin.soy","{/"], + ["entity.name.tag.soy","if"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["text.xml"," "], + ["punctuation.definition.tag.begin.soy","{"], + ["text","ifempty"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["text.xml"," No additional people to greet."] +],[ + "start", + ["text.xml"," "], + ["punctuation.definition.tag.begin.soy","{/"], + ["entity.name.tag.soy","foreach"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["punctuation.definition.tag.begin.soy","{/"], + ["meta.tag.template.soy","template"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start" +],[ + "start" +],[ + "start", + ["punctuation.definition.tag.begin.soy","{/"], + ["entity.name.tag.soy","foreach"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["punctuation.definition.tag.begin.soy","{"], + ["entity.name.tag.soy","if"], + ["meta.tag.if.soy"," "], + ["support.function.soy","length"], + ["meta.tag.if.soy","("], + ["variable.other.soy","$items"], + ["meta.tag.if.soy",") > 5"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["punctuation.definition.tag.begin.soy","{"], + ["entity.name.tag.soy","msg"], + ["meta.tag.msg.soy"," "], + ["entity.other.attribute-name.soy","desc"], + ["keyword.operator.soy","="], + ["string.quoted.double","\"Says hello to the user.\""], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start" +],[ + "start" +],[ + "start", + ["punctuation.definition.tag.begin.soy","{"], + ["entity.name.tag.soy","namespace"], + ["text"," "], + ["variable.parameter.soy","ns"], + ["text"," autoescape=\"contextual\""], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start" +],[ + "start", + ["punctuation.definition.comment.begin.soy","/**"], + ["comment.block.documentation.soy"," Example. "], + ["punctuation.definition.comment.end.soy","*/"] +],[ + "start", + ["punctuation.definition.tag.begin.soy","{"], + ["entity.name.tag.soy","template"], + ["text"," "], + ["entity.name.function.soy",".example"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["text.xml"," foo is "], + ["punctuation.definition.tag.begin.soy","{"], + ["variable.other.soy","$ij.foo"], + ["punctuation.definition.tag.end.soy","}"] +],[ + "start", + ["punctuation.definition.tag.begin.soy","{/"], + ["meta.tag.template.soy","template"], + ["punctuation.definition.tag.end.soy","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_space.json b/lib/ace/mode/_test/tokens_space.json new file mode 100644 index 00000000..918b9a67 --- /dev/null +++ b/lib/ace/mode/_test/tokens_space.json @@ -0,0 +1,322 @@ +[[ + "start", + ["variable","query"] +],[ + "start", + ["empty_line"," "], + ["variable","count"], + ["keyword.operator"," "], + ["string","10"] +],[ + "start", + ["empty_line"," "], + ["variable","created"], + ["keyword.operator"," "], + ["string","2011-06-21T08:10:46Z"] +],[ + "start", + ["empty_line"," "], + ["variable","lang"], + ["keyword.operator"," "], + ["string","en-US"] +],[ + "start", + ["empty_line"," "], + ["variable","results"] +],[ + "start", + ["empty_line"," "], + ["variable","photo"] +],[ + "start", + ["empty_line"," "], + ["variable","0"] +],[ + "start", + ["empty_line"," "], + ["variable","farm"], + ["keyword.operator"," "], + ["string","6"] +],[ + "start", + ["empty_line"," "], + ["variable","id"], + ["keyword.operator"," "], + ["string","5855620975"] +],[ + "start", + ["empty_line"," "], + ["variable","isfamily"], + ["keyword.operator"," "], + ["string","0"] +],[ + "start", + ["empty_line"," "], + ["variable","isfriend"], + ["keyword.operator"," "], + ["string","0"] +],[ + "start", + ["empty_line"," "], + ["variable","ispublic"], + ["keyword.operator"," "], + ["string","1"] +],[ + "start", + ["empty_line"," "], + ["variable","owner"], + ["keyword.operator"," "], + ["string","32021554@N04"] +],[ + "start", + ["empty_line"," "], + ["variable","secret"], + ["keyword.operator"," "], + ["string","f1f5e8515d"] +],[ + "start", + ["empty_line"," "], + ["variable","server"], + ["keyword.operator"," "], + ["string","5110"] +],[ + "start", + ["empty_line"," "], + ["variable","title"], + ["keyword.operator"," "], + ["string","7087 bandit cat"] +],[ + "start", + ["empty_line"," "], + ["variable","1"] +],[ + "start", + ["empty_line"," "], + ["variable","farm"], + ["keyword.operator"," "], + ["string","4"] +],[ + "start", + ["empty_line"," "], + ["variable","id"], + ["keyword.operator"," "], + ["string","5856170534"] +],[ + "start", + ["empty_line"," "], + ["variable","isfamily"], + ["keyword.operator"," "], + ["string","0"] +],[ + "start", + ["empty_line"," "], + ["variable","isfriend"], + ["keyword.operator"," "], + ["string","0"] +],[ + "start", + ["empty_line"," "], + ["variable","ispublic"], + ["keyword.operator"," "], + ["string","1"] +],[ + "start", + ["empty_line"," "], + ["variable","owner"], + ["keyword.operator"," "], + ["string","32021554@N04"] +],[ + "start", + ["empty_line"," "], + ["variable","secret"], + ["keyword.operator"," "], + ["string","ff1efb2a6f"] +],[ + "start", + ["empty_line"," "], + ["variable","server"], + ["keyword.operator"," "], + ["string","3217"] +],[ + "start", + ["empty_line"," "], + ["variable","title"], + ["keyword.operator"," "], + ["string","6975 rusty cat"] +],[ + "start", + ["empty_line"," "], + ["variable","2"] +],[ + "start", + ["empty_line"," "], + ["variable","farm"], + ["keyword.operator"," "], + ["string","6"] +],[ + "start", + ["empty_line"," "], + ["variable","id"], + ["keyword.operator"," "], + ["string","5856172972"] +],[ + "start", + ["empty_line"," "], + ["variable","isfamily"], + ["keyword.operator"," "], + ["string","0"] +],[ + "start", + ["empty_line"," "], + ["variable","isfriend"], + ["keyword.operator"," "], + ["string","0"] +],[ + "start", + ["empty_line"," "], + ["variable","ispublic"], + ["keyword.operator"," "], + ["string","1"] +],[ + "start", + ["empty_line"," "], + ["variable","owner"], + ["keyword.operator"," "], + ["string","51249875@N03"] +],[ + "start", + ["empty_line"," "], + ["variable","secret"], + ["keyword.operator"," "], + ["string","6c6887347c"] +],[ + "start", + ["empty_line"," "], + ["variable","server"], + ["keyword.operator"," "], + ["string","5192"] +],[ + "start", + ["empty_line"," "], + ["variable","title"], + ["keyword.operator"," "], + ["string","watermarked-cats"] +],[ + "start", + ["empty_line"," "], + ["variable","3"] +],[ + "start", + ["empty_line"," "], + ["variable","farm"], + ["keyword.operator"," "], + ["string","6"] +],[ + "start", + ["empty_line"," "], + ["variable","id"], + ["keyword.operator"," "], + ["string","5856168328"] +],[ + "start", + ["empty_line"," "], + ["variable","isfamily"], + ["keyword.operator"," "], + ["string","0"] +],[ + "start", + ["empty_line"," "], + ["variable","isfriend"], + ["keyword.operator"," "], + ["string","0"] +],[ + "start", + ["empty_line"," "], + ["variable","ispublic"], + ["keyword.operator"," "], + ["string","1"] +],[ + "start", + ["empty_line"," "], + ["variable","owner"], + ["keyword.operator"," "], + ["string","32021554@N04"] +],[ + "start", + ["empty_line"," "], + ["variable","secret"], + ["keyword.operator"," "], + ["string","0c1cfdf64c"] +],[ + "start", + ["empty_line"," "], + ["variable","server"], + ["keyword.operator"," "], + ["string","5078"] +],[ + "start", + ["empty_line"," "], + ["variable","title"], + ["keyword.operator"," "], + ["string","7020 mandy cat"] +],[ + "start", + ["empty_line"," "], + ["variable","4"] +],[ + "start", + ["empty_line"," "], + ["variable","farm"], + ["keyword.operator"," "], + ["string","3"] +],[ + "start", + ["empty_line"," "], + ["variable","id"], + ["keyword.operator"," "], + ["string","5856171774"] +],[ + "start", + ["empty_line"," "], + ["variable","isfamily"], + ["keyword.operator"," "], + ["string","0"] +],[ + "start", + ["empty_line"," "], + ["variable","isfriend"], + ["keyword.operator"," "], + ["string","0"] +],[ + "start", + ["empty_line"," "], + ["variable","ispublic"], + ["keyword.operator"," "], + ["string","1"] +],[ + "start", + ["empty_line"," "], + ["variable","owner"], + ["keyword.operator"," "], + ["string","32021554@N04"] +],[ + "start", + ["empty_line"," "], + ["variable","secret"], + ["keyword.operator"," "], + ["string","7f5a3180ab"] +],[ + "start", + ["empty_line"," "], + ["variable","server"], + ["keyword.operator"," "], + ["string","2696"] +],[ + "start", + ["empty_line"," "], + ["variable","title"], + ["keyword.operator"," "], + ["string","7448 bobby cat"] +],[ + "key" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_sql.json b/lib/ace/mode/_test/tokens_sql.json new file mode 100644 index 00000000..09a3ef99 --- /dev/null +++ b/lib/ace/mode/_test/tokens_sql.json @@ -0,0 +1,54 @@ +[[ + "start", + ["keyword","SELECT"], + ["text"," "], + ["identifier","city"], + ["text",", "], + ["support.function","COUNT"], + ["paren.lparen","("], + ["identifier","id"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","AS"], + ["text"," "], + ["identifier","users_count"] +],[ + "start", + ["keyword","FROM"], + ["text"," "], + ["identifier","users"] +],[ + "start", + ["keyword","WHERE"], + ["text"," "], + ["identifier","group_name"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string","'salesman'"] +],[ + "start", + ["keyword","AND"], + ["text"," "], + ["identifier","created"], + ["text"," "], + ["keyword.operator",">"], + ["text"," "], + ["string","'2011-05-21'"] +],[ + "start", + ["keyword","GROUP"], + ["text"," "], + ["keyword","BY"], + ["text"," "], + ["constant.numeric","1"] +],[ + "start", + ["keyword","ORDER"], + ["text"," "], + ["keyword","BY"], + ["text"," "], + ["constant.numeric","2"], + ["text"," "], + ["keyword","DESC"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_stylus.json b/lib/ace/mode/_test/tokens_stylus.json new file mode 100644 index 00000000..f24993f7 --- /dev/null +++ b/lib/ace/mode/_test/tokens_stylus.json @@ -0,0 +1,271 @@ +[[ + "start", + ["comment","// I'm a comment!"] +],[ + "start" +],[ + "comment", + ["comment","/*"] +],[ + "comment", + ["comment"," * Adds the given numbers together."] +],[ + "start", + ["comment"," */"] +],[ + "start" +],[ + "start" +],[ + "comment", + ["comment","/*!"] +],[ + "comment", + ["comment"," * Adds the given numbers together."] +],[ + "start", + ["comment"," */"] +],[ + "start" +],[ + "start" +],[ + "start", + ["entity.name.function.stylus","asdasdasdad"], + ["text","("], + ["text","df, ad"], + ["keyword.operator.stylus","="], + ["constant.numeric","23"], + ["text",")"] +],[ + "start" +],[ + "start", + ["entity.name.function.stylus","add"], + ["text","("], + ["entity.name.tag.stylus","a"], + ["text",", "], + ["entity.name.tag.stylus","b"], + ["text"," "], + ["keyword.operator.stylus","="], + ["text"," "], + ["entity.name.tag.stylus","a"], + ["text",")"] +],[ + "start", + ["text"," "], + ["entity.name.tag.stylus","a"], + ["text"," "], + ["keyword.operator.stylus","+"], + ["text"," "], + ["entity.name.tag.stylus","b"] +],[ + "start", + ["entity.name.function.stylus","green"], + ["text","("], + ["constant.numeric","#0c0"], + ["text",")"] +],[ + "start", + ["text"," add("], + ["constant.numeric","10"], + ["text",", "], + ["constant.numeric","5"], + ["text",")"] +],[ + "start", + ["text"," "], + ["comment","// => 15"] +],[ + "start" +],[ + "start", + ["text"," add("], + ["constant.numeric","10"], + ["text",")"] +],[ + "start", + ["text"," add("], + ["entity.name.tag.stylus","a"], + ["text",", "], + ["entity.name.tag.stylus","b"], + ["text",")"] +],[ + "start" +],[ + "start", + ["entity.language.stylus"," &"], + ["text","asdasd"] +],[ + "start" +],[ + "start", + ["text"," ("], + ["variable.language.stylus","arguments"], + ["text",")"] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword.stylus","@sdfsdf"] +],[ + "start", + ["entity.other.attribute-name.class.stylus",".signatures"] +],[ + "start", + ["text"," "], + ["support.type","background-color"], + ["text"," "], + ["constant.numeric","#e0e8e0"] +],[ + "start", + ["text"," "], + ["support.type","border"], + ["text"," "], + ["constant.numeric","1"], + ["keyword","px"], + ["text"," "], + ["support.constant","solid"], + ["text"," grayLighter"] +],[ + "start", + ["text"," "], + ["support.type","box-shadow"], + ["text"," "], + ["constant.numeric","0"], + ["text"," "], + ["constant.numeric","0"], + ["text"," "], + ["constant.numeric","3"], + ["keyword","px"], + ["text"," grayLightest"] +],[ + "start", + ["text"," "], + ["support.type","border-radius"], + ["text"," "], + ["constant.numeric","3"], + ["keyword","px"] +],[ + "start", + ["text"," "], + ["support.type","padding"], + ["text"," "], + ["constant.numeric","3"], + ["keyword","px"], + ["text"," "], + ["constant.numeric","5"], + ["keyword","px"] +],[ + "start", + ["text"," "], + ["string","\"adsads\""] +],[ + "start", + ["text"," "], + ["support.type","margin-left"], + ["text"," "], + ["constant.numeric","0"] +],[ + "start", + ["text"," "], + ["support.type","list-style"], + ["text"," "], + ["support.constant","none"] +],[ + "start", + ["entity.other.attribute-name.class.stylus",".signature"] +],[ + "start", + ["text"," "], + ["support.type","list-style"], + ["text"," "], + ["support.constant","none"] +],[ + "start", + ["text"," "], + ["support.type","display"], + ["text",": "], + ["support.constant","inline"] +],[ + "start", + ["text"," "], + ["support.type","margin-left"], + ["text"," "], + ["constant.numeric","0"] +],[ + "start", + ["text"," "], + ["keyword.operator.stylus",">"], + ["text"," "], + ["entity.name.tag.stylus","li"] +],[ + "start", + ["text"," "], + ["support.type","display"], + ["text"," "], + ["support.constant","inline"] +],[ + "start", + ["keyword.operator.stylus","is"], + ["text"," "], + ["keyword.operator.stylus","not"] +],[ + "start", + ["entity.other.attribute-name.class.stylus",".signature-values"] +],[ + "start", + ["text"," "], + ["support.type","list-style"], + ["text"," "], + ["support.constant","none"] +],[ + "start", + ["text"," "], + ["support.type","display"], + ["text"," "], + ["support.constant","inline"] +],[ + "start", + ["text"," "], + ["support.type","margin-left"], + ["text"," "], + ["constant.numeric","0"] +],[ + "start", + ["entity.language.stylus"," &"], + ["punctuation",":"], + ["entity.other.attribute-name.pseudo-element.css","before"] +],[ + "start", + ["text"," "], + ["support.type","content"], + ["text"," "], + ["string","'→'"] +],[ + "start", + ["text"," "], + ["support.type","margin"], + ["text"," "], + ["constant.numeric","0"], + ["text"," "], + ["constant.numeric","5"], + ["keyword","px"] +],[ + "start", + ["text"," "], + ["keyword.operator.stylus",">"], + ["text"," "], + ["entity.name.tag.stylus","li"] +],[ + "start", + ["text"," "], + ["keyword.control.stylus","!important"] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword.control.stylus","unless"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_svg.json b/lib/ace/mode/_test/tokens_svg.json new file mode 100644 index 00000000..66ebae75 --- /dev/null +++ b/lib/ace/mode/_test/tokens_svg.json @@ -0,0 +1,684 @@ +[[ + "meta.tag.punctuation.tag-open.xml1", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","svg"] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","width"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"800\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","height"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"600\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","xmlns"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"http://www.w3.org/2000/svg\""] +],[ + "start", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","onload"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"StartAnimation(evt)\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start" +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","title"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Test Tube Progress Bar"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","desc"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","Created for the Web Directions SVG competition"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "js-no_regex", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.script.tag-name.xml","script"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","type"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"text/ecmascript\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["string.cdata.xml",""], + ["text"," "], + ["identifier","max_time"], + ["paren.rparen",")"] +],[ + "js-start", + ["text"," "], + ["keyword","return"], + ["punctuation.operator",";"] +],[ + "js-start", + ["text"," "], + ["comment","// Scale the text string gradually until it is 20 times larger"] +],[ + "js-start", + ["text"," "], + ["identifier","scalefactor"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","("], + ["identifier","timevalue"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "], + ["constant.numeric","650"], + ["paren.rparen",")"], + ["text"," "], + ["keyword.operator","/"], + ["text"," "], + ["identifier","max_time"], + ["punctuation.operator",";"] +],[ + "js-start" +],[ + "js-start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["paren.lparen","("], + ["identifier","timevalue"], + ["text"," "], + ["keyword.operator","<"], + ["text"," "], + ["constant.numeric","30"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "js-start", + ["text"," "], + ["identifier","hickory"], + ["punctuation.operator","."], + ["support.function.dom","setAttribute"], + ["paren.lparen","("], + ["string","\"display\""], + ["punctuation.operator",","], + ["text"," "], + ["string","\"\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "js-start", + ["text"," "], + ["identifier","hickory"], + ["punctuation.operator","."], + ["support.function.dom","setAttribute"], + ["paren.lparen","("], + ["string","\"transform\""], + ["punctuation.operator",","], + ["text"," "], + ["string","\"translate(\""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["paren.lparen","("], + ["constant.numeric","600"], + ["keyword.operator","+"], + ["identifier","scalefactor"], + ["keyword.operator","*"], + ["constant.numeric","3"], + ["keyword.operator","*"], + ["constant.numeric","-1"], + ["text"," "], + ["paren.rparen",")"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","\", -144 )\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "js-no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "js-no_regex" +],[ + "js-start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["paren.lparen","("], + ["identifier","timevalue"], + ["text"," "], + ["keyword.operator",">"], + ["text"," "], + ["constant.numeric","30"], + ["text"," "], + ["keyword.operator","&&"], + ["text"," "], + ["identifier","timevalue"], + ["text"," "], + ["keyword.operator","<"], + ["text"," "], + ["constant.numeric","66"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "js-start", + ["text"," "], + ["identifier","dickory"], + ["punctuation.operator","."], + ["support.function.dom","setAttribute"], + ["paren.lparen","("], + ["string","\"display\""], + ["punctuation.operator",","], + ["text"," "], + ["string","\"\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "js-start", + ["text"," "], + ["identifier","dickory"], + ["punctuation.operator","."], + ["support.function.dom","setAttribute"], + ["paren.lparen","("], + ["string","\"transform\""], + ["punctuation.operator",","], + ["text"," "], + ["string","\"translate(\""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["paren.lparen","("], + ["constant.numeric","-795"], + ["keyword.operator","+"], + ["identifier","scalefactor"], + ["keyword.operator","*"], + ["constant.numeric","2"], + ["paren.rparen",")"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","\", 0 )\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "js-no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "js-start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["paren.lparen","("], + ["identifier","timevalue"], + ["text"," "], + ["keyword.operator",">"], + ["text"," "], + ["constant.numeric","66"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "js-start", + ["text"," "], + ["identifier","dock"], + ["punctuation.operator","."], + ["support.function.dom","setAttribute"], + ["paren.lparen","("], + ["string","\"display\""], + ["punctuation.operator",","], + ["text"," "], + ["string","\"\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "js-start", + ["text"," "], + ["identifier","dock"], + ["punctuation.operator","."], + ["support.function.dom","setAttribute"], + ["paren.lparen","("], + ["string","\"transform\""], + ["punctuation.operator",","], + ["text"," "], + ["string","\"translate(\""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["paren.lparen","("], + ["constant.numeric","1450"], + ["keyword.operator","+"], + ["identifier","scalefactor"], + ["keyword.operator","*"], + ["constant.numeric","2"], + ["keyword.operator","*"], + ["constant.numeric","-1"], + ["paren.rparen",")"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","\", 144 )\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "js-no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "js-no_regex" +],[ + "js-no_regex", + ["text"," "], + ["comment","// Call ShowAndGrowElement again milliseconds later."] +],[ + "js-no_regex", + ["text"," "], + ["identifier","setTimeout"], + ["paren.lparen","("], + ["string","\"ShowAndGrowElement()\""], + ["punctuation.operator",","], + ["text"," "], + ["identifier","timer_increment"], + ["paren.rparen",")"] +],[ + "js-no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "js-no_regex", + ["text"," "], + ["variable.language","window"], + ["punctuation.operator","."], + ["identifier","ShowAndGrowElement"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","ShowAndGrowElement"] +],[ + "start", + ["text"," "], + ["string.cdata.xml","]]>"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","rect"] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","fill"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"#2e3436\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","fill-rule"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"nonzero\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","stroke-width"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"3\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","y"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"0\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","x"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"0\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","height"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"600\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","width"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"800\""] +],[ + "start", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"rect3590\""], + ["meta.tag.punctuation.tag-close.xml","/>"] +],[ + "start" +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","text"] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","style"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"font-size:144px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","x"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"50\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","y"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"350\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"hickory\""] +],[ + "start", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","display"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"none\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," Hickory,"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","text"] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","style"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"font-size:144px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","x"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"50\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","y"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"350\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"dickory\""] +],[ + "start", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","display"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"none\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," dickory,"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","text"] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","style"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"font-size:144px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","x"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"50\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","y"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"350\""] +],[ + "meta.tag.punctuation.tag-open.xml1", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"dock\""] +],[ + "start", + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","display"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"none\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," dock!"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_tcl.json b/lib/ace/mode/_test/tokens_tcl.json new file mode 100644 index 00000000..6a032ddc --- /dev/null +++ b/lib/ace/mode/_test/tokens_tcl.json @@ -0,0 +1,385 @@ +[[ + "commandItem" +],[ + "commandItem", + ["keyword","proc"], + ["text"," "], + ["identifier","dijkstra"], + ["text"," "], + ["paren.lparen","{"], + ["keyword","graph"], + ["text"," "], + ["identifier","origin"], + ["paren.rparen","}"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["comment","# Initialize"] +],[ + "commandItem", + ["text"," "], + ["keyword","dict"], + ["text"," "], + ["identifier","for"], + ["text"," "], + ["paren.lparen","{"], + ["keyword","vertex"], + ["text"," "], + ["identifier","distmap"], + ["paren.rparen","}"], + ["text"," "], + ["variable.instance","$graph"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text","\t"], + ["keyword","dict"], + ["text"," "], + ["identifier","set"], + ["text"," "], + ["identifier","dist"], + ["text"," "], + ["variable.instance","$vertex"], + ["text"," "], + ["identifier","Inf"] +],[ + "commandItem", + ["text","\t"], + ["keyword","dict"], + ["text"," "], + ["identifier","set"], + ["text"," "], + ["identifier","path"], + ["text"," "], + ["variable.instance","$vertex"], + ["text"," "], + ["paren.lparen","{"], + ["paren.rparen","}"] +],[ + "commandItem", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["keyword","dict"], + ["text"," "], + ["identifier","set"], + ["text"," "], + ["identifier","dist"], + ["text"," "], + ["variable.instance","$origin"], + ["text"," 0"] +],[ + "start", + ["text"," "], + ["keyword","dict"], + ["text"," "], + ["identifier","set"], + ["text"," "], + ["identifier","path"], + ["text"," "], + ["variable.instance","$origin"], + ["text"," "], + ["paren.lparen","["], + ["keyword","list"], + ["text"," "], + ["variable.instance","$origin"], + ["paren.rparen","]"] +],[ + "commandItem", + ["text"," "] +],[ + "commandItem", + ["text"," "], + ["keyword","while"], + ["text"," "], + ["paren.lparen","{"], + ["text","["], + ["keyword","dict"], + ["text"," "], + ["identifier","size"], + ["text"," "], + ["variable.instance","$graph"], + ["paren.rparen","]}"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text","\t"], + ["comment","# Find unhandled node with least weight"] +],[ + "start", + ["text","\t"], + ["keyword","set"], + ["text"," "], + ["identifier","d"], + ["text"," "], + ["identifier","Inf"] +],[ + "commandItem", + ["text","\t"], + ["keyword","dict"], + ["text"," "], + ["identifier","for"], + ["text"," "], + ["paren.lparen","{"], + ["keyword","uu"], + ["text"," "], + ["support.function","-"], + ["paren.rparen","}"], + ["text"," "], + ["variable.instance","$graph"], + ["text"," "], + ["paren.lparen","{"] +],[ + "commandItem", + ["text","\t "], + ["keyword","if"], + ["text"," "], + ["paren.lparen","{"], + ["variable.instance","$d"], + ["text"," "], + ["support.function",">"], + ["text"," "], + ["paren.lparen","["], + ["keyword","set"], + ["text"," "], + ["identifier","dd"], + ["text"," "], + ["paren.lparen","["], + ["keyword","dict"], + ["text"," "], + ["identifier","get"], + ["text"," "], + ["variable.instance","$dist"], + ["text"," "], + ["variable.instance","$uu"], + ["paren.rparen","]]}"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text","\t\t"], + ["keyword","set"], + ["text"," "], + ["identifier","u"], + ["text"," "], + ["variable.instance","$uu"] +],[ + "start", + ["text","\t\t"], + ["keyword","set"], + ["text"," "], + ["identifier","d"], + ["text"," "], + ["variable.instance","$dd"] +],[ + "commandItem", + ["text","\t "], + ["paren.rparen","}"] +],[ + "commandItem", + ["text","\t"], + ["paren.rparen","}"] +],[ + "commandItem", + ["text"," "] +],[ + "start", + ["text","\t"], + ["comment","# No such node; graph must be disconnected"] +],[ + "start", + ["text","\t"], + ["keyword","if"], + ["text"," "], + ["paren.lparen","{"], + ["variable.instance","$d"], + ["text"," "], + ["support.function","=="], + ["text"," "], + ["identifier","Inf"], + ["paren.rparen","}"], + ["text"," "], + ["identifier","break"] +],[ + "commandItem", + ["text"," "] +],[ + "commentfollow", + ["text","\t"], + ["comment","# Update the weights for nodes\\"] +],[ + "start", + ["comment","\t lead to by the node we've picked"] +],[ + "commandItem", + ["text","\t"], + ["keyword","dict"], + ["text"," "], + ["identifier","for"], + ["text"," "], + ["paren.lparen","{"], + ["keyword","v"], + ["text"," "], + ["identifier","dd"], + ["paren.rparen","}"], + ["text"," "], + ["paren.lparen","["], + ["keyword","dict"], + ["text"," "], + ["identifier","get"], + ["text"," "], + ["variable.instance","$graph"], + ["text"," "], + ["variable.instance","$u"], + ["paren.rparen","]"], + ["text"," "], + ["paren.lparen","{"] +],[ + "commandItem", + ["text","\t "], + ["keyword","if"], + ["text"," "], + ["paren.lparen","{"], + ["text","["], + ["keyword","dict"], + ["text"," "], + ["identifier","exists"], + ["text"," "], + ["variable.instance","$graph"], + ["text"," "], + ["variable.instance","$v"], + ["paren.rparen","]}"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text","\t\t"], + ["keyword","set"], + ["text"," "], + ["identifier","alt"], + ["text"," "], + ["paren.lparen","["], + ["keyword","expr"], + ["text"," "], + ["paren.lparen","{"], + ["variable.instance","$d"], + ["text"," "], + ["support.function","+"], + ["text"," "], + ["variable.instance","$dd"], + ["paren.rparen","}]"] +],[ + "commandItem", + ["text","\t\t"], + ["keyword","if"], + ["text"," "], + ["paren.lparen","{"], + ["variable.instance","$alt"], + ["text"," "], + ["support.function","<"], + ["text"," "], + ["paren.lparen","["], + ["keyword","dict"], + ["text"," "], + ["identifier","get"], + ["text"," "], + ["variable.instance","$dist"], + ["text"," "], + ["variable.instance","$v"], + ["paren.rparen","]}"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text","\t\t "], + ["keyword","dict"], + ["text"," "], + ["identifier","set"], + ["text"," "], + ["identifier","dist"], + ["text"," "], + ["variable.instance","$v"], + ["text"," "], + ["variable.instance","$alt"] +],[ + "start", + ["text","\t\t "], + ["keyword","dict"], + ["text"," "], + ["identifier","set"], + ["text"," "], + ["identifier","path"], + ["text"," "], + ["variable.instance","$v"], + ["text"," "], + ["paren.lparen","["], + ["keyword","list"], + ["text"," "], + ["support.function","{*}"], + ["paren.lparen","["], + ["keyword","dict"], + ["text"," "], + ["identifier","get"], + ["text"," "], + ["variable.instance","$path"], + ["text"," "], + ["variable.instance","$u"], + ["paren.rparen","]"], + ["text"," "], + ["variable.instance","$v"], + ["paren.rparen","]"] +],[ + "commandItem", + ["text","\t\t"], + ["paren.rparen","}"] +],[ + "commandItem", + ["text","\t "], + ["paren.rparen","}"] +],[ + "commandItem", + ["text","\t"], + ["paren.rparen","}"] +],[ + "commandItem", + ["text"," "] +],[ + "start", + ["text","\t"], + ["comment","# Remove chosen node from graph still to be handled"] +],[ + "start", + ["text","\t"], + ["keyword","dict"], + ["text"," "], + ["identifier","unset"], + ["text"," "], + ["identifier","graph"], + ["text"," "], + ["variable.instance","$u"] +],[ + "commandItem", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["keyword","return"], + ["text"," "], + ["paren.lparen","["], + ["keyword","list"], + ["text"," "], + ["variable.instance","$dist"], + ["text"," "], + ["variable.instance","$path"], + ["paren.rparen","]"] +],[ + "commandItem", + ["paren.rparen","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_tex.json b/lib/ace/mode/_test/tokens_tex.json new file mode 100644 index 00000000..2d023676 --- /dev/null +++ b/lib/ace/mode/_test/tokens_tex.json @@ -0,0 +1,130 @@ +[[ + "start", + ["text","The quadratic formula is $$-b "], + ["keyword","\\pm"], + ["text"," "], + ["keyword","\\sqrt"], + ["paren.keyword.operator","{"], + ["text","b^2 - 4ac"], + ["paren.keyword.operator","}"], + ["text"," "], + ["keyword","\\over"], + ["text"," 2a$$"] +],[ + "start", + ["keyword","\\bye"] +],[ + "start" +],[ + "start", + ["keyword","\\makeatletter"] +],[ + "start", + ["text"," "], + ["keyword","\\newcommand"], + ["paren.keyword.operator","{"], + ["keyword","\\be"], + ["paren.keyword.operator","}{"], + ["comment","%"] +],[ + "start", + ["text"," "], + ["keyword","\\begingroup"] +],[ + "start", + ["text"," "], + ["comment","% \\setlength{\\arraycolsep}{2pt}"] +],[ + "start", + ["text"," "], + ["keyword","\\eqnarray"], + ["comment","%"] +],[ + "start", + ["text"," "], + ["keyword","\\@"], + ["text","ifstar"], + ["paren.keyword.operator","{"], + ["keyword","\\nonumber"], + ["paren.keyword.operator","}{}"], + ["comment","%"] +],[ + "start", + ["text"," "], + ["paren.keyword.operator","}"] +],[ + "start", + ["text"," "], + ["keyword","\\newcommand"], + ["paren.keyword.operator","{"], + ["keyword","\\ee"], + ["paren.keyword.operator","}{"], + ["keyword","\\endeqnarray\\endgroup"], + ["paren.keyword.operator","}"] +],[ + "start", + ["text"," "], + ["keyword","\\makeatother"] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword","\\begin"], + ["paren.keyword.operator","{"], + ["nospell.text","equation"], + ["paren.keyword.operator","}"] +],[ + "start", + ["text"," x="], + ["keyword","\\left\\"], + ["paren.keyword.operator","{"], + ["text"," "], + ["keyword","\\begin"], + ["paren.keyword.operator","{"], + ["nospell.text","array"], + ["paren.keyword.operator","}{"], + ["text","cl"], + ["paren.keyword.operator","}"] +],[ + "start", + ["text"," 0 & "], + ["keyword","\\textrm"], + ["paren.keyword.operator","{"], + ["text","if "], + ["paren.keyword.operator","}"], + ["text","A="], + ["keyword","\\ldots\\\\"] +],[ + "start", + ["text"," 1 & "], + ["keyword","\\textrm"], + ["paren.keyword.operator","{"], + ["text","if "], + ["paren.keyword.operator","}"], + ["text","B="], + ["keyword","\\ldots\\\\"] +],[ + "start", + ["text"," x & "], + ["keyword","\\textrm"], + ["paren.keyword.operator","{"], + ["text","this runs with as much text as you like, but without an raggeright text"] +],[ + "start", + ["text","."], + ["paren.keyword.operator","}"], + ["keyword","\\end"], + ["paren.keyword.operator","{"], + ["nospell.text","array"], + ["paren.keyword.operator","}"], + ["keyword","\\right"], + ["text","."] +],[ + "start", + ["text"," "], + ["keyword","\\end"], + ["paren.keyword.operator","{"], + ["nospell.text","equation"], + ["paren.keyword.operator","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_text.json b/lib/ace/mode/_test/tokens_text.json new file mode 100644 index 00000000..fff7ef42 --- /dev/null +++ b/lib/ace/mode/_test/tokens_text.json @@ -0,0 +1,29 @@ +[[ + "start", + ["text","Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."] +],[ + "start" +],[ + "start", + ["text","Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat."] +],[ + "start" +],[ + "start", + ["text","Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi."] +],[ + "start" +],[ + "start", + ["text","Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat."] +],[ + "start" +],[ + "start", + ["text","Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis."] +],[ + "start" +],[ + "start", + ["text","At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_textile.json b/lib/ace/mode/_test/tokens_textile.json new file mode 100644 index 00000000..59000ce3 --- /dev/null +++ b/lib/ace/mode/_test/tokens_textile.json @@ -0,0 +1,113 @@ +[[ + "start", + ["markup.heading.1","h1"], + ["keyword",". "], + ["text","Textile document"] +],[ + "start" +],[ + "start", + ["markup.heading.2","h2"], + ["keyword",". "], + ["text","Heading Two"] +],[ + "start" +],[ + "start", + ["markup.heading.3","h3"], + ["keyword",". "], + ["text","A two-line"] +],[ + "start", + ["text"," header"] +],[ + "start" +],[ + "start", + ["markup.heading.2","h2"], + ["keyword",". "], + ["text","Another two-line"] +],[ + "start", + ["text","header"] +],[ + "start" +],[ + "start", + ["text","Paragraph:"] +],[ + "start", + ["text","one, two,"] +],[ + "start", + ["text","thee lines!"] +],[ + "start" +],[ + "start", + ["markup.heading","p"], + ["keyword","("], + ["string","classone"], + ["text"," "], + ["string","two"], + ["text"," "], + ["string","three"], + ["keyword","). "], + ["text","This is a paragraph with classes"] +],[ + "start" +],[ + "start", + ["markup.heading","p"], + ["keyword","(#"], + ["string","id"], + ["keyword","). "], + ["text","(one with an id)"] +],[ + "start" +],[ + "start", + ["markup.heading","p"], + ["keyword","("], + ["string","one"], + ["text"," "], + ["string","two"], + ["text"," "], + ["string","three"], + ["keyword","#"], + ["string","my_id"], + ["keyword","). "], + ["text","..classes + id"] +],[ + "start" +],[ + "start", + ["keyword","*"], + ["text"," Unordered list"] +],[ + "start", + ["keyword","**"], + ["text"," sublist"] +],[ + "start", + ["keyword","*"], + ["text"," back again!"] +],[ + "start", + ["keyword","**"], + ["text"," sublist again.."] +],[ + "start" +],[ + "start", + ["keyword","#"], + ["text"," ordered"] +],[ + "start" +],[ + "start", + ["text","bg. Blockquote!"] +],[ + "start", + ["text"," This is a two-list blockquote..!"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_toml.json b/lib/ace/mode/_test/tokens_toml.json new file mode 100644 index 00000000..ec471f74 --- /dev/null +++ b/lib/ace/mode/_test/tokens_toml.json @@ -0,0 +1,131 @@ +[[ + "start", + ["comment.toml","# This is a TOML document. Boom."] +],[ + "start" +],[ + "start", + ["identifier","title"], + ["text"," = "], + ["string","\"TOML Example\""] +],[ + "start" +],[ + "start", + ["variable.keygroup.toml","[owner]"] +],[ + "start", + ["identifier","name"], + ["text"," = "], + ["string","\"Tom Preston-Werner\""] +],[ + "start", + ["identifier","organization"], + ["text"," = "], + ["string","\"GitHub\""] +],[ + "start", + ["identifier","bio"], + ["text"," = "], + ["string","\"GitHub Cofounder & CEO"], + ["constant.language.escape","\\n"], + ["string","Likes tater tots and beer.\""] +],[ + "start", + ["identifier","dob"], + ["text"," = "], + ["support.date.toml","1979-05-27T07:32:00Z"], + ["text"," "], + ["comment.toml","# First class dates? Why not?"] +],[ + "start" +],[ + "start", + ["variable.keygroup.toml","[database]"] +],[ + "start", + ["identifier","server"], + ["text"," = "], + ["string","\"192.168.1.1\""] +],[ + "start", + ["identifier","ports"], + ["text"," = [ "], + ["constant.numeric.toml","8001"], + ["text",", "], + ["constant.numeric.toml","8001"], + ["text",", "], + ["constant.numeric.toml","8002"], + ["text"," ]"] +],[ + "start", + ["identifier","connection_max"], + ["text"," = "], + ["constant.numeric.toml","5000"] +],[ + "start", + ["identifier","enabled"], + ["text"," = "], + ["constant.language.boolean","true"] +],[ + "start" +],[ + "start", + ["variable.keygroup.toml","[servers]"] +],[ + "start" +],[ + "start", + ["text"," "], + ["comment.toml","# You can indent as you please. Tabs or spaces. TOML don't care."] +],[ + "start", + ["variable.keygroup.toml"," [servers.alpha]"] +],[ + "start", + ["text"," "], + ["identifier","ip"], + ["text"," = "], + ["string","\"10.0.0.1\""] +],[ + "start", + ["text"," "], + ["identifier","dc"], + ["text"," = "], + ["string","\"eqdc10\""] +],[ + "start" +],[ + "start", + ["variable.keygroup.toml"," [servers.beta]"] +],[ + "start", + ["text"," "], + ["identifier","ip"], + ["text"," = "], + ["string","\"10.0.0.2\""] +],[ + "start", + ["text"," "], + ["identifier","dc"], + ["text"," = "], + ["string","\"eqdc10\""] +],[ + "start" +],[ + "start", + ["variable.keygroup.toml","[clients]"] +],[ + "start", + ["identifier","data"], + ["text"," = [ ["], + ["string","\"gamma\""], + ["text",", "], + ["string","\"delta\""], + ["text","], ["], + ["constant.numeric.toml","1"], + ["text",", "], + ["constant.numeric.toml","2"], + ["text","] ] "], + ["comment.toml","# just an update to make sure parsers support it"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_twig.json b/lib/ace/mode/_test/tokens_twig.json new file mode 100644 index 00000000..ada8b4a7 --- /dev/null +++ b/lib/ace/mode/_test/tokens_twig.json @@ -0,0 +1,288 @@ +[[ + "start", + ["xml-pe.doctype.xml",""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","html"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","head"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","title"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","My Webpage"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","body"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","ul"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","id"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"navigation\""], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.twig","{%"], + ["text"," "], + ["keyword.control.twig","for"], + ["text"," "], + ["identifier","item"], + ["text"," "], + ["keyword.operator.twig","in"], + ["text"," "], + ["identifier","navigation"], + ["text"," "], + ["meta.tag.twig","%}"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","li"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.anchor.tag-name.xml","a"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","href"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\""], + ["variable.other.readwrite.local.twig","{{"], + ["text"," "], + ["identifier","item"], + ["punctuation.operator","."], + ["identifier","href"], + ["keyword.operator.other","|"], + ["support.function.twig","escape"], + ["text"," "], + ["variable.other.readwrite.local.twig","}}"], + ["string.attribute-value.xml","\""], + ["meta.tag.punctuation.tag-close.xml",">"], + ["variable.other.readwrite.local.twig","{{"], + ["text"," "], + ["identifier","item"], + ["punctuation.operator","."], + ["identifier","caption"], + ["text"," "], + ["variable.other.readwrite.local.twig","}}"], + ["meta.tag.punctuation.end-tag-open.xml",""], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["meta.tag.twig","{%"], + ["text"," "], + ["keyword.control.twig","endfor"], + ["text"," "], + ["meta.tag.twig","%}"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "start", + ["text.xml"," "], + ["meta.tag.twig","{%"], + ["text"," "], + ["keyword.control.twig","if"], + ["text"," "], + ["constant.numeric","1"], + ["text"," "], + ["keyword.operator.twig","not"], + ["text"," "], + ["keyword.operator.twig","in"], + ["text"," "], + ["paren.lparen","["], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["text"," "], + ["constant.numeric","2"], + ["punctuation.operator",","], + ["text"," "], + ["constant.numeric","3"], + ["paren.rparen","]"], + ["text"," "], + ["meta.tag.twig","%}"] +],[ + "start" +],[ + "start", + ["text.xml"," "], + ["comment.block.twig","{# is equivalent to #}"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.twig","{%"], + ["text"," "], + ["keyword.control.twig","if"], + ["text"," "], + ["keyword.operator.twig","not"], + ["text"," "], + ["paren.lparen","("], + ["constant.numeric","1"], + ["text"," "], + ["keyword.operator.twig","in"], + ["text"," "], + ["paren.lparen","["], + ["constant.numeric","1"], + ["punctuation.operator",","], + ["text"," "], + ["constant.numeric","2"], + ["punctuation.operator",","], + ["text"," "], + ["constant.numeric","3"], + ["paren.rparen","])"], + ["text"," "], + ["meta.tag.twig","%}"] +],[ + "start" +],[ + "start", + ["text.xml"," "], + ["meta.tag.twig","{%"], + ["text"," "], + ["keyword.control.twig","autoescape"], + ["text"," "], + ["constant.language.boolean","true"], + ["text"," "], + ["meta.tag.twig","%}"] +],[ + "start", + ["text.xml"," "], + ["variable.other.readwrite.local.twig","{{"], + ["text"," "], + ["identifier","var"], + ["text"," "], + ["variable.other.readwrite.local.twig","}}"] +],[ + "start", + ["text.xml"," "], + ["variable.other.readwrite.local.twig","{{"], + ["text"," "], + ["identifier","var"], + ["keyword.operator.other","|"], + ["support.function.twig","raw"], + ["text"," "], + ["variable.other.readwrite.local.twig","}}"], + ["text.xml"," "], + ["comment.block.twig","{# var won't be escaped #}"] +],[ + "start", + ["text.xml"," "], + ["variable.other.readwrite.local.twig","{{"], + ["text"," "], + ["identifier","var"], + ["keyword.operator.other","|"], + ["support.function.twig","escape"], + ["text"," "], + ["variable.other.readwrite.local.twig","}}"], + ["text.xml"," "], + ["comment.block.twig","{# var won't be doubled-escaped #}"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.twig","{%"], + ["text"," "], + ["keyword.control.twig","endautoescape"], + ["text"," "], + ["meta.tag.twig","%}"] +],[ + "start" +],[ + "start", + ["text.xml"," "], + ["variable.other.readwrite.local.twig","{{"], + ["text"," "], + ["keyword.control.twig","include"], + ["paren.lparen","("], + ["string","'twig.html'"], + ["punctuation.operator",","], + ["text"," "], + ["identifier","sandboxed"], + ["text"," "], + ["keyword.operator.assignment","="], + ["text"," "], + ["constant.language.boolean","true"], + ["paren.rparen",")"], + ["text"," "], + ["variable.other.readwrite.local.twig","}}"] +],[ + "start" +],[ + "start", + ["text.xml"," "], + ["variable.other.readwrite.local.twig","{{"], + ["string","\"string "], + ["constant.language.escape","#{with}"], + ["string"," "], + ["constant.language.escape","\\\""], + ["string"," escapes\""], + ["text"," "], + ["string","'another#one'"], + ["text"," "], + ["variable.other.readwrite.local.twig","}}"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","h1"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","My Webpage"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml"," "], + ["variable.other.readwrite.local.twig","{{"], + ["text"," "], + ["identifier","a_variable"], + ["text"," "], + ["variable.other.readwrite.local.twig","}}"] +],[ + "start", + ["text.xml"," "], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_typescript.json b/lib/ace/mode/_test/tokens_typescript.json new file mode 100644 index 00000000..18f2eea6 --- /dev/null +++ b/lib/ace/mode/_test/tokens_typescript.json @@ -0,0 +1,559 @@ +[[ + "start", + ["keyword.operator.ts","class"], + ["text"," "], + ["identifier","Greeter"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text","\t"], + ["variable.parameter.function.ts","greeting"], + ["text",": "], + ["variable.parameter.function.ts","string"], + ["punctuation.operator",";"] +],[ + "start", + ["text","\t"], + ["keyword.operator.ts","constructor"], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter.function.ts","message"], + ["text",": "], + ["variable.parameter.function.ts","string"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text","\t\t"], + ["storage.type.variable.ts","this."], + ["identifier","greeting"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","message"], + ["punctuation.operator",";"] +],[ + "no_regex", + ["text","\t"], + ["paren.rparen","}"] +],[ + "start", + ["text","\t"], + ["identifier","greet"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text","\t\t"], + ["keyword","return"], + ["text"," "], + ["string","\"Hello, \""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["storage.type.variable.ts","this."], + ["identifier","greeting"], + ["punctuation.operator",";"] +],[ + "no_regex", + ["text","\t"], + ["paren.rparen","}"] +],[ + "no_regex", + ["paren.rparen","}"], + ["text"," "] +],[ + "no_regex" +],[ + "start", + ["storage.type","var"], + ["text"," "], + ["identifier","greeter"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["keyword","new"], + ["text"," "], + ["identifier","Greeter"], + ["paren.lparen","("], + ["string","\"world\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start" +],[ + "no_regex", + ["storage.type","var"], + ["text"," "], + ["identifier","button"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["variable.language","document"], + ["punctuation.operator","."], + ["support.function.dom","createElement"], + ["paren.lparen","("], + ["string","'button'"], + ["paren.rparen",")"] +],[ + "no_regex", + ["identifier","button"], + ["punctuation.operator","."], + ["identifier","innerText"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string","\"Say Hello\""] +],[ + "start", + ["storage.type","button"], + ["punctuation.operator","."], + ["entity.name.function","onclick"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["storage.type","function"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "no_regex", + ["text","\t"], + ["support.function","alert"], + ["paren.lparen","("], + ["entity.name.function.ts","greeter.greet"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["paren.rparen",")"] +],[ + "no_regex", + ["paren.rparen","}"] +],[ + "no_regex" +],[ + "no_regex", + ["variable.language","document"], + ["punctuation.operator","."], + ["identifier","body"], + ["punctuation.operator","."], + ["support.function.dom","appendChild"], + ["paren.lparen","("], + ["identifier","button"], + ["paren.rparen",")"] +],[ + "no_regex" +],[ + "start", + ["keyword","class"], + ["text"," "], + ["identifier","Snake"], + ["text"," "], + ["keyword","extends"], + ["text"," "], + ["identifier","Animal"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["entity.name.function.ts","move"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["support.function","alert"], + ["paren.lparen","("], + ["string","\"Slithering...\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["storage.type.variable.ts","super"], + ["text","("], + ["keyword.other.ts","5"], + ["text",")"], + ["punctuation.operator",";"] +],[ + "no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "no_regex", + ["paren.rparen","}"] +],[ + "no_regex" +],[ + "start", + ["keyword","class"], + ["text"," "], + ["identifier","Horse"], + ["text"," "], + ["keyword","extends"], + ["text"," "], + ["identifier","Animal"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["entity.name.function.ts","move"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["support.function","alert"], + ["paren.lparen","("], + ["string","\"Galloping...\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.operator.ts","super"], + ["punctuation.operator","."], + ["identifier","move"], + ["paren.lparen","("], + ["constant.numeric","45"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "no_regex", + ["paren.rparen","}"] +],[ + "no_regex" +],[ + "start", + ["identifier","module"], + ["text"," "], + ["identifier","Sayings"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword.operator.ts","export"], + ["text"," "], + ["keyword.operator.ts","class"], + ["text"," "], + ["identifier","Greeter"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["variable.parameter.function.ts","greeting"], + ["text",": "], + ["variable.parameter.function.ts","string"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.operator.ts","constructor"], + ["text"," "], + ["paren.lparen","("], + ["variable.parameter.function.ts","message"], + ["text",": "], + ["variable.parameter.function.ts","string"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["storage.type.variable.ts","this."], + ["identifier","greeting"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","message"], + ["punctuation.operator",";"] +],[ + "no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["identifier","greet"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword","return"], + ["text"," "], + ["string","\"Hello, \""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["storage.type.variable.ts","this."], + ["identifier","greeting"], + ["punctuation.operator",";"] +],[ + "no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "no_regex", + ["paren.rparen","}"] +],[ + "start", + ["identifier","module"], + ["text"," "], + ["identifier","Mankala"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword.operator.ts","export"], + ["text"," "], + ["keyword.operator.ts","class"], + ["text"," "], + ["identifier","Features"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["keyword.operator.ts","public"], + ["text"," "], + ["identifier","turnContinues"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.language.boolean","false"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.operator.ts","public"], + ["text"," "], + ["identifier","seedStoredCount"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","0"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.operator.ts","public"], + ["text"," "], + ["identifier","capturedCount"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","0"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword.operator.ts","public"], + ["text"," "], + ["identifier","spaceCaptured"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","NoSpace"], + ["punctuation.operator",";"] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword.operator.ts","public"], + ["text"," "], + ["entity.name.function.ts","clear"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["storage.type.variable.ts","this."], + ["identifier","turnContinues"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.language.boolean","false"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["storage.type.variable.ts","this."], + ["identifier","seedStoredCount"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","0"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["storage.type.variable.ts","this."], + ["identifier","capturedCount"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.numeric","0"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["storage.type.variable.ts","this."], + ["identifier","spaceCaptured"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","NoSpace"], + ["punctuation.operator",";"] +],[ + "no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "no_regex" +],[ + "start", + ["text"," "], + ["keyword","public"], + ["text"," "], + ["identifier","toString"], + ["paren.lparen","("], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["storage.type","var"], + ["text"," "], + ["identifier","stringBuilder"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string","\"\""], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["paren.lparen","("], + ["storage.type.variable.ts","this."], + ["identifier","turnContinues"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["identifier","stringBuilder"], + ["text"," "], + ["keyword.operator","+="], + ["text"," "], + ["string","\" turn continues,\""], + ["punctuation.operator",";"] +],[ + "no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["identifier","stringBuilder"], + ["text"," "], + ["keyword.operator","+="], + ["text"," "], + ["string","\" stores \""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["storage.type.variable.ts","this."], + ["identifier","seedStoredCount"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["paren.lparen","("], + ["storage.type.variable.ts","this."], + ["identifier","capturedCount"], + ["text"," "], + ["keyword.operator",">"], + ["text"," "], + ["constant.numeric","0"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "start", + ["text"," "], + ["identifier","stringBuilder"], + ["text"," "], + ["keyword.operator","+="], + ["text"," "], + ["string","\" captures \""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["storage.type.variable.ts","this."], + ["identifier","capturedCount"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","\" from space \""], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["storage.type.variable.ts","this."], + ["identifier","spaceCaptured"], + ["punctuation.operator",";"] +],[ + "no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["text"," "], + ["keyword","return"], + ["text"," "], + ["identifier","stringBuilder"], + ["punctuation.operator",";"] +],[ + "no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "no_regex", + ["paren.rparen","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_vala.json b/lib/ace/mode/_test/tokens_vala.json new file mode 100644 index 00000000..efe6e7c8 --- /dev/null +++ b/lib/ace/mode/_test/tokens_vala.json @@ -0,0 +1,158 @@ +[[ + "start", + ["meta.using.vala",""], + ["keyword.other.using.vala","using"], + ["meta.using.vala"," "], + ["storage.modifier.using.vala","Gtk"], + ["punctuation.terminator.vala",";"] +],[ + "start", + ["text"," "] +],[ + "text0", + ["storage.type.primitive.array.vala","int"], + ["text"," main ("], + ["storage.type.primitive.array.vala","string"], + ["text","[] args) {"] +],[ + "text0", + ["text"," "], + ["storage.type.vala","Gtk"], + ["keyword.operator.dereference.vala","."], + ["text","init ("], + ["storage.modifier.vala","ref"], + ["text"," args)"], + ["punctuation.terminator.vala",";"] +],[ + "text0", + ["text"," "], + ["storage.type.primitive.vala","var"], + ["text"," foo "], + ["keyword.operator.assignment.vala","="], + ["text"," "], + ["keyword.control.new.vala","new"], + ["text"," "], + ["storage.type.generic.vala","MyFoo>"], + ["text","()"], + ["punctuation.terminator.vala",";"] +],[ + "text0" +],[ + "text0", + ["text"," "], + ["storage.type.primitive.vala","var"], + ["text"," window "], + ["keyword.operator.assignment.vala","="], + ["text"," "], + ["keyword.control.new.vala","new"], + ["text"," "], + ["storage.type.vala","Window"], + ["text","()"], + ["punctuation.terminator.vala",";"] +],[ + "text0", + ["text"," window"], + ["keyword.operator.dereference.vala","."], + ["text","title "], + ["keyword.operator.assignment.vala","="], + ["text"," "], + ["punctuation.definition.string.begin.vala","\""], + ["string.quoted.double.vala","Hello, World!"], + ["punctuation.definition.string.end.vala","\""], + ["punctuation.terminator.vala",";"] +],[ + "text0", + ["text"," window"], + ["keyword.operator.dereference.vala","."], + ["text","border_width "], + ["keyword.operator.assignment.vala","="], + ["text"," "], + ["constant.numeric.vala","10"], + ["punctuation.terminator.vala",";"] +],[ + "text0", + ["text"," window"], + ["keyword.operator.dereference.vala","."], + ["text","window_position "], + ["keyword.operator.assignment.vala","="], + ["text"," "], + ["storage.type.vala","WindowPosition"], + ["keyword.operator.dereference.vala","."], + ["constant.other.vala","CENTER"], + ["punctuation.terminator.vala",";"] +],[ + "text0", + ["text"," window"], + ["keyword.operator.dereference.vala","."], + ["text","set_default_size("], + ["constant.numeric.vala","350"], + ["text",", "], + ["constant.numeric.vala","70"], + ["text",")"], + ["punctuation.terminator.vala",";"] +],[ + "text0", + ["text"," window"], + ["keyword.operator.dereference.vala","."], + ["text","destroy"], + ["keyword.operator.dereference.vala","."], + ["text","connect("], + ["storage.type.vala","Gtk"], + ["keyword.operator.dereference.vala","."], + ["text","main_quit)"], + ["punctuation.terminator.vala",";"] +],[ + "text0", + ["text"," "] +],[ + "text0", + ["text"," "], + ["storage.type.primitive.vala","var"], + ["text"," label "], + ["keyword.operator.assignment.vala","="], + ["text"," "], + ["keyword.control.new.vala","new"], + ["text"," "], + ["storage.type.vala","Label"], + ["text","("], + ["punctuation.definition.string.begin.vala","\""], + ["string.quoted.double.vala","Hello, World!"], + ["punctuation.definition.string.end.vala","\""], + ["text",")"], + ["punctuation.terminator.vala",";"] +],[ + "text0", + ["text"," "] +],[ + "text0", + ["text"," window"], + ["keyword.operator.dereference.vala","."], + ["text","add(label)"], + ["punctuation.terminator.vala",";"] +],[ + "text0", + ["text"," window"], + ["keyword.operator.dereference.vala","."], + ["text","show_all()"], + ["punctuation.terminator.vala",";"] +],[ + "text0", + ["text"," "] +],[ + "text0", + ["text"," "], + ["storage.type.vala","Gtk"], + ["keyword.operator.dereference.vala","."], + ["text","main()"], + ["punctuation.terminator.vala",";"] +],[ + "text0", + ["text"," "], + ["keyword.control.vala","return"], + ["text"," "], + ["constant.numeric.vala","0"], + ["punctuation.terminator.vala",";"] +],[ + "start", + ["text","}"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_vbscript.json b/lib/ace/mode/_test/tokens_vbscript.json new file mode 100644 index 00000000..05d5dd22 --- /dev/null +++ b/lib/ace/mode/_test/tokens_vbscript.json @@ -0,0 +1,203 @@ +[[ + "start", + ["text","myfilename "], + ["keyword.operator.asp","="], + ["text"," "], + ["punctuation.definition.string.begin.asp","\""], + ["string.quoted.double.asp","C:\\Wikipedia - VBScript - Example - Hello World.txt\""] +],[ + "start", + ["text","MakeHelloWorldFile myfilename"] +],[ + "state_4", + ["meta.leading-space"," "] +],[ + "start", + ["storage.type.function.asp","Sub"], + ["text"," "], + ["entity.name.function.asp","MakeHelloWorldFile"], + ["text"," "], + ["punctuation.definition.parameters.asp","("], + ["variable.parameter.function.asp","FileName"], + ["punctuation.definition.parameters.asp",")"] +],[ + "start", + ["punctuation.definition.comment.asp","'"], + ["comment.line.apostrophe.asp","Create a new file in C: drive or overwrite existing file"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.leading-space"," "], + ["storage.type.asp","Set"], + ["text"," FSO "], + ["keyword.operator.asp","="], + ["text"," "], + ["support.function.asp","CreateObject"], + ["text","("], + ["punctuation.definition.string.begin.asp","\""], + ["string.quoted.double.asp","Scripting.FileSystemObject\""], + ["text",")"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.leading-space"," "], + ["keyword.control.asp","If"], + ["text"," FSO."], + ["entity.name.function.asp","FileExists"], + ["text","(FileName) "], + ["keyword.control.asp","Then"], + ["text"," "] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.even-tab.spaces"," "], + ["meta.odd-tab.spaces"," "], + ["text","Answer "], + ["keyword.operator.asp","="], + ["text"," "], + ["support.function.vb.asp","MsgBox"], + ["text"," ("], + ["punctuation.definition.string.begin.asp","\""], + ["string.quoted.double.asp","File \""], + ["text"," "], + ["keyword.operator.asp","&"], + ["text"," FileName "], + ["keyword.operator.asp","&"], + ["text"," "], + ["punctuation.definition.string.begin.asp","\""], + ["string.quoted.double.asp"," exists ... OK to overwrite?\""], + ["text",", vbOKCancel)"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.even-tab.spaces"," "], + ["meta.odd-tab.spaces"," "], + ["punctuation.definition.comment.asp","'"], + ["comment.line.apostrophe.asp","If button selected is not OK, then quit now"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.even-tab.spaces"," "], + ["meta.odd-tab.spaces"," "], + ["punctuation.definition.comment.asp","'"], + ["comment.line.apostrophe.asp","vbOK is a language constant"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.even-tab.spaces"," "], + ["meta.odd-tab.spaces"," "], + ["keyword.control.asp","If"], + ["text"," Answer "], + ["keyword.operator.asp","<>"], + ["text"," vbOK "], + ["keyword.control.asp","Then"], + ["text"," "], + ["keyword.control.asp","Exit Sub"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.leading-space"," "], + ["keyword.control.asp","Else"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.even-tab.spaces"," "], + ["meta.odd-tab.spaces"," "], + ["punctuation.definition.comment.asp","'"], + ["comment.line.apostrophe.asp","Confirm OK to create"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.even-tab.spaces"," "], + ["meta.odd-tab.spaces"," "], + ["text","Answer "], + ["keyword.operator.asp","="], + ["text"," "], + ["support.function.vb.asp","MsgBox"], + ["text"," ("], + ["punctuation.definition.string.begin.asp","\""], + ["string.quoted.double.asp","File \""], + ["text"," "], + ["keyword.operator.asp","&"], + ["text"," FileName "], + ["keyword.operator.asp","&"], + ["text"," "], + ["punctuation.definition.string.begin.asp","\""], + ["string.quoted.double.asp"," ... OK to create?\""], + ["text",", vbOKCancel)"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.even-tab.spaces"," "], + ["meta.odd-tab.spaces"," "], + ["keyword.control.asp","If"], + ["text"," Answer "], + ["keyword.operator.asp","<>"], + ["text"," vbOK "], + ["keyword.control.asp","Then"], + ["text"," "], + ["keyword.control.asp","Exit Sub"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.leading-space"," "], + ["keyword.control.asp","End If"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.leading-space"," "], + ["punctuation.definition.comment.asp","'"], + ["comment.line.apostrophe.asp","Create new file (or replace an existing file)"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.leading-space"," "], + ["storage.type.asp","Set"], + ["text"," FileObject "], + ["keyword.operator.asp","="], + ["text"," FSO.CreateTextFile (FileName)"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.leading-space"," "], + ["text","FileObject.WriteLine "], + ["punctuation.definition.string.begin.asp","\""], + ["string.quoted.double.asp","Time ... \""], + ["text"," "], + ["keyword.operator.asp","&"], + ["text"," "], + ["support.function.vb.asp","Now"], + ["text","()"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.leading-space"," "], + ["text","FileObject.WriteLine "], + ["punctuation.definition.string.begin.asp","\""], + ["string.quoted.double.asp","Hello World\""] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.leading-space"," "], + ["text","FileObject."], + ["entity.name.function.asp","Close"], + ["text","()"] +],[ + "start", + ["meta.odd-tab.spaces"," "], + ["meta.leading-space"," "], + ["support.function.vb.asp","MsgBox"], + ["text"," "], + ["punctuation.definition.string.begin.asp","\""], + ["string.quoted.double.asp","File \""], + ["text"," "], + ["keyword.operator.asp","&"], + ["text"," FileName "], + ["keyword.operator.asp","&"], + ["text"," "], + ["punctuation.definition.string.begin.asp","\""], + ["string.quoted.double.asp"," ... updated.\""] +],[ + "start", + ["storage.type.asp","End Sub"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_velocity.json b/lib/ace/mode/_test/tokens_velocity.json new file mode 100644 index 00000000..ee40761c --- /dev/null +++ b/lib/ace/mode/_test/tokens_velocity.json @@ -0,0 +1,285 @@ +[[ + "vm_comment", + ["comment.block","#*"] +],[ + "vm_comment", + ["comment"," This is a sample comment block that"] +],[ + "vm_comment", + ["comment"," spans multiple lines."] +],[ + "start", + ["comment","*#"] +],[ + "start" +],[ + "start", + ["keyword","#macro"], + ["text"," "], + ["lparen","("], + ["text"," "], + ["identifier","outputItem"], + ["text"," "], + ["variable","$item"], + ["text"," "], + ["rparen",")"] +],[ + "start", + ["text"," "], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","li"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["variable","${"], + ["identifier","item"], + ["variable","}"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["keyword","#end"] +],[ + "start" +],[ + "start", + ["comment","## Define the items to iterate"] +],[ + "start", + ["keyword","#set"], + ["text"," "], + ["lparen","("], + ["text"," "], + ["variable","$items"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["lparen","["], + ["constant.numeric","1"], + ["text.xml",","], + ["text"," "], + ["constant.numeric","2"], + ["text.xml",","], + ["text"," "], + ["constant.numeric","3"], + ["text.xml",","], + ["text"," "], + ["constant.numeric","4"], + ["rparen","]"], + ["text"," "], + ["rparen",")"] +],[ + "start" +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","ul"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text"," "], + ["comment","## Iterate over the items and output the evens."] +],[ + "start", + ["text"," "], + ["keyword","#foreach"], + ["text"," "], + ["lparen","("], + ["text"," "], + ["variable","$item"], + ["text"," "], + ["identifier","in"], + ["text"," "], + ["variable","$items"], + ["text"," "], + ["rparen",")"] +],[ + "start", + ["text"," "], + ["keyword","#if"], + ["text"," "], + ["lparen","("], + ["text"," "], + ["support.function","$_MathTool"], + ["text.xml","."], + ["identifier","mod"], + ["lparen","("], + ["variable","$item"], + ["text.xml",","], + ["text"," "], + ["constant.numeric","2"], + ["rparen",")"], + ["text"," "], + ["keyword.operator","=="], + ["text"," "], + ["constant.numeric","0"], + ["text"," "], + ["rparen",")"] +],[ + "start", + ["text"," "], + ["identifier","#outputItem"], + ["text"," "], + ["lparen","("], + ["variable","$item"], + ["rparen",")"] +],[ + "start", + ["text"," "], + ["keyword","#end"] +],[ + "start", + ["text"," "], + ["keyword","#end"] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "js-start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.script.tag-name.xml","script"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "js-comment_regex_allowed", + ["text"," "], + ["comment","/*"] +],[ + "js-comment_regex_allowed", + ["comment"," A sample function to decomstrate"] +],[ + "js-comment_regex_allowed", + ["comment"," JavaScript highlighting and folding."] +],[ + "js-start", + ["comment"," */"] +],[ + "js-start", + ["text"," "], + ["storage.type","function"], + ["text"," "], + ["entity.name.function","foo"], + ["paren.lparen","("], + ["variable.parameter","items"], + ["punctuation.operator",", "], + ["variable.parameter","nada"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "js-start", + ["text"," "], + ["keyword","for"], + ["text"," "], + ["paren.lparen","("], + ["storage.type","var"], + ["text"," "], + ["identifier","i"], + ["keyword.operator","="], + ["constant.numeric","0"], + ["punctuation.operator",";"], + ["text"," "], + ["identifier","i"], + ["keyword.operator","<"], + ["identifier","items"], + ["punctuation.operator","."], + ["support.constant","length"], + ["punctuation.operator",";"], + ["text"," "], + ["identifier","i"], + ["keyword.operator","++"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","{"] +],[ + "js-start", + ["text"," "], + ["support.function","alert"], + ["paren.lparen","("], + ["identifier","items"], + ["paren.lparen","["], + ["identifier","i"], + ["paren.rparen","]"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["string","\"juhu"], + ["constant.language.escape","\\n"], + ["string","\""], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "js-no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "js-no_regex", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start" +],[ + "css-start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.style.tag-name.xml","style"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + ["css-comment","css-start"], + ["text"," "], + ["comment","/*"] +],[ + ["css-comment","css-start"], + ["comment"," A sample style to decomstrate"] +],[ + ["css-comment","css-start"], + ["comment"," CSS highlighting and folding."] +],[ + "css-start", + ["comment"," */"] +],[ + ["css-ruleset","css-start"], + ["text"," "], + ["variable",".class"], + ["text"," "], + ["paren.lparen","{"] +],[ + ["css-ruleset","css-start"], + ["text"," "], + ["support.type","font-family"], + ["text",": Monaco, "], + ["string","\"Courier New\""], + ["text",", "], + ["support.constant.fonts","monospace"], + ["text",";"] +],[ + ["css-ruleset","css-start"], + ["text"," "], + ["support.type","font-size"], + ["text",": "], + ["constant.numeric","12"], + ["keyword","px"], + ["text",";"] +],[ + ["css-ruleset","css-start"], + ["text"," "], + ["support.type","cursor"], + ["text",": "], + ["support.constant","text"], + ["text",";"] +],[ + "css-start", + ["text"," "], + ["paren.rparen","}"] +],[ + "start", + ["meta.tag.punctuation.end-tag-open.xml",""] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_verilog.json b/lib/ace/mode/_test/tokens_verilog.json new file mode 100644 index 00000000..9680a964 --- /dev/null +++ b/lib/ace/mode/_test/tokens_verilog.json @@ -0,0 +1,113 @@ +[[ + "start", + ["keyword","always"], + ["text"," @"], + ["paren.lparen","("], + ["keyword","negedge"], + ["text"," "], + ["identifier","reset"], + ["text"," "], + ["keyword","or"], + ["text"," "], + ["keyword","posedge"], + ["text"," "], + ["identifier","clk"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","begin"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["text"," "], + ["paren.lparen","("], + ["identifier","reset"], + ["text"," "], + ["keyword.operator","=="], + ["text"," "], + ["constant.numeric","0"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","begin"] +],[ + "start", + ["text"," "], + ["identifier","d_out"], + ["text"," "], + ["keyword.operator","<="], + ["text"," "], + ["constant.numeric","16"], + ["text","'"], + ["identifier","h0000"], + ["text",";"] +],[ + "start", + ["text"," "], + ["identifier","d_out_mem"], + ["text","["], + ["identifier","resetcount"], + ["text","] "], + ["keyword.operator","<="], + ["text"," "], + ["identifier","d_out"], + ["text",";"] +],[ + "start", + ["text"," "], + ["identifier","laststoredvalue"], + ["text"," "], + ["keyword.operator","<="], + ["text"," "], + ["identifier","d_out"], + ["text",";"] +],[ + "start", + ["text"," "], + ["keyword","end"], + ["text"," "], + ["keyword","else"], + ["text"," "], + ["keyword","begin"] +],[ + "start", + ["text"," "], + ["identifier","d_out"], + ["text"," "], + ["keyword.operator","<="], + ["text"," "], + ["identifier","d_out"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","1"], + ["text","'"], + ["identifier","b1"], + ["text","; "] +],[ + "start", + ["text"," "], + ["keyword","end"] +],[ + "start", + ["keyword","end"] +],[ + "start" +],[ + "start", + ["keyword","always"], + ["text"," @"], + ["paren.lparen","("], + ["identifier","bufreadaddr"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["identifier","bufreadval"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","d_out_mem"], + ["text","["], + ["identifier","bufreadaddr"], + ["text","];"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_vhdl.json b/lib/ace/mode/_test/tokens_vhdl.json new file mode 100644 index 00000000..88c6e222 --- /dev/null +++ b/lib/ace/mode/_test/tokens_vhdl.json @@ -0,0 +1,271 @@ +[[ + "start", + ["keyword","library"], + ["text"," "], + ["identifier","IEEE"] +],[ + "start", + ["identifier","user"], + ["text"," "], + ["identifier","IEEE"], + ["punctuation.operator","."], + ["identifier","std_logic_1164"], + ["punctuation.operator","."], + ["keyword","all"], + ["punctuation.operator",";"] +],[ + "start", + ["keyword","use"], + ["text"," "], + ["identifier","IEEE"], + ["punctuation.operator","."], + ["identifier","numeric_std"], + ["punctuation.operator","."], + ["keyword","all"], + ["punctuation.operator",";"] +],[ + "start" +],[ + "start", + ["keyword","entity"], + ["text"," "], + ["identifier","COUNT16"], + ["text"," "], + ["keyword","is"] +],[ + "start" +],[ + "start", + ["text"," "], + ["keyword","port"], + ["text"," "], + ["paren.lparen","("] +],[ + "start", + ["text"," "], + ["identifier","cOut"], + ["text"," "], + ["punctuation.operator",":"], + ["keyword","out"], + ["text"," "], + ["storage.type","std_logic_vector"], + ["paren.lparen","("], + ["constant.numeric","15"], + ["text"," "], + ["keyword","downto"], + ["text"," "], + ["constant.numeric","0"], + ["paren.rparen",")"], + ["punctuation.operator",";"], + ["text"," "], + ["comment","-- counter output"] +],[ + "start", + ["text"," "], + ["identifier","clkEn"], + ["text"," "], + ["punctuation.operator",":"], + ["keyword","in"], + ["text"," "], + ["storage.type","std_logic"], + ["punctuation.operator",";"], + ["text"," "], + ["comment","-- count enable"] +],[ + "start", + ["text"," "], + ["identifier","clk"], + ["text"," "], + ["punctuation.operator",":"], + ["keyword","in"], + ["text"," "], + ["storage.type","std_logic"], + ["punctuation.operator",";"], + ["text"," "], + ["comment","-- clock input"] +],[ + "start", + ["text"," "], + ["identifier","rst"], + ["text"," "], + ["punctuation.operator",":"], + ["keyword","in"], + ["text"," "], + ["storage.type","std_logic"], + ["text"," "], + ["comment","-- reset input"] +],[ + "start", + ["text"," "], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "] +],[ + "start", + ["keyword","end"], + ["text"," "], + ["keyword","entity"], + ["punctuation.operator",";"] +],[ + "start" +],[ + "start", + ["keyword","architecture"], + ["text"," "], + ["identifier","count_rtl"], + ["text"," "], + ["keyword","of"], + ["text"," "], + ["identifier","COUNT16"], + ["text"," "], + ["keyword","is"] +],[ + "start", + ["text"," "], + ["storage.type","signal"], + ["text"," "], + ["identifier","count"], + ["text"," "], + ["punctuation.operator",":"], + ["storage.type","std_logic_vector"], + ["text"," "], + ["paren.lparen","("], + ["constant.numeric","15"], + ["text"," "], + ["keyword","downto"], + ["text"," "], + ["constant.numeric","0"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "] +],[ + "start", + ["keyword","begin"] +],[ + "start", + ["text"," "], + ["keyword","process"], + ["text"," "], + ["paren.lparen","("], + ["identifier","clk"], + ["punctuation.operator",","], + ["text"," "], + ["identifier","rst"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","begin"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["paren.lparen","("], + ["identifier","rst"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string","'1'"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","then"] +],[ + "start", + ["text"," "], + ["identifier","count"], + ["text"," "], + ["keyword.operator","<="], + ["text"," "], + ["paren.lparen","("], + ["keyword","others"], + ["keyword.operator","=>"], + ["string","'0'"], + ["paren.rparen",")"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword","elsif"], + ["paren.lparen","("], + ["identifier","rising_edge"], + ["paren.lparen","("], + ["identifier","clk"], + ["paren.rparen","))"], + ["text"," "], + ["keyword","then"] +],[ + "start", + ["text"," "], + ["keyword","if"], + ["paren.lparen","("], + ["identifier","clkEn"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["string","'1'"], + ["paren.rparen",")"], + ["text"," "], + ["keyword","then"] +],[ + "start", + ["text"," "], + ["identifier","count"], + ["text"," "], + ["keyword.operator","<="], + ["text"," "], + ["identifier","count"], + ["text"," "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","1"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword","end"], + ["text"," "], + ["keyword","if"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["keyword","end"], + ["text"," "], + ["keyword","if"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "] +],[ + "start", + ["text"," "], + ["keyword","end"], + ["text"," "], + ["keyword","process"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "], + ["identifier","cOut"], + ["text"," "], + ["keyword.operator","<="], + ["text"," "], + ["identifier","count"], + ["punctuation.operator",";"] +],[ + "start" +],[ + "start", + ["keyword","end"], + ["text"," "], + ["keyword","architecture"], + ["punctuation.operator",";"] +],[ + "start", + ["text"," "] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_xml.json b/lib/ace/mode/_test/tokens_xml.json new file mode 100644 index 00000000..728be4db --- /dev/null +++ b/lib/ace/mode/_test/tokens_xml.json @@ -0,0 +1,43 @@ +[[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","Juhu"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["text.xml","//Juhu Kinners"], + ["meta.tag.punctuation.end-tag-open.xml",""] +],[ + "start", + ["text.xml","test: two tags in the same lines should be in separate tokens\""] +],[ + "start", + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","Juhu"], + ["meta.tag.punctuation.tag-close.xml",">"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","Kinners"], + ["meta.tag.punctuation.tag-close.xml",">"] +],[ + "start", + ["text.xml","test: multiline attributes\""] +],[ + ["string.attribute-value.xml0","meta.tag.punctuation.tag-open.xml"], + ["meta.tag.punctuation.tag-open.xml","<"], + ["meta.tag.tag-name.xml","copy"], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","set"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"{"] +],[ + ["string.attribute-value.xml0","meta.tag.punctuation.tag-open.xml"], + ["string.attribute-value.xml","}\""], + ["text.tag-whitespace.xml"," "], + ["entity.other.attribute-name.xml","undo"], + ["keyword.operator.attribute-equals.xml","="], + ["string.attribute-value.xml","\"{"] +],[ + "start", + ["string.attribute-value.xml","}\""], + ["meta.tag.punctuation.tag-close.xml","/>"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_xquery.json b/lib/ace/mode/_test/tokens_xquery.json new file mode 100644 index 00000000..aaf9ab9b --- /dev/null +++ b/lib/ace/mode/_test/tokens_xquery.json @@ -0,0 +1,44 @@ +[[ + "[\"start\"]", + ["keyword","xquery"], + ["text"," "], + ["keyword","version"], + ["text"," "], + ["string","\""], + ["string","1.0"], + ["string","\""], + ["text",";"] +],[ + "[\"start\"]" +],[ + "[\"start\"]", + ["keyword","let"], + ["text"," "], + ["variable","$message"], + ["text"," "], + ["keyword.operator",":="], + ["text"," "], + ["string","\""], + ["string","Hello World!"], + ["string","\""] +],[ + "[\"start\",\"StartTag\",\"TagContent\"]", + ["keyword","return"], + ["text"," "], + ["meta.tag",""] +],[ + "[\"start\",\"StartTag\",\"TagContent\"]", + ["text"," "], + ["meta.tag",""], + ["text","{"], + ["variable","$message"], + ["text","}"], + ["meta.tag",""] +],[ + "[\"start\"]", + ["meta.tag",""] +],[ + "[\"start\"]" +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_yaml.json b/lib/ace/mode/_test/tokens_yaml.json new file mode 100644 index 00000000..7c9b45f3 --- /dev/null +++ b/lib/ace/mode/_test/tokens_yaml.json @@ -0,0 +1,150 @@ +[[ + "start", + ["comment","# This sample document was taken from wikipedia:"] +],[ + "start", + ["comment","# http://en.wikipedia.org/wiki/YAML#Sample_document"] +],[ + "start", + ["list.markup","---"] +],[ + "start", + ["meta.tag","receipt"], + ["keyword",": "], + ["text","Oz-Ware Purchase Invoice"] +],[ + "start", + ["meta.tag","date"], + ["keyword",": "], + ["constant.numeric","2007-08-06"] +],[ + "start", + ["meta.tag","customer"], + ["keyword",":"] +],[ + "start", + ["meta.tag"," given"], + ["keyword",": "], + ["text","Dorothy"] +],[ + "start", + ["meta.tag"," family"], + ["keyword",": "], + ["text","Gale"] +],[ + "start" +],[ + "start", + ["meta.tag","items"], + ["keyword",":"] +],[ + "start", + ["list.markup"," - "], + ["meta.tag","part_no"], + ["keyword",": "], + ["string","'A4786'"] +],[ + "start", + ["meta.tag"," descrip"], + ["keyword",": "], + ["text","Water Bucket "], + ["paren.lparen","("], + ["text","Filled"], + ["paren.rparen",")"] +],[ + "start", + ["meta.tag"," price"], + ["keyword",": "], + ["constant.numeric","1.47"] +],[ + "start", + ["meta.tag"," quantity"], + ["keyword",": "], + ["constant.numeric","4"] +],[ + "start" +],[ + "start", + ["list.markup"," - "], + ["meta.tag","part_no"], + ["keyword",": "], + ["string","'E1628'"] +],[ + "start", + ["meta.tag"," descrip"], + ["keyword",": "], + ["text","High Heeled "], + ["string","\"Ruby\""], + ["text"," Slippers"] +],[ + "start", + ["meta.tag"," size"], + ["keyword",": "], + ["constant.numeric","8"] +],[ + "start", + ["meta.tag"," price"], + ["keyword",": "], + ["constant.numeric","100.27"] +],[ + "start", + ["meta.tag"," quantity"], + ["keyword",": "], + ["constant.numeric","1"] +],[ + "start" +],[ + "start", + ["meta.tag","bill-to"], + ["keyword",": "], + ["constant.language","&id001"] +],[ + "qqstring", + ["meta.tag"," street"], + ["keyword",": "], + ["string","|"] +],[ + "qqstring", + ["string"," 123 Tornado Alley"] +],[ + "qqstring", + ["string"," Suite 16"] +],[ + "start", + ["meta.tag"," city"], + ["keyword",": "], + ["text","East Centerville"] +],[ + "start", + ["meta.tag"," state"], + ["keyword",": "], + ["text","KS"] +],[ + "start" +],[ + "start", + ["meta.tag","ship-to"], + ["keyword",": "], + ["constant.language","*id001"] +],[ + "start" +],[ + "qqstring", + ["meta.tag","specialDelivery"], + ["keyword",": "], + ["string",">"] +],[ + "qqstring", + ["string"," Follow the Yellow Brick"] +],[ + "qqstring", + ["string"," Road to the Emerald City."] +],[ + "qqstring", + ["string"," Pay no attention to the"] +],[ + "qqstring", + ["string"," man behind the curtain."] +],[ + "qqstring" +]] \ No newline at end of file diff --git a/lib/ace/mode/abap.js b/lib/ace/mode/abap.js new file mode 100644 index 00000000..c9d5a991 --- /dev/null +++ b/lib/ace/mode/abap.js @@ -0,0 +1,77 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var Rules = require("./abap_highlight_rules").AbapHighlightRules; +var FoldMode = require("./folding/coffee").FoldMode; +var Range = require("../range").Range; +var TextMode = require("./text").Mode; +var oop = require("../lib/oop"); + +function Mode() { + this.HighlightRules = Rules; + this.foldingRules = new FoldMode(); +} + +oop.inherits(Mode, TextMode); + +(function() { + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + return indent; + }; + + this.toggleCommentLines = function(state, doc, startRow, endRow){ + var range = new Range(0, 0, 0, 0); + for (var i = startRow; i <= endRow; ++i) { + var line = doc.getLine(i); + if (hereComment.test(line)) + continue; + + if (commentLine.test(line)) + line = line.replace(commentLine, '$1'); + else + line = line.replace(indentation, '$&#'); + + range.end.row = range.start.row = i; + range.end.column = line.length + 1; + doc.replace(range, line); + } + }; + + this.$id = "ace/mode/abap"; +}).call(Mode.prototype); + +exports.Mode = Mode; + +}); diff --git a/lib/ace/mode/abap_highlight_rules.js b/lib/ace/mode/abap_highlight_rules.js new file mode 100644 index 00000000..bab1e504 --- /dev/null +++ b/lib/ace/mode/abap_highlight_rules.js @@ -0,0 +1,134 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * based on + * " Vim ABAP syntax file + * " Language: SAP - ABAP/R4 + * " Revision: 2.1 + * " Maintainer: Marius Piedallu van Wyk + * " Last Change: 2012 Oct 23 + */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var AbapHighlightRules = function() { + + var keywordMapper = this.createKeywordMapper({ + "variable.language": "this", + "keyword": + "ADD ALIAS ALIASES ASSERT ASSIGN ASSIGNING AT BACK" + + " CALL CASE CATCH CHECK CLASS CLEAR CLOSE CNT COLLECT COMMIT COMMUNICATION COMPUTE CONCATENATE CONDENSE CONSTANTS CONTINUE CONTROLS CONVERT CREATE CURRENCY" + + " DATA DEFINE DEFINITION DEFERRED DELETE DESCRIBE DETAIL DIVIDE DO" + + " ELSE ELSEIF ENDAT ENDCASE ENDCLASS ENDDO ENDEXEC ENDFORM ENDFUNCTION ENDIF ENDIFEND ENDINTERFACE ENDLOOP ENDMETHOD ENDMODULE ENDON ENDPROVIDE ENDSELECT ENDTRY ENDWHILE EVENT EVENTS EXEC EXIT EXPORT EXPORTING EXTRACT" + + " FETCH FIELDS FORM FORMAT FREE FROM FUNCTION" + + " GENERATE GET" + + " HIDE" + + " IF IMPORT IMPORTING INDEX INFOTYPES INITIALIZATION INTERFACE INTERFACES INPUT INSERT IMPLEMENTATION" + + " LEAVE LIKE LINE LOAD LOCAL LOOP" + + " MESSAGE METHOD METHODS MODIFY MODULE MOVE MULTIPLY" + + " ON OVERLAY OPTIONAL OTHERS" + + " PACK PARAMETERS PERFORM POSITION PROGRAM PROVIDE PUT" + + " RAISE RANGES READ RECEIVE RECEIVING REDEFINITION REFERENCE REFRESH REJECT REPLACE REPORT RESERVE RESTORE RETURNING ROLLBACK" + + " SCAN SCROLL SEARCH SELECT SET SHIFT SKIP SORT SORTED SPLIT STANDARD STATICS STEP STOP SUBMIT SUBTRACT SUM SUMMARY SUPPRESS" + + " TABLES TIMES TRANSFER TRANSLATE TRY TYPE TYPES" + + " UNASSIGN ULINE UNPACK UPDATE" + + " WHEN WHILE WINDOW WRITE" + + " OCCURS STRUCTURE OBJECT PROPERTY" + + " CASTING APPEND RAISING VALUE COLOR" + + " CHANGING EXCEPTION EXCEPTIONS DEFAULT CHECKBOX COMMENT" + + " ID NUMBER FOR TITLE OUTPUT" + + " WITH EXIT USING" + + " INTO WHERE GROUP BY HAVING ORDER BY SINGLE" + + " APPENDING CORRESPONDING FIELDS OF TABLE" + + " LEFT RIGHT OUTER INNER JOIN AS CLIENT SPECIFIED BYPASSING BUFFER UP TO ROWS CONNECTING" + + " EQ NE LT LE GT GE NOT AND OR XOR IN LIKE BETWEEN", + "constant.language": + "TRUE FALSE NULL SPACE", + "support.type": + "c n i p f d t x string xstring decfloat16 decfloat34", + "keyword.operator": + "abs sign ceil floor trunc frac acos asin atan cos sin tan" + + " abapOperator cosh sinh tanh exp log log10 sqrt" + + " strlen xstrlen charlen numofchar dbmaxlen lines" + }, "text", true, " "); + + var compoundKeywords = "WITH\\W+(?:HEADER\\W+LINE|FRAME|KEY)|NO\\W+STANDARD\\W+PAGE\\W+HEADING|"+ + "EXIT\\W+FROM\\W+STEP\\W+LOOP|BEGIN\\W+OF\\W+(?:BLOCK|LINE)|BEGIN\\W+OF|"+ + "END\\W+OF\\W+(?:BLOCK|LINE)|END\\W+OF|NO\\W+INTERVALS|"+ + "RESPECTING\\W+BLANKS|SEPARATED\\W+BY|USING\\W+(?:EDIT\\W+MASK)|"+ + "WHERE\\W+(?:LINE)|RADIOBUTTON\\W+GROUP|REF\\W+TO|"+ + "(?:PUBLIC|PRIVATE|PROTECTED)(?:\\W+SECTION)?|DELETING\\W+(?:TRAILING|LEADING)"+ + "(?:ALL\\W+OCCURRENCES)|(?:FIRST|LAST)\\W+OCCURRENCE|INHERITING\\W+FROM|"+ + "LINE-COUNT|ADD-CORRESPONDING|AUTHORITY-CHECK|BREAK-POINT|CLASS-DATA|CLASS-METHODS|"+ + "CLASS-METHOD|DIVIDE-CORRESPONDING|EDITOR-CALL|END-OF-DEFINITION|END-OF-PAGE|END-OF-SELECTION|"+ + "FIELD-GROUPS|FIELD-SYMBOLS|FUNCTION-POOL|MOVE-CORRESPONDING|MULTIPLY-CORRESPONDING|NEW-LINE|"+ + "NEW-PAGE|NEW-SECTION|PRINT-CONTROL|RP-PROVIDE-FROM-LAST|SELECT-OPTIONS|SELECTION-SCREEN|"+ + "START-OF-SELECTION|SUBTRACT-CORRESPONDING|SYNTAX-CHECK|SYNTAX-TRACE|TOP-OF-PAGE|TYPE-POOL|"+ + "TYPE-POOLS|LINE-SIZE|LINE-COUNT|MESSAGE-ID|DISPLAY-MODE|READ(?:-ONLY)?|"+ + "IS\\W+(?:NOT\\W+)?(?:ASSIGNED|BOUND|INITIAL|SUPPLIED)"; + + this.$rules = { + "start" : [ + {token : "string", regex : "`", next : "string"}, + {token : "string", regex : "'", next : "qstring"}, + {token : "doc.comment", regex : /^\*.+/}, + {token : "comment", regex : /".+$/}, + {token : "invalid", regex: "\\.{2,}"}, + {token : "keyword.operator", regex: /\W[\-+\%=<>*]\W|\*\*|[~:,\.&$]|->*?|=>/}, + {token : "paren.lparen", regex : "[\\[({]"}, + {token : "paren.rparen", regex : "[\\])}]"}, + {token : "constant.numeric", regex: "[+-]?\\d+\\b"}, + {token : "variable.parameter", regex : /sy|pa?\d\d\d\d\|t\d\d\d\.|innnn/}, + {token : "keyword", regex : compoundKeywords}, + {token : "variable.parameter", regex : /\w+-\w+(?:-\w+)*/}, + {token : keywordMapper, regex : "\\b\\w+\\b"}, + {caseInsensitive: true} + ], + "qstring" : [ + {token : "constant.language.escape", regex : "''"}, + {token : "string", regex : "'", next : "start"}, + {defaultToken : "string"} + ], + "string" : [ + {token : "constant.language.escape", regex : "``"}, + {token : "string", regex : "`", next : "start"}, + {defaultToken : "string"} + ] + }; +}; +oop.inherits(AbapHighlightRules, TextHighlightRules); + +exports.AbapHighlightRules = AbapHighlightRules; +}); diff --git a/lib/ace/mode/abc.js b/lib/ace/mode/abc.js new file mode 100644 index 00000000..b6eb237a --- /dev/null +++ b/lib/ace/mode/abc.js @@ -0,0 +1,58 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/* + THIS FILE WAS AUTOGENERATED BY mode.tmpl.js + */ + +define(function (require, exports, module) { + "use strict"; + + var oop = require("../lib/oop"); + var TextMode = require("./text").Mode; + var ABCHighlightRules = require("./abc_highlight_rules").ABCHighlightRules; +// TODO: pick appropriate fold mode + var FoldMode = require("./folding/cstyle").FoldMode; + + var Mode = function () { + this.HighlightRules = ABCHighlightRules; + this.foldingRules = new FoldMode(); + }; + oop.inherits(Mode, TextMode); + + (function () { + // this.lineCommentStart = ""%.*""; + // this.blockComment = {start: ""/*"", end: ""*/""}; + // Extra logic goes here. + this.$id = "ace/mode/abc" + }).call(Mode.prototype); + + exports.Mode = Mode; +}); \ No newline at end of file diff --git a/lib/ace/mode/abc_highlight_rules.js b/lib/ace/mode/abc_highlight_rules.js new file mode 100644 index 00000000..6ffe9c9b --- /dev/null +++ b/lib/ace/mode/abc_highlight_rules.js @@ -0,0 +1,114 @@ +/* This file was partially autogenerated from https://github.com/jimhawkridge/SublimeABC + + Modifications + + - more classes to express the abc semantic + - added syntax highlighting for Zupfnoter conventions (https://github.com/bwl21/zupfnoter) + - separate note pitch and note duration - even if it looks the same + + ***********************************************************************************************/ + + +define(function (require, exports, module) { + "use strict"; + + var oop = require("../lib/oop"); + var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + + var ABCHighlightRules = function () { + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + + this.$rules = { + start: [ + { + token: ['zupfnoter.information.comment.line.percentage', 'information.keyword', 'in formation.keyword.embedded'], + regex: '(%%%%)(hn\\.[a-z]*)(.*)', + comment: 'Instruction Comment' + }, + { + token: ['information.comment.line.percentage', 'information.keyword.embedded'], + regex: '(%%)(.*)', + comment: 'Instruction Comment' + }, + + { + token: 'comment.line.percentage', + regex: '%.*', + comment: 'Comments' + }, + + { + token: 'barline.keyword.operator', + regex: '[\\[:]*[|:][|\\]:]*(?:\\[?[0-9]+)?|\\[[0-9]+', + comment: 'Bar lines' + }, + { + token: ['information.keyword.embedded', 'information.argument.string.unquoted'], + regex: '(\\[[A-Za-z]:)([^\\]]*\\])', + comment: 'embedded Header lines' + }, + { + token: ['information.keyword', 'information.argument.string.unquoted'], + regex: '^([A-Za-z]:)([^%\\\\]*)', + comment: 'Header lines' + }, + { + token: ['text', 'entity.name.function', 'string.unquoted', 'text'], + regex: '(\\[)([A-Z]:)(.*?)(\\])', + comment: 'Inline fields' + }, + { + token: ['accent.constant.language', 'pitch.constant.numeric', 'duration.constant.numeric'], + regex: '([\\^=_]*)([A-Ga-gz][,\']*)([0-9]*/*[><0-9]*)', + comment: 'Notes' + }, + { + token: 'zupfnoter.jumptarget.string.quoted', + regex: '[\\"!]\\^\\:.*?[\\"!]', + comment: 'Zupfnoter jumptarget' + }, { + token: 'zupfnoter.goto.string.quoted', + regex: '[\\"!]\\^\\@.*?[\\"!]', + comment: 'Zupfnoter goto' + }, + { + token: 'zupfnoter.annotation.string.quoted', + regex: '[\\"!]\\^\\!.*?[\\"!]', + comment: 'Zupfnoter annoation' + }, + { + token: 'zupfnoter.annotationref.string.quoted', + regex: '[\\"!]\\^\\#.*?[\\"!]', + comment: 'Zupfnoter annotation reference' + }, + { + token: 'chordname.string.quoted', + regex: '[\\"!]\\^.*?[\\"!]', + comment: 'abc chord' + }, + { + token: 'string.quoted', + regex: '[\\"!].*?[\\"!]', + comment: 'abc annotation' + } + + ] + }; + + // this.embedRules(JsonHighlightRules, "json-") + + this.normalizeRules(); + }; + + ABCHighlightRules.metaData = { + fileTypes: ['abc'], + name: 'ABC', + scopeName: 'text.abcnotation' + }; + + + oop.inherits(ABCHighlightRules, TextHighlightRules); + + exports.ABCHighlightRules = ABCHighlightRules; +}); diff --git a/lib/ace/mode/actionscript.js b/lib/ace/mode/actionscript.js new file mode 100644 index 00000000..7daf2941 --- /dev/null +++ b/lib/ace/mode/actionscript.js @@ -0,0 +1,58 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * ***** END LICENSE BLOCK ***** */ + +/* + THIS FILE WAS AUTOGENERATED BY mode.tmpl.js +*/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var ActionScriptHighlightRules = require("./actionscript_highlight_rules").ActionScriptHighlightRules; +// TODO: pick appropriate fold mode +var FoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = ActionScriptHighlightRules; + this.foldingRules = new FoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.lineCommentStart = "//"; + this.blockComment = {start: "/*", end: "*/"}; + this.$id = "ace/mode/actionscript"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); \ No newline at end of file diff --git a/lib/ace/mode/actionscript_highlight_rules.js b/lib/ace/mode/actionscript_highlight_rules.js new file mode 100644 index 00000000..1f30d9c2 --- /dev/null +++ b/lib/ace/mode/actionscript_highlight_rules.js @@ -0,0 +1,141 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/* This file was autogenerated from tm bundles\actionscript.tmbundle\Syntaxes\ActionScript.plist (uuid: ) */ +/**************************************************************************************** + * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. * + * fileTypes * + ****************************************************************************************/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var ActionScriptHighlightRules = function() { + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + + this.$rules = { start: + [ { token: 'support.class.actionscript.2', + regex: '\\b(?:R(?:ecordset|DBMSResolver|adioButton(?:Group)?)|X(?:ML(?:Socket|Node|Connector)?|UpdateResolverDataHolder)|M(?:M(?:Save|Execute)|icrophoneMicrophone|o(?:use|vieClip(?:Loader)?)|e(?:nu(?:Bar)?|dia(?:Controller|Display|Playback))|ath)|B(?:yName|inding|utton)|S(?:haredObject|ystem|crollPane|t(?:yleSheet|age|ream)|ound|e(?:ndEvent|rviceObject)|OAPCall|lide)|N(?:umericStepper|et(?:stream|S(?:tream|ervices)|Connection|Debug(?:Config)?))|C(?:heckBox|o(?:ntextMenu(?:Item)?|okie|lor|m(?:ponentMixins|boBox))|ustomActions|lient|amera)|T(?:ypedValue|ext(?:Snapshot|Input|F(?:ield|ormat)|Area)|ree|AB)|Object|D(?:ownload|elta(?:Item|Packet)?|at(?:e(?:Chooser|Field)?|a(?:G(?:lue|rid)|Set|Type)))|U(?:RL|TC|IScrollBar)|P(?:opUpManager|endingCall|r(?:intJob|o(?:duct|gressBar)))|E(?:ndPoint|rror)|Video|Key|F(?:RadioButton|GridColumn|MessageBox|BarChart|S(?:croll(?:Bar|Pane)|tyleFormat|plitView)|orm|C(?:heckbox|omboBox|alendar)|unction|T(?:icker|ooltip(?:Lite)?|ree(?:Node)?)|IconButton|D(?:ataGrid|raggablePane)|P(?:ieChart|ushButton|ro(?:gressBar|mptBox))|L(?:i(?:stBox|neChart)|oadingBox)|AdvancedMessageBox)|W(?:indow|SDLURL|ebService(?:Connector)?)|L(?:ist|o(?:calConnection|ad(?:er|Vars)|g)|a(?:unch|bel))|A(?:sBroadcaster|cc(?:ordion|essibility)|S(?:Set(?:Native|PropFlags)|N(?:ew|ative)|C(?:onstructor|lamp(?:2)?)|InstanceOf)|pplication|lert|rray))\\b' }, + { token: 'support.function.actionscript.2', + regex: '\\b(?:s(?:h(?:ift|ow(?:GridLines|Menu|Border|Settings|Headers|ColumnHeaders|Today|Preferences)?|ad(?:ow|ePane))|c(?:hema|ale(?:X|Mode|Y|Content)|r(?:oll(?:Track|Drag)?|een(?:Resolution|Color|DPI)))|t(?:yleSheet|op(?:Drag|A(?:nimation|llSounds|gent))?|epSize|a(?:tus|rt(?:Drag|A(?:nimation|gent))?))|i(?:n|ze|lence(?:TimeOut|Level))|o(?:ngname|urce|rt(?:Items(?:By)?|On(?:HeaderRelease)?|able(?:Columns)?)?)|u(?:ppressInvalidCalls|bstr(?:ing)?)|p(?:li(?:ce|t)|aceCol(?:umnsEqually|lumnsEqually))|e(?:nd(?:DefaultPushButtonEvent|AndLoad)?|curity|t(?:R(?:GB|o(?:otNode|w(?:Height|Count))|esizable(?:Columns)?|a(?:nge|te))|G(?:ain|roupName)|X(?:AxisTitle)?|M(?:i(?:n(?:imum|utes)|lliseconds)|o(?:nth(?:Names)?|tionLevel|de)|ultilineMode|e(?:ssage|nu(?:ItemEnabled(?:At)?|EnabledAt)|dia)|a(?:sk|ximum))|B(?:u(?:tton(?:s|Width)|fferTime)|a(?:seTabIndex|ndwidthLimit|ckground))|S(?:howAsDisabled|croll(?:ing|Speed|Content|Target|P(?:osition|roperties)|barState|Location)|t(?:yle(?:Property)?|opOnFocus|at(?:us|e))|i(?:ze|lenceLevel)|ort(?:able(?:Columns)?|Function)|p(?:litterBarPosition|acing)|e(?:conds|lect(?:Multiple|ion(?:Required|Type)?|Style|Color|ed(?:Node(?:s)?|Cell|I(?:nd(?:ices|ex)|tem(?:s)?))?|able))|kin|m(?:oothness|allScroll))|H(?:ighlight(?:s|Color)|Scroll|o(?:urs|rizontal)|eader(?:Symbol|Height|Text|Property|Format|Width|Location)?|as(?:Shader|CloseBox))|Y(?:ear|AxisTitle)?|N(?:ode(?:Properties|ExpansionHandler)|ewTextFormat)|C(?:h(?:ildNodes|a(?:ngeHandler|rt(?:Title|EventHandler)))|o(?:ntent(?:Size)?|okie|lumns)|ell(?:Symbol|Data)|l(?:i(?:ckHandler|pboard)|oseHandler)|redentials)|T(?:ype(?:dVaule)?|i(?:tle(?:barHeight)?|p(?:Target|Offset)?|me(?:out(?:Handler)?)?)|oggle|extFormat|ransform)|I(?:s(?:Branch|Open)|n(?:terval|putProperty)|con(?:SymbolName)?|te(?:rator|m(?:ByKey|Symbol)))|Orientation|D(?:i(?:splay(?:Range|Graphics|Mode|Clip|Text|edMonth)|rection)|uration|e(?:pth(?:Below|To|Above)|fault(?:GatewayURL|Mappings|NodeIconSymbolName)|l(?:iveryMode|ay)|bug(?:ID)?)|a(?:yOfWeekNames|t(?:e(?:Filter)?|a(?:Mapping(?:s)?|Item(?:Text|Property|Format)|Provider|All(?:Height|Property|Format|Width))?))|ra(?:wConnectors|gContent))|U(?:se(?:Shadow|HandCursor|EchoSuppression|rInput|Fade)|TC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear))|P(?:osition|ercentComplete|an(?:e(?:M(?:inimumSize|aximumSize)|Size|Title))?|ro(?:pert(?:y(?:Data)?|iesAt)|gress))|E(?:nabled|dit(?:Handler|able)|xpand(?:NodeTrigger|erSymbolName))|V(?:Scroll|olume|alue(?:Source)?)|KeyFrameInterval|Quality|F(?:i(?:eld|rst(?:DayOfWeek|VisibleNode))|ocus|ullYear|ps|ade(?:InLength|OutLength)|rame(?:Color|Width))|Width|L(?:ine(?:Color|Weight)|o(?:opback|adTarget)|a(?:rgeScroll|bel(?:Source|Placement)?))|A(?:s(?:Boolean|String|Number)|n(?:yTypedValue|imation)|ctiv(?:e(?:State(?:Handler)?|Handler)|ateHandler)|utoH(?:ideScrollBar|eight)))?|paratorBefore|ek|lect(?:ion(?:Disabled|Unfocused)?|ed(?:Node(?:s)?|Child|I(?:nd(?:ices|ex)|tem(?:s)?)|Dat(?:e|a))?|able(?:Ranges)?)|rver(?:String)?)|kip|qrt|wapDepths|lice|aveToSharedObj|moothing)|h(?:scroll(?:Policy)?|tml(?:Text)?|i(?:t(?:Test(?:TextNearPos)?|Area)|de(?:BuiltInItems|Child)?|ghlight(?:2D|3D)?)|orizontal|e(?:ight|ader(?:Re(?:nderer|lease)|Height|Text))|P(?:osition|ageScrollSize)|a(?:s(?:childNodes|MP3|S(?:creen(?:Broadcast|Playback)|treaming(?:Video|Audio)|ort)|Next|OwnProperty|Pr(?:inting|evious)|EmbeddedVideo|VideoEncoder|A(?:ccesibility|udio(?:Encoder)?))|ndlerName)|LineScrollSize)|ye(?:sLabel|ar)|n(?:o(?:t|de(?:Name|Close|Type|Open|Value)|Label)|u(?:llValue|mChild(?:S(?:creens|lides)|ren|Forms))|e(?:w(?:Item|line|Value|LocationDialog)|xt(?:S(?:cene|ibling|lide)|TabIndex|Value|Frame)?)?|ame(?:s)?)|c(?:h(?:ildNodes|eck|a(?:nge(?:sPending)?|r(?:CodeAt|At))|r)|o(?:s|n(?:st(?:ant|ructor)|nect|c(?:urrency|at)|t(?:ent(?:Type|Path)?|ains|rol(?:Placement|lerPolicy))|denseWhite|version)|py|l(?:or|umn(?:Stretch|Name(?:s)?|Count))|m(?:p(?:onent|lete)|ment))|u(?:stomItems|ePoint(?:s)?|r(?:veTo|Value|rent(?:Slide|ChildSlide|Item|F(?:ocused(?:S(?:creen|lide)|Form)|ps))))|e(?:il|ll(?:Renderer|Press|Edit|Focus(?:In|Out)))|l(?:i(?:ck|ents)|o(?:se(?:Button|Pane)?|ne(?:Node)?)|ear(?:S(?:haredObjects|treams)|Timeout|Interval)?)|a(?:ncelLabel|tch|p(?:tion|abilities)|l(?:cFields|l(?:e(?:e|r))?))|reate(?:GatewayConnection|Menu|Se(?:rver|gment)|C(?:hild(?:AtDepth)?|l(?:ient|ass(?:ChildAtDepth|Object(?:AtDepth)?))|all)|Text(?:Node|Field)|Item|Object(?:AtDepth)?|PopUp|E(?:lement|mptyMovieClip)))|t(?:h(?:is|row)|ype(?:of|Name)?|i(?:tle(?:StyleDeclaration)?|me(?:out)?)|o(?:talTime|String|olTipText|p|UpperCase|ggle(?:HighQuality)?|Lo(?:caleString|werCase))|e(?:st|llTarget|xt(?:RightMargin|Bold|S(?:ize|elected)|Height|Color|I(?:ndent|talic)|Disabled|Underline|F(?:ield|ont)|Width|LeftMargin|Align)?)|a(?:n|rget(?:Path)?|b(?:Stops|Children|Index|Enabled|leName))|r(?:y|igger|ac(?:e|k(?:AsMenu)?)))|i(?:s(?:Running|Branch|NaN|Con(?:soleOpen|nected)|Toggled|Installed|Open|D(?:own|ebugger)|P(?:urchased|ro(?:totypeOf|pertyEnumerable))|Empty|F(?:inite|ullyPopulated)|Local|Active)|n(?:s(?:tall|ertBefore)|cludeDeltaPacketInfo|t|it(?:ialize|Component|Pod|A(?:pplication|gent))?|de(?:nt|terminate|x(?:InParent(?:Slide|Form)?|Of)?)|put|validate|finity|LocalInternetCache)?|con(?:F(?:ield|unction))?|t(?:e(?:ratorScrolled|m(?:s|RollO(?:ut|ver)|ClassName))|alic)|d3|p|fFrameLoaded|gnore(?:Case|White))|o(?:s|n(?:R(?:ollO(?:ut|ver)|e(?:s(?:ize|ult)|l(?:ease(?:Outside)?|aseOutside)))|XML|Mouse(?:Move|Down|Up|Wheel)|S(?:ync|croller|tatus|oundComplete|e(?:tFocus|lect(?:edItem)?))|N(?:oticeEvent|etworkChange)|C(?:hanged|onnect|l(?:ipEvent|ose))|ID3|D(?:isconnect|eactivate|ata|ragO(?:ut|ver))|Un(?:install|load)|P(?:aymentResult|ress)|EnterFrame|K(?:illFocus|ey(?:Down|Up))|Fault|Lo(?:ad|g)|A(?:ctiv(?:ity|ate)|ppSt(?:op|art)))?|pe(?:n|ration)|verLayChildren|kLabel|ldValue|r(?:d)?)|d(?:i(?:s(?:connect|play(?:Normal|ed(?:Month|Year)|Full)|able(?:Shader|d(?:Ranges|Days)|CloseBox|Events))|rection)|o(?:cTypeDecl|tall|Decoding|main|LazyDecoding)|u(?:plicateMovieClip|ration)|e(?:stroy(?:ChildAt|Object)|code|fault(?:PushButton(?:Enabled)?|KeydownHandler)?|l(?:ta(?:Packet(?:Changed)?)?|ete(?:PopUp|All)?)|blocking)|a(?:shBoardSave|yNames|ta(?:Provider)?|rkshadow)|r(?:opdown(?:Width)?|a(?:w|gO(?:ut|ver))))|u(?:se(?:Sort|HandCursor|Codepage|EchoSuppression)|n(?:shift|install|derline|escape|format|watch|lo(?:ck|ad(?:Movie(?:Num)?)?))|pdate(?:Results|Mode|I(?:nputProperties|tem(?:ByIndex)?)|P(?:acket|roperties)|View|AfterEvent)|rl)|join|p(?:ixelAspectRatio|o(?:sition|p|w)|u(?:sh|rge|blish)|ercen(?:tComplete|Loaded)|lay(?:head(?:Change|Time)|ing|Hidden|erType)?|a(?:ssword|use|r(?:se(?:XML|CSS|Int|Float)|ent(?:Node|Is(?:S(?:creen|lide)|Form))|ams))|r(?:int(?:Num|AsBitmap(?:Num)?)?|o(?:to(?:type)?|pert(?:y|ies)|gress)|e(?:ss|v(?:ious(?:S(?:ibling|lide)|Value)?|Scene|Frame)|ferred(?:Height|Width))))|e(?:scape|n(?:code(?:r)?|ter(?:Frame)?|dFill|able(?:Shader|d|CloseBox|Events))|dit(?:able|Field|LocationDialog)|v(?:ent|al(?:uate)?)|q|x(?:tended|p|ec(?:ute)?|actSettings)|m(?:phasized(?:StyleDeclaration)?|bedFonts))|v(?:i(?:sible|ewPod)|ScrollPolicy|o(?:id|lume)|ersion|P(?:osition|ageScrollSize)|a(?:l(?:idat(?:ionError|e(?:Property|ActivationKey)?)|ue(?:Of)?)|riable)|LineScrollSize)|k(?:ind|ey(?:Down|Up|Press|FrameInterval))|q(?:sort|uality)|f(?:scommand|i(?:n(?:d(?:Text|First|Last)?|ally)|eldInfo|lter(?:ed|Func)?|rst(?:Slide|Child|DayOfWeek|VisibleNode)?)|o(?:nt|cus(?:In|edCell|Out|Enabled)|r(?:egroundDisabled|mat(?:ter)?))|unctionName|ps|l(?:oor|ush)|ace|romCharCode)|w(?:i(?:th|dth)|ordWrap|atch|riteAccess)|l(?:t|i(?:st(?:Owner)?|ne(?:Style|To))|o(?:c(?:k|a(?:t(?:ion|eByld)|l(?:ToGlobal|FileReadDisable)))|opback|ad(?:Movie(?:Num)?|S(?:crollContent|ound)|ed|Variables(?:Num)?|Application)?|g(?:Changes)?)|e(?:ngth|ft(?:Margin)?|ading)?|a(?:st(?:Slide|Child|Index(?:Of)?)?|nguage|b(?:el(?:Placement|F(?:ield|unction))?|leField)))|a(?:s(?:scociate(?:Controller|Display)|in|pectRatio|function)|nd|c(?:ceptConnection|tiv(?:ityLevel|ePlayControl)|os)|t(?:t(?:ach(?:Movie|Sound|Video|Audio)|ributes)|an(?:2)?)|dd(?:header|RequestHeader|Menu(?:Item(?:At)?|At)?|Sort|Header|No(?:tice|de(?:At)?)|C(?:olumn(?:At)?|uePoint)|T(?:oLocalInternetCache|reeNode(?:At)?)|I(?:con|tem(?:s(?:At)?|At)?)|DeltaItem|P(?:od|age|roperty)|EventListener|View|FieldInfo|Listener|Animation)?|uto(?:Size|Play|KeyNav|Load)|pp(?:endChild|ly(?:Changes|Updates)?)|vHardwareDisable|fterLoaded|l(?:ternateRowColors|ign|l(?:ow(?:InsecureDomain|Domain)|Transitions(?:InDone|OutDone))|bum)|r(?:tist|row|g(?:uments|List))|gent|bs)|r(?:ight(?:Margin)?|o(?:ot(?:S(?:creen|lide)|Form)|und|w(?:Height|Count)|llO(?:ut|ver))|e(?:s(?:yncDepth|t(?:orePane|artAnimation|rict)|iz(?:e|able(?:Columns)?)|olveDelta|ult(?:s)?|ponse)|c(?:o(?:ncile(?:Results|Updates)|rd)|eive(?:Video|Audio))|draw|jectConnection|place(?:Sel|ItemAt|AllItems)?|ve(?:al(?:Child)?|rse)|quest(?:SizeChange|Payment)?|f(?:errer|resh(?:ScrollContent|Destinations|Pane|FromSources)?)|lease(?:Outside)?|ad(?:Only|Access)|gister(?:SkinElement|C(?:olor(?:Style|Name)|lass)|InheritingStyle|Proxy)|move(?:Range|M(?:ovieClip|enu(?:Item(?:At)?|At))|Background|Sort|No(?:tice|de(?:sAt|At)?)|C(?:olum(?:nAt|At)|uePoints)|T(?:extField|reeNode(?:At)?)|Item(?:At)?|Pod|EventListener|FromLocalInternetCache|Listener|All(?:C(?:olumns|uePoints)|Items)?))|a(?:ndom|te|dioDot))|g(?:t|oto(?:Slide|NextSlide|PreviousSlide|FirstSlide|LastSlide|And(?:Stop|Play))|e(?:nre|t(?:R(?:GB|o(?:otNode|wCount)|e(?:sizable|mote))|X(?:AxisTitle)?|M(?:i(?:n(?:imum(?:Size)?|utes)|lliseconds)|onth(?:Names)?|ultilineMode|e(?:ssage|nu(?:ItemAt|EnabledAt|At))|aximum(?:Size)?)|B(?:ytes(?:Total|Loaded)|ounds|utton(?:s|Width)|eginIndex|a(?:ndwidthLimit|ckground))|S(?:howAsDisabled|croll(?:ing|Speed|Content|Position|barState|Location)|t(?:yle(?:Names)?|opOnFocus|ate)|ize|o(?:urce|rtState)|p(?:litterBarPosition|acing)|e(?:conds|lect(?:Multiple|ion(?:Required|Type)|Style|ed(?:Node(?:s)?|Cell|Text|I(?:nd(?:ices|ex)|tem(?:s)?))?)|rvice)|moothness|WFVersion)|H(?:ighlight(?:s|Color)|ours|e(?:ight|ader(?:Height|Text|Property|Format|Width|Location)?)|as(?:Shader|CloseBox))|Y(?:ear|AxisTitle)?|N(?:o(?:tices|de(?:DisplayedAt|At))|um(?:Children|berAvailable)|e(?:wTextFormat|xtHighestDepth))|C(?:h(?:ild(?:S(?:creen|lide)|Nodes|Form|At)|artTitle)|o(?:n(?:tent|figInfo)|okie|de|unt|lumn(?:Names|Count|Index|At))|uePoint|ellIndex|loseHandler|a(?:ll|retIndex))|T(?:ypedValue|i(?:tle(?:barHeight)?|p(?:Target|Offset)?|me(?:stamp|zoneOffset|out(?:State|Handler)|r)?)|oggle|ext(?:Extent|Format)?|r(?:ee(?:NodeAt|Length)|ans(?:form|actionId)))|I(?:s(?:Branch|Open)|n(?:stanceAtDepth|d(?:icesByKey|exByKey))|con(?:SymbolName)?|te(?:rator|m(?:sByKey|By(?:Name|Key)|id|ID|At))|d)|O(?:utput(?:Parameter(?:s|ByName)?|Value(?:s)?)|peration|ri(?:entation|ginalCellData))|D(?:i(?:s(?:play(?:Range|Mode|Clip|Index|edMonth)|kUsage)|rection)|uration|e(?:pth|faultNodeIconSymbolName|l(?:taPacket|ay)|bug(?:Config|ID)?)|a(?:y(?:OfWeekNames)?|t(?:e|a(?:Mapping(?:s)?|Item(?:Text|Property|Format)|Label|All(?:Height|Property|Format|Width))?))|rawConnectors)|U(?:se(?:Shadow|HandCursor|rInput|Fade)|RL|TC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear))|P(?:o(?:sition|ds)|ercentComplete|a(?:n(?:e(?:M(?:inimums|aximums)|Height|Title|Width))?|rentNode)|r(?:operty(?:Name|Data)?|efer(?:ences|red(?:Height|Width))))|E(?:n(?:dIndex|abled)|ditingData|x(?:panderSymbolName|andNodeTrigger))|V(?:iewed(?:Pods|Applications)|olume|ersion|alue(?:Source)?)|F(?:i(?:eld|rst(?:DayOfWeek|VisibleNode))|o(?:ntList|cus)|ullYear|ade(?:InLength|OutLength)|rame(?:Color|Width))|Width|L(?:ine(?:Color|Weight)|o(?:cal|adTarget)|ength|a(?:stTabIndex|bel(?:Source)?))|A(?:s(?:cii|Boolean|String|Number)|n(?:yTypedValue|imation)|ctiv(?:eState(?:Handler)?|ateHandler)|utoH(?:ideScrollBar|eight)|llItems|gent))?)?|lobal(?:StyleFormat|ToLocal)?|ain|roupName)|x(?:updatePackety|mlDecl)?|m(?:y(?:MethodName|Call)|in(?:imum)?|o(?:nthNames|tion(?:TimeOut|Level)|de(?:lChanged)?|use(?:Move|O(?:ut|ver)|Down(?:Somewhere|Outside)?|Up(?:Somewhere)?|WheelEnabled)|ve(?:To)?)|u(?:ted|lti(?:pleS(?:imultaneousAllowed|elections)|line))|e(?:ssage|nu(?:Show|Hide)?|th(?:od)?|diaType)|a(?:nufacturer|tch|x(?:scroll|hscroll|imum|HPosition|Chars|VPosition)?)|b(?:substring|chr|ord|length))|b(?:ytes(?:Total|Loaded)|indFormat(?:Strings|Function)|o(?:ttom(?:Scroll)?|ld|rder(?:Color)?)|u(?:tton(?:Height|Width)|iltInItems|ffer(?:Time|Length)|llet)|e(?:foreApplyUpdates|gin(?:GradientFill|Fill))|lockIndent|a(?:ndwidth|ckground(?:Style|Color|Disabled)?)|roadcastMessage)|onHTTPStatus)\\b' }, + { token: 'support.constant.actionscript.2', + regex: '\\b(?:__proto__|__resolve|_accProps|_alpha|_changed|_currentframe|_droptarget|_flash|_focusrect|_framesloaded|_global|_height|_highquality|_level|_listeners|_lockroot|_name|_parent|_quality|_root|_rotation|_soundbuftime|_target|_totalframes|_url|_visible|_width|_x|_xmouse|_xscale|_y|_ymouse|_yscale)\\b' }, + { token: 'keyword.control.actionscript.2', + regex: '\\b(?:dynamic|extends|import|implements|interface|public|private|new|static|super|var|for|in|break|continue|while|do|return|if|else|case|switch)\\b' }, + { token: 'storage.type.actionscript.2', + regex: '\\b(?:Boolean|Number|String|Void)\\b' }, + { token: 'constant.language.actionscript.2', + regex: '\\b(?:null|undefined|true|false)\\b' }, + { token: 'constant.numeric.actionscript.2', + regex: '\\b(?:0(?:x|X)[0-9a-fA-F]*|(?:[0-9]+\\.?[0-9]*|\\.[0-9]+)(?:(?:e|E)(?:\\+|-)?[0-9]+)?)(?:L|l|UL|ul|u|U|F|f)?\\b' }, + { token: 'punctuation.definition.string.begin.actionscript.2', + regex: '"', + push: + [ { token: 'punctuation.definition.string.end.actionscript.2', + regex: '"', + next: 'pop' }, + { token: 'constant.character.escape.actionscript.2', + regex: '\\\\.' }, + { defaultToken: 'string.quoted.double.actionscript.2' } ] }, + { token: 'punctuation.definition.string.begin.actionscript.2', + regex: '\'', + push: + [ { token: 'punctuation.definition.string.end.actionscript.2', + regex: '\'', + next: 'pop' }, + { token: 'constant.character.escape.actionscript.2', + regex: '\\\\.' }, + { defaultToken: 'string.quoted.single.actionscript.2' } ] }, + { token: 'support.constant.actionscript.2', + regex: '\\b(?:BACKSPACE|CAPSLOCK|CONTROL|DELETEKEY|DOWN|END|ENTER|HOME|INSERT|LEFT|LN10|LN2|LOG10E|LOG2E|MAX_VALUE|MIN_VALUE|NEGATIVE_INFINITY|NaN|PGDN|PGUP|PI|POSITIVE_INFINITY|RIGHT|SPACE|SQRT1_2|SQRT2|UP)\\b' }, + { token: 'punctuation.definition.comment.actionscript.2', + regex: '/\\*', + push: + [ { token: 'punctuation.definition.comment.actionscript.2', + regex: '\\*/', + next: 'pop' }, + { defaultToken: 'comment.block.actionscript.2' } ] }, + { token: 'punctuation.definition.comment.actionscript.2', + regex: '//.*$', + push_: + [ { token: 'comment.line.double-slash.actionscript.2', + regex: '$', + next: 'pop' }, + { defaultToken: 'comment.line.double-slash.actionscript.2' } ] }, + { token: 'keyword.operator.actionscript.2', + regex: '\\binstanceof\\b' }, + { token: 'keyword.operator.symbolic.actionscript.2', + regex: '[-!%&*+=/?:]' }, + { token: + [ 'meta.preprocessor.actionscript.2', + 'punctuation.definition.preprocessor.actionscript.2', + 'meta.preprocessor.actionscript.2' ], + regex: '^([ \\t]*)(#)([a-zA-Z]+)' }, + { token: + [ 'storage.type.function.actionscript.2', + 'meta.function.actionscript.2', + 'entity.name.function.actionscript.2', + 'meta.function.actionscript.2', + 'punctuation.definition.parameters.begin.actionscript.2' ], + regex: '\\b(function)(\\s+)([a-zA-Z_]\\w*)(\\s*)(\\()', + push: + [ { token: 'punctuation.definition.parameters.end.actionscript.2', + regex: '\\)', + next: 'pop' }, + { token: 'variable.parameter.function.actionscript.2', + regex: '[^,)$]+' }, + { defaultToken: 'meta.function.actionscript.2' } ] }, + { token: + [ 'storage.type.class.actionscript.2', + 'meta.class.actionscript.2', + 'entity.name.type.class.actionscript.2', + 'meta.class.actionscript.2', + 'storage.modifier.extends.actionscript.2', + 'meta.class.actionscript.2', + 'entity.other.inherited-class.actionscript.2' ], + regex: '\\b(class)(\\s+)([a-zA-Z_](?:\\w|\\.)*)(?:(\\s+)(extends)(\\s+)([a-zA-Z_](?:\\w|\\.)*))?' } ] } + + this.normalizeRules(); +}; + +ActionScriptHighlightRules.metaData = { fileTypes: [ 'as' ], + keyEquivalent: '^~A', + name: 'ActionScript', + scopeName: 'source.actionscript.2' } + + +oop.inherits(ActionScriptHighlightRules, TextHighlightRules); + +exports.ActionScriptHighlightRules = ActionScriptHighlightRules; +}); \ No newline at end of file diff --git a/lib/ace/mode/ada.js b/lib/ace/mode/ada.js new file mode 100644 index 00000000..dc1dfa14 --- /dev/null +++ b/lib/ace/mode/ada.js @@ -0,0 +1,54 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var AdaHighlightRules = require("./ada_highlight_rules").AdaHighlightRules; +var Range = require("../range").Range; + +var Mode = function() { + this.HighlightRules = AdaHighlightRules; +}; +oop.inherits(Mode, TextMode); + +(function() { + + this.lineCommentStart = "--"; + + this.$id = "ace/mode/ada"; +}).call(Mode.prototype); + +exports.Mode = Mode; + +}); + diff --git a/lib/ace/mode/ada_highlight_rules.js b/lib/ace/mode/ada_highlight_rules.js new file mode 100644 index 00000000..b345966c --- /dev/null +++ b/lib/ace/mode/ada_highlight_rules.js @@ -0,0 +1,93 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var AdaHighlightRules = function() { +var keywords = "abort|else|new|return|abs|elsif|not|reverse|abstract|end|null|accept|entry|select|" + +"access|exception|of|separate|aliased|exit|or|some|all|others|subtype|and|for|out|synchronized|" + +"array|function|overriding|at|tagged|generic|package|task|begin|goto|pragma|terminate|" + +"body|private|then|if|procedure|type|case|in|protected|constant|interface|until|" + +"|is|raise|use|declare|range|delay|limited|record|when|delta|loop|rem|while|digits|renames|with|do|mod|requeue|xor"; + + var builtinConstants = ( + "true|false|null" + ); + + var builtinFunctions = ( + "count|min|max|avg|sum|rank|now|coalesce|main" + ); + + var keywordMapper = this.createKeywordMapper({ + "support.function": builtinFunctions, + "keyword": keywords, + "constant.language": builtinConstants + }, "identifier", true); + + this.$rules = { + "start" : [ { + token : "comment", + regex : "--.*$" + }, { + token : "string", // " string + regex : '".*?"' + }, { + token : "string", // ' string + regex : "'.*?'" + }, { + token : "constant.numeric", // float + regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" + }, { + token : keywordMapper, + regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + }, { + token : "keyword.operator", + regex : "\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|=" + }, { + token : "paren.lparen", + regex : "[\\(]" + }, { + token : "paren.rparen", + regex : "[\\)]" + }, { + token : "text", + regex : "\\s+" + } ] + }; +}; + +oop.inherits(AdaHighlightRules, TextHighlightRules); + +exports.AdaHighlightRules = AdaHighlightRules; +}); \ No newline at end of file diff --git a/lib/ace/mode/apache_conf.js b/lib/ace/mode/apache_conf.js new file mode 100644 index 00000000..2379b44b --- /dev/null +++ b/lib/ace/mode/apache_conf.js @@ -0,0 +1,62 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Contributor(s): + * + * + * + * ***** END LICENSE BLOCK ***** */ + +/* + THIS FILE WAS AUTOGENERATED BY mode.tmpl.js +*/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var ApacheConfHighlightRules = require("./apache_conf_highlight_rules").ApacheConfHighlightRules; +// TODO: pick appropriate fold mode +var FoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = ApacheConfHighlightRules; + this.foldingRules = new FoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.lineCommentStart = "#"; + this.$id = "ace/mode/apache_conf"; + // Extra logic goes here. +}).call(Mode.prototype); + +exports.Mode = Mode; +}); \ No newline at end of file diff --git a/lib/ace/mode/apache_conf_highlight_rules.js b/lib/ace/mode/apache_conf_highlight_rules.js new file mode 100644 index 00000000..c310612d --- /dev/null +++ b/lib/ace/mode/apache_conf_highlight_rules.js @@ -0,0 +1,231 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/* This file was autogenerated from https://raw.github.com/colinta/ApacheConf.tmLanguage/master/ApacheConf.tmLanguage (uuid: ) */ +/**************************************************************************************** + * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. * + * fileTypes * + ****************************************************************************************/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var ApacheConfHighlightRules = function() { + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + + this.$rules = { start: + [ { token: + [ 'punctuation.definition.comment.apacheconf', + 'comment.line.hash.ini', + 'comment.line.hash.ini' ], + regex: '^((?:\\s)*)(#)(.*$)' }, + { token: + [ 'punctuation.definition.tag.apacheconf', + 'entity.tag.apacheconf', + 'text', + 'string.value.apacheconf', + 'punctuation.definition.tag.apacheconf' ], + regex: '(<)(Proxy|ProxyMatch|IfVersion|Directory|DirectoryMatch|Files|FilesMatch|IfDefine|IfModule|Limit|LimitExcept|Location|LocationMatch|VirtualHost)(?:(\\s)(.+?))?(>)' }, + { token: + [ 'punctuation.definition.tag.apacheconf', + 'entity.tag.apacheconf', + 'punctuation.definition.tag.apacheconf' ], + regex: '()' }, + { token: + [ 'keyword.alias.apacheconf', 'text', + 'string.regexp.apacheconf', 'text', + 'string.replacement.apacheconf', 'text' ], + regex: '(Rewrite(?:Rule|Cond))(\\s+)(.+?)(\\s+)(.+?)($|\\s)' }, + { token: + [ 'keyword.alias.apacheconf', 'text', + 'entity.status.apacheconf', 'text', + 'string.regexp.apacheconf', 'text', + 'string.path.apacheconf', 'text' ], + regex: '(RedirectMatch)(?:(\\s+)(\\d\\d\\d|permanent|temp|seeother|gone))?(\\s+)(.+?)(\\s+)(?:(.+?)($|\\s))?' }, + { token: + [ 'keyword.alias.apacheconf', 'text', + 'entity.status.apacheconf', 'text', + 'string.path.apacheconf', 'text', + 'string.path.apacheconf', 'text' ], + regex: '(Redirect)(?:(\\s+)(\\d\\d\\d|permanent|temp|seeother|gone))?(\\s+)(.+?)(\\s+)(?:(.+?)($|\\s))?' }, + { token: + [ 'keyword.alias.apacheconf', 'text', + 'string.regexp.apacheconf', 'text', + 'string.path.apacheconf', 'text' ], + regex: '(ScriptAliasMatch|AliasMatch)(\\s+)(.+?)(\\s+)(?:(.+?)(\\s))?' }, + { token: + [ 'keyword.alias.apacheconf', 'text', + 'string.path.apacheconf', 'text', + 'string.path.apacheconf', 'text' ], + regex: '(RedirectPermanent|RedirectTemp|ScriptAlias|Alias)(\\s+)(.+?)(\\s+)(?:(.+?)($|\\s))?' }, + { token: 'keyword.core.apacheconf', + regex: '\\b(?:AcceptPathInfo|AccessFileName|AddDefaultCharset|AddOutputFilterByType|AllowEncodedSlashes|AllowOverride|AuthName|AuthType|CGIMapExtension|ContentDigest|DefaultType|DocumentRoot|EnableMMAP|EnableSendfile|ErrorDocument|ErrorLog|FileETag|ForceType|HostnameLookups|IdentityCheck|Include|KeepAlive|KeepAliveTimeout|LimitInternalRecursion|LimitRequestBody|LimitRequestFields|LimitRequestFieldSize|LimitRequestLine|LimitXMLRequestBody|LogLevel|MaxKeepAliveRequests|NameVirtualHost|Options|Require|RLimitCPU|RLimitMEM|RLimitNPROC|Satisfy|ScriptInterpreterSource|ServerAdmin|ServerAlias|ServerName|ServerPath|ServerRoot|ServerSignature|ServerTokens|SetHandler|SetInputFilter|SetOutputFilter|TimeOut|TraceEnable|UseCanonicalName)\\b' }, + { token: 'keyword.mpm.apacheconf', + regex: '\\b(?:AcceptMutex|AssignUserID|BS2000Account|ChildPerUserID|CoreDumpDirectory|EnableExceptionHook|Group|Listen|ListenBacklog|LockFile|MaxClients|MaxMemFree|MaxRequestsPerChild|MaxRequestsPerThread|MaxSpareServers|MaxSpareThreads|MaxThreads|MaxThreadsPerChild|MinSpareServers|MinSpareThreads|NumServers|PidFile|ReceiveBufferSize|ScoreBoardFile|SendBufferSize|ServerLimit|StartServers|StartThreads|ThreadLimit|ThreadsPerChild|ThreadStackSize|User|Win32DisableAcceptEx)\\b' }, + { token: 'keyword.access.apacheconf', + regex: '\\b(?:Allow|Deny|Order)\\b' }, + { token: 'keyword.actions.apacheconf', + regex: '\\b(?:Action|Script)\\b' }, + { token: 'keyword.alias.apacheconf', + regex: '\\b(?:Alias|AliasMatch|Redirect|RedirectMatch|RedirectPermanent|RedirectTemp|ScriptAlias|ScriptAliasMatch)\\b' }, + { token: 'keyword.auth.apacheconf', + regex: '\\b(?:AuthAuthoritative|AuthGroupFile|AuthUserFile)\\b' }, + { token: 'keyword.auth_anon.apacheconf', + regex: '\\b(?:Anonymous|Anonymous_Authoritative|Anonymous_LogEmail|Anonymous_MustGiveEmail|Anonymous_NoUserID|Anonymous_VerifyEmail)\\b' }, + { token: 'keyword.auth_dbm.apacheconf', + regex: '\\b(?:AuthDBMAuthoritative|AuthDBMGroupFile|AuthDBMType|AuthDBMUserFile)\\b' }, + { token: 'keyword.auth_digest.apacheconf', + regex: '\\b(?:AuthDigestAlgorithm|AuthDigestDomain|AuthDigestFile|AuthDigestGroupFile|AuthDigestNcCheck|AuthDigestNonceFormat|AuthDigestNonceLifetime|AuthDigestQop|AuthDigestShmemSize)\\b' }, + { token: 'keyword.auth_ldap.apacheconf', + regex: '\\b(?:AuthLDAPAuthoritative|AuthLDAPBindDN|AuthLDAPBindPassword|AuthLDAPCharsetConfig|AuthLDAPCompareDNOnServer|AuthLDAPDereferenceAliases|AuthLDAPEnabled|AuthLDAPFrontPageHack|AuthLDAPGroupAttribute|AuthLDAPGroupAttributeIsDN|AuthLDAPRemoteUserIsDN|AuthLDAPUrl)\\b' }, + { token: 'keyword.autoindex.apacheconf', + regex: '\\b(?:AddAlt|AddAltByEncoding|AddAltByType|AddDescription|AddIcon|AddIconByEncoding|AddIconByType|DefaultIcon|HeaderName|IndexIgnore|IndexOptions|IndexOrderDefault|ReadmeName)\\b' }, + { token: 'keyword.cache.apacheconf', + regex: '\\b(?:CacheDefaultExpire|CacheDisable|CacheEnable|CacheForceCompletion|CacheIgnoreCacheControl|CacheIgnoreHeaders|CacheIgnoreNoLastMod|CacheLastModifiedFactor|CacheMaxExpire)\\b' }, + { token: 'keyword.cern_meta.apacheconf', + regex: '\\b(?:MetaDir|MetaFiles|MetaSuffix)\\b' }, + { token: 'keyword.cgi.apacheconf', + regex: '\\b(?:ScriptLog|ScriptLogBuffer|ScriptLogLength)\\b' }, + { token: 'keyword.cgid.apacheconf', + regex: '\\b(?:ScriptLog|ScriptLogBuffer|ScriptLogLength|ScriptSock)\\b' }, + { token: 'keyword.charset_lite.apacheconf', + regex: '\\b(?:CharsetDefault|CharsetOptions|CharsetSourceEnc)\\b' }, + { token: 'keyword.dav.apacheconf', + regex: '\\b(?:Dav|DavDepthInfinity|DavMinTimeout|DavLockDB)\\b' }, + { token: 'keyword.deflate.apacheconf', + regex: '\\b(?:DeflateBufferSize|DeflateCompressionLevel|DeflateFilterNote|DeflateMemLevel|DeflateWindowSize)\\b' }, + { token: 'keyword.dir.apacheconf', + regex: '\\b(?:DirectoryIndex|DirectorySlash)\\b' }, + { token: 'keyword.disk_cache.apacheconf', + regex: '\\b(?:CacheDirLength|CacheDirLevels|CacheExpiryCheck|CacheGcClean|CacheGcDaily|CacheGcInterval|CacheGcMemUsage|CacheGcUnused|CacheMaxFileSize|CacheMinFileSize|CacheRoot|CacheSize|CacheTimeMargin)\\b' }, + { token: 'keyword.dumpio.apacheconf', + regex: '\\b(?:DumpIOInput|DumpIOOutput)\\b' }, + { token: 'keyword.env.apacheconf', + regex: '\\b(?:PassEnv|SetEnv|UnsetEnv)\\b' }, + { token: 'keyword.expires.apacheconf', + regex: '\\b(?:ExpiresActive|ExpiresByType|ExpiresDefault)\\b' }, + { token: 'keyword.ext_filter.apacheconf', + regex: '\\b(?:ExtFilterDefine|ExtFilterOptions)\\b' }, + { token: 'keyword.file_cache.apacheconf', + regex: '\\b(?:CacheFile|MMapFile)\\b' }, + { token: 'keyword.headers.apacheconf', + regex: '\\b(?:Header|RequestHeader)\\b' }, + { token: 'keyword.imap.apacheconf', + regex: '\\b(?:ImapBase|ImapDefault|ImapMenu)\\b' }, + { token: 'keyword.include.apacheconf', + regex: '\\b(?:SSIEndTag|SSIErrorMsg|SSIStartTag|SSITimeFormat|SSIUndefinedEcho|XBitHack)\\b' }, + { token: 'keyword.isapi.apacheconf', + regex: '\\b(?:ISAPIAppendLogToErrors|ISAPIAppendLogToQuery|ISAPICacheFile|ISAPIFakeAsync|ISAPILogNotSupported|ISAPIReadAheadBuffer)\\b' }, + { token: 'keyword.ldap.apacheconf', + regex: '\\b(?:LDAPCacheEntries|LDAPCacheTTL|LDAPConnectionTimeout|LDAPOpCacheEntries|LDAPOpCacheTTL|LDAPSharedCacheFile|LDAPSharedCacheSize|LDAPTrustedCA|LDAPTrustedCAType)\\b' }, + { token: 'keyword.log.apacheconf', + regex: '\\b(?:BufferedLogs|CookieLog|CustomLog|LogFormat|TransferLog|ForensicLog)\\b' }, + { token: 'keyword.mem_cache.apacheconf', + regex: '\\b(?:MCacheMaxObjectCount|MCacheMaxObjectSize|MCacheMaxStreamingBuffer|MCacheMinObjectSize|MCacheRemovalAlgorithm|MCacheSize)\\b' }, + { token: 'keyword.mime.apacheconf', + regex: '\\b(?:AddCharset|AddEncoding|AddHandler|AddInputFilter|AddLanguage|AddOutputFilter|AddType|DefaultLanguage|ModMimeUsePathInfo|MultiviewsMatch|RemoveCharset|RemoveEncoding|RemoveHandler|RemoveInputFilter|RemoveLanguage|RemoveOutputFilter|RemoveType|TypesConfig)\\b' }, + { token: 'keyword.misc.apacheconf', + regex: '\\b(?:ProtocolEcho|Example|AddModuleInfo|MimeMagicFile|CheckSpelling|ExtendedStatus|SuexecUserGroup|UserDir)\\b' }, + { token: 'keyword.negotiation.apacheconf', + regex: '\\b(?:CacheNegotiatedDocs|ForceLanguagePriority|LanguagePriority)\\b' }, + { token: 'keyword.nw_ssl.apacheconf', + regex: '\\b(?:NWSSLTrustedCerts|NWSSLUpgradeable|SecureListen)\\b' }, + { token: 'keyword.proxy.apacheconf', + regex: '\\b(?:AllowCONNECT|NoProxy|ProxyBadHeader|ProxyBlock|ProxyDomain|ProxyErrorOverride|ProxyFtpDirCharset|ProxyIOBufferSize|ProxyMaxForwards|ProxyPass|ProxyPassReverse|ProxyPreserveHost|ProxyReceiveBufferSize|ProxyRemote|ProxyRemoteMatch|ProxyRequests|ProxyTimeout|ProxyVia)\\b' }, + { token: 'keyword.rewrite.apacheconf', + regex: '\\b(?:RewriteBase|RewriteCond|RewriteEngine|RewriteLock|RewriteLog|RewriteLogLevel|RewriteMap|RewriteOptions|RewriteRule)\\b' }, + { token: 'keyword.setenvif.apacheconf', + regex: '\\b(?:BrowserMatch|BrowserMatchNoCase|SetEnvIf|SetEnvIfNoCase)\\b' }, + { token: 'keyword.so.apacheconf', + regex: '\\b(?:LoadFile|LoadModule)\\b' }, + { token: 'keyword.ssl.apacheconf', + regex: '\\b(?:SSLCACertificateFile|SSLCACertificatePath|SSLCARevocationFile|SSLCARevocationPath|SSLCertificateChainFile|SSLCertificateFile|SSLCertificateKeyFile|SSLCipherSuite|SSLEngine|SSLMutex|SSLOptions|SSLPassPhraseDialog|SSLProtocol|SSLProxyCACertificateFile|SSLProxyCACertificatePath|SSLProxyCARevocationFile|SSLProxyCARevocationPath|SSLProxyCipherSuite|SSLProxyEngine|SSLProxyMachineCertificateFile|SSLProxyMachineCertificatePath|SSLProxyProtocol|SSLProxyVerify|SSLProxyVerifyDepth|SSLRandomSeed|SSLRequire|SSLRequireSSL|SSLSessionCache|SSLSessionCacheTimeout|SSLUserName|SSLVerifyClient|SSLVerifyDepth)\\b' }, + { token: 'keyword.usertrack.apacheconf', + regex: '\\b(?:CookieDomain|CookieExpires|CookieName|CookieStyle|CookieTracking)\\b' }, + { token: 'keyword.vhost_alias.apacheconf', + regex: '\\b(?:VirtualDocumentRoot|VirtualDocumentRootIP|VirtualScriptAlias|VirtualScriptAliasIP)\\b' }, + { token: + [ 'keyword.php.apacheconf', + 'text', + 'entity.property.apacheconf', + 'text', + 'string.value.apacheconf', + 'text' ], + regex: '\\b(php_value|php_flag)\\b(?:(\\s+)(.+?)(?:(\\s+)(.+?))?)?(\\s)' }, + { token: + [ 'punctuation.variable.apacheconf', + 'variable.env.apacheconf', + 'variable.misc.apacheconf', + 'punctuation.variable.apacheconf' ], + regex: '(%\\{)(?:(HTTP_USER_AGENT|HTTP_REFERER|HTTP_COOKIE|HTTP_FORWARDED|HTTP_HOST|HTTP_PROXY_CONNECTION|HTTP_ACCEPT|REMOTE_ADDR|REMOTE_HOST|REMOTE_PORT|REMOTE_USER|REMOTE_IDENT|REQUEST_METHOD|SCRIPT_FILENAME|PATH_INFO|QUERY_STRING|AUTH_TYPE|DOCUMENT_ROOT|SERVER_ADMIN|SERVER_NAME|SERVER_ADDR|SERVER_PORT|SERVER_PROTOCOL|SERVER_SOFTWARE|TIME_YEAR|TIME_MON|TIME_DAY|TIME_HOUR|TIME_MIN|TIME_SEC|TIME_WDAY|TIME|API_VERSION|THE_REQUEST|REQUEST_URI|REQUEST_FILENAME|IS_SUBREQ|HTTPS)|(.*?))(\\})' }, + { token: [ 'entity.mime-type.apacheconf', 'text' ], + regex: '\\b((?:text|image|application|video|audio)/.+?)(\\s)' }, + { token: 'entity.helper.apacheconf', + regex: '\\b(?:from|unset|set|on|off)\\b', + caseInsensitive: true }, + { token: 'constant.integer.apacheconf', regex: '\\b\\d+\\b' }, + { token: + [ 'text', + 'punctuation.definition.flag.apacheconf', + 'string.flag.apacheconf', + 'punctuation.definition.flag.apacheconf', + 'text' ], + regex: '(\\s)(\\[)(.*?)(\\])(\\s)' } ] } + + this.normalizeRules(); +}; + +ApacheConfHighlightRules.metaData = { fileTypes: + [ 'conf', + 'CONF', + 'htaccess', + 'HTACCESS', + 'htgroups', + 'HTGROUPS', + 'htpasswd', + 'HTPASSWD', + '.htaccess', + '.HTACCESS', + '.htgroups', + '.HTGROUPS', + '.htpasswd', + '.HTPASSWD' ], + name: 'Apache Conf', + scopeName: 'source.apacheconf' } + + +oop.inherits(ApacheConfHighlightRules, TextHighlightRules); + +exports.ApacheConfHighlightRules = ApacheConfHighlightRules; +}); \ No newline at end of file diff --git a/lib/ace/mode/applescript.js b/lib/ace/mode/applescript.js new file mode 100644 index 00000000..81bc3533 --- /dev/null +++ b/lib/ace/mode/applescript.js @@ -0,0 +1,55 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var Tokenizer = require("../tokenizer").Tokenizer; +var AppleScriptHighlightRules = require("./applescript_highlight_rules").AppleScriptHighlightRules; +// TODO: pick appropriate fold mode +var FoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = AppleScriptHighlightRules; + this.foldingRules = new FoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.lineCommentStart = "--"; + this.blockComment = {start: "(*", end: "*)"}; + this.$id = "ace/mode/applescript"; + // Extra logic goes here. +}).call(Mode.prototype); + +exports.Mode = Mode; +}); diff --git a/lib/ace/mode/applescript_highlight_rules.js b/lib/ace/mode/applescript_highlight_rules.js new file mode 100644 index 00000000..d830d780 --- /dev/null +++ b/lib/ace/mode/applescript_highlight_rules.js @@ -0,0 +1,139 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var AppleScriptHighlightRules = function() { + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + var keywords = ( + "about|above|after|against|and|around|as|at|back|before|beginning|" + + "behind|below|beneath|beside|between|but|by|considering|" + + "contain|contains|continue|copy|div|does|eighth|else|end|equal|" + + "equals|error|every|exit|fifth|first|for|fourth|from|front|" + + "get|given|global|if|ignoring|in|into|is|it|its|last|local|me|" + + "middle|mod|my|ninth|not|of|on|onto|or|over|prop|property|put|ref|" + + "reference|repeat|returning|script|second|set|seventh|since|" + + "sixth|some|tell|tenth|that|the|then|third|through|thru|" + + "timeout|times|to|transaction|try|until|where|while|whose|with|without" + ); + + var builtinConstants = ( + "AppleScript|false|linefeed|return|pi|quote|result|space|tab|true" + ); + + var builtinFunctions = ( + "activate|beep|count|delay|launch|log|offset|read|round|run|say|" + + "summarize|write" + ); + + var builtinTypes = ( + "alias|application|boolean|class|constant|date|file|integer|list|" + + "number|real|record|string|text|character|characters|contents|day|" + + "frontmost|id|item|length|month|name|paragraph|paragraphs|rest|" + + "reverse|running|time|version|weekday|word|words|year" + ); + + var keywordMapper = this.createKeywordMapper({ + "support.function": builtinFunctions, + "constant.language": builtinConstants, + "support.type": builtinTypes, + "keyword": keywords + }, "identifier"); + + this.$rules = { + "start": [ + { + token: "comment", + regex: "--.*$" + }, + { + token : "comment", // multi line comment + regex : "\\(\\*", + next : "comment" + }, + { + token: "string", // " string + regex: '".*?"' + }, + { + token: "support.type", + regex: '\\b(POSIX file|POSIX path|(date|time) string|quoted form)\\b' + }, + { + token: "support.function", + regex: '\\b(clipboard info|the clipboard|info for|list (disks|folder)|' + + 'mount volume|path to|(close|open for) access|(get|set) eof|' + + 'current date|do shell script|get volume settings|random number|' + + 'set volume|system attribute|system info|time to GMT|' + + '(load|run|store) script|scripting components|' + + 'ASCII (character|number)|localized string|' + + 'choose (application|color|file|file name|' + + 'folder|from list|remote application|URL)|' + + 'display (alert|dialog))\\b|^\\s*return\\b' + }, + { + token: "constant.language", + regex: '\\b(text item delimiters|current application|missing value)\\b' + }, + { + token: "keyword", + regex: '\\b(apart from|aside from|instead of|out of|greater than|' + + "isn't|(doesn't|does not) (equal|come before|come after|contain)|" + + '(greater|less) than( or equal)?|(starts?|ends|begins?) with|' + + 'contained by|comes (before|after)|a (ref|reference))\\b' + }, + { + token: keywordMapper, + regex: "[a-zA-Z][a-zA-Z0-9_]*\\b" + } + ], + "comment": [ + { + token: "comment", // closing comment + regex: "\\*\\)", + next: "start" + }, { + defaultToken: "comment" + } + ] + } + + this.normalizeRules(); +}; + +oop.inherits(AppleScriptHighlightRules, TextHighlightRules); + +exports.AppleScriptHighlightRules = AppleScriptHighlightRules; +}); diff --git a/lib/ace/mode/asciidoc.js b/lib/ace/mode/asciidoc.js new file mode 100644 index 00000000..894d9763 --- /dev/null +++ b/lib/ace/mode/asciidoc.js @@ -0,0 +1,64 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var AsciidocHighlightRules = require("./asciidoc_highlight_rules").AsciidocHighlightRules; +var AsciidocFoldMode = require("./folding/asciidoc").FoldMode; + +var Mode = function() { + this.HighlightRules = AsciidocHighlightRules; + + this.foldingRules = new AsciidocFoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.type = "text"; + this.getNextLineIndent = function(state, line, tab) { + if (state == "listblock") { + var match = /^((?:.+)?)([-+*][ ]+)/.exec(line); + if (match) { + return new Array(match[1].length + 1).join(" ") + match[2]; + } else { + return ""; + } + } else { + return this.$getIndent(line); + } + }; + this.$id = "ace/mode/asciidoc"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); diff --git a/lib/ace/mode/asciidoc_highlight_rules.js b/lib/ace/mode/asciidoc_highlight_rules.js new file mode 100644 index 00000000..c0d1a305 --- /dev/null +++ b/lib/ace/mode/asciidoc_highlight_rules.js @@ -0,0 +1,234 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var AsciidocHighlightRules = function() { + var identifierRe = "[a-zA-Z\u00a1-\uffff]+\\b"; + + this.$rules = { + "start": [ + {token: "empty", regex: /$/}, + {token: "literal", regex: /^\.{4,}\s*$/, next: "listingBlock"}, + {token: "literal", regex: /^-{4,}\s*$/, next: "literalBlock"}, + {token: "string", regex: /^\+{4,}\s*$/, next: "passthroughBlock"}, + {token: "keyword", regex: /^={4,}\s*$/}, + {token: "text", regex: /^\s*$/}, + // immediately return to the start mode without matching anything + {token: "empty", regex: "", next: "dissallowDelimitedBlock"} + ], + + "dissallowDelimitedBlock": [ + {include: "paragraphEnd"}, + {token: "comment", regex: '^//.+$'}, + {token: "keyword", regex: "^(?:NOTE|TIP|IMPORTANT|WARNING|CAUTION):"}, + + {include: "listStart"}, + {token: "literal", regex: /^\s+.+$/, next: "indentedBlock"}, + {token: "empty", regex: "", next: "text"} + ], + + "paragraphEnd": [ + {token: "doc.comment", regex: /^\/{4,}\s*$/, next: "commentBlock"}, + {token: "tableBlock", regex: /^\s*[|!]=+\s*$/, next: "tableBlock"}, + // open block, ruller + {token: "keyword", regex: /^(?:--|''')\s*$/, next: "start"}, + {token: "option", regex: /^\[.*\]\s*$/, next: "start"}, + {token: "pageBreak", regex: /^>{3,}$/, next: "start"}, + {token: "literal", regex: /^\.{4,}\s*$/, next: "listingBlock"}, + {token: "titleUnderline", regex: /^(?:={2,}|-{2,}|~{2,}|\^{2,}|\+{2,})\s*$/, next: "start"}, + {token: "singleLineTitle", regex: /^={1,5}\s+\S.*$/, next: "start"}, + + {token: "otherBlock", regex: /^(?:\*{2,}|_{2,})\s*$/, next: "start"}, + // .optional title + {token: "optionalTitle", regex: /^\.[^.\s].+$/, next: "start"} + ], + + "listStart": [ + {token: "keyword", regex: /^\s*(?:\d+\.|[a-zA-Z]\.|[ixvmIXVM]+\)|\*{1,5}|-|\.{1,5})\s/, next: "listText"}, + {token: "meta.tag", regex: /^.+(?::{2,4}|;;)(?: |$)/, next: "listText"}, + {token: "support.function.list.callout", regex: /^(?:<\d+>|\d+>|>) /, next: "text"}, + // continuation + {token: "keyword", regex: /^\+\s*$/, next: "start"} + ], + + "text": [ + {token: ["link", "variable.language"], regex: /((?:https?:\/\/|ftp:\/\/|file:\/\/|mailto:|callto:)[^\s\[]+)(\[.*?\])/}, + {token: "link", regex: /(?:https?:\/\/|ftp:\/\/|file:\/\/|mailto:|callto:)[^\s\[]+/}, + {token: "link", regex: /\b[\w\.\/\-]+@[\w\.\/\-]+\b/}, + {include: "macros"}, + {include: "paragraphEnd"}, + {token: "literal", regex:/\+{3,}/, next:"smallPassthrough"}, + {token: "escape", regex: /\((?:C|TM|R)\)|\.{3}|->|<-|=>|<=|&#(?:\d+|x[a-fA-F\d]+);|(?: |^)--(?=\s+\S)/}, + {token: "escape", regex: /\\[_*'`+#]|\\{2}[_*'`+#]{2}/}, + {token: "keyword", regex: /\s\+$/}, + // any word + {token: "text", regex: identifierRe}, + {token: ["keyword", "string", "keyword"], + regex: /(<<[\w\d\-$]+,)(.*?)(>>|$)/}, + {token: "keyword", regex: /<<[\w\d\-$]+,?|>>/}, + {token: "constant.character", regex: /\({2,3}.*?\){2,3}/}, + // Anchor + {token: "keyword", regex: /\[\[.+?\]\]/}, + // bibliography + {token: "support", regex: /^\[{3}[\w\d =\-]+\]{3}/}, + + {include: "quotes"}, + // text block end + {token: "empty", regex: /^\s*$/, next: "start"} + ], + + "listText": [ + {include: "listStart"}, + {include: "text"} + ], + + "indentedBlock": [ + {token: "literal", regex: /^[\s\w].+$/, next: "indentedBlock"}, + {token: "literal", regex: "", next: "start"} + ], + + "listingBlock": [ + {token: "literal", regex: /^\.{4,}\s*$/, next: "dissallowDelimitedBlock"}, + {token: "constant.numeric", regex: '<\\d+>'}, + {token: "literal", regex: '[^<]+'}, + {token: "literal", regex: '<'} + ], + "literalBlock": [ + {token: "literal", regex: /^-{4,}\s*$/, next: "dissallowDelimitedBlock"}, + {token: "constant.numeric", regex: '<\\d+>'}, + {token: "literal", regex: '[^<]+'}, + {token: "literal", regex: '<'} + ], + "passthroughBlock": [ + {token: "literal", regex: /^\+{4,}\s*$/, next: "dissallowDelimitedBlock"}, + {token: "literal", regex: identifierRe + "|\\d+"}, + {include: "macros"}, + {token: "literal", regex: "."} + ], + + "smallPassthrough": [ + {token: "literal", regex: /[+]{3,}/, next: "dissallowDelimitedBlock"}, + {token: "literal", regex: /^\s*$/, next: "dissallowDelimitedBlock"}, + {token: "literal", regex: identifierRe + "|\\d+"}, + {include: "macros"} + ], + + "commentBlock": [ + {token: "doc.comment", regex: /^\/{4,}\s*$/, next: "dissallowDelimitedBlock"}, + {token: "doc.comment", regex: '^.*$'} + ], + "tableBlock": [ + {token: "tableBlock", regex: /^\s*\|={3,}\s*$/, next: "dissallowDelimitedBlock"}, + {token: "tableBlock", regex: /^\s*!={3,}\s*$/, next: "innerTableBlock"}, + {token: "tableBlock", regex: /\|/}, + {include: "text", noEscape: true} + ], + "innerTableBlock": [ + {token: "tableBlock", regex: /^\s*!={3,}\s*$/, next: "tableBlock"}, + {token: "tableBlock", regex: /^\s*|={3,}\s*$/, next: "dissallowDelimitedBlock"}, + {token: "tableBlock", regex: /\!/} + ], + "macros": [ + {token: "macro", regex: /{[\w\-$]+}/}, + {token: ["text", "string", "text", "constant.character", "text"], regex: /({)([\w\-$]+)(:)?(.+)?(})/}, + {token: ["text", "markup.list.macro", "keyword", "string"], regex: /(\w+)(footnote(?:ref)?::?)([^\s\[]+)?(\[.*?\])?/}, + {token: ["markup.list.macro", "keyword", "string"], regex: /([a-zA-Z\-][\w\.\/\-]*::?)([^\s\[]+)(\[.*?\])?/}, + {token: ["markup.list.macro", "keyword"], regex: /([a-zA-Z\-][\w\.\/\-]+::?)(\[.*?\])/}, + {token: "keyword", regex: /^:.+?:(?= |$)/} + ], + + "quotes": [ + {token: "string.italic", regex: /__[^_\s].*?__/}, + {token: "string.italic", regex: quoteRule("_")}, + + {token: "keyword.bold", regex: /\*\*[^*\s].*?\*\*/}, + {token: "keyword.bold", regex: quoteRule("\\*")}, + + {token: "literal", regex: quoteRule("\\+")}, + {token: "literal", regex: /\+\+[^+\s].*?\+\+/}, + {token: "literal", regex: /\$\$.+?\$\$/}, + {token: "literal", regex: quoteRule("`")}, + + {token: "keyword", regex: quoteRule("^")}, + {token: "keyword", regex: quoteRule("~")}, + {token: "keyword", regex: /##?/}, + {token: "keyword", regex: /(?:\B|^)``|\b''/} + ] + + }; + + function quoteRule(ch) { + var prefix = /\w/.test(ch) ? "\\b" : "(?:\\B|^)"; + return prefix + ch + "[^" + ch + "].*?" + ch + "(?![\\w*])"; + } + + //addQuoteBlock("text") + + var tokenMap = { + macro: "constant.character", + tableBlock: "doc.comment", + titleUnderline: "markup.heading", + singleLineTitle: "markup.heading", + pageBreak: "string", + option: "string.regexp", + otherBlock: "markup.list", + literal: "support.function", + optionalTitle: "constant.numeric", + escape: "constant.language.escape", + link: "markup.underline.list" + }; + + for (var state in this.$rules) { + var stateRules = this.$rules[state]; + for (var i = stateRules.length; i--; ) { + var rule = stateRules[i]; + if (rule.include || typeof rule == "string") { + var args = [i, 1].concat(this.$rules[rule.include || rule]); + if (rule.noEscape) { + args = args.filter(function(x) { + return !x.next; + }); + } + stateRules.splice.apply(stateRules, args); + } else if (rule.token in tokenMap) { + rule.token = tokenMap[rule.token]; + } + } + } +}; +oop.inherits(AsciidocHighlightRules, TextHighlightRules); + +exports.AsciidocHighlightRules = AsciidocHighlightRules; +}); diff --git a/lib/ace/mode/assembly_x86.js b/lib/ace/mode/assembly_x86.js new file mode 100644 index 00000000..d6343e80 --- /dev/null +++ b/lib/ace/mode/assembly_x86.js @@ -0,0 +1,56 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * ***** END LICENSE BLOCK ***** */ + +/* + THIS FILE WAS AUTOGENERATED BY mode.tmpl.js +*/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var AssemblyX86HighlightRules = require("./assembly_x86_highlight_rules").AssemblyX86HighlightRules; +var FoldMode = require("./folding/coffee").FoldMode; + +var Mode = function() { + this.HighlightRules = AssemblyX86HighlightRules; + this.foldingRules = new FoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.lineCommentStart = ";"; + this.$id = "ace/mode/assembly_x86"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); \ No newline at end of file diff --git a/lib/ace/mode/assembly_x86_highlight_rules.js b/lib/ace/mode/assembly_x86_highlight_rules.js new file mode 100644 index 00000000..247d1d0c --- /dev/null +++ b/lib/ace/mode/assembly_x86_highlight_rules.js @@ -0,0 +1,114 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/* This file was autogenerated from Assembly x86.tmLanguage (uuid: ) */ +/**************************************************************************************** + * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. * + * fileTypes * + ****************************************************************************************/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var AssemblyX86HighlightRules = function() { + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + + this.$rules = { start: + [ { token: 'keyword.control.assembly', + regex: '\\b(?:aaa|aad|aam|aas|adc|add|addpd|addps|addsd|addss|addsubpd|addsubps|aesdec|aesdeclast|aesenc|aesenclast|aesimc|aeskeygenassist|and|andpd|andps|andnpd|andnps|arpl|blendpd|blendps|blendvpd|blendvps|bound|bsf|bsr|bswap|bt|btc|btr|bts|cbw|cwde|cdqe|clc|cld|cflush|clts|cmc|cmov(?:n?e|ge?|ae?|le?|be?|n?o|n?z)|cmp|cmppd|cmpps|cmps|cnpsb|cmpsw|cmpsd|cmpsq|cmpss|cmpxchg|cmpxchg8b|cmpxchg16b|comisd|comiss|cpuid|crc32|cvtdq2pd|cvtdq2ps|cvtpd2dq|cvtpd2pi|cvtpd2ps|cvtpi2pd|cvtpi2ps|cvtps2dq|cvtps2pd|cvtps2pi|cvtsd2si|cvtsd2ss|cvts2sd|cvtsi2ss|cvtss2sd|cvtss2si|cvttpd2dq|cvtpd2pi|cvttps2dq|cvttps2pi|cvttps2dq|cvttps2pi|cvttsd2si|cvttss2si|cwd|cdq|cqo|daa|das|dec|div|divpd|divps|divsd|divss|dppd|dpps|emms|enter|extractps|f2xm1|fabs|fadd|faddp|fiadd|fbld|fbstp|fchs|fclex|fnclex|fcmov(?:n?e|ge?|ae?|le?|be?|n?o|n?z)|fcom|fcmop|fcompp|fcomi|fcomip|fucomi|fucomip|fcos|fdecstp|fdiv|fdivp|fidiv|fdivr|fdivrp|fidivr|ffree|ficom|ficomp|fild|fincstp|finit|fnint|fist|fistp|fisttp|fld|fld1|fldl2t|fldl2e|fldpi|fldlg2|fldln2|fldz|fldcw|fldenv|fmul|fmulp|fimul|fnop|fpatan|fprem|fprem1|fptan|frndint|frstor|fsave|fnsave|fscale|fsin|fsincos|fsqrt|fst|fstp|fstcw|fnstcw|fstenv|fnstenv|fsts|fnstsw|fsub|fsubp|fisub|fsubr|fsubrp|fisubr|ftst|fucom|fucomp|fucompp|fxam|fxch|fxrstor|fxsave|fxtract|fyl2x|fyl2xp1|haddpd|haddps|husbpd|hsubps|idiv|imul|in|inc|ins|insb|insw|insd|insertps|int|into|invd|invplg|invpcid|iret|iretd|iretq|lahf|lar|lddqu|ldmxcsr|lds|les|lfs|lgs|lss|lea|leave|lfence|lgdt|lidt|llgdt|lmsw|lock|lods|lodsb|lodsw|lodsd|lodsq|lsl|ltr|maskmovdqu|maskmovq|maxpd|maxps|maxsd|maxss|mfence|minpd|minps|minsd|minss|monitor|mov|movapd|movaps|movbe|movd|movq|movddup|movdqa|movdqu|movq2q|movhlps|movhpd|movhps|movlhps|movlpd|movlps|movmskpd|movmskps|movntdqa|movntdq|movnti|movntpd|movntps|movntq|movq|movq2dq|movs|movsb|movsw|movsd|movsq|movsd|movshdup|movsldup|movss|movsx|movsxd|movupd|movups|movzx|mpsadbw|mul|mulpd|mulps|mulsd|mulss|mwait|neg|not|or|orpd|orps|out|outs|outsb|outsw|outsd|pabsb|pabsw|pabsd|packsswb|packssdw|packusdw|packuswbpaddb|paddw|paddd|paddq|paddsb|paddsw|paddusb|paddusw|palignr|pand|pandn|pause|pavgb|pavgw|pblendvb|pblendw|pclmulqdq|pcmpeqb|pcmpeqw|pcmpeqd|pcmpeqq|pcmpestri|pcmpestrm|pcmptb|pcmptgw|pcmpgtd|pcmpgtq|pcmpistri|pcmpisrm|pextrb|pextrd|pextrq|pextrw|phaddw|phaddd|phaddsw|phinposuw|phsubw|phsubd|phsubsw|pinsrb|pinsrd|pinsrq|pinsrw|pmaddubsw|pmadddwd|pmaxsb|pmaxsd|pmaxsw|pmaxsw|pmaxub|pmaxud|pmaxuw|pminsb|pminsd|pminsw|pminub|pminud|pminuw|pmovmskb|pmovsx|pmovzx|pmuldq|pmulhrsw|pmulhuw|pmulhw|pmulld|pmullw|pmuludw|pop|popa|popad|popcnt|popf|popfd|popfq|por|prefetch|psadbw|pshufb|pshufd|pshufhw|pshuflw|pshufw|psignb|psignw|psignd|pslldq|psllw|pslld|psllq|psraw|psrad|psrldq|psrlw|psrld|psrlq|psubb|psubw|psubd|psubq|psubsb|psubsw|psubusb|psubusw|test|ptest|punpckhbw|punpckhwd|punpckhdq|punpckhddq|punpcklbw|punpcklwd|punpckldq|punpckldqd|push|pusha|pushad|pushf|pushfd|pxor|prcl|rcr|rol|ror|rcpps|rcpss|rdfsbase|rdgsbase|rdmsr|rdpmc|rdrand|rdtsc|rdtscp|rep|repe|repz|repne|repnz|roundpd|roundps|roundsd|roundss|rsm|rsqrps|rsqrtss|sahf|sal|sar|shl|shr|sbb|scas|scasb|scasw|scasd|set(?:n?e|ge?|ae?|le?|be?|n?o|n?z)|sfence|sgdt|shld|shrd|shufpd|shufps|sidt|sldt|smsw|sqrtpd|sqrtps|sqrtsd|sqrtss|stc|std|stmxcsr|stos|stosb|stosw|stosd|stosq|str|sub|subpd|subps|subsd|subss|swapgs|syscall|sysenter|sysexit|sysret|teset|ucomisd|ucomiss|ud2|unpckhpd|unpckhps|unpcklpd|unpcklps|vbroadcast|vcvtph2ps|vcvtp2sph|verr|verw|vextractf128|vinsertf128|vmaskmov|vpermilpd|vpermilps|vperm2f128|vtestpd|vtestps|vzeroall|vzeroupper|wait|fwait|wbinvd|wrfsbase|wrgsbase|wrmsr|xadd|xchg|xgetbv|xlat|xlatb|xor|xorpd|xorps|xrstor|xsave|xsaveopt|xsetbv|lzcnt|extrq|insertq|movntsd|movntss|vfmaddpd|vfmaddps|vfmaddsd|vfmaddss|vfmaddsubbpd|vfmaddsubps|vfmsubaddpd|vfmsubaddps|vfmsubpd|vfmsubps|vfmsubsd|vfnmaddpd|vfnmaddps|vfnmaddsd|vfnmaddss|vfnmsubpd|vfnmusbps|vfnmusbsd|vfnmusbss|cvt|xor|cli|sti|hlt|nop|lock|wait|enter|leave|ret|loop(?:n?e|n?z)?|call|j(?:mp|n?e|ge?|ae?|le?|be?|n?o|n?z))\\b', + caseInsensitive: true }, + { token: 'variable.parameter.register.assembly', + regex: '\\b(?:CS|DS|ES|FS|GS|SS|RAX|EAX|RBX|EBX|RCX|ECX|RDX|EDX|RCX|RIP|EIP|IP|RSP|ESP|SP|RSI|ESI|SI|RDI|EDI|DI|RFLAGS|EFLAGS|FLAGS|R8-15|(?:Y|X)MM(?:[0-9]|10|11|12|13|14|15)|(?:A|B|C|D)(?:X|H|L)|CR(?:[0-4]|DR(?:[0-7]|TR6|TR7|EFER)))\\b', + caseInsensitive: true }, + { token: 'constant.character.decimal.assembly', + regex: '\\b[0-9]+\\b' }, + { token: 'constant.character.hexadecimal.assembly', + regex: '\\b0x[A-F0-9]+\\b', + caseInsensitive: true }, + { token: 'constant.character.hexadecimal.assembly', + regex: '\\b[A-F0-9]+h\\b', + caseInsensitive: true }, + { token: 'string.assembly', regex: /'([^\\']|\\.)*'/ }, + { token: 'string.assembly', regex: /"([^\\"]|\\.)*"/ }, + { token: 'support.function.directive.assembly', + regex: '^\\[', + push: + [ { token: 'support.function.directive.assembly', + regex: '\\]$', + next: 'pop' }, + { defaultToken: 'support.function.directive.assembly' } ] }, + { token: + [ 'support.function.directive.assembly', + 'support.function.directive.assembly', + 'entity.name.function.assembly' ], + regex: '(^struc)( )([_a-zA-Z][_a-zA-Z0-9]*)' }, + { token: 'support.function.directive.assembly', + regex: '^endstruc\\b' }, + { token: + [ 'support.function.directive.assembly', + 'entity.name.function.assembly', + 'support.function.directive.assembly', + 'constant.character.assembly' ], + regex: '^(%macro )([_a-zA-Z][_a-zA-Z0-9]*)( )([0-9]+)' }, + { token: 'support.function.directive.assembly', + regex: '^%endmacro' }, + { token: + [ 'text', + 'support.function.directive.assembly', + 'text', + 'entity.name.function.assembly' ], + regex: '(\\s*)(%define|%xdefine|%idefine|%undef|%assign|%defstr|%strcat|%strlen|%substr|%00|%0|%rotate|%rep|%endrep|%include|\\$\\$|\\$|%unmacro|%if|%elif|%else|%endif|%(?:el)?ifdef|%(?:el)?ifmacro|%(?:el)?ifctx|%(?:el)?ifidn|%(?:el)?ifidni|%(?:el)?ifid|%(?:el)?ifnum|%(?:el)?ifstr|%(?:el)?iftoken|%(?:el)?ifempty|%(?:el)?ifenv|%pathsearch|%depend|%use|%push|%pop|%repl|%arg|%stacksize|%local|%error|%warning|%fatal|%line|%!|%comment|%endcomment|__NASM_VERSION_ID__|__NASM_VER__|__FILE__|__LINE__|__BITS__|__OUTPUT_FORMAT__|__DATE__|__TIME__|__DATE_NUM__|_TIME__NUM__|__UTC_DATE__|__UTC_TIME__|__UTC_DATE_NUM__|__UTC_TIME_NUM__|__POSIX_TIME__|__PASS__|ISTRUC|AT|IEND|BITS 16|BITS 32|BITS 64|USE16|USE32|__SECT__|ABSOLUTE|EXTERN|GLOBAL|COMMON|CPU|FLOAT)\\b( ?)((?:[_a-zA-Z][_a-zA-Z0-9]*)?)', + caseInsensitive: true }, + { token: 'support.function.directive.assembly', + regex: '\\b(?:d[bwdqtoy]|res[bwdqto]|equ|times|align|alignb|sectalign|section|ptr|byte|word|dword|qword|incbin)\\b', + caseInsensitive: true }, + { token: 'entity.name.function.assembly', regex: '^\\s*%%[\\w.]+?:$' }, + { token: 'entity.name.function.assembly', regex: '^\\s*%\\$[\\w.]+?:$' }, + { token: 'entity.name.function.assembly', regex: '^[\\w.]+?:' }, + { token: 'entity.name.function.assembly', regex: '^[\\w.]+?\\b' }, + { token: 'comment.assembly', regex: ';.*$' } ] + } + + this.normalizeRules(); +}; + +AssemblyX86HighlightRules.metaData = { fileTypes: [ 'asm' ], + name: 'Assembly x86', + scopeName: 'source.assembly' } + + +oop.inherits(AssemblyX86HighlightRules, TextHighlightRules); + +exports.AssemblyX86HighlightRules = AssemblyX86HighlightRules; +}); \ No newline at end of file diff --git a/lib/ace/mode/autohotkey.js b/lib/ace/mode/autohotkey.js new file mode 100644 index 00000000..d7093fd5 --- /dev/null +++ b/lib/ace/mode/autohotkey.js @@ -0,0 +1,57 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/* + THIS FILE WAS AUTOGENERATED BY mode.tmpl.js +*/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var AutoHotKeyHighlightRules = require("./autohotkey_highlight_rules").AutoHotKeyHighlightRules; +// TODO: pick appropriate fold mode +var FoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = AutoHotKeyHighlightRules; + this.foldingRules = new FoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.lineCommentStart = ";"; + this.blockComment = {start: "/*", end: "*/"}; + this.$id = "ace/mode/autohotkey"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); \ No newline at end of file diff --git a/lib/ace/mode/autohotkey_highlight_rules.js b/lib/ace/mode/autohotkey_highlight_rules.js new file mode 100644 index 00000000..45193996 --- /dev/null +++ b/lib/ace/mode/autohotkey_highlight_rules.js @@ -0,0 +1,107 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/* This file was autogenerated from C:\Users\LED\Desktop\AutoHotKey.tmLanguage (uuid: ) */ +/**************************************************************************************** + * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. * + * fileTypes * + ****************************************************************************************/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var AutoHotKeyHighlightRules = function() { + var autoItKeywords = 'And|ByRef|Case|Const|ContinueCase|ContinueLoop|Default|Dim|Do|Else|ElseIf|EndFunc|EndIf|EndSelect|EndSwitch|EndWith|Enum|Exit|ExitLoop|False|For|Func|Global|If|In|Local|Next|Not|Or|ReDim|Return|Select|Step|Switch|Then|To|True|Until|WEnd|While|With|' + + 'Abs|ACos|AdlibDisable|AdlibEnable|Asc|AscW|ASin|Assign|ATan|AutoItSetOption|AutoItWinGetTitle|AutoItWinSetTitle|Beep|Binary|BinaryLen|BinaryMid|BinaryToString|BitAND|BitNOT|BitOR|BitRotate|BitShift|BitXOR|BlockInput|Break|Call|CDTray|Ceiling|Chr|ChrW|ClipGet|ClipPut|ConsoleRead|ConsoleWrite|ConsoleWriteError|ControlClick|ControlCommand|ControlDisable|ControlEnable|ControlFocus|ControlGetFocus|ControlGetHandle|ControlGetPos|ControlGetText|ControlHide|ControlListView|ControlMove|ControlSend|ControlSetText|ControlShow|ControlTreeView|Cos|Dec|DirCopy|DirCreate|DirGetSize|DirMove|DirRemove|DllCall|DllCallbackFree|DllCallbackGetPtr|DllCallbackRegister|DllClose|DllOpen|DllStructCreate|DllStructGetData|DllStructGetPtr|DllStructGetSize|DllStructSetData|DriveGetDrive|DriveGetFileSystem|DriveGetLabel|DriveGetSerial|DriveGetType|DriveMapAdd|DriveMapDel|DriveMapGet|DriveSetLabel|DriveSpaceFree|DriveSpaceTotal|DriveStatus|EnvGet|EnvSet|EnvUpdate|Eval|Execute|Exp|FileChangeDir|FileClose|FileCopy|FileCreateNTFSLink|FileCreateShortcut|FileDelete|FileExists|FileFindFirstFile|FileFindNextFile|FileGetAttrib|FileGetLongName|FileGetShortcut|FileGetShortName|FileGetSize|FileGetTime|FileGetVersion|FileInstall|FileMove|FileOpen|FileOpenDialog|FileRead|FileReadLine|FileRecycle|FileRecycleEmpty|FileSaveDialog|FileSelectFolder|FileSetAttrib|FileSetTime|FileWrite|FileWriteLine|Floor|FtpSetProxy|GUICreate|GUICtrlCreateAvi|GUICtrlCreateButton|GUICtrlCreateCheckbox|GUICtrlCreateCombo|GUICtrlCreateContextMenu|GUICtrlCreateDate|GUICtrlCreateDummy|GUICtrlCreateEdit|GUICtrlCreateGraphic|GUICtrlCreateGroup|GUICtrlCreateIcon|GUICtrlCreateInput|GUICtrlCreateLabel|GUICtrlCreateList|GUICtrlCreateListView|GUICtrlCreateListViewItem|GUICtrlCreateMenu|GUICtrlCreateMenuItem|GUICtrlCreateMonthCal|GUICtrlCreateObj|GUICtrlCreatePic|GUICtrlCreateProgress|GUICtrlCreateRadio|GUICtrlCreateSlider|GUICtrlCreateTab|GUICtrlCreateTabItem|GUICtrlCreateTreeView|GUICtrlCreateTreeViewItem|GUICtrlCreateUpdown|GUICtrlDelete|GUICtrlGetHandle|GUICtrlGetState|GUICtrlRead|GUICtrlRecvMsg|GUICtrlRegisterListViewSort|GUICtrlSendMsg|GUICtrlSendToDummy|GUICtrlSetBkColor|GUICtrlSetColor|GUICtrlSetCursor|GUICtrlSetData|GUICtrlSetFont|GUICtrlSetDefColor|GUICtrlSetDefBkColor|GUICtrlSetGraphic|GUICtrlSetImage|GUICtrlSetLimit|GUICtrlSetOnEvent|GUICtrlSetPos|GUICtrlSetResizing|GUICtrlSetState|GUICtrlSetStyle|GUICtrlSetTip|GUIDelete|GUIGetCursorInfo|GUIGetMsg|GUIGetStyle|GUIRegisterMsg|GUISetAccelerators()|GUISetBkColor|GUISetCoord|GUISetCursor|GUISetFont|GUISetHelp|GUISetIcon|GUISetOnEvent|GUISetState|GUISetStyle|GUIStartGroup|GUISwitch|Hex|HotKeySet|HttpSetProxy|HWnd|InetGet|InetGetSize|IniDelete|IniRead|IniReadSection|IniReadSectionNames|IniRenameSection|IniWrite|IniWriteSection|InputBox|Int|IsAdmin|IsArray|IsBinary|IsBool|IsDeclared|IsDllStruct|IsFloat|IsHWnd|IsInt|IsKeyword|IsNumber|IsObj|IsPtr|IsString|Log|MemGetStats|Mod|MouseClick|MouseClickDrag|MouseDown|MouseGetCursor|MouseGetPos|MouseMove|MouseUp|MouseWheel|MsgBox|Number|ObjCreate|ObjEvent|ObjGet|ObjName|Opt|Ping|PixelChecksum|PixelGetColor|PixelSearch|PluginClose|PluginOpen|ProcessClose|ProcessExists|ProcessGetStats|ProcessList|ProcessSetPriority|ProcessWait|ProcessWaitClose|ProgressOff|ProgressOn|ProgressSet|Ptr|Random|RegDelete|RegEnumKey|RegEnumVal|RegRead|RegWrite|Round|Run|RunAs|RunAsWait|RunWait|Send|SendKeepActive|SetError|SetExtended|ShellExecute|ShellExecuteWait|Shutdown|Sin|Sleep|SoundPlay|SoundSetWaveVolume|SplashImageOn|SplashOff|SplashTextOn|Sqrt|SRandom|StatusbarGetText|StderrRead|StdinWrite|StdioClose|StdoutRead|String|StringAddCR|StringCompare|StringFormat|StringInStr|StringIsAlNum|StringIsAlpha|StringIsASCII|StringIsDigit|StringIsFloat|StringIsInt|StringIsLower|StringIsSpace|StringIsUpper|StringIsXDigit|StringLeft|StringLen|StringLower|StringMid|StringRegExp|StringRegExpReplace|StringReplace|StringRight|StringSplit|StringStripCR|StringStripWS|StringToBinary|StringTrimLeft|StringTrimRight|StringUpper|Tan|TCPAccept|TCPCloseSocket|TCPConnect|TCPListen|TCPNameToIP|TCPRecv|TCPSend|TCPShutdown|TCPStartup|TimerDiff|TimerInit|ToolTip|TrayCreateItem|TrayCreateMenu|TrayGetMsg|TrayItemDelete|TrayItemGetHandle|TrayItemGetState|TrayItemGetText|TrayItemSetOnEvent|TrayItemSetState|TrayItemSetText|TraySetClick|TraySetIcon|TraySetOnEvent|TraySetPauseIcon|TraySetState|TraySetToolTip|TrayTip|UBound|UDPBind|UDPCloseSocket|UDPOpen|UDPRecv|UDPSend|UDPShutdown|UDPStartup|VarGetType|WinActivate|WinActive|WinClose|WinExists|WinFlash|WinGetCaretPos|WinGetClassList|WinGetClientSize|WinGetHandle|WinGetPos|WinGetProcess|WinGetState|WinGetText|WinGetTitle|WinKill|WinList|WinMenuSelectItem|WinMinimizeAll|WinMinimizeAllUndo|WinMove|WinSetOnTop|WinSetState|WinSetTitle|WinSetTrans|WinWait|WinWaitActive|WinWaitClose|WinWaitNotActive|' + + 'ArrayAdd|ArrayBinarySearch|ArrayConcatenate|ArrayDelete|ArrayDisplay|ArrayFindAll|ArrayInsert|ArrayMax|ArrayMaxIndex|ArrayMin|ArrayMinIndex|ArrayPop|ArrayPush|ArrayReverse|ArraySearch|ArraySort|ArraySwap|ArrayToClip|ArrayToString|ArrayTrim|ChooseColor|ChooseFont|ClipBoard_ChangeChain|ClipBoard_Close|ClipBoard_CountFormats|ClipBoard_Empty|ClipBoard_EnumFormats|ClipBoard_FormatStr|ClipBoard_GetData|ClipBoard_GetDataEx|ClipBoard_GetFormatName|ClipBoard_GetOpenWindow|ClipBoard_GetOwner|ClipBoard_GetPriorityFormat|ClipBoard_GetSequenceNumber|ClipBoard_GetViewer|ClipBoard_IsFormatAvailable|ClipBoard_Open|ClipBoard_RegisterFormat|ClipBoard_SetData|ClipBoard_SetDataEx|ClipBoard_SetViewer|ClipPutFile|ColorConvertHSLtoRGB|ColorConvertRGBtoHSL|ColorGetBlue|ColorGetGreen|ColorGetRed|Date_Time_CompareFileTime|Date_Time_DOSDateTimeToArray|Date_Time_DOSDateTimeToFileTime|Date_Time_DOSDateTimeToStr|Date_Time_DOSDateToArray|Date_Time_DOSDateToStr|Date_Time_DOSTimeToArray|Date_Time_DOSTimeToStr|Date_Time_EncodeFileTime|Date_Time_EncodeSystemTime|Date_Time_FileTimeToArray|Date_Time_FileTimeToDOSDateTime|Date_Time_FileTimeToLocalFileTime|Date_Time_FileTimeToStr|Date_Time_FileTimeToSystemTime|Date_Time_GetFileTime|Date_Time_GetLocalTime|Date_Time_GetSystemTime|Date_Time_GetSystemTimeAdjustment|Date_Time_GetSystemTimeAsFileTime|Date_Time_GetSystemTimes|Date_Time_GetTickCount|Date_Time_GetTimeZoneInformation|Date_Time_LocalFileTimeToFileTime|Date_Time_SetFileTime|Date_Time_SetLocalTime|Date_Time_SetSystemTime|Date_Time_SetSystemTimeAdjustment|Date_Time_SetTimeZoneInformation|Date_Time_SystemTimeToArray|Date_Time_SystemTimeToDateStr|Date_Time_SystemTimeToDateTimeStr|Date_Time_SystemTimeToFileTime|Date_Time_SystemTimeToTimeStr|Date_Time_SystemTimeToTzSpecificLocalTime|Date_Time_TzSpecificLocalTimeToSystemTime|DateAdd|DateDayOfWeek|DateDaysInMonth|DateDiff|DateIsLeapYear|DateIsValid|DateTimeFormat|DateTimeSplit|DateToDayOfWeek|DateToDayOfWeekISO|DateToDayValue|DateToMonth|DayValueToDate|DebugBugReportEnv|DebugOut|DebugSetup|Degree|EventLog__Backup|EventLog__Clear|EventLog__Close|EventLog__Count|EventLog__DeregisterSource|EventLog__Full|EventLog__Notify|EventLog__Oldest|EventLog__Open|EventLog__OpenBackup|EventLog__Read|EventLog__RegisterSource|EventLog__Report|FileCountLines|FileCreate|FileListToArray|FilePrint|FileReadToArray|FileWriteFromArray|FileWriteLog|FileWriteToLine|GDIPlus_ArrowCapCreate|GDIPlus_ArrowCapDispose|GDIPlus_ArrowCapGetFillState|GDIPlus_ArrowCapGetHeight|GDIPlus_ArrowCapGetMiddleInset|GDIPlus_ArrowCapGetWidth|GDIPlus_ArrowCapSetFillState|GDIPlus_ArrowCapSetHeight|GDIPlus_ArrowCapSetMiddleInset|GDIPlus_ArrowCapSetWidth|GDIPlus_BitmapCloneArea|GDIPlus_BitmapCreateFromFile|GDIPlus_BitmapCreateFromGraphics|GDIPlus_BitmapCreateFromHBITMAP|GDIPlus_BitmapCreateHBITMAPFromBitmap|GDIPlus_BitmapDispose|GDIPlus_BitmapLockBits|GDIPlus_BitmapUnlockBits|GDIPlus_BrushClone|GDIPlus_BrushCreateSolid|GDIPlus_BrushDispose|GDIPlus_BrushGetType|GDIPlus_CustomLineCapDispose|GDIPlus_Decoders|GDIPlus_DecodersGetCount|GDIPlus_DecodersGetSize|GDIPlus_Encoders|GDIPlus_EncodersGetCLSID|GDIPlus_EncodersGetCount|GDIPlus_EncodersGetParamList|GDIPlus_EncodersGetParamListSize|GDIPlus_EncodersGetSize|GDIPlus_FontCreate|GDIPlus_FontDispose|GDIPlus_FontFamilyCreate|GDIPlus_FontFamilyDispose|GDIPlus_GraphicsClear|GDIPlus_GraphicsCreateFromHDC|GDIPlus_GraphicsCreateFromHWND|GDIPlus_GraphicsDispose|GDIPlus_GraphicsDrawArc|GDIPlus_GraphicsDrawBezier|GDIPlus_GraphicsDrawClosedCurve|GDIPlus_GraphicsDrawCurve|GDIPlus_GraphicsDrawEllipse|GDIPlus_GraphicsDrawImage|GDIPlus_GraphicsDrawImageRect|GDIPlus_GraphicsDrawImageRectRect|GDIPlus_GraphicsDrawLine|GDIPlus_GraphicsDrawPie|GDIPlus_GraphicsDrawPolygon|GDIPlus_GraphicsDrawRect|GDIPlus_GraphicsDrawString|GDIPlus_GraphicsDrawStringEx|GDIPlus_GraphicsFillClosedCurve|GDIPlus_GraphicsFillEllipse|GDIPlus_GraphicsFillPie|GDIPlus_GraphicsFillRect|GDIPlus_GraphicsGetDC|GDIPlus_GraphicsGetSmoothingMode|GDIPlus_GraphicsMeasureString|GDIPlus_GraphicsReleaseDC|GDIPlus_GraphicsSetSmoothingMode|GDIPlus_GraphicsSetTransform|GDIPlus_ImageDispose|GDIPlus_ImageGetGraphicsContext|GDIPlus_ImageGetHeight|GDIPlus_ImageGetWidth|GDIPlus_ImageLoadFromFile|GDIPlus_ImageSaveToFile|GDIPlus_ImageSaveToFileEx|GDIPlus_MatrixCreate|GDIPlus_MatrixDispose|GDIPlus_MatrixRotate|GDIPlus_ParamAdd|GDIPlus_ParamInit|GDIPlus_PenCreate|GDIPlus_PenDispose|GDIPlus_PenGetAlignment|GDIPlus_PenGetColor|GDIPlus_PenGetCustomEndCap|GDIPlus_PenGetDashCap|GDIPlus_PenGetDashStyle|GDIPlus_PenGetEndCap|GDIPlus_PenGetWidth|GDIPlus_PenSetAlignment|GDIPlus_PenSetColor|GDIPlus_PenSetCustomEndCap|GDIPlus_PenSetDashCap|GDIPlus_PenSetDashStyle|GDIPlus_PenSetEndCap|GDIPlus_PenSetWidth|GDIPlus_RectFCreate|GDIPlus_Shutdown|GDIPlus_Startup|GDIPlus_StringFormatCreate|GDIPlus_StringFormatDispose|GetIP|GUICtrlAVI_Close|GUICtrlAVI_Create|GUICtrlAVI_Destroy|GUICtrlAVI_Open|GUICtrlAVI_OpenEx|GUICtrlAVI_Play|GUICtrlAVI_Seek|GUICtrlAVI_Show|GUICtrlAVI_Stop|GUICtrlButton_Click|GUICtrlButton_Create|GUICtrlButton_Destroy|GUICtrlButton_Enable|GUICtrlButton_GetCheck|GUICtrlButton_GetFocus|GUICtrlButton_GetIdealSize|GUICtrlButton_GetImage|GUICtrlButton_GetImageList|GUICtrlButton_GetState|GUICtrlButton_GetText|GUICtrlButton_GetTextMargin|GUICtrlButton_SetCheck|GUICtrlButton_SetFocus|GUICtrlButton_SetImage|GUICtrlButton_SetImageList|GUICtrlButton_SetSize|GUICtrlButton_SetState|GUICtrlButton_SetStyle|GUICtrlButton_SetText|GUICtrlButton_SetTextMargin|GUICtrlButton_Show|GUICtrlComboBox_AddDir|GUICtrlComboBox_AddString|GUICtrlComboBox_AutoComplete|GUICtrlComboBox_BeginUpdate|GUICtrlComboBox_Create|GUICtrlComboBox_DeleteString|GUICtrlComboBox_Destroy|GUICtrlComboBox_EndUpdate|GUICtrlComboBox_FindString|GUICtrlComboBox_FindStringExact|GUICtrlComboBox_GetComboBoxInfo|GUICtrlComboBox_GetCount|GUICtrlComboBox_GetCurSel|GUICtrlComboBox_GetDroppedControlRect|GUICtrlComboBox_GetDroppedControlRectEx|GUICtrlComboBox_GetDroppedState|GUICtrlComboBox_GetDroppedWidth|GUICtrlComboBox_GetEditSel|GUICtrlComboBox_GetEditText|GUICtrlComboBox_GetExtendedUI|GUICtrlComboBox_GetHorizontalExtent|GUICtrlComboBox_GetItemHeight|GUICtrlComboBox_GetLBText|GUICtrlComboBox_GetLBTextLen|GUICtrlComboBox_GetList|GUICtrlComboBox_GetListArray|GUICtrlComboBox_GetLocale|GUICtrlComboBox_GetLocaleCountry|GUICtrlComboBox_GetLocaleLang|GUICtrlComboBox_GetLocalePrimLang|GUICtrlComboBox_GetLocaleSubLang|GUICtrlComboBox_GetMinVisible|GUICtrlComboBox_GetTopIndex|GUICtrlComboBox_InitStorage|GUICtrlComboBox_InsertString|GUICtrlComboBox_LimitText|GUICtrlComboBox_ReplaceEditSel|GUICtrlComboBox_ResetContent|GUICtrlComboBox_SelectString|GUICtrlComboBox_SetCurSel|GUICtrlComboBox_SetDroppedWidth|GUICtrlComboBox_SetEditSel|GUICtrlComboBox_SetEditText|GUICtrlComboBox_SetExtendedUI|GUICtrlComboBox_SetHorizontalExtent|GUICtrlComboBox_SetItemHeight|GUICtrlComboBox_SetMinVisible|GUICtrlComboBox_SetTopIndex|GUICtrlComboBox_ShowDropDown|GUICtrlComboBoxEx_AddDir|GUICtrlComboBoxEx_AddString|GUICtrlComboBoxEx_BeginUpdate|GUICtrlComboBoxEx_Create|GUICtrlComboBoxEx_CreateSolidBitMap|GUICtrlComboBoxEx_DeleteString|GUICtrlComboBoxEx_Destroy|GUICtrlComboBoxEx_EndUpdate|GUICtrlComboBoxEx_FindStringExact|GUICtrlComboBoxEx_GetComboBoxInfo|GUICtrlComboBoxEx_GetComboControl|GUICtrlComboBoxEx_GetCount|GUICtrlComboBoxEx_GetCurSel|GUICtrlComboBoxEx_GetDroppedControlRect|GUICtrlComboBoxEx_GetDroppedControlRectEx|GUICtrlComboBoxEx_GetDroppedState|GUICtrlComboBoxEx_GetDroppedWidth|GUICtrlComboBoxEx_GetEditControl|GUICtrlComboBoxEx_GetEditSel|GUICtrlComboBoxEx_GetEditText|GUICtrlComboBoxEx_GetExtendedStyle|GUICtrlComboBoxEx_GetExtendedUI|GUICtrlComboBoxEx_GetImageList|GUICtrlComboBoxEx_GetItem|GUICtrlComboBoxEx_GetItemEx|GUICtrlComboBoxEx_GetItemHeight|GUICtrlComboBoxEx_GetItemImage|GUICtrlComboBoxEx_GetItemIndent|GUICtrlComboBoxEx_GetItemOverlayImage|GUICtrlComboBoxEx_GetItemParam|GUICtrlComboBoxEx_GetItemSelectedImage|GUICtrlComboBoxEx_GetItemText|GUICtrlComboBoxEx_GetItemTextLen|GUICtrlComboBoxEx_GetList|GUICtrlComboBoxEx_GetListArray|GUICtrlComboBoxEx_GetLocale|GUICtrlComboBoxEx_GetLocaleCountry|GUICtrlComboBoxEx_GetLocaleLang|GUICtrlComboBoxEx_GetLocalePrimLang|GUICtrlComboBoxEx_GetLocaleSubLang|GUICtrlComboBoxEx_GetMinVisible|GUICtrlComboBoxEx_GetTopIndex|GUICtrlComboBoxEx_InitStorage|GUICtrlComboBoxEx_InsertString|GUICtrlComboBoxEx_LimitText|GUICtrlComboBoxEx_ReplaceEditSel|GUICtrlComboBoxEx_ResetContent|GUICtrlComboBoxEx_SetCurSel|GUICtrlComboBoxEx_SetDroppedWidth|GUICtrlComboBoxEx_SetEditSel|GUICtrlComboBoxEx_SetEditText|GUICtrlComboBoxEx_SetExtendedStyle|GUICtrlComboBoxEx_SetExtendedUI|GUICtrlComboBoxEx_SetImageList|GUICtrlComboBoxEx_SetItem|GUICtrlComboBoxEx_SetItemEx|GUICtrlComboBoxEx_SetItemHeight|GUICtrlComboBoxEx_SetItemImage|GUICtrlComboBoxEx_SetItemIndent|GUICtrlComboBoxEx_SetItemOverlayImage|GUICtrlComboBoxEx_SetItemParam|GUICtrlComboBoxEx_SetItemSelectedImage|GUICtrlComboBoxEx_SetMinVisible|GUICtrlComboBoxEx_SetTopIndex|GUICtrlComboBoxEx_ShowDropDown|GUICtrlDTP_Create|GUICtrlDTP_Destroy|GUICtrlDTP_GetMCColor|GUICtrlDTP_GetMCFont|GUICtrlDTP_GetMonthCal|GUICtrlDTP_GetRange|GUICtrlDTP_GetRangeEx|GUICtrlDTP_GetSystemTime|GUICtrlDTP_GetSystemTimeEx|GUICtrlDTP_SetFormat|GUICtrlDTP_SetMCColor|GUICtrlDTP_SetMCFont|GUICtrlDTP_SetRange|GUICtrlDTP_SetRangeEx|GUICtrlDTP_SetSystemTime|GUICtrlDTP_SetSystemTimeEx|GUICtrlEdit_AppendText|GUICtrlEdit_BeginUpdate|GUICtrlEdit_CanUndo|GUICtrlEdit_CharFromPos|GUICtrlEdit_Create|GUICtrlEdit_Destroy|GUICtrlEdit_EmptyUndoBuffer|GUICtrlEdit_EndUpdate|GUICtrlEdit_Find|GUICtrlEdit_FmtLines|GUICtrlEdit_GetFirstVisibleLine|GUICtrlEdit_GetLimitText|GUICtrlEdit_GetLine|GUICtrlEdit_GetLineCount|GUICtrlEdit_GetMargins|GUICtrlEdit_GetModify|GUICtrlEdit_GetPasswordChar|GUICtrlEdit_GetRECT|GUICtrlEdit_GetRECTEx|GUICtrlEdit_GetSel|GUICtrlEdit_GetText|GUICtrlEdit_GetTextLen|GUICtrlEdit_HideBalloonTip|GUICtrlEdit_InsertText|GUICtrlEdit_LineFromChar|GUICtrlEdit_LineIndex|GUICtrlEdit_LineLength|GUICtrlEdit_LineScroll|GUICtrlEdit_PosFromChar|GUICtrlEdit_ReplaceSel|GUICtrlEdit_Scroll|GUICtrlEdit_SetLimitText|GUICtrlEdit_SetMargins|GUICtrlEdit_SetModify|GUICtrlEdit_SetPasswordChar|GUICtrlEdit_SetReadOnly|GUICtrlEdit_SetRECT|GUICtrlEdit_SetRECTEx|GUICtrlEdit_SetRECTNP|GUICtrlEdit_SetRectNPEx|GUICtrlEdit_SetSel|GUICtrlEdit_SetTabStops|GUICtrlEdit_SetText|GUICtrlEdit_ShowBalloonTip|GUICtrlEdit_Undo|GUICtrlHeader_AddItem|GUICtrlHeader_ClearFilter|GUICtrlHeader_ClearFilterAll|GUICtrlHeader_Create|GUICtrlHeader_CreateDragImage|GUICtrlHeader_DeleteItem|GUICtrlHeader_Destroy|GUICtrlHeader_EditFilter|GUICtrlHeader_GetBitmapMargin|GUICtrlHeader_GetImageList|GUICtrlHeader_GetItem|GUICtrlHeader_GetItemAlign|GUICtrlHeader_GetItemBitmap|GUICtrlHeader_GetItemCount|GUICtrlHeader_GetItemDisplay|GUICtrlHeader_GetItemFlags|GUICtrlHeader_GetItemFormat|GUICtrlHeader_GetItemImage|GUICtrlHeader_GetItemOrder|GUICtrlHeader_GetItemParam|GUICtrlHeader_GetItemRect|GUICtrlHeader_GetItemRectEx|GUICtrlHeader_GetItemText|GUICtrlHeader_GetItemWidth|GUICtrlHeader_GetOrderArray|GUICtrlHeader_GetUnicodeFormat|GUICtrlHeader_HitTest|GUICtrlHeader_InsertItem|GUICtrlHeader_Layout|GUICtrlHeader_OrderToIndex|GUICtrlHeader_SetBitmapMargin|GUICtrlHeader_SetFilterChangeTimeout|GUICtrlHeader_SetHotDivider|GUICtrlHeader_SetImageList|GUICtrlHeader_SetItem|GUICtrlHeader_SetItemAlign|GUICtrlHeader_SetItemBitmap|GUICtrlHeader_SetItemDisplay|GUICtrlHeader_SetItemFlags|GUICtrlHeader_SetItemFormat|GUICtrlHeader_SetItemImage|GUICtrlHeader_SetItemOrder|GUICtrlHeader_SetItemParam|GUICtrlHeader_SetItemText|GUICtrlHeader_SetItemWidth|GUICtrlHeader_SetOrderArray|GUICtrlHeader_SetUnicodeFormat|GUICtrlIpAddress_ClearAddress|GUICtrlIpAddress_Create|GUICtrlIpAddress_Destroy|GUICtrlIpAddress_Get|GUICtrlIpAddress_GetArray|GUICtrlIpAddress_GetEx|GUICtrlIpAddress_IsBlank|GUICtrlIpAddress_Set|GUICtrlIpAddress_SetArray|GUICtrlIpAddress_SetEx|GUICtrlIpAddress_SetFocus|GUICtrlIpAddress_SetFont|GUICtrlIpAddress_SetRange|GUICtrlIpAddress_ShowHide|GUICtrlListBox_AddFile|GUICtrlListBox_AddString|GUICtrlListBox_BeginUpdate|GUICtrlListBox_Create|GUICtrlListBox_DeleteString|GUICtrlListBox_Destroy|GUICtrlListBox_Dir|GUICtrlListBox_EndUpdate|GUICtrlListBox_FindInText|GUICtrlListBox_FindString|GUICtrlListBox_GetAnchorIndex|GUICtrlListBox_GetCaretIndex|GUICtrlListBox_GetCount|GUICtrlListBox_GetCurSel|GUICtrlListBox_GetHorizontalExtent|GUICtrlListBox_GetItemData|GUICtrlListBox_GetItemHeight|GUICtrlListBox_GetItemRect|GUICtrlListBox_GetItemRectEx|GUICtrlListBox_GetListBoxInfo|GUICtrlListBox_GetLocale|GUICtrlListBox_GetLocaleCountry|GUICtrlListBox_GetLocaleLang|GUICtrlListBox_GetLocalePrimLang|GUICtrlListBox_GetLocaleSubLang|GUICtrlListBox_GetSel|GUICtrlListBox_GetSelCount|GUICtrlListBox_GetSelItems|GUICtrlListBox_GetSelItemsText|GUICtrlListBox_GetText|GUICtrlListBox_GetTextLen|GUICtrlListBox_GetTopIndex|GUICtrlListBox_InitStorage|GUICtrlListBox_InsertString|GUICtrlListBox_ItemFromPoint|GUICtrlListBox_ReplaceString|GUICtrlListBox_ResetContent|GUICtrlListBox_SelectString|GUICtrlListBox_SelItemRange|GUICtrlListBox_SelItemRangeEx|GUICtrlListBox_SetAnchorIndex|GUICtrlListBox_SetCaretIndex|GUICtrlListBox_SetColumnWidth|GUICtrlListBox_SetCurSel|GUICtrlListBox_SetHorizontalExtent|GUICtrlListBox_SetItemData|GUICtrlListBox_SetItemHeight|GUICtrlListBox_SetLocale|GUICtrlListBox_SetSel|GUICtrlListBox_SetTabStops|GUICtrlListBox_SetTopIndex|GUICtrlListBox_Sort|GUICtrlListBox_SwapString|GUICtrlListBox_UpdateHScroll|GUICtrlListView_AddArray|GUICtrlListView_AddColumn|GUICtrlListView_AddItem|GUICtrlListView_AddSubItem|GUICtrlListView_ApproximateViewHeight|GUICtrlListView_ApproximateViewRect|GUICtrlListView_ApproximateViewWidth|GUICtrlListView_Arrange|GUICtrlListView_BeginUpdate|GUICtrlListView_CancelEditLabel|GUICtrlListView_ClickItem|GUICtrlListView_CopyItems|GUICtrlListView_Create|GUICtrlListView_CreateDragImage|GUICtrlListView_CreateSolidBitMap|GUICtrlListView_DeleteAllItems|GUICtrlListView_DeleteColumn|GUICtrlListView_DeleteItem|GUICtrlListView_DeleteItemsSelected|GUICtrlListView_Destroy|GUICtrlListView_DrawDragImage|GUICtrlListView_EditLabel|GUICtrlListView_EnableGroupView|GUICtrlListView_EndUpdate|GUICtrlListView_EnsureVisible|GUICtrlListView_FindInText|GUICtrlListView_FindItem|GUICtrlListView_FindNearest|GUICtrlListView_FindParam|GUICtrlListView_FindText|GUICtrlListView_GetBkColor|GUICtrlListView_GetBkImage|GUICtrlListView_GetCallbackMask|GUICtrlListView_GetColumn|GUICtrlListView_GetColumnCount|GUICtrlListView_GetColumnOrder|GUICtrlListView_GetColumnOrderArray|GUICtrlListView_GetColumnWidth|GUICtrlListView_GetCounterPage|GUICtrlListView_GetEditControl|GUICtrlListView_GetExtendedListViewStyle|GUICtrlListView_GetGroupInfo|GUICtrlListView_GetGroupViewEnabled|GUICtrlListView_GetHeader|GUICtrlListView_GetHotCursor|GUICtrlListView_GetHotItem|GUICtrlListView_GetHoverTime|GUICtrlListView_GetImageList|GUICtrlListView_GetISearchString|GUICtrlListView_GetItem|GUICtrlListView_GetItemChecked|GUICtrlListView_GetItemCount|GUICtrlListView_GetItemCut|GUICtrlListView_GetItemDropHilited|GUICtrlListView_GetItemEx|GUICtrlListView_GetItemFocused|GUICtrlListView_GetItemGroupID|GUICtrlListView_GetItemImage|GUICtrlListView_GetItemIndent|GUICtrlListView_GetItemParam|GUICtrlListView_GetItemPosition|GUICtrlListView_GetItemPositionX|GUICtrlListView_GetItemPositionY|GUICtrlListView_GetItemRect|GUICtrlListView_GetItemRectEx|GUICtrlListView_GetItemSelected|GUICtrlListView_GetItemSpacing|GUICtrlListView_GetItemSpacingX|GUICtrlListView_GetItemSpacingY|GUICtrlListView_GetItemState|GUICtrlListView_GetItemStateImage|GUICtrlListView_GetItemText|GUICtrlListView_GetItemTextArray|GUICtrlListView_GetItemTextString|GUICtrlListView_GetNextItem|GUICtrlListView_GetNumberOfWorkAreas|GUICtrlListView_GetOrigin|GUICtrlListView_GetOriginX|GUICtrlListView_GetOriginY|GUICtrlListView_GetOutlineColor|GUICtrlListView_GetSelectedColumn|GUICtrlListView_GetSelectedCount|GUICtrlListView_GetSelectedIndices|GUICtrlListView_GetSelectionMark|GUICtrlListView_GetStringWidth|GUICtrlListView_GetSubItemRect|GUICtrlListView_GetTextBkColor|GUICtrlListView_GetTextColor|GUICtrlListView_GetToolTips|GUICtrlListView_GetTopIndex|GUICtrlListView_GetUnicodeFormat|GUICtrlListView_GetView|GUICtrlListView_GetViewDetails|GUICtrlListView_GetViewLarge|GUICtrlListView_GetViewList|GUICtrlListView_GetViewRect|GUICtrlListView_GetViewSmall|GUICtrlListView_GetViewTile|GUICtrlListView_HideColumn|GUICtrlListView_HitTest|GUICtrlListView_InsertColumn|GUICtrlListView_InsertGroup|GUICtrlListView_InsertItem|GUICtrlListView_JustifyColumn|GUICtrlListView_MapIDToIndex|GUICtrlListView_MapIndexToID|GUICtrlListView_RedrawItems|GUICtrlListView_RegisterSortCallBack|GUICtrlListView_RemoveAllGroups|GUICtrlListView_RemoveGroup|GUICtrlListView_Scroll|GUICtrlListView_SetBkColor|GUICtrlListView_SetBkImage|GUICtrlListView_SetCallBackMask|GUICtrlListView_SetColumn|GUICtrlListView_SetColumnOrder|GUICtrlListView_SetColumnOrderArray|GUICtrlListView_SetColumnWidth|GUICtrlListView_SetExtendedListViewStyle|GUICtrlListView_SetGroupInfo|GUICtrlListView_SetHotItem|GUICtrlListView_SetHoverTime|GUICtrlListView_SetIconSpacing|GUICtrlListView_SetImageList|GUICtrlListView_SetItem|GUICtrlListView_SetItemChecked|GUICtrlListView_SetItemCount|GUICtrlListView_SetItemCut|GUICtrlListView_SetItemDropHilited|GUICtrlListView_SetItemEx|GUICtrlListView_SetItemFocused|GUICtrlListView_SetItemGroupID|GUICtrlListView_SetItemImage|GUICtrlListView_SetItemIndent|GUICtrlListView_SetItemParam|GUICtrlListView_SetItemPosition|GUICtrlListView_SetItemPosition32|GUICtrlListView_SetItemSelected|GUICtrlListView_SetItemState|GUICtrlListView_SetItemStateImage|GUICtrlListView_SetItemText|GUICtrlListView_SetOutlineColor|GUICtrlListView_SetSelectedColumn|GUICtrlListView_SetSelectionMark|GUICtrlListView_SetTextBkColor|GUICtrlListView_SetTextColor|GUICtrlListView_SetToolTips|GUICtrlListView_SetUnicodeFormat|GUICtrlListView_SetView|GUICtrlListView_SetWorkAreas|GUICtrlListView_SimpleSort|GUICtrlListView_SortItems|GUICtrlListView_SubItemHitTest|GUICtrlListView_UnRegisterSortCallBack|GUICtrlMenu_AddMenuItem|GUICtrlMenu_AppendMenu|GUICtrlMenu_CheckMenuItem|GUICtrlMenu_CheckRadioItem|GUICtrlMenu_CreateMenu|GUICtrlMenu_CreatePopup|GUICtrlMenu_DeleteMenu|GUICtrlMenu_DestroyMenu|GUICtrlMenu_DrawMenuBar|GUICtrlMenu_EnableMenuItem|GUICtrlMenu_FindItem|GUICtrlMenu_FindParent|GUICtrlMenu_GetItemBmp|GUICtrlMenu_GetItemBmpChecked|GUICtrlMenu_GetItemBmpUnchecked|GUICtrlMenu_GetItemChecked|GUICtrlMenu_GetItemCount|GUICtrlMenu_GetItemData|GUICtrlMenu_GetItemDefault|GUICtrlMenu_GetItemDisabled|GUICtrlMenu_GetItemEnabled|GUICtrlMenu_GetItemGrayed|GUICtrlMenu_GetItemHighlighted|GUICtrlMenu_GetItemID|GUICtrlMenu_GetItemInfo|GUICtrlMenu_GetItemRect|GUICtrlMenu_GetItemRectEx|GUICtrlMenu_GetItemState|GUICtrlMenu_GetItemStateEx|GUICtrlMenu_GetItemSubMenu|GUICtrlMenu_GetItemText|GUICtrlMenu_GetItemType|GUICtrlMenu_GetMenu|GUICtrlMenu_GetMenuBackground|GUICtrlMenu_GetMenuBarInfo|GUICtrlMenu_GetMenuContextHelpID|GUICtrlMenu_GetMenuData|GUICtrlMenu_GetMenuDefaultItem|GUICtrlMenu_GetMenuHeight|GUICtrlMenu_GetMenuInfo|GUICtrlMenu_GetMenuStyle|GUICtrlMenu_GetSystemMenu|GUICtrlMenu_InsertMenuItem|GUICtrlMenu_InsertMenuItemEx|GUICtrlMenu_IsMenu|GUICtrlMenu_LoadMenu|GUICtrlMenu_MapAccelerator|GUICtrlMenu_MenuItemFromPoint|GUICtrlMenu_RemoveMenu|GUICtrlMenu_SetItemBitmaps|GUICtrlMenu_SetItemBmp|GUICtrlMenu_SetItemBmpChecked|GUICtrlMenu_SetItemBmpUnchecked|GUICtrlMenu_SetItemChecked|GUICtrlMenu_SetItemData|GUICtrlMenu_SetItemDefault|GUICtrlMenu_SetItemDisabled|GUICtrlMenu_SetItemEnabled|GUICtrlMenu_SetItemGrayed|GUICtrlMenu_SetItemHighlighted|GUICtrlMenu_SetItemID|GUICtrlMenu_SetItemInfo|GUICtrlMenu_SetItemState|GUICtrlMenu_SetItemSubMenu|GUICtrlMenu_SetItemText|GUICtrlMenu_SetItemType|GUICtrlMenu_SetMenu|GUICtrlMenu_SetMenuBackground|GUICtrlMenu_SetMenuContextHelpID|GUICtrlMenu_SetMenuData|GUICtrlMenu_SetMenuDefaultItem|GUICtrlMenu_SetMenuHeight|GUICtrlMenu_SetMenuInfo|GUICtrlMenu_SetMenuStyle|GUICtrlMenu_TrackPopupMenu|GUICtrlMonthCal_Create|GUICtrlMonthCal_Destroy|GUICtrlMonthCal_GetColor|GUICtrlMonthCal_GetColorArray|GUICtrlMonthCal_GetCurSel|GUICtrlMonthCal_GetCurSelStr|GUICtrlMonthCal_GetFirstDOW|GUICtrlMonthCal_GetFirstDOWStr|GUICtrlMonthCal_GetMaxSelCount|GUICtrlMonthCal_GetMaxTodayWidth|GUICtrlMonthCal_GetMinReqHeight|GUICtrlMonthCal_GetMinReqRect|GUICtrlMonthCal_GetMinReqRectArray|GUICtrlMonthCal_GetMinReqWidth|GUICtrlMonthCal_GetMonthDelta|GUICtrlMonthCal_GetMonthRange|GUICtrlMonthCal_GetMonthRangeMax|GUICtrlMonthCal_GetMonthRangeMaxStr|GUICtrlMonthCal_GetMonthRangeMin|GUICtrlMonthCal_GetMonthRangeMinStr|GUICtrlMonthCal_GetMonthRangeSpan|GUICtrlMonthCal_GetRange|GUICtrlMonthCal_GetRangeMax|GUICtrlMonthCal_GetRangeMaxStr|GUICtrlMonthCal_GetRangeMin|GUICtrlMonthCal_GetRangeMinStr|GUICtrlMonthCal_GetSelRange|GUICtrlMonthCal_GetSelRangeMax|GUICtrlMonthCal_GetSelRangeMaxStr|GUICtrlMonthCal_GetSelRangeMin|GUICtrlMonthCal_GetSelRangeMinStr|GUICtrlMonthCal_GetToday|GUICtrlMonthCal_GetTodayStr|GUICtrlMonthCal_GetUnicodeFormat|GUICtrlMonthCal_HitTest|GUICtrlMonthCal_SetColor|GUICtrlMonthCal_SetCurSel|GUICtrlMonthCal_SetDayState|GUICtrlMonthCal_SetFirstDOW|GUICtrlMonthCal_SetMaxSelCount|GUICtrlMonthCal_SetMonthDelta|GUICtrlMonthCal_SetRange|GUICtrlMonthCal_SetSelRange|GUICtrlMonthCal_SetToday|GUICtrlMonthCal_SetUnicodeFormat|GUICtrlRebar_AddBand|GUICtrlRebar_AddToolBarBand|GUICtrlRebar_BeginDrag|GUICtrlRebar_Create|GUICtrlRebar_DeleteBand|GUICtrlRebar_Destroy|GUICtrlRebar_DragMove|GUICtrlRebar_EndDrag|GUICtrlRebar_GetBandBackColor|GUICtrlRebar_GetBandBorders|GUICtrlRebar_GetBandBordersEx|GUICtrlRebar_GetBandChildHandle|GUICtrlRebar_GetBandChildSize|GUICtrlRebar_GetBandCount|GUICtrlRebar_GetBandForeColor|GUICtrlRebar_GetBandHeaderSize|GUICtrlRebar_GetBandID|GUICtrlRebar_GetBandIdealSize|GUICtrlRebar_GetBandLength|GUICtrlRebar_GetBandLParam|GUICtrlRebar_GetBandMargins|GUICtrlRebar_GetBandMarginsEx|GUICtrlRebar_GetBandRect|GUICtrlRebar_GetBandRectEx|GUICtrlRebar_GetBandStyle|GUICtrlRebar_GetBandStyleBreak|GUICtrlRebar_GetBandStyleChildEdge|GUICtrlRebar_GetBandStyleFixedBMP|GUICtrlRebar_GetBandStyleFixedSize|GUICtrlRebar_GetBandStyleGripperAlways|GUICtrlRebar_GetBandStyleHidden|GUICtrlRebar_GetBandStyleHideTitle|GUICtrlRebar_GetBandStyleNoGripper|GUICtrlRebar_GetBandStyleTopAlign|GUICtrlRebar_GetBandStyleUseChevron|GUICtrlRebar_GetBandStyleVariableHeight|GUICtrlRebar_GetBandText|GUICtrlRebar_GetBarHeight|GUICtrlRebar_GetBKColor|GUICtrlRebar_GetColorScheme|GUICtrlRebar_GetRowCount|GUICtrlRebar_GetRowHeight|GUICtrlRebar_GetTextColor|GUICtrlRebar_GetToolTips|GUICtrlRebar_GetUnicodeFormat|GUICtrlRebar_HitTest|GUICtrlRebar_IDToIndex|GUICtrlRebar_MaximizeBand|GUICtrlRebar_MinimizeBand|GUICtrlRebar_MoveBand|GUICtrlRebar_SetBandBackColor|GUICtrlRebar_SetBandForeColor|GUICtrlRebar_SetBandHeaderSize|GUICtrlRebar_SetBandID|GUICtrlRebar_SetBandIdealSize|GUICtrlRebar_SetBandLength|GUICtrlRebar_SetBandLParam|GUICtrlRebar_SetBandStyle|GUICtrlRebar_SetBandStyleBreak|GUICtrlRebar_SetBandStyleChildEdge|GUICtrlRebar_SetBandStyleFixedBMP|GUICtrlRebar_SetBandStyleFixedSize|GUICtrlRebar_SetBandStyleGripperAlways|GUICtrlRebar_SetBandStyleHidden|GUICtrlRebar_SetBandStyleHideTitle|GUICtrlRebar_SetBandStyleNoGripper|GUICtrlRebar_SetBandStyleTopAlign|GUICtrlRebar_SetBandStyleUseChevron|GUICtrlRebar_SetBandStyleVariableHeight|GUICtrlRebar_SetBandText|GUICtrlRebar_SetBKColor|GUICtrlRebar_SetColorScheme|GUICtrlRebar_SetTextColor|GUICtrlRebar_SetToolTips|GUICtrlRebar_SetUnicodeFormat|GUICtrlRebar_ShowBand|GUICtrlSlider_ClearSel|GUICtrlSlider_ClearTics|GUICtrlSlider_Create|GUICtrlSlider_Destroy|GUICtrlSlider_GetBuddy|GUICtrlSlider_GetChannelRect|GUICtrlSlider_GetLineSize|GUICtrlSlider_GetNumTics|GUICtrlSlider_GetPageSize|GUICtrlSlider_GetPos|GUICtrlSlider_GetPTics|GUICtrlSlider_GetRange|GUICtrlSlider_GetRangeMax|GUICtrlSlider_GetRangeMin|GUICtrlSlider_GetSel|GUICtrlSlider_GetSelEnd|GUICtrlSlider_GetSelStart|GUICtrlSlider_GetThumbLength|GUICtrlSlider_GetThumbRect|GUICtrlSlider_GetThumbRectEx|GUICtrlSlider_GetTic|GUICtrlSlider_GetTicPos|GUICtrlSlider_GetToolTips|GUICtrlSlider_GetUnicodeFormat|GUICtrlSlider_SetBuddy|GUICtrlSlider_SetLineSize|GUICtrlSlider_SetPageSize|GUICtrlSlider_SetPos|GUICtrlSlider_SetRange|GUICtrlSlider_SetRangeMax|GUICtrlSlider_SetRangeMin|GUICtrlSlider_SetSel|GUICtrlSlider_SetSelEnd|GUICtrlSlider_SetSelStart|GUICtrlSlider_SetThumbLength|GUICtrlSlider_SetTic|GUICtrlSlider_SetTicFreq|GUICtrlSlider_SetTipSide|GUICtrlSlider_SetToolTips|GUICtrlSlider_SetUnicodeFormat|GUICtrlStatusBar_Create|GUICtrlStatusBar_Destroy|GUICtrlStatusBar_EmbedControl|GUICtrlStatusBar_GetBorders|GUICtrlStatusBar_GetBordersHorz|GUICtrlStatusBar_GetBordersRect|GUICtrlStatusBar_GetBordersVert|GUICtrlStatusBar_GetCount|GUICtrlStatusBar_GetHeight|GUICtrlStatusBar_GetIcon|GUICtrlStatusBar_GetParts|GUICtrlStatusBar_GetRect|GUICtrlStatusBar_GetRectEx|GUICtrlStatusBar_GetText|GUICtrlStatusBar_GetTextFlags|GUICtrlStatusBar_GetTextLength|GUICtrlStatusBar_GetTextLengthEx|GUICtrlStatusBar_GetTipText|GUICtrlStatusBar_GetUnicodeFormat|GUICtrlStatusBar_GetWidth|GUICtrlStatusBar_IsSimple|GUICtrlStatusBar_Resize|GUICtrlStatusBar_SetBkColor|GUICtrlStatusBar_SetIcon|GUICtrlStatusBar_SetMinHeight|GUICtrlStatusBar_SetParts|GUICtrlStatusBar_SetSimple|GUICtrlStatusBar_SetText|GUICtrlStatusBar_SetTipText|GUICtrlStatusBar_SetUnicodeFormat|GUICtrlStatusBar_ShowHide|GUICtrlTab_Create|GUICtrlTab_DeleteAllItems|GUICtrlTab_DeleteItem|GUICtrlTab_DeselectAll|GUICtrlTab_Destroy|GUICtrlTab_FindTab|GUICtrlTab_GetCurFocus|GUICtrlTab_GetCurSel|GUICtrlTab_GetDisplayRect|GUICtrlTab_GetDisplayRectEx|GUICtrlTab_GetExtendedStyle|GUICtrlTab_GetImageList|GUICtrlTab_GetItem|GUICtrlTab_GetItemCount|GUICtrlTab_GetItemImage|GUICtrlTab_GetItemParam|GUICtrlTab_GetItemRect|GUICtrlTab_GetItemRectEx|GUICtrlTab_GetItemState|GUICtrlTab_GetItemText|GUICtrlTab_GetRowCount|GUICtrlTab_GetToolTips|GUICtrlTab_GetUnicodeFormat|GUICtrlTab_HighlightItem|GUICtrlTab_HitTest|GUICtrlTab_InsertItem|GUICtrlTab_RemoveImage|GUICtrlTab_SetCurFocus|GUICtrlTab_SetCurSel|GUICtrlTab_SetExtendedStyle|GUICtrlTab_SetImageList|GUICtrlTab_SetItem|GUICtrlTab_SetItemImage|GUICtrlTab_SetItemParam|GUICtrlTab_SetItemSize|GUICtrlTab_SetItemState|GUICtrlTab_SetItemText|GUICtrlTab_SetMinTabWidth|GUICtrlTab_SetPadding|GUICtrlTab_SetToolTips|GUICtrlTab_SetUnicodeFormat|GUICtrlToolbar_AddBitmap|GUICtrlToolbar_AddButton|GUICtrlToolbar_AddButtonSep|GUICtrlToolbar_AddString|GUICtrlToolbar_ButtonCount|GUICtrlToolbar_CheckButton|GUICtrlToolbar_ClickAccel|GUICtrlToolbar_ClickButton|GUICtrlToolbar_ClickIndex|GUICtrlToolbar_CommandToIndex|GUICtrlToolbar_Create|GUICtrlToolbar_Customize|GUICtrlToolbar_DeleteButton|GUICtrlToolbar_Destroy|GUICtrlToolbar_EnableButton|GUICtrlToolbar_FindToolbar|GUICtrlToolbar_GetAnchorHighlight|GUICtrlToolbar_GetBitmapFlags|GUICtrlToolbar_GetButtonBitmap|GUICtrlToolbar_GetButtonInfo|GUICtrlToolbar_GetButtonInfoEx|GUICtrlToolbar_GetButtonParam|GUICtrlToolbar_GetButtonRect|GUICtrlToolbar_GetButtonRectEx|GUICtrlToolbar_GetButtonSize|GUICtrlToolbar_GetButtonState|GUICtrlToolbar_GetButtonStyle|GUICtrlToolbar_GetButtonText|GUICtrlToolbar_GetColorScheme|GUICtrlToolbar_GetDisabledImageList|GUICtrlToolbar_GetExtendedStyle|GUICtrlToolbar_GetHotImageList|GUICtrlToolbar_GetHotItem|GUICtrlToolbar_GetImageList|GUICtrlToolbar_GetInsertMark|GUICtrlToolbar_GetInsertMarkColor|GUICtrlToolbar_GetMaxSize|GUICtrlToolbar_GetMetrics|GUICtrlToolbar_GetPadding|GUICtrlToolbar_GetRows|GUICtrlToolbar_GetString|GUICtrlToolbar_GetStyle|GUICtrlToolbar_GetStyleAltDrag|GUICtrlToolbar_GetStyleCustomErase|GUICtrlToolbar_GetStyleFlat|GUICtrlToolbar_GetStyleList|GUICtrlToolbar_GetStyleRegisterDrop|GUICtrlToolbar_GetStyleToolTips|GUICtrlToolbar_GetStyleTransparent|GUICtrlToolbar_GetStyleWrapable|GUICtrlToolbar_GetTextRows|GUICtrlToolbar_GetToolTips|GUICtrlToolbar_GetUnicodeFormat|GUICtrlToolbar_HideButton|GUICtrlToolbar_HighlightButton|GUICtrlToolbar_HitTest|GUICtrlToolbar_IndexToCommand|GUICtrlToolbar_InsertButton|GUICtrlToolbar_InsertMarkHitTest|GUICtrlToolbar_IsButtonChecked|GUICtrlToolbar_IsButtonEnabled|GUICtrlToolbar_IsButtonHidden|GUICtrlToolbar_IsButtonHighlighted|GUICtrlToolbar_IsButtonIndeterminate|GUICtrlToolbar_IsButtonPressed|GUICtrlToolbar_LoadBitmap|GUICtrlToolbar_LoadImages|GUICtrlToolbar_MapAccelerator|GUICtrlToolbar_MoveButton|GUICtrlToolbar_PressButton|GUICtrlToolbar_SetAnchorHighlight|GUICtrlToolbar_SetBitmapSize|GUICtrlToolbar_SetButtonBitMap|GUICtrlToolbar_SetButtonInfo|GUICtrlToolbar_SetButtonInfoEx|GUICtrlToolbar_SetButtonParam|GUICtrlToolbar_SetButtonSize|GUICtrlToolbar_SetButtonState|GUICtrlToolbar_SetButtonStyle|GUICtrlToolbar_SetButtonText|GUICtrlToolbar_SetButtonWidth|GUICtrlToolbar_SetCmdID|GUICtrlToolbar_SetColorScheme|GUICtrlToolbar_SetDisabledImageList|GUICtrlToolbar_SetDrawTextFlags|GUICtrlToolbar_SetExtendedStyle|GUICtrlToolbar_SetHotImageList|GUICtrlToolbar_SetHotItem|GUICtrlToolbar_SetImageList|GUICtrlToolbar_SetIndent|GUICtrlToolbar_SetIndeterminate|GUICtrlToolbar_SetInsertMark|GUICtrlToolbar_SetInsertMarkColor|GUICtrlToolbar_SetMaxTextRows|GUICtrlToolbar_SetMetrics|GUICtrlToolbar_SetPadding|GUICtrlToolbar_SetParent|GUICtrlToolbar_SetRows|GUICtrlToolbar_SetStyle|GUICtrlToolbar_SetStyleAltDrag|GUICtrlToolbar_SetStyleCustomErase|GUICtrlToolbar_SetStyleFlat|GUICtrlToolbar_SetStyleList|GUICtrlToolbar_SetStyleRegisterDrop|GUICtrlToolbar_SetStyleToolTips|GUICtrlToolbar_SetStyleTransparent|GUICtrlToolbar_SetStyleWrapable|GUICtrlToolbar_SetToolTips|GUICtrlToolbar_SetUnicodeFormat|GUICtrlToolbar_SetWindowTheme|GUICtrlTreeView_Add|GUICtrlTreeView_AddChild|GUICtrlTreeView_AddChildFirst|GUICtrlTreeView_AddFirst|GUICtrlTreeView_BeginUpdate|GUICtrlTreeView_ClickItem|GUICtrlTreeView_Create|GUICtrlTreeView_CreateDragImage|GUICtrlTreeView_CreateSolidBitMap|GUICtrlTreeView_Delete|GUICtrlTreeView_DeleteAll|GUICtrlTreeView_DeleteChildren|GUICtrlTreeView_Destroy|GUICtrlTreeView_DisplayRect|GUICtrlTreeView_DisplayRectEx|GUICtrlTreeView_EditText|GUICtrlTreeView_EndEdit|GUICtrlTreeView_EndUpdate|GUICtrlTreeView_EnsureVisible|GUICtrlTreeView_Expand|GUICtrlTreeView_ExpandedOnce|GUICtrlTreeView_FindItem|GUICtrlTreeView_FindItemEx|GUICtrlTreeView_GetBkColor|GUICtrlTreeView_GetBold|GUICtrlTreeView_GetChecked|GUICtrlTreeView_GetChildCount|GUICtrlTreeView_GetChildren|GUICtrlTreeView_GetCount|GUICtrlTreeView_GetCut|GUICtrlTreeView_GetDropTarget|GUICtrlTreeView_GetEditControl|GUICtrlTreeView_GetExpanded|GUICtrlTreeView_GetFirstChild|GUICtrlTreeView_GetFirstItem|GUICtrlTreeView_GetFirstVisible|GUICtrlTreeView_GetFocused|GUICtrlTreeView_GetHeight|GUICtrlTreeView_GetImageIndex|GUICtrlTreeView_GetImageListIconHandle|GUICtrlTreeView_GetIndent|GUICtrlTreeView_GetInsertMarkColor|GUICtrlTreeView_GetISearchString|GUICtrlTreeView_GetItemByIndex|GUICtrlTreeView_GetItemHandle|GUICtrlTreeView_GetItemParam|GUICtrlTreeView_GetLastChild|GUICtrlTreeView_GetLineColor|GUICtrlTreeView_GetNext|GUICtrlTreeView_GetNextChild|GUICtrlTreeView_GetNextSibling|GUICtrlTreeView_GetNextVisible|GUICtrlTreeView_GetNormalImageList|GUICtrlTreeView_GetParentHandle|GUICtrlTreeView_GetParentParam|GUICtrlTreeView_GetPrev|GUICtrlTreeView_GetPrevChild|GUICtrlTreeView_GetPrevSibling|GUICtrlTreeView_GetPrevVisible|GUICtrlTreeView_GetScrollTime|GUICtrlTreeView_GetSelected|GUICtrlTreeView_GetSelectedImageIndex|GUICtrlTreeView_GetSelection|GUICtrlTreeView_GetSiblingCount|GUICtrlTreeView_GetState|GUICtrlTreeView_GetStateImageIndex|GUICtrlTreeView_GetStateImageList|GUICtrlTreeView_GetText|GUICtrlTreeView_GetTextColor|GUICtrlTreeView_GetToolTips|GUICtrlTreeView_GetTree|GUICtrlTreeView_GetUnicodeFormat|GUICtrlTreeView_GetVisible|GUICtrlTreeView_GetVisibleCount|GUICtrlTreeView_HitTest|GUICtrlTreeView_HitTestEx|GUICtrlTreeView_HitTestItem|GUICtrlTreeView_Index|GUICtrlTreeView_InsertItem|GUICtrlTreeView_IsFirstItem|GUICtrlTreeView_IsParent|GUICtrlTreeView_Level|GUICtrlTreeView_SelectItem|GUICtrlTreeView_SelectItemByIndex|GUICtrlTreeView_SetBkColor|GUICtrlTreeView_SetBold|GUICtrlTreeView_SetChecked|GUICtrlTreeView_SetCheckedByIndex|GUICtrlTreeView_SetChildren|GUICtrlTreeView_SetCut|GUICtrlTreeView_SetDropTarget|GUICtrlTreeView_SetFocused|GUICtrlTreeView_SetHeight|GUICtrlTreeView_SetIcon|GUICtrlTreeView_SetImageIndex|GUICtrlTreeView_SetIndent|GUICtrlTreeView_SetInsertMark|GUICtrlTreeView_SetInsertMarkColor|GUICtrlTreeView_SetItemHeight|GUICtrlTreeView_SetItemParam|GUICtrlTreeView_SetLineColor|GUICtrlTreeView_SetNormalImageList|GUICtrlTreeView_SetScrollTime|GUICtrlTreeView_SetSelected|GUICtrlTreeView_SetSelectedImageIndex|GUICtrlTreeView_SetState|GUICtrlTreeView_SetStateImageIndex|GUICtrlTreeView_SetStateImageList|GUICtrlTreeView_SetText|GUICtrlTreeView_SetTextColor|GUICtrlTreeView_SetToolTips|GUICtrlTreeView_SetUnicodeFormat|GUICtrlTreeView_Sort|GUIImageList_Add|GUIImageList_AddBitmap|GUIImageList_AddIcon|GUIImageList_AddMasked|GUIImageList_BeginDrag|GUIImageList_Copy|GUIImageList_Create|GUIImageList_Destroy|GUIImageList_DestroyIcon|GUIImageList_DragEnter|GUIImageList_DragLeave|GUIImageList_DragMove|GUIImageList_Draw|GUIImageList_DrawEx|GUIImageList_Duplicate|GUIImageList_EndDrag|GUIImageList_GetBkColor|GUIImageList_GetIcon|GUIImageList_GetIconHeight|GUIImageList_GetIconSize|GUIImageList_GetIconSizeEx|GUIImageList_GetIconWidth|GUIImageList_GetImageCount|GUIImageList_GetImageInfoEx|GUIImageList_Remove|GUIImageList_ReplaceIcon|GUIImageList_SetBkColor|GUIImageList_SetIconSize|GUIImageList_SetImageCount|GUIImageList_Swap|GUIScrollBars_EnableScrollBar|GUIScrollBars_GetScrollBarInfoEx|GUIScrollBars_GetScrollBarRect|GUIScrollBars_GetScrollBarRGState|GUIScrollBars_GetScrollBarXYLineButton|GUIScrollBars_GetScrollBarXYThumbBottom|GUIScrollBars_GetScrollBarXYThumbTop|GUIScrollBars_GetScrollInfo|GUIScrollBars_GetScrollInfoEx|GUIScrollBars_GetScrollInfoMax|GUIScrollBars_GetScrollInfoMin|GUIScrollBars_GetScrollInfoPage|GUIScrollBars_GetScrollInfoPos|GUIScrollBars_GetScrollInfoTrackPos|GUIScrollBars_GetScrollPos|GUIScrollBars_GetScrollRange|GUIScrollBars_Init|GUIScrollBars_ScrollWindow|GUIScrollBars_SetScrollInfo|GUIScrollBars_SetScrollInfoMax|GUIScrollBars_SetScrollInfoMin|GUIScrollBars_SetScrollInfoPage|GUIScrollBars_SetScrollInfoPos|GUIScrollBars_SetScrollRange|GUIScrollBars_ShowScrollBar|GUIToolTip_Activate|GUIToolTip_AddTool|GUIToolTip_AdjustRect|GUIToolTip_BitsToTTF|GUIToolTip_Create|GUIToolTip_DelTool|GUIToolTip_Destroy|GUIToolTip_EnumTools|GUIToolTip_GetBubbleHeight|GUIToolTip_GetBubbleSize|GUIToolTip_GetBubbleWidth|GUIToolTip_GetCurrentTool|GUIToolTip_GetDelayTime|GUIToolTip_GetMargin|GUIToolTip_GetMarginEx|GUIToolTip_GetMaxTipWidth|GUIToolTip_GetText|GUIToolTip_GetTipBkColor|GUIToolTip_GetTipTextColor|GUIToolTip_GetTitleBitMap|GUIToolTip_GetTitleText|GUIToolTip_GetToolCount|GUIToolTip_GetToolInfo|GUIToolTip_HitTest|GUIToolTip_NewToolRect|GUIToolTip_Pop|GUIToolTip_PopUp|GUIToolTip_SetDelayTime|GUIToolTip_SetMargin|GUIToolTip_SetMaxTipWidth|GUIToolTip_SetTipBkColor|GUIToolTip_SetTipTextColor|GUIToolTip_SetTitle|GUIToolTip_SetToolInfo|GUIToolTip_SetWindowTheme|GUIToolTip_ToolExists|GUIToolTip_ToolToArray|GUIToolTip_TrackActivate|GUIToolTip_TrackPosition|GUIToolTip_TTFToBits|GUIToolTip_Update|GUIToolTip_UpdateTipText|HexToString|IE_Example|IE_Introduction|IE_VersionInfo|IEAction|IEAttach|IEBodyReadHTML|IEBodyReadText|IEBodyWriteHTML|IECreate|IECreateEmbedded|IEDocGetObj|IEDocInsertHTML|IEDocInsertText|IEDocReadHTML|IEDocWriteHTML|IEErrorHandlerDeRegister|IEErrorHandlerRegister|IEErrorNotify|IEFormElementCheckBoxSelect|IEFormElementGetCollection|IEFormElementGetObjByName|IEFormElementGetValue|IEFormElementOptionSelect|IEFormElementRadioSelect|IEFormElementSetValue|IEFormGetCollection|IEFormGetObjByName|IEFormImageClick|IEFormReset|IEFormSubmit|IEFrameGetCollection|IEFrameGetObjByName|IEGetObjById|IEGetObjByName|IEHeadInsertEventScript|IEImgClick|IEImgGetCollection|IEIsFrameSet|IELinkClickByIndex|IELinkClickByText|IELinkGetCollection|IELoadWait|IELoadWaitTimeout|IENavigate|IEPropertyGet|IEPropertySet|IEQuit|IETableGetCollection|IETableWriteToArray|IETagNameAllGetCollection|IETagNameGetCollection|Iif|INetExplorerCapable|INetGetSource|INetMail|INetSmtpMail|IsPressed|MathCheckDiv|Max|MemGlobalAlloc|MemGlobalFree|MemGlobalLock|MemGlobalSize|MemGlobalUnlock|MemMoveMemory|MemMsgBox|MemShowError|MemVirtualAlloc|MemVirtualAllocEx|MemVirtualFree|MemVirtualFreeEx|Min|MouseTrap|NamedPipes_CallNamedPipe|NamedPipes_ConnectNamedPipe|NamedPipes_CreateNamedPipe|NamedPipes_CreatePipe|NamedPipes_DisconnectNamedPipe|NamedPipes_GetNamedPipeHandleState|NamedPipes_GetNamedPipeInfo|NamedPipes_PeekNamedPipe|NamedPipes_SetNamedPipeHandleState|NamedPipes_TransactNamedPipe|NamedPipes_WaitNamedPipe|Net_Share_ConnectionEnum|Net_Share_FileClose|Net_Share_FileEnum|Net_Share_FileGetInfo|Net_Share_PermStr|Net_Share_ResourceStr|Net_Share_SessionDel|Net_Share_SessionEnum|Net_Share_SessionGetInfo|Net_Share_ShareAdd|Net_Share_ShareCheck|Net_Share_ShareDel|Net_Share_ShareEnum|Net_Share_ShareGetInfo|Net_Share_ShareSetInfo|Net_Share_StatisticsGetSvr|Net_Share_StatisticsGetWrk|Now|NowCalc|NowCalcDate|NowDate|NowTime|PathFull|PathMake|PathSplit|ProcessGetName|ProcessGetPriority|Radian|ReplaceStringInFile|RunDOS|ScreenCapture_Capture|ScreenCapture_CaptureWnd|ScreenCapture_SaveImage|ScreenCapture_SetBMPFormat|ScreenCapture_SetJPGQuality|ScreenCapture_SetTIFColorDepth|ScreenCapture_SetTIFCompression|Security__AdjustTokenPrivileges|Security__GetAccountSid|Security__GetLengthSid|Security__GetTokenInformation|Security__ImpersonateSelf|Security__IsValidSid|Security__LookupAccountName|Security__LookupAccountSid|Security__LookupPrivilegeValue|Security__OpenProcessToken|Security__OpenThreadToken|Security__OpenThreadTokenEx|Security__SetPrivilege|Security__SidToStringSid|Security__SidTypeStr|Security__StringSidToSid|SendMessage|SendMessageA|SetDate|SetTime|Singleton|SoundClose|SoundLength|SoundOpen|SoundPause|SoundPlay|SoundPos|SoundResume|SoundSeek|SoundStatus|SoundStop|SQLite_Changes|SQLite_Close|SQLite_Display2DResult|SQLite_Encode|SQLite_ErrCode|SQLite_ErrMsg|SQLite_Escape|SQLite_Exec|SQLite_FetchData|SQLite_FetchNames|SQLite_GetTable|SQLite_GetTable2d|SQLite_LastInsertRowID|SQLite_LibVersion|SQLite_Open|SQLite_Query|SQLite_QueryFinalize|SQLite_QueryReset|SQLite_QuerySingleRow|SQLite_SaveMode|SQLite_SetTimeout|SQLite_Shutdown|SQLite_SQLiteExe|SQLite_Startup|SQLite_TotalChanges|StringAddComma|StringBetween|StringEncrypt|StringInsert|StringProper|StringRepeat|StringReverse|StringSplit|StringToHex|TCPIpToName|TempFile|TicksToTime|Timer_Diff|Timer_GetTimerID|Timer_Init|Timer_KillAllTimers|Timer_KillTimer|Timer_SetTimer|TimeToTicks|VersionCompare|viClose|viExecCommand|viFindGpib|viGpibBusReset|viGTL|viOpen|viSetAttribute|viSetTimeout|WeekNumberISO|WinAPI_AttachConsole|WinAPI_AttachThreadInput|WinAPI_Beep|WinAPI_BitBlt|WinAPI_CallNextHookEx|WinAPI_Check|WinAPI_ClientToScreen|WinAPI_CloseHandle|WinAPI_CommDlgExtendedError|WinAPI_CopyIcon|WinAPI_CreateBitmap|WinAPI_CreateCompatibleBitmap|WinAPI_CreateCompatibleDC|WinAPI_CreateEvent|WinAPI_CreateFile|WinAPI_CreateFont|WinAPI_CreateFontIndirect|WinAPI_CreateProcess|WinAPI_CreateSolidBitmap|WinAPI_CreateSolidBrush|WinAPI_CreateWindowEx|WinAPI_DefWindowProc|WinAPI_DeleteDC|WinAPI_DeleteObject|WinAPI_DestroyIcon|WinAPI_DestroyWindow|WinAPI_DrawEdge|WinAPI_DrawFrameControl|WinAPI_DrawIcon|WinAPI_DrawIconEx|WinAPI_DrawText|WinAPI_EnableWindow|WinAPI_EnumDisplayDevices|WinAPI_EnumWindows|WinAPI_EnumWindowsPopup|WinAPI_EnumWindowsTop|WinAPI_ExpandEnvironmentStrings|WinAPI_ExtractIconEx|WinAPI_FatalAppExit|WinAPI_FillRect|WinAPI_FindExecutable|WinAPI_FindWindow|WinAPI_FlashWindow|WinAPI_FlashWindowEx|WinAPI_FloatToInt|WinAPI_FlushFileBuffers|WinAPI_FormatMessage|WinAPI_FrameRect|WinAPI_FreeLibrary|WinAPI_GetAncestor|WinAPI_GetAsyncKeyState|WinAPI_GetClassName|WinAPI_GetClientHeight|WinAPI_GetClientRect|WinAPI_GetClientWidth|WinAPI_GetCurrentProcess|WinAPI_GetCurrentProcessID|WinAPI_GetCurrentThread|WinAPI_GetCurrentThreadId|WinAPI_GetCursorInfo|WinAPI_GetDC|WinAPI_GetDesktopWindow|WinAPI_GetDeviceCaps|WinAPI_GetDIBits|WinAPI_GetDlgCtrlID|WinAPI_GetDlgItem|WinAPI_GetFileSizeEx|WinAPI_GetFocus|WinAPI_GetForegroundWindow|WinAPI_GetIconInfo|WinAPI_GetLastError|WinAPI_GetLastErrorMessage|WinAPI_GetModuleHandle|WinAPI_GetMousePos|WinAPI_GetMousePosX|WinAPI_GetMousePosY|WinAPI_GetObject|WinAPI_GetOpenFileName|WinAPI_GetOverlappedResult|WinAPI_GetParent|WinAPI_GetProcessAffinityMask|WinAPI_GetSaveFileName|WinAPI_GetStdHandle|WinAPI_GetStockObject|WinAPI_GetSysColor|WinAPI_GetSysColorBrush|WinAPI_GetSystemMetrics|WinAPI_GetTextExtentPoint32|WinAPI_GetWindow|WinAPI_GetWindowDC|WinAPI_GetWindowHeight|WinAPI_GetWindowLong|WinAPI_GetWindowRect|WinAPI_GetWindowText|WinAPI_GetWindowThreadProcessId|WinAPI_GetWindowWidth|WinAPI_GetXYFromPoint|WinAPI_GlobalMemStatus|WinAPI_GUIDFromString|WinAPI_GUIDFromStringEx|WinAPI_HiWord|WinAPI_InProcess|WinAPI_IntToFloat|WinAPI_InvalidateRect|WinAPI_IsClassName|WinAPI_IsWindow|WinAPI_IsWindowVisible|WinAPI_LoadBitmap|WinAPI_LoadImage|WinAPI_LoadLibrary|WinAPI_LoadLibraryEx|WinAPI_LoadShell32Icon|WinAPI_LoadString|WinAPI_LocalFree|WinAPI_LoWord|WinAPI_MakeDWord|WinAPI_MAKELANGID|WinAPI_MAKELCID|WinAPI_MakeLong|WinAPI_MessageBeep|WinAPI_Mouse_Event|WinAPI_MoveWindow|WinAPI_MsgBox|WinAPI_MulDiv|WinAPI_MultiByteToWideChar|WinAPI_MultiByteToWideCharEx|WinAPI_OpenProcess|WinAPI_PointFromRect|WinAPI_PostMessage|WinAPI_PrimaryLangId|WinAPI_PtInRect|WinAPI_ReadFile|WinAPI_ReadProcessMemory|WinAPI_RectIsEmpty|WinAPI_RedrawWindow|WinAPI_RegisterWindowMessage|WinAPI_ReleaseCapture|WinAPI_ReleaseDC|WinAPI_ScreenToClient|WinAPI_SelectObject|WinAPI_SetBkColor|WinAPI_SetCapture|WinAPI_SetCursor|WinAPI_SetDefaultPrinter|WinAPI_SetDIBits|WinAPI_SetEvent|WinAPI_SetFocus|WinAPI_SetFont|WinAPI_SetHandleInformation|WinAPI_SetLastError|WinAPI_SetParent|WinAPI_SetProcessAffinityMask|WinAPI_SetSysColors|WinAPI_SetTextColor|WinAPI_SetWindowLong|WinAPI_SetWindowPos|WinAPI_SetWindowsHookEx|WinAPI_SetWindowText|WinAPI_ShowCursor|WinAPI_ShowError|WinAPI_ShowMsg|WinAPI_ShowWindow|WinAPI_StringFromGUID|WinAPI_SubLangId|WinAPI_SystemParametersInfo|WinAPI_TwipsPerPixelX|WinAPI_TwipsPerPixelY|WinAPI_UnhookWindowsHookEx|WinAPI_UpdateLayeredWindow|WinAPI_UpdateWindow|WinAPI_ValidateClassName|WinAPI_WaitForInputIdle|WinAPI_WaitForMultipleObjects|WinAPI_WaitForSingleObject|WinAPI_WideCharToMultiByte|WinAPI_WindowFromPoint|WinAPI_WriteConsole|WinAPI_WriteFile|WinAPI_WriteProcessMemory|WinNet_AddConnection|WinNet_AddConnection2|WinNet_AddConnection3|WinNet_CancelConnection|WinNet_CancelConnection2|WinNet_CloseEnum|WinNet_ConnectionDialog|WinNet_ConnectionDialog1|WinNet_DisconnectDialog|WinNet_DisconnectDialog1|WinNet_EnumResource|WinNet_GetConnection|WinNet_GetConnectionPerformance|WinNet_GetLastError|WinNet_GetNetworkInformation|WinNet_GetProviderName|WinNet_GetResourceInformation|WinNet_GetResourceParent|WinNet_GetUniversalName|WinNet_GetUser|WinNet_OpenEnum|WinNet_RestoreConnection|WinNet_UseConnection|Word_VersionInfo|WordAttach|WordCreate|WordDocAdd|WordDocAddLink|WordDocAddPicture|WordDocClose|WordDocFindReplace|WordDocGetCollection|WordDocLinkGetCollection|WordDocOpen|WordDocPrint|WordDocPropertyGet|WordDocPropertySet|WordDocSave|WordDocSaveAs|WordErrorHandlerDeRegister|WordErrorHandlerRegister|WordErrorNotify|WordMacroRun|WordPropertyGet|WordPropertySet|WordQuit|' + + 'ce|comments-end|comments-start|cs|include|include-once|NoTrayIcon|RequireAdmin|' + + 'AutoIt3Wrapper_Au3Check_Parameters|AutoIt3Wrapper_Au3Check_Stop_OnWarning|AutoIt3Wrapper_Change2CUI|AutoIt3Wrapper_Compression|AutoIt3Wrapper_cvsWrapper_Parameters|AutoIt3Wrapper_Icon|AutoIt3Wrapper_Outfile|AutoIt3Wrapper_Outfile_Type|AutoIt3Wrapper_Plugin_Funcs|AutoIt3Wrapper_Res_Comment|AutoIt3Wrapper_Res_Description|AutoIt3Wrapper_Res_Field|AutoIt3Wrapper_Res_File_Add|AutoIt3Wrapper_Res_Fileversion|AutoIt3Wrapper_Res_FileVersion_AutoIncrement|AutoIt3Wrapper_Res_Icon_Add|AutoIt3Wrapper_Res_Language|AutoIt3Wrapper_Res_LegalCopyright|AutoIt3Wrapper_res_requestedExecutionLevel|AutoIt3Wrapper_Res_SaveSource|AutoIt3Wrapper_Run_After|AutoIt3Wrapper_Run_Au3check|AutoIt3Wrapper_Run_Before|AutoIt3Wrapper_Run_cvsWrapper|AutoIt3Wrapper_Run_Debug_Mode|AutoIt3Wrapper_Run_Obfuscator|AutoIt3Wrapper_Run_Tidy|AutoIt3Wrapper_Tidy_Stop_OnError|AutoIt3Wrapper_UseAnsi|AutoIt3Wrapper_UseUpx|AutoIt3Wrapper_UseX64|AutoIt3Wrapper_Version|EndRegion|forceref|Obfuscator_Ignore_Funcs|Obfuscator_Ignore_Variables|Obfuscator_Parameters|Region|Tidy_Parameters' + var atKeywords = 'AppDataCommonDir|AppDataDir|AutoItExe|AutoItPID|AutoItUnicode|AutoItVersion|AutoItX64|COM_EventObj|CommonFilesDir|Compiled|ComputerName|ComSpec|CR|CRLF|DesktopCommonDir|DesktopDepth|DesktopDir|DesktopHeight|DesktopRefresh|DesktopWidth|DocumentsCommonDir|error|exitCode|exitMethod|extended|FavoritesCommonDir|FavoritesDir|GUI_CtrlHandle|GUI_CtrlId|GUI_DragFile|GUI_DragId|GUI_DropId|GUI_WinHandle|HomeDrive|HomePath|HomeShare|HotKeyPressed|HOUR|InetGetActive|InetGetBytesRead|IPAddress1|IPAddress2|IPAddress3|IPAddress4|KBLayout|LF|LogonDNSDomain|LogonDomain|LogonServer|MDAY|MIN|MON|MyDocumentsDir|NumParams|OSBuild|OSLang|OSServicePack|OSTYPE|OSVersion|ProcessorArch|ProgramFilesDir|ProgramsCommonDir|ProgramsDir|ScriptDir|ScriptFullPath|ScriptLineNumber|ScriptName|SEC|StartMenuCommonDir|StartMenuDir|StartupCommonDir|StartupDir|SW_DISABLE|SW_ENABLE|SW_HIDE|SW_LOCK|SW_MAXIMIZE|SW_MINIMIZE|SW_RESTORE|SW_SHOW|SW_SHOWDEFAULT|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_SHOWMINNOACTIVE|SW_SHOWNA|SW_SHOWNOACTIVATE|SW_SHOWNORMAL|SW_UNLOCK|SystemDir|TAB|TempDir|TRAY_ID|TrayIconFlashing|TrayIconVisible|UserName|UserProfileDir|WDAY|WindowsDir|WorkingDir|YDAY|YEAR' + + this.$rules = { start: + [ { token: 'comment.line.ahk', regex: '(?:^| );.*$' }, + { token: 'comment.block.ahk', + regex: '/\\*', push: + [ { token: 'comment.block.ahk', regex: '\\*/', next: 'pop' }, + { defaultToken: 'comment.block.ahk' } ] }, + { token: 'doc.comment.ahk', + regex: '#cs', push: + [ { token: 'doc.comment.ahk', regex: '#ce', next: 'pop' }, + { defaultToken: 'doc.comment.ahk' } ] }, + { token: 'keyword.command.ahk', + regex: '(?:\\b|^)(?:allowsamelinecomments|clipboardtimeout|commentflag|errorstdout|escapechar|hotkeyinterval|hotkeymodifiertimeout|hotstring|include|includeagain|installkeybdhook|installmousehook|keyhistory|ltrim|maxhotkeysperinterval|maxmem|maxthreads|maxthreadsbuffer|maxthreadsperhotkey|noenv|notrayicon|persistent|singleinstance|usehook|winactivateforce|autotrim|blockinput|click|clipwait|continue|control|controlclick|controlfocus|controlget|controlgetfocus|controlgetpos|controlgettext|controlmove|controlsend|controlsendraw|controlsettext|coordmode|critical|detecthiddentext|detecthiddenwindows|drive|driveget|drivespacefree|edit|endrepeat|envadd|envdiv|envget|envmult|envset|envsub|envupdate|exit|exitapp|fileappend|filecopy|filecopydir|filecreatedir|filecreateshortcut|filedelete|filegetattrib|filegetshortcut|filegetsize|filegettime|filegetversion|fileinstall|filemove|filemovedir|fileread|filereadline|filerecycle|filerecycleempty|fileremovedir|fileselectfile|fileselectfolder|filesetattrib|filesettime|formattime|getkeystate|gosub|goto|groupactivate|groupadd|groupclose|groupdeactivate|gui|guicontrol|guicontrolget|hideautoitwin|hotkey|ifequal|ifexist|ifgreater|ifgreaterorequal|ifinstring|ifless|iflessorequal|ifmsgbox|ifnotequal|ifnotexist|ifnotinstring|ifwinactive|ifwinexist|ifwinnotactive|ifwinnotexist|imagesearch|inidelete|iniread|iniwrite|input|inputbox|keyhistory|keywait|listhotkeys|listlines|listvars|menu|mouseclick|mouseclickdrag|mousegetpos|mousemove|msgbox|onexit|outputdebug|pause|pixelgetcolor|pixelsearch|postmessage|process|progress|random|regdelete|regread|regwrite|reload|repeat|run|runas|runwait|send|sendevent|sendinput|sendmode|sendplay|sendmessage|sendraw|setbatchlines|setcapslockstate|setcontroldelay|setdefaultmousespeed|setenv|setformat|setkeydelay|setmousedelay|setnumlockstate|setscrolllockstate|setstorecapslockmode|settimer|settitlematchmode|setwindelay|setworkingdir|shutdown|sleep|sort|soundbeep|soundget|soundgetwavevolume|soundplay|soundset|soundsetwavevolume|splashimage|splashtextoff|splashtexton|splitpath|statusbargettext|statusbarwait|stringcasesense|stringgetpos|stringleft|stringlen|stringlower|stringmid|stringreplace|stringright|stringsplit|stringtrimleft|stringtrimright|stringupper|suspend|sysget|thread|tooltip|transform|traytip|urldownloadtofile|while|winactivate|winactivatebottom|winclose|winget|wingetactivestats|wingetactivetitle|wingetclass|wingetpos|wingettext|wingettitle|winhide|winkill|winmaximize|winmenuselectitem|winminimize|winminimizeall|winminimizeallundo|winmove|winrestore|winset|winsettitle|winshow|winwait|winwaitactive|winwaitclose|winwaitnotactive)\\b', + caseInsensitive: true }, + { token: 'keyword.control.ahk', + regex: '(?:\\b|^)(?:if|else|return|loop|break|for|while|global|local|byref)\\b', + caseInsensitive: true }, + { token: 'support.function.ahk', + regex: '(?:\\b|^)(?:abs|acos|asc|asin|atan|ceil|chr|cos|dllcall|exp|fileexist|floor|getkeystate|il_add|il_create|il_destroy|instr|substr|isfunc|islabel|ln|log|lv_add|lv_delete|lv_deletecol|lv_getcount|lv_getnext|lv_gettext|lv_insert|lv_insertcol|lv_modify|lv_modifycol|lv_setimagelist|mod|onmessage|numget|numput|registercallback|regexmatch|regexreplace|round|sin|tan|sqrt|strlen|sb_seticon|sb_setparts|sb_settext|tv_add|tv_delete|tv_getchild|tv_getcount|tv_getnext|tv_get|tv_getparent|tv_getprev|tv_getselection|tv_gettext|tv_modify|varsetcapacity|winactive|winexist)\\b', + caseInsensitive: true }, + { token: 'variable.predefined.ahk', + regex: '(?:\\b|^)(?:a_ahkpath|a_ahkversion|a_appdata|a_appdatacommon|a_autotrim|a_batchlines|a_caretx|a_carety|a_computername|a_controldelay|a_cursor|a_dd|a_ddd|a_dddd|a_defaultmousespeed|a_desktop|a_desktopcommon|a_detecthiddentext|a_detecthiddenwindows|a_endchar|a_eventinfo|a_exitreason|a_formatfloat|a_formatinteger|a_gui|a_guievent|a_guicontrol|a_guicontrolevent|a_guiheight|a_guiwidth|a_guix|a_guiy|a_hour|a_iconfile|a_iconhidden|a_iconnumber|a_icontip|a_index|a_ipaddress1|a_ipaddress2|a_ipaddress3|a_ipaddress4|a_isadmin|a_iscompiled|a_iscritical|a_ispaused|a_issuspended|a_keydelay|a_language|a_lasterror|a_linefile|a_linenumber|a_loopfield|a_loopfileattrib|a_loopfiledir|a_loopfileext|a_loopfilefullpath|a_loopfilelongpath|a_loopfilename|a_loopfileshortname|a_loopfileshortpath|a_loopfilesize|a_loopfilesizekb|a_loopfilesizemb|a_loopfiletimeaccessed|a_loopfiletimecreated|a_loopfiletimemodified|a_loopreadline|a_loopregkey|a_loopregname|a_loopregsubkey|a_loopregtimemodified|a_loopregtype|a_mday|a_min|a_mm|a_mmm|a_mmmm|a_mon|a_mousedelay|a_msec|a_mydocuments|a_now|a_nowutc|a_numbatchlines|a_ostype|a_osversion|a_priorhotkey|programfiles|a_programfiles|a_programs|a_programscommon|a_screenheight|a_screenwidth|a_scriptdir|a_scriptfullpath|a_scriptname|a_sec|a_space|a_startmenu|a_startmenucommon|a_startup|a_startupcommon|a_stringcasesense|a_tab|a_temp|a_thisfunc|a_thishotkey|a_thislabel|a_thismenu|a_thismenuitem|a_thismenuitempos|a_tickcount|a_timeidle|a_timeidlephysical|a_timesincepriorhotkey|a_timesincethishotkey|a_titlematchmode|a_titlematchmodespeed|a_username|a_wday|a_windelay|a_windir|a_workingdir|a_yday|a_year|a_yweek|a_yyyy|clipboard|clipboardall|comspec|errorlevel)\\b', + caseInsensitive: true }, + { token: 'support.constant.ahk', + regex: '(?:\\b|^)(?:shift|lshift|rshift|alt|lalt|ralt|control|lcontrol|rcontrol|ctrl|lctrl|rctrl|lwin|rwin|appskey|altdown|altup|shiftdown|shiftup|ctrldown|ctrlup|lwindown|lwinup|rwindown|rwinup|lbutton|rbutton|mbutton|wheelup|wheelleft|wheelright|wheeldown|xbutton1|xbutton2|joy1|joy2|joy3|joy4|joy5|joy6|joy7|joy8|joy9|joy10|joy11|joy12|joy13|joy14|joy15|joy16|joy17|joy18|joy19|joy20|joy21|joy22|joy23|joy24|joy25|joy26|joy27|joy28|joy29|joy30|joy31|joy32|joyx|joyy|joyz|joyr|joyu|joyv|joypov|joyname|joybuttons|joyaxes|joyinfo|space|tab|enter|escape|esc|backspace|bs|delete|del|insert|ins|pgup|pgdn|home|end|up|down|left|right|printscreen|ctrlbreak|pause|scrolllock|capslock|numlock|numpad0|numpad1|numpad2|numpad3|numpad4|numpad5|numpad6|numpad7|numpad8|numpad9|numpadmult|numpadadd|numpadsub|numpaddiv|numpaddot|numpaddel|numpadins|numpadclear|numpadup|numpaddown|numpadleft|numpadright|numpadhome|numpadend|numpadpgup|numpadpgdn|numpadenter|f1|f2|f3|f4|f5|f6|f7|f8|f9|f10|f11|f12|f13|f14|f15|f16|f17|f18|f19|f20|f21|f22|f23|f24|browser_back|browser_forward|browser_refresh|browser_stop|browser_search|browser_favorites|browser_home|volume_mute|volume_down|volume_up|media_next|media_prev|media_stop|media_play_pause|launch_mail|launch_media|launch_app1|launch_app2)\\b', + caseInsensitive: true }, + { token: 'variable.parameter', + regex: '(?:\\b|^)(?:pixel|mouse|screen|relative|rgb|ltrim|rtrim|join|low|belownormal|normal|abovenormal|high|realtime|ahk_id|ahk_pid|ahk_class|ahk_group|between|contains|in|is|integer|float|integerfast|floatfast|number|digit|xdigit|alpha|upper|lower|alnum|time|date|not|or|and|alwaysontop|topmost|top|bottom|transparent|transcolor|redraw|region|id|idlast|processname|minmax|controllist|count|list|capacity|statuscd|eject|lock|unlock|label|filesystem|label|setlabel|serial|type|status|static|seconds|minutes|hours|days|read|parse|logoff|close|error|single|tray|add|rename|check|uncheck|togglecheck|enable|disable|toggleenable|default|nodefault|standard|nostandard|color|delete|deleteall|icon|noicon|tip|click|show|mainwindow|nomainwindow|useerrorlevel|text|picture|pic|groupbox|button|checkbox|radio|dropdownlist|ddl|combobox|listbox|listview|datetime|monthcal|updown|slider|tab|tab2|statusbar|treeview|iconsmall|tile|report|sortdesc|nosort|nosorthdr|grid|hdr|autosize|range|xm|ym|ys|xs|xp|yp|font|resize|owner|submit|nohide|minimize|maximize|restore|noactivate|na|cancel|destroy|center|margin|maxsize|minsize|owndialogs|guiescape|guiclose|guisize|guicontextmenu|guidropfiles|tabstop|section|altsubmit|wrap|hscroll|vscroll|border|top|bottom|buttons|expand|first|imagelist|lines|wantctrla|wantf2|vis|visfirst|number|uppercase|lowercase|limit|password|multi|wantreturn|group|background|bold|italic|strike|underline|norm|backgroundtrans|theme|caption|delimiter|minimizebox|maximizebox|sysmenu|toolwindow|flash|style|exstyle|check3|checked|checkedgray|readonly|password|hidden|left|right|center|notab|section|move|focus|hide|choose|choosestring|text|pos|enabled|disabled|visible|lastfound|lastfoundexist|alttab|shiftalttab|alttabmenu|alttabandmenu|alttabmenudismiss|notimers|interrupt|priority|waitclose|blind|raw|unicode|deref|pow|bitnot|bitand|bitor|bitxor|bitshiftleft|bitshiftright|yes|no|ok|cancel|abort|retry|ignore|tryagain|on|off|all|hkey_local_machine|hkey_users|hkey_current_user|hkey_classes_root|hkey_current_config|hklm|hku|hkcu|hkcr|hkcc|reg_sz|reg_expand_sz|reg_multi_sz|reg_dword|reg_qword|reg_binary|reg_link|reg_resource_list|reg_full_resource_descriptor|reg_resource_requirements_list|reg_dword_big_endian)\\b', + caseInsensitive: true }, + { keywordMap: {"constant.language": autoItKeywords}, regex: '\\w+\\b'}, + { keywordMap: {"variable.function": atKeywords}, regex: '@\\w+\\b'}, + { token : "constant.numeric", regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"}, + { token: 'keyword.operator.ahk', + regex: '=|==|<>|:=|<|>|\\*|\\/|\\+|:|\\?|\\-' }, + { token: 'punctuation.ahk', + regex: '#|`|::|,|\\{|\\}|\\(|\\)|\\%' }, + { token: + [ 'punctuation.quote.double', + 'string.quoted.ahk', + 'punctuation.quote.double' ], + regex: '(")((?:[^"]|"")*)(")' }, + { token: [ 'label.ahk', 'punctuation.definition.label.ahk' ], + regex: '^([^: ]+)(:)(?!:)' } ] } + + this.normalizeRules(); +}; + +AutoHotKeyHighlightRules.metaData = { name: 'AutoHotKey', + scopeName: 'source.ahk', + fileTypes: [ 'ahk' ], + foldingStartMarker: '^\\s*/\\*|^(?![^{]*?;|[^{]*?/\\*(?!.*?\\*/.*?\\{)).*?\\{\\s*($|;|/\\*(?!.*?\\*/.*\\S))', + foldingStopMarker: '^\\s*\\*/|^\\s*\\}' } + + +oop.inherits(AutoHotKeyHighlightRules, TextHighlightRules); + +exports.AutoHotKeyHighlightRules = AutoHotKeyHighlightRules; +}); \ No newline at end of file diff --git a/lib/ace/mode/batchfile.js b/lib/ace/mode/batchfile.js new file mode 100644 index 00000000..e080464c --- /dev/null +++ b/lib/ace/mode/batchfile.js @@ -0,0 +1,61 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Contributor(s): + * + * + * + * ***** END LICENSE BLOCK ***** */ + +/* + THIS FILE WAS AUTOGENERATED BY mode.tmpl.js +*/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var BatchFileHighlightRules = require("./batchfile_highlight_rules").BatchFileHighlightRules; +var FoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = BatchFileHighlightRules; + this.foldingRules = new FoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.lineCommentStart = "::"; + this.blockComment = ""; + this.$id = "ace/mode/batchfile"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); \ No newline at end of file diff --git a/lib/ace/mode/batchfile_highlight_rules.js b/lib/ace/mode/batchfile_highlight_rules.js new file mode 100644 index 00000000..be0380d8 --- /dev/null +++ b/lib/ace/mode/batchfile_highlight_rules.js @@ -0,0 +1,97 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/* This file was autogenerated from C:\Users\LED\AppData\Roaming\Sublime Text 2\Packages\Batch File\Batch File.tmLanguage (uuid: ) */ +/**************************************************************************************** + * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. * + * fileTypes * + ****************************************************************************************/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var BatchFileHighlightRules = function() { + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + + this.$rules = { start: + [ { token: 'keyword.command.dosbatch', + regex: '\\b(?:append|assoc|at|attrib|break|cacls|cd|chcp|chdir|chkdsk|chkntfs|cls|cmd|color|comp|compact|convert|copy|date|del|dir|diskcomp|diskcopy|doskey|echo|endlocal|erase|fc|find|findstr|format|ftype|graftabl|help|keyb|label|md|mkdir|mode|more|move|path|pause|popd|print|prompt|pushd|rd|recover|ren|rename|replace|restore|rmdir|set|setlocal|shift|sort|start|subst|time|title|tree|type|ver|verify|vol|xcopy)\\b', + caseInsensitive: true }, + { token: 'keyword.control.statement.dosbatch', + regex: '\\b(?:goto|call|exit)\\b', + caseInsensitive: true }, + { token: 'keyword.control.conditional.if.dosbatch', + regex: '\\bif\\s+not\\s+(?:exist|defined|errorlevel|cmdextversion)\\b', + caseInsensitive: true }, + { token: 'keyword.control.conditional.dosbatch', + regex: '\\b(?:if|else)\\b', + caseInsensitive: true }, + { token: 'keyword.control.repeat.dosbatch', + regex: '\\bfor\\b', + caseInsensitive: true }, + { token: 'keyword.operator.dosbatch', + regex: '\\b(?:EQU|NEQ|LSS|LEQ|GTR|GEQ)\\b' }, + { token: ['doc.comment', 'comment'], + regex: '(?:^|\\b)(rem)($|\\s.*$)', + caseInsensitive: true }, + { token: 'comment.line.colons.dosbatch', + regex: '::.*$' }, + { include: 'variable' }, + { token: 'punctuation.definition.string.begin.shell', + regex: '"', + push: [ + { token: 'punctuation.definition.string.end.shell', regex: '"', next: 'pop' }, + { include: 'variable' }, + { defaultToken: 'string.quoted.double.dosbatch' } ] }, + { token: 'keyword.operator.pipe.dosbatch', regex: '[|]' }, + { token: 'keyword.operator.redirect.shell', + regex: '&>|\\d*>&\\d*|\\d*(?:>>|>|<)|\\d*<&|\\d*<>' } ], + variable: [ + { token: 'constant.numeric', regex: '%%\\w+|%[*\\d]|%\\w+%'}, + { token: 'constant.numeric', regex: '%~\\d+'}, + { token: ['markup.list', 'constant.other', 'markup.list'], + regex: '(%)(\\w+)(%?)' }]} + + this.normalizeRules(); +}; + +BatchFileHighlightRules.metaData = { name: 'Batch File', + scopeName: 'source.dosbatch', + fileTypes: [ 'bat' ] } + + +oop.inherits(BatchFileHighlightRules, TextHighlightRules); + +exports.BatchFileHighlightRules = BatchFileHighlightRules; +}); \ No newline at end of file diff --git a/lib/ace/mode/behaviour.js b/lib/ace/mode/behaviour.js new file mode 100644 index 00000000..c1c6cb15 --- /dev/null +++ b/lib/ace/mode/behaviour.js @@ -0,0 +1,90 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var Behaviour = function() { + this.$behaviours = {}; +}; + +(function () { + + this.add = function (name, action, callback) { + switch (undefined) { + case this.$behaviours: + this.$behaviours = {}; + case this.$behaviours[name]: + this.$behaviours[name] = {}; + } + this.$behaviours[name][action] = callback; + } + + this.addBehaviours = function (behaviours) { + for (var key in behaviours) { + for (var action in behaviours[key]) { + this.add(key, action, behaviours[key][action]); + } + } + } + + this.remove = function (name) { + if (this.$behaviours && this.$behaviours[name]) { + delete this.$behaviours[name]; + } + } + + this.inherit = function (mode, filter) { + if (typeof mode === "function") { + var behaviours = new mode().getBehaviours(filter); + } else { + var behaviours = mode.getBehaviours(filter); + } + this.addBehaviours(behaviours); + } + + this.getBehaviours = function (filter) { + if (!filter) { + return this.$behaviours; + } else { + var ret = {} + for (var i = 0; i < filter.length; i++) { + if (this.$behaviours[filter[i]]) { + ret[filter[i]] = this.$behaviours[filter[i]]; + } + } + return ret; + } + } + +}).call(Behaviour.prototype); + +exports.Behaviour = Behaviour; +}); diff --git a/lib/ace/mode/behaviour/behaviour_test.js b/lib/ace/mode/behaviour/behaviour_test.js new file mode 100644 index 00000000..245edf99 --- /dev/null +++ b/lib/ace/mode/behaviour/behaviour_test.js @@ -0,0 +1,179 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); + require("../../test/mockdom"); +} + +define(function(require, exports, module) { +"use strict"; + +require("../../multi_select"); +var assert = require("../../test/assertions"); +var Range = require("../../range").Range; +var Editor = require("../../editor").Editor; +var EditSession = require("../../edit_session").EditSession; +var MockRenderer = require("../../test/mockrenderer").MockRenderer; +var JavaScriptMode = require("../javascript").Mode; +var XMLMode = require("../xml").Mode; +var editor; +var exec = function(name, times, args) { + do { + editor.commands.exec(name, editor, args); + } while(times --> 1); +}; +var testRanges = function(str) { + assert.equal(editor.selection.getAllRanges() + "", str + ""); +}; + +module.exports = { + "test: cstyle": function() { + function testValue(line) { + assert.equal(editor.getValue(), Array(4).join(line + "\n")); + } + function testSelection(line, col, inc) { + editor.selection.rangeList.ranges.forEach(function(r) { + assert.range(r, line, col, line, col); + line += (inc || 1); + }); + } + var doc = new EditSession([ + "", + "", + "", + "" + ], new JavaScriptMode()); + editor = new Editor(new MockRenderer(), doc); + editor.setOption("behavioursEnabled", true); + + editor.navigateFileStart(); + exec("addCursorBelow", 2); + + exec("insertstring", 1, "if "); + + // pairing ( + exec("insertstring", 1, "("); + testValue("if ()"); + testSelection(0, 4); + exec("insertstring", 1, ")"); + testValue("if ()"); + testSelection(0, 5); + + // pairing [ + exec("gotoleft", 1); + exec("insertstring", 1, "["); + testValue("if ([])"); + testSelection(0, 5); + + exec("insertstring", 1, "]"); + testValue("if ([])"); + testSelection(0, 6); + + // test deletion + exec("gotoleft", 1); + exec("backspace", 1); + testValue("if ()"); + testSelection(0, 4); + + exec("gotolineend", 1); + exec("insertstring", 1, "{"); + testValue("if (){}"); + testSelection(0, 6); + + exec("insertstring", 1, "}"); + testValue("if (){}"); + testSelection(0, 7); + + exec("gotolinestart", 1); + exec("insertstring", 1, "("); + testValue("(if (){}"); + exec("backspace", 1); + + editor.setValue(""); + exec("insertstring", 1, "{"); + assert.equal(editor.getValue(), "{"); + exec("insertstring", 1, "\n"); + assert.equal(editor.getValue(), "{\n \n}"); + + editor.setValue(""); + exec("insertstring", 1, "("); + exec("insertstring", 1, '"'); + exec("insertstring", 1, '"'); + assert.equal(editor.getValue(), '("")'); + exec("backspace", 1); + exec("insertstring", 1, '"'); + assert.equal(editor.getValue(), '("")'); + + editor.setValue("('foo')", 1); + exec("gotoleft", 1); + exec("selectleft", 1); + exec("selectMoreBefore", 1); + exec("insertstring", 1, "'"); + assert.equal(editor.getValue(), "('foo')"); + exec("selectleft", 1); + exec("insertstring", 1, '"'); + assert.equal(editor.getValue(), '("foo")'); + exec("selectleft", 1); + exec("insertstring", 1, '"'); + assert.equal(editor.getValue(), '("foo")'); + + editor.setValue("", 1); + exec("selectleft", 1); + exec("insertstring", 1, '"'); + assert.equal(editor.getValue(), '""'); + exec("insertstring", 1, '\\'); + exec("insertstring", 1, 'n'); + exec("insertstring", 1, '"'); + assert.equal(editor.getValue(), '"\\n"'); + + }, + "test: xml": function() { + editor = new Editor(new MockRenderer()); + editor.setValue(["", + " " + ].join("\n")); + editor.session.setMode(new XMLMode); + exec("gotolinedown", 1); + exec("gotolineend", 1); + exec("insertstring", 1, '\n'); + assert.equal(editor.session.getLine(2), " "); + exec("gotolineup", 1); + exec("gotolineend", 1); + exec("insertstring", 1, '\n'); + assert.equal(editor.session.getLine(2), " "); + } +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec(); +} diff --git a/lib/ace/mode/behaviour/css.js b/lib/ace/mode/behaviour/css.js new file mode 100644 index 00000000..1c35f744 --- /dev/null +++ b/lib/ace/mode/behaviour/css.js @@ -0,0 +1,108 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Behaviour = require("../behaviour").Behaviour; +var CstyleBehaviour = require("./cstyle").CstyleBehaviour; +var TokenIterator = require("../../token_iterator").TokenIterator; + +var CssBehaviour = function () { + + this.inherit(CstyleBehaviour); + + this.add("colon", "insertion", function (state, action, editor, session, text) { + if (text === ':') { + var cursor = editor.getCursorPosition(); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + var token = iterator.getCurrentToken(); + if (token && token.value.match(/\s+/)) { + token = iterator.stepBackward(); + } + if (token && token.type === 'support.type') { + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar === ':') { + return { + text: '', + selection: [1, 1] + } + } + if (!line.substring(cursor.column).match(/^\s*;/)) { + return { + text: ':;', + selection: [1, 1] + } + } + } + } + }); + + this.add("colon", "deletion", function (state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && selected === ':') { + var cursor = editor.getCursorPosition(); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + var token = iterator.getCurrentToken(); + if (token && token.value.match(/\s+/)) { + token = iterator.stepBackward(); + } + if (token && token.type === 'support.type') { + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.end.column, range.end.column + 1); + if (rightChar === ';') { + range.end.column ++; + return range; + } + } + } + }); + + this.add("semicolon", "insertion", function (state, action, editor, session, text) { + if (text === ';') { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar === ';') { + return { + text: '', + selection: [1, 1] + } + } + } + }); + +} +oop.inherits(CssBehaviour, CstyleBehaviour); + +exports.CssBehaviour = CssBehaviour; +}); diff --git a/lib/ace/mode/behaviour/cstyle.js b/lib/ace/mode/behaviour/cstyle.js new file mode 100644 index 00000000..dd1b0d14 --- /dev/null +++ b/lib/ace/mode/behaviour/cstyle.js @@ -0,0 +1,393 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Behaviour = require("../behaviour").Behaviour; +var TokenIterator = require("../../token_iterator").TokenIterator; +var lang = require("../../lib/lang"); + +var SAFE_INSERT_IN_TOKENS = + ["text", "paren.rparen", "punctuation.operator"]; +var SAFE_INSERT_BEFORE_TOKENS = + ["text", "paren.rparen", "punctuation.operator", "comment"]; + +var context; +var contextCache = {}; +var initContext = function(editor) { + var id = -1; + if (editor.multiSelect) { + id = editor.selection.index; + if (contextCache.rangeCount != editor.multiSelect.rangeCount) + contextCache = {rangeCount: editor.multiSelect.rangeCount}; + } + if (contextCache[id]) + return context = contextCache[id]; + context = contextCache[id] = { + autoInsertedBrackets: 0, + autoInsertedRow: -1, + autoInsertedLineEnd: "", + maybeInsertedBrackets: 0, + maybeInsertedRow: -1, + maybeInsertedLineStart: "", + maybeInsertedLineEnd: "" + }; +}; + +var getWrapped = function(selection, selected, opening, closing) { + var rowDiff = selection.end.row - selection.start.row; + return { + text: opening + selected + closing, + selection: [ + 0, + selection.start.column + 1, + rowDiff, + selection.end.column + (rowDiff ? 0 : 1) + ] + }; +}; + +var CstyleBehaviour = function() { + this.add("braces", "insertion", function(state, action, editor, session, text) { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + if (text == '{') { + initContext(editor); + var selection = editor.getSelectionRange(); + var selected = session.doc.getTextRange(selection); + if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) { + return getWrapped(selection, selected, '{', '}'); + } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { + if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode) { + CstyleBehaviour.recordAutoInsert(editor, session, "}"); + return { + text: '{}', + selection: [1, 1] + }; + } else { + CstyleBehaviour.recordMaybeInsert(editor, session, "{"); + return { + text: '{', + selection: [1, 1] + }; + } + } + } else if (text == '}') { + initContext(editor); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar == '}') { + var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row}); + if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { + CstyleBehaviour.popAutoInsertedClosing(); + return { + text: '', + selection: [1, 1] + }; + } + } + } else if (text == "\n" || text == "\r\n") { + initContext(editor); + var closing = ""; + if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) { + closing = lang.stringRepeat("}", context.maybeInsertedBrackets); + CstyleBehaviour.clearMaybeInsertedClosing(); + } + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar === '}') { + var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}'); + if (!openBracePos) + return null; + var next_indent = this.$getIndent(session.getLine(openBracePos.row)); + } else if (closing) { + var next_indent = this.$getIndent(line); + } else { + CstyleBehaviour.clearMaybeInsertedClosing(); + return; + } + var indent = next_indent + session.getTabString(); + + return { + text: '\n' + indent + '\n' + next_indent + closing, + selection: [1, indent.length, 1, indent.length] + }; + } else { + CstyleBehaviour.clearMaybeInsertedClosing(); + } + }); + + this.add("braces", "deletion", function(state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && selected == '{') { + initContext(editor); + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.end.column, range.end.column + 1); + if (rightChar == '}') { + range.end.column++; + return range; + } else { + context.maybeInsertedBrackets--; + } + } + }); + + this.add("parens", "insertion", function(state, action, editor, session, text) { + if (text == '(') { + initContext(editor); + var selection = editor.getSelectionRange(); + var selected = session.doc.getTextRange(selection); + if (selected !== "" && editor.getWrapBehavioursEnabled()) { + return getWrapped(selection, selected, '(', ')'); + } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { + CstyleBehaviour.recordAutoInsert(editor, session, ")"); + return { + text: '()', + selection: [1, 1] + }; + } + } else if (text == ')') { + initContext(editor); + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar == ')') { + var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row}); + if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { + CstyleBehaviour.popAutoInsertedClosing(); + return { + text: '', + selection: [1, 1] + }; + } + } + } + }); + + this.add("parens", "deletion", function(state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && selected == '(') { + initContext(editor); + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.start.column + 1, range.start.column + 2); + if (rightChar == ')') { + range.end.column++; + return range; + } + } + }); + + this.add("brackets", "insertion", function(state, action, editor, session, text) { + if (text == '[') { + initContext(editor); + var selection = editor.getSelectionRange(); + var selected = session.doc.getTextRange(selection); + if (selected !== "" && editor.getWrapBehavioursEnabled()) { + return getWrapped(selection, selected, '[', ']'); + } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { + CstyleBehaviour.recordAutoInsert(editor, session, "]"); + return { + text: '[]', + selection: [1, 1] + }; + } + } else if (text == ']') { + initContext(editor); + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar == ']') { + var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row}); + if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { + CstyleBehaviour.popAutoInsertedClosing(); + return { + text: '', + selection: [1, 1] + }; + } + } + } + }); + + this.add("brackets", "deletion", function(state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && selected == '[') { + initContext(editor); + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.start.column + 1, range.start.column + 2); + if (rightChar == ']') { + range.end.column++; + return range; + } + } + }); + + this.add("string_dquotes", "insertion", function(state, action, editor, session, text) { + if (text == '"' || text == "'") { + initContext(editor); + var quote = text; + var selection = editor.getSelectionRange(); + var selected = session.doc.getTextRange(selection); + if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) { + return getWrapped(selection, selected, quote, quote); + } else if (!selected) { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var leftChar = line.substring(cursor.column-1, cursor.column); + var rightChar = line.substring(cursor.column, cursor.column + 1); + + var token = session.getTokenAt(cursor.row, cursor.column); + var rightToken = session.getTokenAt(cursor.row, cursor.column + 1); + // We're escaped. + if (leftChar == "\\" && token && /escape/.test(token.type)) + return null; + + var stringBefore = token && /string|escape/.test(token.type); + var stringAfter = !rightToken || /string|escape/.test(rightToken.type); + + var pair; + if (rightChar == quote) { + pair = stringBefore !== stringAfter; + } else { + if (stringBefore && !stringAfter) + return null; // wrap string with different quote + if (stringBefore && stringAfter) + return null; // do not pair quotes inside strings + var wordRe = session.$mode.tokenRe; + wordRe.lastIndex = 0; + var isWordBefore = wordRe.test(leftChar); + wordRe.lastIndex = 0; + var isWordAfter = wordRe.test(leftChar); + if (isWordBefore || isWordAfter) + return null; // before or after alphanumeric + if (rightChar && !/[\s;,.})\]\\]/.test(rightChar)) + return null; // there is rightChar and it isn't closing + pair = true; + } + return { + text: pair ? quote + quote : "", + selection: [1,1] + }; + } + } + }); + + this.add("string_dquotes", "deletion", function(state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && (selected == '"' || selected == "'")) { + initContext(editor); + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.start.column + 1, range.start.column + 2); + if (rightChar == selected) { + range.end.column++; + return range; + } + } + }); + +}; + + +CstyleBehaviour.isSaneInsertion = function(editor, session) { + var cursor = editor.getCursorPosition(); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + + // Don't insert in the middle of a keyword/identifier/lexical + if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) { + // Look ahead in case we're at the end of a token + var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1); + if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) + return false; + } + + // Only insert in front of whitespace/comments + iterator.stepForward(); + return iterator.getCurrentTokenRow() !== cursor.row || + this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS); +}; + +CstyleBehaviour.$matchTokenType = function(token, types) { + return types.indexOf(token.type || token) > -1; +}; + +CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + // Reset previous state if text or context changed too much + if (!this.isAutoInsertedClosing(cursor, line, context.autoInsertedLineEnd[0])) + context.autoInsertedBrackets = 0; + context.autoInsertedRow = cursor.row; + context.autoInsertedLineEnd = bracket + line.substr(cursor.column); + context.autoInsertedBrackets++; +}; + +CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + if (!this.isMaybeInsertedClosing(cursor, line)) + context.maybeInsertedBrackets = 0; + context.maybeInsertedRow = cursor.row; + context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket; + context.maybeInsertedLineEnd = line.substr(cursor.column); + context.maybeInsertedBrackets++; +}; + +CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) { + return context.autoInsertedBrackets > 0 && + cursor.row === context.autoInsertedRow && + bracket === context.autoInsertedLineEnd[0] && + line.substr(cursor.column) === context.autoInsertedLineEnd; +}; + +CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) { + return context.maybeInsertedBrackets > 0 && + cursor.row === context.maybeInsertedRow && + line.substr(cursor.column) === context.maybeInsertedLineEnd && + line.substr(0, cursor.column) == context.maybeInsertedLineStart; +}; + +CstyleBehaviour.popAutoInsertedClosing = function() { + context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1); + context.autoInsertedBrackets--; +}; + +CstyleBehaviour.clearMaybeInsertedClosing = function() { + if (context) { + context.maybeInsertedBrackets = 0; + context.maybeInsertedRow = -1; + } +}; + + + +oop.inherits(CstyleBehaviour, Behaviour); + +exports.CstyleBehaviour = CstyleBehaviour; +}); diff --git a/lib/ace/mode/behaviour/html.js b/lib/ace/mode/behaviour/html.js new file mode 100644 index 00000000..181655c0 --- /dev/null +++ b/lib/ace/mode/behaviour/html.js @@ -0,0 +1,46 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var XmlBehaviour = require("../behaviour/xml").XmlBehaviour; + +var HtmlBehaviour = function () { + + XmlBehaviour.call(this); + +}; + +oop.inherits(HtmlBehaviour, XmlBehaviour); + +exports.HtmlBehaviour = HtmlBehaviour; +}); diff --git a/lib/ace/mode/behaviour/xml.js b/lib/ace/mode/behaviour/xml.js new file mode 100644 index 00000000..068fdb31 --- /dev/null +++ b/lib/ace/mode/behaviour/xml.js @@ -0,0 +1,204 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Behaviour = require("../behaviour").Behaviour; +var TokenIterator = require("../../token_iterator").TokenIterator; +var lang = require("../../lib/lang"); + +function is(token, type) { + return token.type.lastIndexOf(type + ".xml") > -1; +} + +var XmlBehaviour = function () { + + this.add("string_dquotes", "insertion", function (state, action, editor, session, text) { + if (text == '"' || text == "'") { + var quote = text; + var selected = session.doc.getTextRange(editor.getSelectionRange()); + if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) { + return { + text: quote + selected + quote, + selection: false + }; + } + + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + var token = iterator.getCurrentToken(); + + if (rightChar == quote && (is(token, "attribute-value") || is(token, "string"))) { + // Ignore input and move right one if we're typing over the closing quote. + return { + text: "", + selection: [1, 1] + }; + } + + if (!token) + token = iterator.stepBackward(); + + if (!token) + return; + + while (is(token, "tag-whitespace") || is(token, "whitespace")) { + token = iterator.stepBackward(); + } + var rightSpace = !rightChar || rightChar.match(/\s/); + if (is(token, "attribute-equals") && (rightSpace || rightChar == '>') || (is(token, "decl-attribute-equals") && (rightSpace || rightChar == '?'))) { + return { + text: quote + quote, + selection: [1, 1] + }; + } + } + }); + + this.add("string_dquotes", "deletion", function(state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && (selected == '"' || selected == "'")) { + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.start.column + 1, range.start.column + 2); + if (rightChar == selected) { + range.end.column++; + return range; + } + } + }); + + this.add("autoclosing", "insertion", function (state, action, editor, session, text) { + if (text == '>') { + var position = editor.getCursorPosition(); + var iterator = new TokenIterator(session, position.row, position.column); + var token = iterator.getCurrentToken() || iterator.stepBackward(); + + // exit if we're not in a tag + if (!token || !(is(token, "tag-name") || is(token, "tag-whitespace") || is(token, "attribute-name") || is(token, "attribute-equals") || is(token, "attribute-value"))) + return; + + // exit if we're inside of a quoted attribute value + if (is(token, "reference.attribute-value")) + return; + if (is(token, "attribute-value")) { + var firstChar = token.value.charAt(0); + if (firstChar == '"' || firstChar == "'") { + var lastChar = token.value.charAt(token.value.length - 1); + var tokenEnd = iterator.getCurrentTokenColumn() + token.value.length; + if (tokenEnd > position.column || tokenEnd == position.column && firstChar != lastChar) + return; + } + } + + // find tag name + while (!is(token, "tag-name")) { + token = iterator.stepBackward(); + } + + var tokenRow = iterator.getCurrentTokenRow(); + var tokenColumn = iterator.getCurrentTokenColumn(); + + // exit if the tag is ending + if (is(iterator.stepBackward(), "end-tag-open")) + return; + + var element = token.value; + if (tokenRow == position.row) + element = element.substring(0, position.column - tokenColumn); + + if (this.voidElements.hasOwnProperty(element.toLowerCase())) + return; + + return { + text: ">" + "", + selection: [1, 1] + }; + } + }); + + this.add("autoindent", "insertion", function (state, action, editor, session, text) { + if (text == "\n") { + var cursor = editor.getCursorPosition(); + var line = session.getLine(cursor.row); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + var token = iterator.getCurrentToken(); + + if (token && token.type.indexOf("tag-close") !== -1) { + if (token.value == "/>") + return; + //get tag name + while (token && token.type.indexOf("tag-name") === -1) { + token = iterator.stepBackward(); + } + + if (!token) { + return; + } + + var tag = token.value; + var row = iterator.getCurrentTokenRow(); + + //don't indent after closing tag + token = iterator.stepBackward(); + if (!token || token.type.indexOf("end-tag") !== -1) { + return; + } + + if (this.voidElements && !this.voidElements[tag]) { + var nextToken = session.getTokenAt(cursor.row, cursor.column+1); + var line = session.getLine(row); + var nextIndent = this.$getIndent(line); + var indent = nextIndent + session.getTabString(); + + if (nextToken && nextToken.value === "') { + var position = editor.getCursorPosition(); + var iterator = new TokenIterator(session, position.row, position.column); + var token = iterator.getCurrentToken(); + var atCursor = false; + var state = JSON.parse(state).pop(); + if ((token && token.value === '>') || state !== "StartTag") return; + if (!token || !hasType(token, 'meta.tag') && !(hasType(token, 'text') && token.value.match('/'))){ + do { + token = iterator.stepBackward(); + } while (token && (hasType(token, 'string') || hasType(token, 'keyword.operator') || hasType(token, 'entity.attribute-name') || hasType(token, 'text'))); + } else { + atCursor = true; + } + var previous = iterator.stepBackward(); + if (!token || !hasType(token, 'meta.tag') || (previous !== null && previous.value.match('/'))) { + return + } + var tag = token.value.substring(1); + if (atCursor){ + var tag = tag.substring(0, position.column - token.start); + } + + return { + text: '>' + '', + selection: [1, 1] + } + } + }); + + } + oop.inherits(XQueryBehaviour, Behaviour); + + exports.XQueryBehaviour = XQueryBehaviour; +}); diff --git a/lib/ace/mode/c9search.js b/lib/ace/mode/c9search.js new file mode 100644 index 00000000..3286456a --- /dev/null +++ b/lib/ace/mode/c9search.js @@ -0,0 +1,67 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var C9SearchHighlightRules = require("./c9search_highlight_rules").C9SearchHighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var C9StyleFoldMode = require("./folding/c9search").FoldMode; + +var Mode = function() { + this.HighlightRules = C9SearchHighlightRules; + this.$outdent = new MatchingBraceOutdent(); + this.foldingRules = new C9StyleFoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + return indent; + }; + + this.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); + }; + + this.autoOutdent = function(state, doc, row) { + this.$outdent.autoOutdent(doc, row); + }; + + this.$id = "ace/mode/c9search"; +}).call(Mode.prototype); + +exports.Mode = Mode; + +}); diff --git a/lib/ace/mode/c9search_highlight_rules.js b/lib/ace/mode/c9search_highlight_rules.js new file mode 100644 index 00000000..43ec4bf8 --- /dev/null +++ b/lib/ace/mode/c9search_highlight_rules.js @@ -0,0 +1,182 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var lang = require("../lib/lang"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +function safeCreateRegexp(source, flag) { + try { + return new RegExp(source, flag); + } catch(e) {} +} + +var C9SearchHighlightRules = function() { + + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + this.$rules = { + "start" : [ + { + tokenNames : ["c9searchresults.constant.numeric", "c9searchresults.text", "c9searchresults.text", "c9searchresults.keyword"], + regex : "(^\\s+[0-9]+)(:\\s)(.+)", + onMatch : function(val, state, stack) { + var values = this.splitRegex.exec(val); + var types = this.tokenNames; + var tokens = [{ + type: types[0], + value: values[1] + },{ + type: types[1], + value: values[2] + }]; + + var regex = stack[1]; + var str = values[3]; + + var m; + var last = 0; + if (regex && regex.exec) { + regex.lastIndex = 0; + while (m = regex.exec(str)) { + var skipped = str.substring(last, m.index); + last = regex.lastIndex; + if (skipped) + tokens.push({type: types[2], value: skipped}); + if (m[0]) + tokens.push({type: types[3], value: m[0]}); + else if (!skipped) + break; + } + } + if (last < str.length) + tokens.push({type: types[2], value: str.substr(last)}); + return tokens; + } + }, + { + token : ["string", "text"], // single line + regex : "(\\S.*)(:$)" + }, + { + regex : "Searching for .*$", + onMatch: function(val, state, stack) { + var parts = val.split("\x01"); + if (parts.length < 3) + return "text"; + + var options, search, replace; + + var i = 0; + var tokens = [{ + value: parts[i++] + "'", + type: "text" + }, { + value: search = parts[i++], + type: "text" // "c9searchresults.keyword" + }, { + value: "'" + parts[i++], + type: "text" + }]; + + // replaced + if (parts[2] !== " in") { + replace = parts[i]; + tokens.push({ + value: "'" + parts[i++] + "'", + type: "text" + }, { + value: parts[i++], + type: "text" + }); + } + // path + tokens.push({ + value: " " + parts[i++] + " ", + type: "text" + }); + // options + if (parts[i+1]) { + options = parts[i+1]; + tokens.push({ + value: "(" + parts[i+1] + ")", + type: "text" + }); + i += 1; + } else { + i -= 1; + } + while (i++ < parts.length) { + parts[i] && tokens.push({ + value: parts[i], + type: "text" + }); + } + + if (replace) { + search = replace; + options = ""; + } + + if (search) { + if (!/regex/.test(options)) + search = lang.escapeRegExp(search); + if (/whole/.test(options)) + search = "\\b" + search + "\\b"; + } + + var regex = search && safeCreateRegexp( + "(" + search + ")", + / sensitive/.test(options) ? "g" : "ig" + ); + if (regex) { + stack[0] = state; + stack[1] = regex; + } + + return tokens; + } + }, + { + regex : "\\d+", + token: "constant.numeric" + } + ] + }; +}; + +oop.inherits(C9SearchHighlightRules, TextHighlightRules); + +exports.C9SearchHighlightRules = C9SearchHighlightRules; + +}); \ No newline at end of file diff --git a/lib/ace/mode/c_cpp.js b/lib/ace/mode/c_cpp.js index 08bd249e..a2dc133f 100644 --- a/lib/ace/mode/c_cpp.js +++ b/lib/ace/mode/c_cpp.js @@ -1,91 +1,63 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Gastón Kleiman - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var oop = require("pilot/oop"); -var TextMode = require("ace/mode/text").Mode; -var Tokenizer = require("ace/tokenizer").Tokenizer; -var c_cppHighlightRules = require("ace/mode/c_cpp_highlight_rules").c_cppHighlightRules; -var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent; -var Range = require("ace/range").Range; +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var c_cppHighlightRules = require("./c_cpp_highlight_rules").c_cppHighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var Range = require("../range").Range; +var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; +var CStyleFoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { - this.$tokenizer = new Tokenizer(new c_cppHighlightRules().getRules()); + this.HighlightRules = c_cppHighlightRules; + this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CstyleBehaviour(); + + this.foldingRules = new CStyleFoldMode(); }; oop.inherits(Mode, TextMode); (function() { - this.toggleCommentLines = function(state, doc, startRow, endRow) { - var outdent = true; - var outentedRows = []; - var re = /^(\s*)\/\//; - - for (var i=startRow; i<= endRow; i++) { - if (!re.test(doc.getLine(i))) { - outdent = false; - break; - } - } - - if (outdent) { - var deleteRange = new Range(0, 0, 0, 0); - for (var i=startRow; i<= endRow; i++) - { - var line = doc.getLine(i); - var m = line.match(re); - deleteRange.start.row = i; - deleteRange.end.row = i; - deleteRange.end.column = m[0].length; - doc.replace(deleteRange, m[1]); - } - } - else { - doc.indentRows(startRow, endRow, "//"); - } - }; + this.lineCommentStart = "//"; + this.blockComment = {start: "/*", end: "*/"}; this.getNextLineIndent = function(state, line, tab) { var indent = this.$getIndent(line); - var tokenizedLine = this.$tokenizer.getLineTokens(line, state); + var tokenizedLine = this.getTokenizer().getLineTokens(line, state); var tokens = tokenizedLine.tokens; var endState = tokenizedLine.state; @@ -122,6 +94,7 @@ oop.inherits(Mode, TextMode); this.$outdent.autoOutdent(doc, row); }; + this.$id = "ace/mode/c_cpp"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/lib/ace/mode/c_cpp_highlight_rules.js b/lib/ace/mode/c_cpp_highlight_rules.js index a1eb37b0..9d2f33dc 100644 --- a/lib/ace/mode/c_cpp_highlight_rules.js +++ b/lib/ace/mode/c_cpp_highlight_rules.js @@ -1,169 +1,193 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Gastón Kleiman - * - * Based on Bespin's C/C++ Syntax Plugin by Marc McIntyre. - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - define(function(require, exports, module) { +"use strict"; -var oop = require("pilot/oop"); -var lang = require("pilot/lang"); -var DocCommentHighlightRules = require("ace/mode/doc_comment_highlight_rules").DocCommentHighlightRules; -var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; +var oop = require("../lib/oop"); +var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +// used by objective-c +var cFunctions = exports.cFunctions = "\\b(?:hypot(?:f|l)?|s(?:scanf|ystem|nprintf|ca(?:nf|lb(?:n(?:f|l)?|ln(?:f|l)?))|i(?:n(?:h(?:f|l)?|f|l)?|gn(?:al|bit))|tr(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(?:jmp|vbuf|locale|buf)|qrt(?:f|l)?|w(?:scanf|printf)|rand)|n(?:e(?:arbyint(?:f|l)?|xt(?:toward(?:f|l)?|after(?:f|l)?))|an(?:f|l)?)|c(?:s(?:in(?:h(?:f|l)?|f|l)?|qrt(?:f|l)?)|cos(?:h(?:f)?|f|l)?|imag(?:f|l)?|t(?:ime|an(?:h(?:f|l)?|f|l)?)|o(?:s(?:h(?:f|l)?|f|l)?|nj(?:f|l)?|pysign(?:f|l)?)|p(?:ow(?:f|l)?|roj(?:f|l)?)|e(?:il(?:f|l)?|xp(?:f|l)?)|l(?:o(?:ck|g(?:f|l)?)|earerr)|a(?:sin(?:h(?:f|l)?|f|l)?|cos(?:h(?:f|l)?|f|l)?|tan(?:h(?:f|l)?|f|l)?|lloc|rg(?:f|l)?|bs(?:f|l)?)|real(?:f|l)?|brt(?:f|l)?)|t(?:ime|o(?:upper|lower)|an(?:h(?:f|l)?|f|l)?|runc(?:f|l)?|gamma(?:f|l)?|mp(?:nam|file))|i(?:s(?:space|n(?:ormal|an)|cntrl|inf|digit|u(?:nordered|pper)|p(?:unct|rint)|finite|w(?:space|c(?:ntrl|type)|digit|upper|p(?:unct|rint)|lower|al(?:num|pha)|graph|xdigit|blank)|l(?:ower|ess(?:equal|greater)?)|al(?:num|pha)|gr(?:eater(?:equal)?|aph)|xdigit|blank)|logb(?:f|l)?|max(?:div|abs))|di(?:v|fftime)|_Exit|unget(?:c|wc)|p(?:ow(?:f|l)?|ut(?:s|c(?:har)?|wc(?:har)?)|error|rintf)|e(?:rf(?:c(?:f|l)?|f|l)?|x(?:it|p(?:2(?:f|l)?|f|l|m1(?:f|l)?)?))|v(?:s(?:scanf|nprintf|canf|printf|w(?:scanf|printf))|printf|f(?:scanf|printf|w(?:scanf|printf))|w(?:scanf|printf)|a_(?:start|copy|end|arg))|qsort|f(?:s(?:canf|e(?:tpos|ek))|close|tell|open|dim(?:f|l)?|p(?:classify|ut(?:s|c|w(?:s|c))|rintf)|e(?:holdexcept|set(?:e(?:nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(?:aiseexcept|ror)|get(?:e(?:nv|xceptflag)|round))|flush|w(?:scanf|ide|printf|rite)|loor(?:f|l)?|abs(?:f|l)?|get(?:s|c|pos|w(?:s|c))|re(?:open|e|ad|xp(?:f|l)?)|m(?:in(?:f|l)?|od(?:f|l)?|a(?:f|l|x(?:f|l)?)?))|l(?:d(?:iv|exp(?:f|l)?)|o(?:ngjmp|cal(?:time|econv)|g(?:1(?:p(?:f|l)?|0(?:f|l)?)|2(?:f|l)?|f|l|b(?:f|l)?)?)|abs|l(?:div|abs|r(?:int(?:f|l)?|ound(?:f|l)?))|r(?:int(?:f|l)?|ound(?:f|l)?)|gamma(?:f|l)?)|w(?:scanf|c(?:s(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?|mbs)|pbrk|ftime|len|r(?:chr|tombs)|xfrm)|to(?:b|mb)|rtomb)|printf|mem(?:set|c(?:hr|py|mp)|move))|a(?:s(?:sert|ctime|in(?:h(?:f|l)?|f|l)?)|cos(?:h(?:f|l)?|f|l)?|t(?:o(?:i|f|l(?:l)?)|exit|an(?:h(?:f|l)?|2(?:f|l)?|f|l)?)|b(?:s|ort))|g(?:et(?:s|c(?:har)?|env|wc(?:har)?)|mtime)|r(?:int(?:f|l)?|ound(?:f|l)?|e(?:name|alloc|wind|m(?:ove|quo(?:f|l)?|ainder(?:f|l)?))|a(?:nd|ise))|b(?:search|towc)|m(?:odf(?:f|l)?|em(?:set|c(?:hr|py|mp)|move)|ktime|alloc|b(?:s(?:init|towcs|rtowcs)|towc|len|r(?:towc|len))))\\b" var c_cppHighlightRules = function() { - var docComment = new DocCommentHighlightRules(); - - var keywords = lang.arrayToMap( - ("and|double|not_eq|throw|and_eq|dynamic_cast|operator|true|" + - "asm|else|or|try|auto|enum|or_eq|typedef|bitand|explicit|private|" + - "typeid|bitor|extern|protected|typename|bool|false|public|union|" + - "break|float|register|unsigned|case|fro|reinterpret-cast|using|catch|" + - "friend|return|virtual|char|goto|short|void|class|if|signed|volatile|" + - "compl|inline|sizeof|wchar_t|const|int|static|while|const-cast|long|" + - "static_cast|xor|continue|mutable|struct|xor_eq|default|namespace|" + - "switch|delete|new|template|do|not|this|for").split("|") + var keywordControls = ( + "break|case|continue|default|do|else|for|goto|if|_Pragma|" + + "return|switch|while|catch|operator|try|throw|using" + ); + + var storageType = ( + "asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|" + + "_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|" + + "class|wchar_t|template|char16_t|char32_t" ); - var buildinConstants = lang.arrayToMap( - ("NULL").split("|") + var storageModifiers = ( + "const|extern|register|restrict|static|volatile|inline|private|" + + "protected|public|friend|explicit|virtual|export|mutable|typename|" + + "constexpr|new|delete|alignas|alignof|decltype|noexcept|thread_local" ); + var keywordOperators = ( + "and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq" + + "const_cast|dynamic_cast|reinterpret_cast|static_cast|sizeof|namespace" + ); + + var builtinConstants = ( + "NULL|true|false|TRUE|FALSE|nullptr" + ); + + var keywordMapper = this.$keywords = this.createKeywordMapper({ + "keyword.control" : keywordControls, + "storage.type" : storageType, + "storage.modifier" : storageModifiers, + "keyword.operator" : keywordOperators, + "variable.language": "this", + "constant.language": builtinConstants + }, "identifier"); + + var identifierRe = "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\d\\$_\u00a1-\uffff]*\\b"; + // regexp must not have capturing parentheses. Use (?:) instead. // regexps are ordered -> the first match is used - this.$rules = { + this.$rules = { "start" : [ - { - token : "comment", - regex : "\\/\\/.*$" - }, - docComment.getStartRule("doc-start"), - { - token : "comment", // multi line comment - regex : "\\/\\*", - next : "comment" - }, { - token : "string", // single line - regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' - }, { - token : "string", // multi line string start - regex : '["].*\\\\$', - next : "qqstring" - }, { - token : "string", // single line - regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" - }, { - token : "string", // multi line string start - regex : "['].*\\\\$", - next : "qstring" - }, { - token : "constant.numeric", // hex - regex : "0[xX][0-9a-fA-F]+\\b" - }, { - token : "constant.numeric", // float - regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" - }, { - token : "constant", // - regex : "<[a-zA-Z0-9.]+>" - }, { - token : "keyword", // pre-compiler directivs - regex : "(?:#include|#pragma|#line|#define|#undef|#ifdef|#else|#elif|#endif|#ifndef)" - }, { - token : function(value) { - if (value == "this") - return "variable.language"; - else if (keywords.hasOwnProperty(value)) - return "keyword"; - else if (buildinConstants.hasOwnProperty(value)) - return "constant.language"; - else - return "identifier"; - }, - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" - }, { - token : "keyword.operator", - regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)" - }, { - token : "lparen", - regex : "[[({]" - }, { - token : "rparen", - regex : "[\\])}]" - }, { - token : "text", - regex : "\\s+" - } + { + token : "comment", + regex : "//", + next : "singleLineComment" + }, + DocCommentHighlightRules.getStartRule("doc-start"), + { + token : "comment", // multi line comment + regex : "\\/\\*", + next : "comment" + }, { + token : "string", // single line + regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' + }, { + token : "string", // multi line string start + regex : '["].*\\\\$', + next : "qqstring" + }, { + token : "string", // single line + regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" + }, { + token : "string", // multi line string start + regex : "['].*\\\\$", + next : "qstring" + }, { + token : "constant.numeric", // hex + regex : "0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b" + }, { + token : "constant.numeric", // float + regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b" + }, { + token : "keyword", // pre-compiler directives + regex : "#\\s*(?:include|import|pragma|line|define|undef)\\b", + next : "directive" + }, { + token : "keyword", // special case pre-compiler directive + regex : "#\\s*(?:endif|if|ifdef|else|elif|ifndef)\\b" + }, { + token : "support.function.C99.c", + regex : cFunctions + }, { + token : keywordMapper, + regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + }, { + token : "keyword.operator", + regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)" + }, { + token : "punctuation.operator", + regex : "\\?|\\:|\\,|\\;|\\." + }, { + token : "paren.lparen", + regex : "[[({]" + }, { + token : "paren.rparen", + regex : "[\\])}]" + }, { + token : "text", + regex : "\\s+" + } ], "comment" : [ - { - token : "comment", // closing comment - regex : ".*?\\*\\/", - next : "start" - }, { - token : "comment", // comment spanning whole line - regex : ".+" - } + { + token : "comment", // closing comment + regex : ".*?\\*\\/", + next : "start" + }, { + token : "comment", // comment spanning whole line + regex : ".+" + } + ], + "singleLineComment" : [ + { + token : "comment", + regex : /\\$/, + next : "singleLineComment" + }, { + token : "comment", + regex : /$/, + next : "start" + }, { + defaultToken: "comment" + } ], "qqstring" : [ { - token : "string", - regex : '(?:(?:\\\\.)|(?:[^"\\\\]))*?"', - next : "start" - }, { - token : "string", - regex : '.+' - } + token : "string", + regex : '(?:(?:\\\\.)|(?:[^"\\\\]))*?"', + next : "start" + }, { + defaultToken : "string" + } ], "qstring" : [ - { - token : "string", - regex : "(?:(?:\\\\.)|(?:[^'\\\\]))*?'", - next : "start" - }, { - token : "string", - regex : '.+' - } + { + token : "string", + regex : "(?:(?:\\\\.)|(?:[^'\\\\]))*?'", + next : "start" + }, { + defaultToken : "string" + } + ], + "directive" : [ + { + token : "constant.other.multiline", + regex : /\\/ + }, + { + token : "constant.other.multiline", + regex : /.*\\/ + }, + { + token : "constant.other", + regex : "\\s*<.+?>", + next : "start" + }, + { + token : "constant.other", // single line + regex : '\\s*["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]', + next : "start" + }, + { + token : "constant.other", // single line + regex : "\\s*['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']", + next : "start" + }, + // "\" implies multiline, while "/" implies comment + { + token : "constant.other", + regex : /[^\\\/]+/, + next : "start" + } ] }; - this.addRules(docComment.getRules(), "doc-"); - this.$rules["doc-start"][0].next = "start"; + this.embedRules(DocCommentHighlightRules, "doc-", + [ DocCommentHighlightRules.getEndRule("start") ]); }; oop.inherits(c_cppHighlightRules, TextHighlightRules); diff --git a/lib/ace/mode/cirru.js b/lib/ace/mode/cirru.js new file mode 100644 index 00000000..5f1c4d9e --- /dev/null +++ b/lib/ace/mode/cirru.js @@ -0,0 +1,51 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2014, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var CirruHighlightRules = require("./cirru_highlight_rules").CirruHighlightRules; +var CoffeeFoldMode = require("./folding/coffee").FoldMode; + +var Mode = function() { + this.HighlightRules = CirruHighlightRules; + this.foldingRules = new CoffeeFoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.lineCommentStart = "--"; + this.$id = "ace/mode/cirru"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); diff --git a/lib/ace/mode/cirru_highlight_rules.js b/lib/ace/mode/cirru_highlight_rules.js new file mode 100644 index 00000000..737ec0be --- /dev/null +++ b/lib/ace/mode/cirru_highlight_rules.js @@ -0,0 +1,125 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2014, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +// see http://cirru.org for more about this language +var CirruHighlightRules = function() { + this.$rules = { + start: [{ + token: 'constant.numeric', + regex: /[\d\.]+/ + }, { + token: 'comment.line.double-dash', + regex: /--/, + next: 'comment', + }, { + token: 'storage.modifier', + regex: /\(/, + }, { + token: 'storage.modifier', + regex: /\,/, + next: 'line', + }, { + token: 'support.function', + regex: /[^\(\)\"\s]+/, + next: 'line' + }, { + token: 'string.quoted.double', + regex: /"/, + next: 'string', + }, { + token: 'storage.modifier', + regex: /\)/, + }], + comment: [{ + token: 'comment.line.double-dash', + regex: /\ +[^\n]+/, + next: 'start', + }], + string: [{ + token: 'string.quoted.double', + regex: /"/, + next: 'line', + }, { + token: 'constant.character.escape', + regex: /\\/, + next: 'escape', + }, { + token: 'string.quoted.double', + regex: /[^\\\"]+/, + }], + escape: [{ + token: 'constant.character.escape', + regex: /./, + next: 'string', + }], + line: [{ + token: 'constant.numeric', + regex: /[\d\.]+/ + }, { + token: 'markup.raw', + regex: /^\s*/, + next: 'start', + }, { + token: 'storage.modifier', + regex: /\$/, + next: 'start', + }, { + token: 'variable.parameter', + regex: /[^\(\)\"\s]+/ + }, { + token: 'storage.modifier', + regex: /\(/, + next: 'start' + }, { + token: 'storage.modifier', + regex: /\)/, + }, { + token: 'markup.raw', + regex: /^\ */, + next: 'start', + }, { + token: 'string.quoted.double', + regex: /"/, + next: 'string', + }] + } + +}; + +oop.inherits(CirruHighlightRules, TextHighlightRules); + +exports.CirruHighlightRules = CirruHighlightRules; +}); diff --git a/lib/ace/mode/clojure.js b/lib/ace/mode/clojure.js new file mode 100644 index 00000000..ee44ac3e --- /dev/null +++ b/lib/ace/mode/clojure.js @@ -0,0 +1,128 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var ClojureHighlightRules = require("./clojure_highlight_rules").ClojureHighlightRules; +var MatchingParensOutdent = require("./matching_parens_outdent").MatchingParensOutdent; + +var Mode = function() { + this.HighlightRules = ClojureHighlightRules; + this.$outdent = new MatchingParensOutdent(); +}; +oop.inherits(Mode, TextMode); + +(function() { + + this.lineCommentStart = ";"; + this.minorIndentFunctions = ["defn", "defn-", "defmacro", "def", "deftest", "testing"]; + + this.$toIndent = function(str) { + return str.split('').map(function(ch) { + if (/\s/.exec(ch)) { + return ch; + } else { + return ' '; + } + }).join(''); + }; + + this.$calculateIndent = function(line, tab) { + var baseIndent = this.$getIndent(line); + var delta = 0; + var isParen, ch; + // Walk back from end of line, find matching braces + for (var i = line.length - 1; i >= 0; i--) { + ch = line[i]; + if (ch === '(') { + delta--; + isParen = true; + } else if (ch === '(' || ch === '[' || ch === '{') { + delta--; + isParen = false; + } else if (ch === ')' || ch === ']' || ch === '}') { + delta++; + } + if (delta < 0) { + break; + } + } + if (delta < 0 && isParen) { + // Were more brackets opened than closed and was a ( left open? + i += 1; + var iBefore = i; + var fn = ''; + while (true) { + ch = line[i]; + if (ch === ' ' || ch === '\t') { + if(this.minorIndentFunctions.indexOf(fn) !== -1) { + return this.$toIndent(line.substring(0, iBefore - 1) + tab); + } else { + return this.$toIndent(line.substring(0, i + 1)); + } + } else if (ch === undefined) { + return this.$toIndent(line.substring(0, iBefore - 1) + tab); + } + fn += line[i]; + i++; + } + } else if(delta < 0 && !isParen) { + // Were more brackets openend than closed and was it not a (? + return this.$toIndent(line.substring(0, i+1)); + } else if(delta > 0) { + // Mere more brackets closed than opened? Outdent. + baseIndent = baseIndent.substring(0, baseIndent.length - tab.length); + return baseIndent; + } else { + // Were they nicely matched? Just indent like line before. + return baseIndent; + } + }; + + this.getNextLineIndent = function(state, line, tab) { + return this.$calculateIndent(line, tab); + }; + + this.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); + }; + + this.autoOutdent = function(state, doc, row) { + this.$outdent.autoOutdent(doc, row); + }; + + this.$id = "ace/mode/clojure"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); diff --git a/lib/ace/mode/clojure_highlight_rules.js b/lib/ace/mode/clojure_highlight_rules.js new file mode 100644 index 00000000..f7e28d87 --- /dev/null +++ b/lib/ace/mode/clojure_highlight_rules.js @@ -0,0 +1,200 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + + + +var ClojureHighlightRules = function() { + + var builtinFunctions = ( + '* *1 *2 *3 *agent* *allow-unresolved-vars* *assert* *clojure-version* ' + + '*command-line-args* *compile-files* *compile-path* *e *err* *file* ' + + '*flush-on-newline* *in* *macro-meta* *math-context* *ns* *out* ' + + '*print-dup* *print-length* *print-level* *print-meta* *print-readably* ' + + '*read-eval* *source-path* *use-context-classloader* ' + + '*warn-on-reflection* + - -> ->> .. / < <= = ' + + '== > > >= >= accessor aclone ' + + 'add-classpath add-watch agent agent-errors aget alength alias all-ns ' + + 'alter alter-meta! alter-var-root amap ancestors and apply areduce ' + + 'array-map aset aset-boolean aset-byte aset-char aset-double aset-float ' + + 'aset-int aset-long aset-short assert assoc assoc! assoc-in associative? ' + + 'atom await await-for await1 bases bean bigdec bigint binding bit-and ' + + 'bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left ' + + 'bit-shift-right bit-test bit-xor boolean boolean-array booleans ' + + 'bound-fn bound-fn* butlast byte byte-array bytes cast char char-array ' + + 'char-escape-string char-name-string char? chars chunk chunk-append ' + + 'chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? ' + + 'class class? clear-agent-errors clojure-version coll? comment commute ' + + 'comp comparator compare compare-and-set! compile complement concat cond ' + + 'condp conj conj! cons constantly construct-proxy contains? count ' + + 'counted? create-ns create-struct cycle dec decimal? declare definline ' + + 'defmacro defmethod defmulti defn defn- defonce defstruct delay delay? ' + + 'deliver deref derive descendants destructure disj disj! dissoc dissoc! ' + + 'distinct distinct? doall doc dorun doseq dosync dotimes doto double ' + + 'double-array doubles drop drop-last drop-while empty empty? ensure ' + + 'enumeration-seq eval even? every? false? ffirst file-seq filter find ' + + 'find-doc find-ns find-var first float float-array float? floats flush ' + + 'fn fn? fnext for force format future future-call future-cancel ' + + 'future-cancelled? future-done? future? gen-class gen-interface gensym ' + + 'get get-in get-method get-proxy-class get-thread-bindings get-validator ' + + 'hash hash-map hash-set identical? identity if-let if-not ifn? import ' + + 'in-ns inc init-proxy instance? int int-array integer? interleave intern ' + + 'interpose into into-array ints io! isa? iterate iterator-seq juxt key ' + + 'keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list ' + + 'list* list? load load-file load-reader load-string loaded-libs locking ' + + 'long long-array longs loop macroexpand macroexpand-1 make-array ' + + 'make-hierarchy map map? mapcat max max-key memfn memoize merge ' + + 'merge-with meta method-sig methods min min-key mod name namespace neg? ' + + 'newline next nfirst nil? nnext not not-any? not-empty not-every? not= ' + + 'ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ' + + 'ns-refers ns-resolve ns-unalias ns-unmap nth nthnext num number? odd? ' + + 'or parents partial partition pcalls peek persistent! pmap pop pop! ' + + 'pop-thread-bindings pos? pr pr-str prefer-method prefers ' + + 'primitives-classnames print print-ctor print-doc print-dup print-method ' + + 'print-namespace-doc print-simple print-special-doc print-str printf ' + + 'println println-str prn prn-str promise proxy proxy-call-with-super ' + + 'proxy-mappings proxy-name proxy-super push-thread-bindings pvalues quot ' + + 'rand rand-int range ratio? rational? rationalize re-find re-groups ' + + 're-matcher re-matches re-pattern re-seq read read-line read-string ' + + 'reduce ref ref-history-count ref-max-history ref-min-history ref-set ' + + 'refer refer-clojure release-pending-sends rem remove remove-method ' + + 'remove-ns remove-watch repeat repeatedly replace replicate require ' + + 'reset! reset-meta! resolve rest resultset-seq reverse reversible? rseq ' + + 'rsubseq second select-keys send send-off seq seq? seque sequence ' + + 'sequential? set set-validator! set? short short-array shorts ' + + 'shutdown-agents slurp some sort sort-by sorted-map sorted-map-by ' + + 'sorted-set sorted-set-by sorted? special-form-anchor special-symbol? ' + + 'split-at split-with str stream? string? struct struct-map subs subseq ' + + 'subvec supers swap! symbol symbol? sync syntax-symbol-anchor take ' + + 'take-last take-nth take-while test the-ns time to-array to-array-2d ' + + 'trampoline transient tree-seq true? type unchecked-add unchecked-dec ' + + 'unchecked-divide unchecked-inc unchecked-multiply unchecked-negate ' + + 'unchecked-remainder unchecked-subtract underive unquote ' + + 'unquote-splicing update-in update-proxy use val vals var-get var-set ' + + 'var? vary-meta vec vector vector? when when-first when-let when-not ' + + 'while with-bindings with-bindings* with-in-str with-loading-context ' + + 'with-local-vars with-meta with-open with-out-str with-precision xml-seq ' + + 'zero? zipmap' + ); + + var keywords = ('throw try var ' + + 'def do fn if let loop monitor-enter monitor-exit new quote recur set!' + ); + + var buildinConstants = ("true false nil"); + + var keywordMapper = this.createKeywordMapper({ + "keyword": keywords, + "constant.language": buildinConstants, + "support.function": builtinFunctions + }, "identifier", false, " "); + + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + + this.$rules = { + "start" : [ + { + token : "comment", + regex : ";.*$" + }, { + token : "keyword", //parens + regex : "[\\(|\\)]" + }, { + token : "keyword", //lists + regex : "[\\'\\(]" + }, { + token : "keyword", //vectors + regex : "[\\[|\\]]" + }, { + token : "keyword", //sets and maps + regex : "[\\{|\\}|\\#\\{|\\#\\}]" + }, { + token : "keyword", // ampersands + regex : '[\\&]' + }, { + token : "keyword", // metadata + regex : '[\\#\\^\\{]' + }, { + token : "keyword", // anonymous fn syntactic sugar + regex : '[\\%]' + }, { + token : "keyword", // deref reader macro + regex : '[@]' + }, { + token : "constant.numeric", // hex + regex : "0[xX][0-9a-fA-F]+\\b" + }, { + token : "constant.numeric", // float + regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" + }, { + token : "constant.language", + regex : '[!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+||=|!=|<=|>=|<>|<|>|!|&&]' + }, { + token : keywordMapper, + regex : "[a-zA-Z_$][a-zA-Z0-9_$\\-]*\\b" + }, { + token : "string", // single line + regex : '"', + next: "string" + }, { + token : "constant", // symbol + regex : /:[^()\[\]{}'"\^%`,;\s]+/ + }, { + token : "string.regexp", //Regular Expressions + regex : '/#"(?:\\.|(?:\\\")|[^\""\n])*"/g' + } + + ], + "string" : [ + { + token : "constant.language.escape", + regex : "\\\\.|\\\\$" + }, { + token : "string", + regex : '[^"\\\\]+' + }, { + token : "string", + regex : '"', + next : "start" + } + ] + }; +}; + +oop.inherits(ClojureHighlightRules, TextHighlightRules); + +exports.ClojureHighlightRules = ClojureHighlightRules; +}); diff --git a/lib/ace/mode/cobol.js b/lib/ace/mode/cobol.js new file mode 100644 index 00000000..91713bd0 --- /dev/null +++ b/lib/ace/mode/cobol.js @@ -0,0 +1,53 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var CobolHighlightRules = require("./cobol_highlight_rules").CobolHighlightRules; +var Range = require("../range").Range; + +var Mode = function() { + this.HighlightRules = CobolHighlightRules; +}; +oop.inherits(Mode, TextMode); + +(function() { + + this.lineCommentStart = "*"; + + this.$id = "ace/mode/cobol"; +}).call(Mode.prototype); + +exports.Mode = Mode; + +}); diff --git a/lib/ace/mode/cobol_highlight_rules.js b/lib/ace/mode/cobol_highlight_rules.js new file mode 100644 index 00000000..36335c93 --- /dev/null +++ b/lib/ace/mode/cobol_highlight_rules.js @@ -0,0 +1,100 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var CobolHighlightRules = function() { +var keywords = "ACCEPT|MERGE|SUM|ADD||MESSAGE|TABLE|ADVANCING|MODE|TAPE|" + +"AFTER|MULTIPLY|TEST|ALL|NEGATIVE|TEXT|ALPHABET|NEXT|THAN|" + +"ALSO|NO|THEN|ALTERNATE|NOT|THROUGH|AND|NUMBER|THRU|ANY|OCCURS|" + +"TIME|ARE|OF|TO|AREA|OFF|TOP||ASCENDING|OMITTED|TRUE|ASSIGN|ON|TYPE|AT|OPEN|" + +"UNIT|AUTHOR|OR|UNTIL|BEFORE|OTHER|UP|BLANK|OUTPUT|USE|BLOCK|PAGE|USING|BOTTOM|" + +"PERFORM|VALUE|BY|PIC|VALUES|CALL|PICTURE|WHEN|CANCEL|PLUS|WITH|CD|POINTER|WRITE|" + +"CHARACTER|POSITION||ZERO|CLOSE|POSITIVE|ZEROS|COLUMN|PROCEDURE|ZEROES|COMMA|PROGRAM|" + +"COMMON|PROGRAM-ID|COMMUNICATION|QUOTE|COMP|RANDOM|COMPUTE|READ|CONTAINS|RECEIVE|CONFIGURATION|" + +"RECORD|CONTINUE|REDEFINES|CONTROL|REFERENCE|COPY|REMAINDER|COUNT|REPLACE|DATA|REPORT|DATE|RESERVE|" + +"DAY|RESET|DELETE|RETURN|DESTINATION|REWIND|DISABLE|REWRITE|DISPLAY|RIGHT|DIVIDE|RUN|DOWN|SAME|" + +"ELSE|SEARCH|ENABLE|SECTION|END|SELECT|ENVIRONMENT|SENTENCE|EQUAL|SET|ERROR|SIGN|EXIT|SEQUENTIAL|" + +"EXTERNAL|SIZE|FLASE|SORT|FILE|SOURCE|LENGTH|SPACE|LESS|STANDARD|LIMIT|START|LINE|STOP|LOCK|STRING|LOW-VALUE|SUBTRACT"; + + var builtinConstants = ( + "true|false|null" + ); + + var builtinFunctions = ( + "count|min|max|avg|sum|rank|now|coalesce|main" + ); + + var keywordMapper = this.createKeywordMapper({ + "support.function": builtinFunctions, + "keyword": keywords, + "constant.language": builtinConstants + }, "identifier", true); + + this.$rules = { + "start" : [ { + token : "comment", + regex : "\\*.*$" + }, { + token : "string", // " string + regex : '".*?"' + }, { + token : "string", // ' string + regex : "'.*?'" + }, { + token : "constant.numeric", // float + regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" + }, { + token : keywordMapper, + regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + }, { + token : "keyword.operator", + regex : "\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|=" + }, { + token : "paren.lparen", + regex : "[\\(]" + }, { + token : "paren.rparen", + regex : "[\\)]" + }, { + token : "text", + regex : "\\s+" + } ] + }; +}; + +oop.inherits(CobolHighlightRules, TextHighlightRules); + +exports.CobolHighlightRules = CobolHighlightRules; +}); \ No newline at end of file diff --git a/lib/ace/mode/coffee.js b/lib/ace/mode/coffee.js index 27a9360a..e866f2b0 100644 --- a/lib/ace/mode/coffee.js +++ b/lib/ace/mode/coffee.js @@ -1,99 +1,135 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Satoshi Murakami - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var Tokenizer = require("ace/tokenizer").Tokenizer; -var Rules = require("ace/mode/coffee_highlight_rules").CoffeeHighlightRules; -var Outdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent; -var Range = require("ace/range").Range; -var TextMode = require("ace/mode/text").Mode; -var oop = require("pilot/oop") +var Rules = require("./coffee_highlight_rules").CoffeeHighlightRules; +var Outdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var FoldMode = require("./folding/coffee").FoldMode; +var Range = require("../range").Range; +var TextMode = require("./text").Mode; +var WorkerClient = require("../worker/worker_client").WorkerClient; +var oop = require("../lib/oop"); -function CoffeeMode() { - this.$tokenizer = new Tokenizer(new Rules().getRules()); - this.$outdent = new Outdent(); -}; +function Mode() { + this.HighlightRules = Rules; + this.$outdent = new Outdent(); + this.foldingRules = new FoldMode(); +} -oop.inherits(CoffeeMode, TextMode); +oop.inherits(Mode, TextMode); -var proto = CoffeeMode.prototype; -var indenter = /(?:[({[=:]|[-=]>|\b(?:else|switch|try|catch(?:\s*[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)?|finally))\s*$/; -var commentLine = /^(\s*)#/; -var hereComment = /^\s*###(?!#)/; -var indentation = /^\s*/; +(function() { + + /*: + [({[=:] # Opening parentheses or brackets + |[-=]> # OR single or double arrow + |\b(?: # OR one of these words: + else # else + |try # OR try + |(?:swi|ca)tch # OR catch, optionally followed by: + (?:\s*[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)? # a variable + |finally # OR finally + ))\s*$ # all as the last thing on a line (allowing trailing space) + | # ---- OR ---- : + ^\s* # a line starting with optional space + (else\b\s*)? # followed by an optional "else" + (?: # followed by one of the following: + if # if + |for # OR for + |while # OR while + |loop # OR loop + )\b # (as a word) + (?!.*\bthen\b) # ... but NOT followed by "then" on the line + */ + var indenter = /(?:[({[=:]|[-=]>|\b(?:else|try|(?:swi|ca)tch(?:\s+[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)?|finally))\s*$|^\s*(else\b\s*)?(?:if|for|while|loop)\b(?!.*\bthen\b)/; + var commentLine = /^(\s*)#/; + var hereComment = /^\s*###(?!#)/; + var indentation = /^\s*/; + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + var tokens = this.getTokenizer().getLineTokens(line, state).tokens; + + if (!(tokens.length && tokens[tokens.length - 1].type === 'comment') && + state === 'start' && indenter.test(line)) + indent += tab; + return indent; + }; + + this.toggleCommentLines = function(state, doc, startRow, endRow){ + console.log("toggle"); + var range = new Range(0, 0, 0, 0); + for (var i = startRow; i <= endRow; ++i) { + var line = doc.getLine(i); + if (hereComment.test(line)) + continue; + + if (commentLine.test(line)) + line = line.replace(commentLine, '$1'); + else + line = line.replace(indentation, '$&#'); + + range.end.row = range.start.row = i; + range.end.column = line.length + 1; + doc.replace(range, line); + } + }; + + this.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); + }; + + this.autoOutdent = function(state, doc, row) { + this.$outdent.autoOutdent(doc, row); + }; + + this.createWorker = function(session) { + var worker = new WorkerClient(["ace"], "ace/mode/coffee_worker", "Worker"); + worker.attachToDocument(session.getDocument()); + + worker.on("annotate", function(e) { + session.setAnnotations(e.data); + }); + + worker.on("terminate", function() { + session.clearAnnotations(); + }); + + return worker; + }; -proto.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - var tokens = this.$tokenizer.getLineTokens(line, state).tokens; + this.$id = "ace/mode/coffee"; +}).call(Mode.prototype); - if (!(tokens.length && tokens[tokens.length - 1].type === 'comment') && - state === 'start' && indenter.test(line)) - indent += tab; - return indent; -}; +exports.Mode = Mode; -proto.toggleCommentLines = function(state, doc, startRow, endRow){ - console.log("toggle"); - var range = new Range(0, 0, 0, 0); - for (var i = startRow; i <= endRow; ++i) { - var line = doc.getLine(i); - if (hereComment.test(line)) - continue; - - if (commentLine.test(line)) - line = line.replace(commentLine, '$1'); - else - line = line.replace(indentation, '$&#'); - - range.end.row = range.start.row = i; - range.end.column = line.length + 1; - doc.replace(range, line); - } -}; - -proto.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); -}; - -proto.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); -}; - -exports.Mode = CoffeeMode; - -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/coffee/coffee-script.js b/lib/ace/mode/coffee/coffee-script.js new file mode 100644 index 00000000..9e9719f7 --- /dev/null +++ b/lib/ace/mode/coffee/coffee-script.js @@ -0,0 +1,62 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + + var Lexer = require("./lexer").Lexer; + var parser = require("./parser"); + + var lexer = new Lexer(); + parser.lexer = { + lex: function() { + var tag, token; + token = this.tokens[this.pos++]; + if (token) { + tag = token[0], this.yytext = token[1], this.yylloc = token[2]; + this.yylineno = this.yylloc.first_line; + } else { + tag = ''; + } + return tag; + }, + setInput: function(tokens) { + this.tokens = tokens; + return this.pos = 0; + }, + upcomingInput: function() { + return ""; + } + }; + parser.yy = require('./nodes'); + + exports.parse = function(code) { + return parser.parse(lexer.tokenize(code)); + }; +}); diff --git a/lib/ace/mode/coffee/helpers.js b/lib/ace/mode/coffee/helpers.js new file mode 100644 index 00000000..60412fc6 --- /dev/null +++ b/lib/ace/mode/coffee/helpers.js @@ -0,0 +1,271 @@ +/** + * Copyright (c) 2009-2013 Jeremy Ashkenas + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +define(function(require, exports, module) { +// Generated by CoffeeScript 1.6.3 + + var buildLocationData, extend, flatten, last, repeat, syntaxErrorToString, _ref; + + exports.starts = function(string, literal, start) { + return literal === string.substr(start, literal.length); + }; + + exports.ends = function(string, literal, back) { + var len; + len = literal.length; + return literal === string.substr(string.length - len - (back || 0), len); + }; + + exports.repeat = repeat = function(str, n) { + var res; + res = ''; + while (n > 0) { + if (n & 1) { + res += str; + } + n >>>= 1; + str += str; + } + return res; + }; + + exports.compact = function(array) { + var item, _i, _len, _results; + _results = []; + for (_i = 0, _len = array.length; _i < _len; _i++) { + item = array[_i]; + if (item) { + _results.push(item); + } + } + return _results; + }; + + exports.count = function(string, substr) { + var num, pos; + num = pos = 0; + if (!substr.length) { + return 1 / 0; + } + while (pos = 1 + string.indexOf(substr, pos)) { + num++; + } + return num; + }; + + exports.merge = function(options, overrides) { + return extend(extend({}, options), overrides); + }; + + extend = exports.extend = function(object, properties) { + var key, val; + for (key in properties) { + val = properties[key]; + object[key] = val; + } + return object; + }; + + exports.flatten = flatten = function(array) { + var element, flattened, _i, _len; + flattened = []; + for (_i = 0, _len = array.length; _i < _len; _i++) { + element = array[_i]; + if (element instanceof Array) { + flattened = flattened.concat(flatten(element)); + } else { + flattened.push(element); + } + } + return flattened; + }; + + exports.del = function(obj, key) { + var val; + val = obj[key]; + delete obj[key]; + return val; + }; + + exports.last = last = function(array, back) { + return array[array.length - (back || 0) - 1]; + }; + + exports.some = (_ref = Array.prototype.some) != null ? _ref : function(fn) { + var e, _i, _len; + for (_i = 0, _len = this.length; _i < _len; _i++) { + e = this[_i]; + if (fn(e)) { + return true; + } + } + return false; + }; + + exports.invertLiterate = function(code) { + var line, lines, maybe_code; + maybe_code = true; + lines = (function() { + var _i, _len, _ref1, _results; + _ref1 = code.split('\n'); + _results = []; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + line = _ref1[_i]; + if (maybe_code && /^([ ]{4}|[ ]{0,3}\t)/.test(line)) { + _results.push(line); + } else if (maybe_code = /^\s*$/.test(line)) { + _results.push(line); + } else { + _results.push('# ' + line); + } + } + return _results; + })(); + return lines.join('\n'); + }; + + buildLocationData = function(first, last) { + if (!last) { + return first; + } else { + return { + first_line: first.first_line, + first_column: first.first_column, + last_line: last.last_line, + last_column: last.last_column + }; + } + }; + + exports.addLocationDataFn = function(first, last) { + return function(obj) { + if (((typeof obj) === 'object') && (!!obj['updateLocationDataIfMissing'])) { + obj.updateLocationDataIfMissing(buildLocationData(first, last)); + } + return obj; + }; + }; + + exports.locationDataToString = function(obj) { + var locationData; + if (("2" in obj) && ("first_line" in obj[2])) { + locationData = obj[2]; + } else if ("first_line" in obj) { + locationData = obj; + } + if (locationData) { + return ("" + (locationData.first_line + 1) + ":" + (locationData.first_column + 1) + "-") + ("" + (locationData.last_line + 1) + ":" + (locationData.last_column + 1)); + } else { + return "No location data"; + } + }; + + exports.baseFileName = function(file, stripExt, useWinPathSep) { + var parts, pathSep; + if (stripExt == null) { + stripExt = false; + } + if (useWinPathSep == null) { + useWinPathSep = false; + } + pathSep = useWinPathSep ? /\\|\// : /\//; + parts = file.split(pathSep); + file = parts[parts.length - 1]; + if (!(stripExt && file.indexOf('.') >= 0)) { + return file; + } + parts = file.split('.'); + parts.pop(); + if (parts[parts.length - 1] === 'coffee' && parts.length > 1) { + parts.pop(); + } + return parts.join('.'); + }; + + exports.isCoffee = function(file) { + return /\.((lit)?coffee|coffee\.md)$/.test(file); + }; + + exports.isLiterate = function(file) { + return /\.(litcoffee|coffee\.md)$/.test(file); + }; + + exports.throwSyntaxError = function(message, location) { + var error; + if (location.last_line == null) { + location.last_line = location.first_line; + } + if (location.last_column == null) { + location.last_column = location.first_column; + } + error = new SyntaxError(message); + error.location = location; + error.toString = syntaxErrorToString; + error.stack = error.toString(); + throw error; + }; + + exports.updateSyntaxError = function(error, code, filename) { + if (error.toString === syntaxErrorToString) { + error.code || (error.code = code); + error.filename || (error.filename = filename); + error.stack = error.toString(); + } + return error; + }; + + syntaxErrorToString = function() { + var codeLine, colorize, colorsEnabled, end, filename, first_column, first_line, last_column, last_line, marker, start, _ref1, _ref2; + if (!(this.code && this.location)) { + return Error.prototype.toString.call(this); + } + _ref1 = this.location, first_line = _ref1.first_line, first_column = _ref1.first_column, last_line = _ref1.last_line, last_column = _ref1.last_column; + if (last_line == null) { + last_line = first_line; + } + if (last_column == null) { + last_column = first_column; + } + filename = this.filename || '[stdin]'; + codeLine = this.code.split('\n')[first_line]; + start = first_column; + end = first_line === last_line ? last_column + 1 : codeLine.length; + marker = repeat(' ', start) + repeat('^', end - start); + if (typeof process !== "undefined" && process !== null) { + colorsEnabled = process.stdout.isTTY && !process.env.NODE_DISABLE_COLORS; + } + if ((_ref2 = this.colorful) != null ? _ref2 : colorsEnabled) { + colorize = function(str) { + return "\x1B[1;31m" + str + "\x1B[0m"; + }; + codeLine = codeLine.slice(0, start) + colorize(codeLine.slice(start, end)) + codeLine.slice(end); + marker = colorize(marker); + } + return "" + filename + ":" + (first_line + 1) + ":" + (first_column + 1) + ": error: " + this.message + "\n" + codeLine + "\n" + marker; + }; + + +}); \ No newline at end of file diff --git a/lib/ace/mode/coffee/lexer.js b/lib/ace/mode/coffee/lexer.js new file mode 100644 index 00000000..05d85236 --- /dev/null +++ b/lib/ace/mode/coffee/lexer.js @@ -0,0 +1,935 @@ +/** + * Copyright (c) 2009-2013 Jeremy Ashkenas + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +define(function(require, exports, module) { +// Generated by CoffeeScript 1.6.3 + + var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, invertLiterate, key, last, locationDataToString, repeat, starts, throwSyntaxError, _ref, _ref1, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + + _ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES; + + _ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last, repeat = _ref1.repeat, invertLiterate = _ref1.invertLiterate, locationDataToString = _ref1.locationDataToString, throwSyntaxError = _ref1.throwSyntaxError; + + exports.Lexer = Lexer = (function() { + function Lexer() {} + + Lexer.prototype.tokenize = function(code, opts) { + var consumed, i, tag, _ref2; + if (opts == null) { + opts = {}; + } + this.literate = opts.literate; + this.indent = 0; + this.baseIndent = 0; + this.indebt = 0; + this.outdebt = 0; + this.indents = []; + this.ends = []; + this.tokens = []; + this.chunkLine = opts.line || 0; + this.chunkColumn = opts.column || 0; + code = this.clean(code); + i = 0; + while (this.chunk = code.slice(i)) { + consumed = this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken(); + _ref2 = this.getLineAndColumnFromChunk(consumed), this.chunkLine = _ref2[0], this.chunkColumn = _ref2[1]; + i += consumed; + } + this.closeIndentation(); + if (tag = this.ends.pop()) { + this.error("missing " + tag); + } + if (opts.rewrite === false) { + return this.tokens; + } + return (new Rewriter).rewrite(this.tokens); + }; + + Lexer.prototype.clean = function(code) { + if (code.charCodeAt(0) === BOM) { + code = code.slice(1); + } + code = code.replace(/\r/g, '').replace(TRAILING_SPACES, ''); + if (WHITESPACE.test(code)) { + code = "\n" + code; + this.chunkLine--; + } + if (this.literate) { + code = invertLiterate(code); + } + return code; + }; + + Lexer.prototype.identifierToken = function() { + var colon, colonOffset, forcedIdentifier, id, idLength, input, match, poppedToken, prev, tag, tagToken, _ref2, _ref3, _ref4; + if (!(match = IDENTIFIER.exec(this.chunk))) { + return 0; + } + input = match[0], id = match[1], colon = match[2]; + idLength = id.length; + poppedToken = void 0; + if (id === 'own' && this.tag() === 'FOR') { + this.token('OWN', id); + return id.length; + } + forcedIdentifier = colon || (prev = last(this.tokens)) && (((_ref2 = prev[0]) === '.' || _ref2 === '?.' || _ref2 === '::' || _ref2 === '?::') || !prev.spaced && prev[0] === '@'); + tag = 'IDENTIFIER'; + if (!forcedIdentifier && (__indexOf.call(JS_KEYWORDS, id) >= 0 || __indexOf.call(COFFEE_KEYWORDS, id) >= 0)) { + tag = id.toUpperCase(); + if (tag === 'WHEN' && (_ref3 = this.tag(), __indexOf.call(LINE_BREAK, _ref3) >= 0)) { + tag = 'LEADING_WHEN'; + } else if (tag === 'FOR') { + this.seenFor = true; + } else if (tag === 'UNLESS') { + tag = 'IF'; + } else if (__indexOf.call(UNARY, tag) >= 0) { + tag = 'UNARY'; + } else if (__indexOf.call(RELATION, tag) >= 0) { + if (tag !== 'INSTANCEOF' && this.seenFor) { + tag = 'FOR' + tag; + this.seenFor = false; + } else { + tag = 'RELATION'; + if (this.value() === '!') { + poppedToken = this.tokens.pop(); + id = '!' + id; + } + } + } + } + if (__indexOf.call(JS_FORBIDDEN, id) >= 0) { + if (forcedIdentifier) { + tag = 'IDENTIFIER'; + id = new String(id); + id.reserved = true; + } else if (__indexOf.call(RESERVED, id) >= 0) { + this.error("reserved word \"" + id + "\""); + } + } + if (!forcedIdentifier) { + if (__indexOf.call(COFFEE_ALIASES, id) >= 0) { + id = COFFEE_ALIAS_MAP[id]; + } + tag = (function() { + switch (id) { + case '!': + return 'UNARY'; + case '==': + case '!=': + return 'COMPARE'; + case '&&': + case '||': + return 'LOGIC'; + case 'true': + case 'false': + return 'BOOL'; + case 'break': + case 'continue': + return 'STATEMENT'; + default: + return tag; + } + })(); + } + tagToken = this.token(tag, id, 0, idLength); + if (poppedToken) { + _ref4 = [poppedToken[2].first_line, poppedToken[2].first_column], tagToken[2].first_line = _ref4[0], tagToken[2].first_column = _ref4[1]; + } + if (colon) { + colonOffset = input.lastIndexOf(':'); + this.token(':', ':', colonOffset, colon.length); + } + return input.length; + }; + + Lexer.prototype.numberToken = function() { + var binaryLiteral, lexedLength, match, number, octalLiteral; + if (!(match = NUMBER.exec(this.chunk))) { + return 0; + } + number = match[0]; + if (/^0[BOX]/.test(number)) { + this.error("radix prefix '" + number + "' must be lowercase"); + } else if (/E/.test(number) && !/^0x/.test(number)) { + this.error("exponential notation '" + number + "' must be indicated with a lowercase 'e'"); + } else if (/^0\d*[89]/.test(number)) { + this.error("decimal literal '" + number + "' must not be prefixed with '0'"); + } else if (/^0\d+/.test(number)) { + this.error("octal literal '" + number + "' must be prefixed with '0o'"); + } + lexedLength = number.length; + if (octalLiteral = /^0o([0-7]+)/.exec(number)) { + number = '0x' + parseInt(octalLiteral[1], 8).toString(16); + } + if (binaryLiteral = /^0b([01]+)/.exec(number)) { + number = '0x' + parseInt(binaryLiteral[1], 2).toString(16); + } + this.token('NUMBER', number, 0, lexedLength); + return lexedLength; + }; + + Lexer.prototype.stringToken = function() { + var octalEsc, quote, string, trimmed; + switch (quote = this.chunk.charAt(0)) { + case "'": + string = SIMPLESTR.exec(this.chunk)[0]; + break; + case '"': + string = this.balancedString(this.chunk, '"'); + } + if (!string) { + return 0; + } + trimmed = this.removeNewlines(string.slice(1, -1)); + if (quote === '"' && 0 < string.indexOf('#{', 1)) { + this.interpolateString(trimmed, { + strOffset: 1, + lexedLength: string.length + }); + } else { + this.token('STRING', quote + this.escapeLines(trimmed) + quote, 0, string.length); + } + if (octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test(string)) { + this.error("octal escape sequences " + string + " are not allowed"); + } + return string.length; + }; + + Lexer.prototype.heredocToken = function() { + var doc, heredoc, match, quote; + if (!(match = HEREDOC.exec(this.chunk))) { + return 0; + } + heredoc = match[0]; + quote = heredoc.charAt(0); + doc = this.sanitizeHeredoc(match[2], { + quote: quote, + indent: null + }); + if (quote === '"' && 0 <= doc.indexOf('#{')) { + this.interpolateString(doc, { + heredoc: true, + strOffset: 3, + lexedLength: heredoc.length + }); + } else { + this.token('STRING', this.makeString(doc, quote, true), 0, heredoc.length); + } + return heredoc.length; + }; + + Lexer.prototype.commentToken = function() { + var comment, here, match; + if (!(match = this.chunk.match(COMMENT))) { + return 0; + } + comment = match[0], here = match[1]; + if (here) { + this.token('HERECOMMENT', this.sanitizeHeredoc(here, { + herecomment: true, + indent: repeat(' ', this.indent) + }), 0, comment.length); + } + return comment.length; + }; + + Lexer.prototype.jsToken = function() { + var match, script; + if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) { + return 0; + } + this.token('JS', (script = match[0]).slice(1, -1), 0, script.length); + return script.length; + }; + + Lexer.prototype.regexToken = function() { + var flags, length, match, prev, regex, _ref2, _ref3; + if (this.chunk.charAt(0) !== '/') { + return 0; + } + if (match = HEREGEX.exec(this.chunk)) { + length = this.heregexToken(match); + return length; + } + prev = last(this.tokens); + if (prev && (_ref2 = prev[0], __indexOf.call((prev.spaced ? NOT_REGEX : NOT_SPACED_REGEX), _ref2) >= 0)) { + return 0; + } + if (!(match = REGEX.exec(this.chunk))) { + return 0; + } + _ref3 = match, match = _ref3[0], regex = _ref3[1], flags = _ref3[2]; + if (regex.slice(0, 2) === '/*') { + this.error('regular expressions cannot begin with `*`'); + } + if (regex === '//') { + regex = '/(?:)/'; + } + this.token('REGEX', "" + regex + flags, 0, match.length); + return match.length; + }; + + Lexer.prototype.heregexToken = function(match) { + var body, flags, flagsOffset, heregex, plusToken, prev, re, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4; + heregex = match[0], body = match[1], flags = match[2]; + if (0 > body.indexOf('#{')) { + re = this.escapeLines(body.replace(HEREGEX_OMIT, '$1$2').replace(/\//g, '\\/'), true); + if (re.match(/^\*/)) { + this.error('regular expressions cannot begin with `*`'); + } + this.token('REGEX', "/" + (re || '(?:)') + "/" + flags, 0, heregex.length); + return heregex.length; + } + this.token('IDENTIFIER', 'RegExp', 0, 0); + this.token('CALL_START', '(', 0, 0); + tokens = []; + _ref2 = this.interpolateString(body, { + regex: true + }); + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + token = _ref2[_i]; + tag = token[0], value = token[1]; + if (tag === 'TOKENS') { + tokens.push.apply(tokens, value); + } else if (tag === 'NEOSTRING') { + if (!(value = value.replace(HEREGEX_OMIT, '$1$2'))) { + continue; + } + value = value.replace(/\\/g, '\\\\'); + token[0] = 'STRING'; + token[1] = this.makeString(value, '"', true); + tokens.push(token); + } else { + this.error("Unexpected " + tag); + } + prev = last(this.tokens); + plusToken = ['+', '+']; + plusToken[2] = prev[2]; + tokens.push(plusToken); + } + tokens.pop(); + if (((_ref3 = tokens[0]) != null ? _ref3[0] : void 0) !== 'STRING') { + this.token('STRING', '""', 0, 0); + this.token('+', '+', 0, 0); + } + (_ref4 = this.tokens).push.apply(_ref4, tokens); + if (flags) { + flagsOffset = heregex.lastIndexOf(flags); + this.token(',', ',', flagsOffset, 0); + this.token('STRING', '"' + flags + '"', flagsOffset, flags.length); + } + this.token(')', ')', heregex.length - 1, 0); + return heregex.length; + }; + + Lexer.prototype.lineToken = function() { + var diff, indent, match, noNewlines, size; + if (!(match = MULTI_DENT.exec(this.chunk))) { + return 0; + } + indent = match[0]; + this.seenFor = false; + size = indent.length - 1 - indent.lastIndexOf('\n'); + noNewlines = this.unfinished(); + if (size - this.indebt === this.indent) { + if (noNewlines) { + this.suppressNewlines(); + } else { + this.newlineToken(0); + } + return indent.length; + } + if (size > this.indent) { + if (noNewlines) { + this.indebt = size - this.indent; + this.suppressNewlines(); + return indent.length; + } + if (!this.tokens.length) { + this.baseIndent = this.indent = size; + return indent.length; + } + diff = size - this.indent + this.outdebt; + this.token('INDENT', diff, indent.length - size, size); + this.indents.push(diff); + this.ends.push('OUTDENT'); + this.outdebt = this.indebt = 0; + } else if (size < this.baseIndent) { + this.error('missing indentation', indent.length); + } else { + this.indebt = 0; + this.outdentToken(this.indent - size, noNewlines, indent.length); + } + this.indent = size; + return indent.length; + }; + + Lexer.prototype.outdentToken = function(moveOut, noNewlines, outdentLength) { + var dent, len; + while (moveOut > 0) { + len = this.indents.length - 1; + if (this.indents[len] === void 0) { + moveOut = 0; + } else if (this.indents[len] === this.outdebt) { + moveOut -= this.outdebt; + this.outdebt = 0; + } else if (this.indents[len] < this.outdebt) { + this.outdebt -= this.indents[len]; + moveOut -= this.indents[len]; + } else { + dent = this.indents.pop() + this.outdebt; + moveOut -= dent; + this.outdebt = 0; + this.pair('OUTDENT'); + this.token('OUTDENT', dent, 0, outdentLength); + } + } + if (dent) { + this.outdebt -= moveOut; + } + while (this.value() === ';') { + this.tokens.pop(); + } + if (!(this.tag() === 'TERMINATOR' || noNewlines)) { + this.token('TERMINATOR', '\n', outdentLength, 0); + } + return this; + }; + + Lexer.prototype.whitespaceToken = function() { + var match, nline, prev; + if (!((match = WHITESPACE.exec(this.chunk)) || (nline = this.chunk.charAt(0) === '\n'))) { + return 0; + } + prev = last(this.tokens); + if (prev) { + prev[match ? 'spaced' : 'newLine'] = true; + } + if (match) { + return match[0].length; + } else { + return 0; + } + }; + + Lexer.prototype.newlineToken = function(offset) { + while (this.value() === ';') { + this.tokens.pop(); + } + if (this.tag() !== 'TERMINATOR') { + this.token('TERMINATOR', '\n', offset, 0); + } + return this; + }; + + Lexer.prototype.suppressNewlines = function() { + if (this.value() === '\\') { + this.tokens.pop(); + } + return this; + }; + + Lexer.prototype.literalToken = function() { + var match, prev, tag, value, _ref2, _ref3, _ref4, _ref5; + if (match = OPERATOR.exec(this.chunk)) { + value = match[0]; + if (CODE.test(value)) { + this.tagParameters(); + } + } else { + value = this.chunk.charAt(0); + } + tag = value; + prev = last(this.tokens); + if (value === '=' && prev) { + if (!prev[1].reserved && (_ref2 = prev[1], __indexOf.call(JS_FORBIDDEN, _ref2) >= 0)) { + this.error("reserved word \"" + (this.value()) + "\" can't be assigned"); + } + if ((_ref3 = prev[1]) === '||' || _ref3 === '&&') { + prev[0] = 'COMPOUND_ASSIGN'; + prev[1] += '='; + return value.length; + } + } + if (value === ';') { + this.seenFor = false; + tag = 'TERMINATOR'; + } else if (__indexOf.call(MATH, value) >= 0) { + tag = 'MATH'; + } else if (__indexOf.call(COMPARE, value) >= 0) { + tag = 'COMPARE'; + } else if (__indexOf.call(COMPOUND_ASSIGN, value) >= 0) { + tag = 'COMPOUND_ASSIGN'; + } else if (__indexOf.call(UNARY, value) >= 0) { + tag = 'UNARY'; + } else if (__indexOf.call(SHIFT, value) >= 0) { + tag = 'SHIFT'; + } else if (__indexOf.call(LOGIC, value) >= 0 || value === '?' && (prev != null ? prev.spaced : void 0)) { + tag = 'LOGIC'; + } else if (prev && !prev.spaced) { + if (value === '(' && (_ref4 = prev[0], __indexOf.call(CALLABLE, _ref4) >= 0)) { + if (prev[0] === '?') { + prev[0] = 'FUNC_EXIST'; + } + tag = 'CALL_START'; + } else if (value === '[' && (_ref5 = prev[0], __indexOf.call(INDEXABLE, _ref5) >= 0)) { + tag = 'INDEX_START'; + switch (prev[0]) { + case '?': + prev[0] = 'INDEX_SOAK'; + } + } + } + switch (value) { + case '(': + case '{': + case '[': + this.ends.push(INVERSES[value]); + break; + case ')': + case '}': + case ']': + this.pair(value); + } + this.token(tag, value); + return value.length; + }; + + Lexer.prototype.sanitizeHeredoc = function(doc, options) { + var attempt, herecomment, indent, match, _ref2; + indent = options.indent, herecomment = options.herecomment; + if (herecomment) { + if (HEREDOC_ILLEGAL.test(doc)) { + this.error("block comment cannot contain \"*/\", starting"); + } + if (doc.indexOf('\n') < 0) { + return doc; + } + } else { + while (match = HEREDOC_INDENT.exec(doc)) { + attempt = match[1]; + if (indent === null || (0 < (_ref2 = attempt.length) && _ref2 < indent.length)) { + indent = attempt; + } + } + } + if (indent) { + doc = doc.replace(RegExp("\\n" + indent, "g"), '\n'); + } + if (!herecomment) { + doc = doc.replace(/^\n/, ''); + } + return doc; + }; + + Lexer.prototype.tagParameters = function() { + var i, stack, tok, tokens; + if (this.tag() !== ')') { + return this; + } + stack = []; + tokens = this.tokens; + i = tokens.length; + tokens[--i][0] = 'PARAM_END'; + while (tok = tokens[--i]) { + switch (tok[0]) { + case ')': + stack.push(tok); + break; + case '(': + case 'CALL_START': + if (stack.length) { + stack.pop(); + } else if (tok[0] === '(') { + tok[0] = 'PARAM_START'; + return this; + } else { + return this; + } + } + } + return this; + }; + + Lexer.prototype.closeIndentation = function() { + return this.outdentToken(this.indent); + }; + + Lexer.prototype.balancedString = function(str, end) { + var continueCount, i, letter, match, prev, stack, _i, _ref2; + continueCount = 0; + stack = [end]; + for (i = _i = 1, _ref2 = str.length; 1 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 1 <= _ref2 ? ++_i : --_i) { + if (continueCount) { + --continueCount; + continue; + } + switch (letter = str.charAt(i)) { + case '\\': + ++continueCount; + continue; + case end: + stack.pop(); + if (!stack.length) { + return str.slice(0, +i + 1 || 9e9); + } + end = stack[stack.length - 1]; + continue; + } + if (end === '}' && (letter === '"' || letter === "'")) { + stack.push(end = letter); + } else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) { + continueCount += match[0].length - 1; + } else if (end === '}' && letter === '{') { + stack.push(end = '}'); + } else if (end === '"' && prev === '#' && letter === '{') { + stack.push(end = '}'); + } + prev = letter; + } + return this.error("missing " + (stack.pop()) + ", starting"); + }; + + Lexer.prototype.interpolateString = function(str, options) { + var column, expr, heredoc, i, inner, interpolated, len, letter, lexedLength, line, locationToken, nested, offsetInChunk, pi, plusToken, popped, regex, rparen, strOffset, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4; + if (options == null) { + options = {}; + } + heredoc = options.heredoc, regex = options.regex, offsetInChunk = options.offsetInChunk, strOffset = options.strOffset, lexedLength = options.lexedLength; + offsetInChunk = offsetInChunk || 0; + strOffset = strOffset || 0; + lexedLength = lexedLength || str.length; + tokens = []; + pi = 0; + i = -1; + while (letter = str.charAt(i += 1)) { + if (letter === '\\') { + i += 1; + continue; + } + if (!(letter === '#' && str.charAt(i + 1) === '{' && (expr = this.balancedString(str.slice(i + 1), '}')))) { + continue; + } + if (pi < i) { + tokens.push(this.makeToken('NEOSTRING', str.slice(pi, i), strOffset + pi)); + } + inner = expr.slice(1, -1); + if (inner.length) { + _ref2 = this.getLineAndColumnFromChunk(strOffset + i + 1), line = _ref2[0], column = _ref2[1]; + nested = new Lexer().tokenize(inner, { + line: line, + column: column, + rewrite: false + }); + popped = nested.pop(); + if (((_ref3 = nested[0]) != null ? _ref3[0] : void 0) === 'TERMINATOR') { + popped = nested.shift(); + } + if (len = nested.length) { + if (len > 1) { + nested.unshift(this.makeToken('(', '(', strOffset + i + 1, 0)); + nested.push(this.makeToken(')', ')', strOffset + i + 1 + inner.length, 0)); + } + tokens.push(['TOKENS', nested]); + } + } + i += expr.length; + pi = i + 1; + } + if ((i > pi && pi < str.length)) { + tokens.push(this.makeToken('NEOSTRING', str.slice(pi), strOffset + pi)); + } + if (regex) { + return tokens; + } + if (!tokens.length) { + return this.token('STRING', '""', offsetInChunk, lexedLength); + } + if (tokens[0][0] !== 'NEOSTRING') { + tokens.unshift(this.makeToken('NEOSTRING', '', offsetInChunk)); + } + if (interpolated = tokens.length > 1) { + this.token('(', '(', offsetInChunk, 0); + } + for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) { + token = tokens[i]; + tag = token[0], value = token[1]; + if (i) { + if (i) { + plusToken = this.token('+', '+'); + } + locationToken = tag === 'TOKENS' ? value[0] : token; + plusToken[2] = { + first_line: locationToken[2].first_line, + first_column: locationToken[2].first_column, + last_line: locationToken[2].first_line, + last_column: locationToken[2].first_column + }; + } + if (tag === 'TOKENS') { + (_ref4 = this.tokens).push.apply(_ref4, value); + } else if (tag === 'NEOSTRING') { + token[0] = 'STRING'; + token[1] = this.makeString(value, '"', heredoc); + this.tokens.push(token); + } else { + this.error("Unexpected " + tag); + } + } + if (interpolated) { + rparen = this.makeToken(')', ')', offsetInChunk + lexedLength, 0); + rparen.stringEnd = true; + this.tokens.push(rparen); + } + return tokens; + }; + + Lexer.prototype.pair = function(tag) { + var size, wanted; + if (tag !== (wanted = last(this.ends))) { + if ('OUTDENT' !== wanted) { + this.error("unmatched " + tag); + } + this.indent -= size = last(this.indents); + this.outdentToken(size, true); + return this.pair(tag); + } + return this.ends.pop(); + }; + + Lexer.prototype.getLineAndColumnFromChunk = function(offset) { + var column, lineCount, lines, string; + if (offset === 0) { + return [this.chunkLine, this.chunkColumn]; + } + if (offset >= this.chunk.length) { + string = this.chunk; + } else { + string = this.chunk.slice(0, +(offset - 1) + 1 || 9e9); + } + lineCount = count(string, '\n'); + column = this.chunkColumn; + if (lineCount > 0) { + lines = string.split('\n'); + column = last(lines).length; + } else { + column += string.length; + } + return [this.chunkLine + lineCount, column]; + }; + + Lexer.prototype.makeToken = function(tag, value, offsetInChunk, length) { + var lastCharacter, locationData, token, _ref2, _ref3; + if (offsetInChunk == null) { + offsetInChunk = 0; + } + if (length == null) { + length = value.length; + } + locationData = {}; + _ref2 = this.getLineAndColumnFromChunk(offsetInChunk), locationData.first_line = _ref2[0], locationData.first_column = _ref2[1]; + lastCharacter = Math.max(0, length - 1); + _ref3 = this.getLineAndColumnFromChunk(offsetInChunk + lastCharacter), locationData.last_line = _ref3[0], locationData.last_column = _ref3[1]; + token = [tag, value, locationData]; + return token; + }; + + Lexer.prototype.token = function(tag, value, offsetInChunk, length) { + var token; + token = this.makeToken(tag, value, offsetInChunk, length); + this.tokens.push(token); + return token; + }; + + Lexer.prototype.tag = function(index, tag) { + var tok; + return (tok = last(this.tokens, index)) && (tag ? tok[0] = tag : tok[0]); + }; + + Lexer.prototype.value = function(index, val) { + var tok; + return (tok = last(this.tokens, index)) && (val ? tok[1] = val : tok[1]); + }; + + Lexer.prototype.unfinished = function() { + var _ref2; + return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS'); + }; + + Lexer.prototype.removeNewlines = function(str) { + return str.replace(/^\s*\n\s*/, '').replace(/([^\\]|\\\\)\s*\n\s*$/, '$1'); + }; + + Lexer.prototype.escapeLines = function(str, heredoc) { + str = str.replace(/\\[^\S\n]*(\n|\\)\s*/g, function(escaped, character) { + if (character === '\n') { + return ''; + } else { + return escaped; + } + }); + if (heredoc) { + return str.replace(MULTILINER, '\\n'); + } else { + return str.replace(/\s*\n\s*/g, ' '); + } + }; + + Lexer.prototype.makeString = function(body, quote, heredoc) { + if (!body) { + return quote + quote; + } + body = body.replace(RegExp("\\\\(" + quote + "|\\\\)", "g"), function(match, contents) { + if (contents === quote) { + return contents; + } else { + return match; + } + }); + body = body.replace(RegExp("" + quote, "g"), '\\$&'); + return quote + this.escapeLines(body, heredoc) + quote; + }; + + Lexer.prototype.error = function(message, offset) { + var first_column, first_line, _ref2; + if (offset == null) { + offset = 0; + } + _ref2 = this.getLineAndColumnFromChunk(offset), first_line = _ref2[0], first_column = _ref2[1]; + return throwSyntaxError(message, { + first_line: first_line, + first_column: first_column + }); + }; + + return Lexer; + + })(); + + JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super']; + + COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when']; + + COFFEE_ALIAS_MAP = { + and: '&&', + or: '||', + is: '==', + isnt: '!=', + not: '!', + yes: 'true', + no: 'false', + on: 'true', + off: 'false' + }; + + COFFEE_ALIASES = (function() { + var _results; + _results = []; + for (key in COFFEE_ALIAS_MAP) { + _results.push(key); + } + return _results; + })(); + + COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat(COFFEE_ALIASES); + + RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind', '__indexOf', 'implements', 'interface', 'package', 'private', 'protected', 'public', 'static', 'yield']; + + STRICT_PROSCRIBED = ['arguments', 'eval']; + + JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED).concat(STRICT_PROSCRIBED); + + exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS).concat(STRICT_PROSCRIBED); + + exports.STRICT_PROSCRIBED = STRICT_PROSCRIBED; + + BOM = 65279; + + IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/; + + NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i; + + HEREDOC = /^("""|''')((?:\\[\s\S]|[^\\])*?)(?:\n[^\n\S]*)?\1/; + + OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?(\.|::)|\.{2,3})/; + + WHITESPACE = /^[^\n\S]+/; + + COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/; + + CODE = /^[-=]>/; + + MULTI_DENT = /^(?:\n[^\n\S]*)+/; + + SIMPLESTR = /^'[^\\']*(?:\\[\s\S][^\\']*)*'/; + + JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/; + + REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/; + + HEREGEX = /^\/{3}((?:\\?[\s\S])+?)\/{3}([imgy]{0,4})(?!\w)/; + + HEREGEX_OMIT = /((?:\\\\)+)|\\(\s|\/)|\s+(?:#.*)?/g; + + MULTILINER = /\n/g; + + HEREDOC_INDENT = /\n+([^\n\S]*)/g; + + HEREDOC_ILLEGAL = /\*\//; + + LINE_CONTINUER = /^\s*(?:,|\??\.(?![.\d])|::)/; + + TRAILING_SPACES = /\s+$/; + + COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|=']; + + UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO']; + + LOGIC = ['&&', '||', '&', '|', '^']; + + SHIFT = ['<<', '>>', '>>>']; + + COMPARE = ['==', '!=', '<', '>', '<=', '>=']; + + MATH = ['*', '/', '%']; + + RELATION = ['IN', 'OF', 'INSTANCEOF']; + + BOOL = ['TRUE', 'FALSE']; + + NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--']; + + NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING', ']'); + + CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER']; + + INDEXABLE = CALLABLE.concat('NUMBER', 'BOOL', 'NULL', 'UNDEFINED'); + + 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 new file mode 100644 index 00000000..52afdf2c --- /dev/null +++ b/lib/ace/mode/coffee/nodes.js @@ -0,0 +1,3106 @@ +/** + * Copyright (c) 2009-2013 Jeremy Ashkenas + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +define(function(require, exports, module) { +// Generated by CoffeeScript 1.6.3 + + var Access, Arr, Assign, Base, Block, Call, Class, Code, CodeFragment, Comment, Existence, Extends, For, HEXNUM, IDENTIFIER, IDENTIFIER_STR, IS_REGEX, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, NUMBER, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, addLocationDataFn, compact, del, ends, extend, flatten, fragmentsToText, isLiteralArguments, isLiteralThis, last, locationDataToString, merge, multident, parseNum, some, starts, throwSyntaxError, unfoldSoak, utility, _ref, _ref1, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, + __slice = [].slice; + + Error.stackTraceLimit = Infinity; + + Scope = require('./scope').Scope; + + _ref = require('./lexer'), RESERVED = _ref.RESERVED, STRICT_PROSCRIBED = _ref.STRICT_PROSCRIBED; + + _ref1 = require('./helpers'), compact = _ref1.compact, flatten = _ref1.flatten, extend = _ref1.extend, merge = _ref1.merge, del = _ref1.del, starts = _ref1.starts, ends = _ref1.ends, last = _ref1.last, some = _ref1.some, addLocationDataFn = _ref1.addLocationDataFn, locationDataToString = _ref1.locationDataToString, throwSyntaxError = _ref1.throwSyntaxError; + + exports.extend = extend; + + exports.addLocationDataFn = addLocationDataFn; + + YES = function() { + return true; + }; + + NO = function() { + return false; + }; + + THIS = function() { + return this; + }; + + NEGATE = function() { + this.negated = !this.negated; + return this; + }; + + exports.CodeFragment = CodeFragment = (function() { + function CodeFragment(parent, code) { + var _ref2; + this.code = "" + code; + this.locationData = parent != null ? parent.locationData : void 0; + this.type = (parent != null ? (_ref2 = parent.constructor) != null ? _ref2.name : void 0 : void 0) || 'unknown'; + } + + CodeFragment.prototype.toString = function() { + return "" + this.code + (this.locationData ? ": " + locationDataToString(this.locationData) : ''); + }; + + return CodeFragment; + + })(); + + fragmentsToText = function(fragments) { + var fragment; + return ((function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = fragments.length; _i < _len; _i++) { + fragment = fragments[_i]; + _results.push(fragment.code); + } + return _results; + })()).join(''); + }; + + exports.Base = Base = (function() { + function Base() {} + + Base.prototype.compile = function(o, lvl) { + return fragmentsToText(this.compileToFragments(o, lvl)); + }; + + Base.prototype.compileToFragments = function(o, lvl) { + var node; + o = extend({}, o); + if (lvl) { + o.level = lvl; + } + node = this.unfoldSoak(o) || this; + node.tab = o.indent; + if (o.level === LEVEL_TOP || !node.isStatement(o)) { + return node.compileNode(o); + } else { + return node.compileClosure(o); + } + }; + + Base.prototype.compileClosure = function(o) { + var args, argumentsNode, func, jumpNode, meth; + if (jumpNode = this.jumps()) { + jumpNode.error('cannot use a pure statement in an expression'); + } + o.sharedScope = true; + func = new Code([], Block.wrap([this])); + args = []; + if ((argumentsNode = this.contains(isLiteralArguments)) || this.contains(isLiteralThis)) { + args = [new Literal('this')]; + if (argumentsNode) { + meth = 'apply'; + args.push(new Literal('arguments')); + } else { + meth = 'call'; + } + func = new Value(func, [new Access(new Literal(meth))]); + } + return (new Call(func, args)).compileNode(o); + }; + + Base.prototype.cache = function(o, level, reused) { + var ref, sub; + if (!this.isComplex()) { + ref = level ? this.compileToFragments(o, level) : this; + return [ref, ref]; + } else { + ref = new Literal(reused || o.scope.freeVariable('ref')); + sub = new Assign(ref, this); + if (level) { + return [sub.compileToFragments(o, level), [this.makeCode(ref.value)]]; + } else { + return [sub, ref]; + } + } + }; + + Base.prototype.cacheToCodeFragments = function(cacheValues) { + return [fragmentsToText(cacheValues[0]), fragmentsToText(cacheValues[1])]; + }; + + Base.prototype.makeReturn = function(res) { + var me; + me = this.unwrapAll(); + if (res) { + return new Call(new Literal("" + res + ".push"), [me]); + } else { + return new Return(me); + } + }; + + Base.prototype.contains = function(pred) { + var node; + node = void 0; + this.traverseChildren(false, function(n) { + if (pred(n)) { + node = n; + return false; + } + }); + return node; + }; + + Base.prototype.lastNonComment = function(list) { + var i; + i = list.length; + while (i--) { + if (!(list[i] instanceof Comment)) { + return list[i]; + } + } + return null; + }; + + Base.prototype.toString = function(idt, name) { + var tree; + if (idt == null) { + idt = ''; + } + if (name == null) { + name = this.constructor.name; + } + tree = '\n' + idt + name; + if (this.soak) { + tree += '?'; + } + this.eachChild(function(node) { + return tree += node.toString(idt + TAB); + }); + return tree; + }; + + Base.prototype.eachChild = function(func) { + var attr, child, _i, _j, _len, _len1, _ref2, _ref3; + if (!this.children) { + return this; + } + _ref2 = this.children; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + attr = _ref2[_i]; + if (this[attr]) { + _ref3 = flatten([this[attr]]); + for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { + child = _ref3[_j]; + if (func(child) === false) { + return this; + } + } + } + } + return this; + }; + + Base.prototype.traverseChildren = function(crossScope, func) { + return this.eachChild(function(child) { + var recur; + recur = func(child); + if (recur !== false) { + return child.traverseChildren(crossScope, func); + } + }); + }; + + Base.prototype.invert = function() { + return new Op('!', this); + }; + + Base.prototype.unwrapAll = function() { + var node; + node = this; + while (node !== (node = node.unwrap())) { + continue; + } + return node; + }; + + Base.prototype.children = []; + + Base.prototype.isStatement = NO; + + Base.prototype.jumps = NO; + + Base.prototype.isComplex = YES; + + Base.prototype.isChainable = NO; + + Base.prototype.isAssignable = NO; + + Base.prototype.unwrap = THIS; + + Base.prototype.unfoldSoak = NO; + + Base.prototype.assigns = NO; + + Base.prototype.updateLocationDataIfMissing = function(locationData) { + if (this.locationData) { + return this; + } + this.locationData = locationData; + return this.eachChild(function(child) { + return child.updateLocationDataIfMissing(locationData); + }); + }; + + Base.prototype.error = function(message) { + return throwSyntaxError(message, this.locationData); + }; + + Base.prototype.makeCode = function(code) { + return new CodeFragment(this, code); + }; + + Base.prototype.wrapInBraces = function(fragments) { + return [].concat(this.makeCode('('), fragments, this.makeCode(')')); + }; + + Base.prototype.joinFragmentArrays = function(fragmentsList, joinStr) { + var answer, fragments, i, _i, _len; + answer = []; + for (i = _i = 0, _len = fragmentsList.length; _i < _len; i = ++_i) { + fragments = fragmentsList[i]; + if (i) { + answer.push(this.makeCode(joinStr)); + } + answer = answer.concat(fragments); + } + return answer; + }; + + return Base; + + })(); + + exports.Block = Block = (function(_super) { + __extends(Block, _super); + + function Block(nodes) { + this.expressions = compact(flatten(nodes || [])); + } + + Block.prototype.children = ['expressions']; + + Block.prototype.push = function(node) { + this.expressions.push(node); + return this; + }; + + Block.prototype.pop = function() { + return this.expressions.pop(); + }; + + Block.prototype.unshift = function(node) { + this.expressions.unshift(node); + return this; + }; + + Block.prototype.unwrap = function() { + if (this.expressions.length === 1) { + return this.expressions[0]; + } else { + return this; + } + }; + + Block.prototype.isEmpty = function() { + return !this.expressions.length; + }; + + Block.prototype.isStatement = function(o) { + var exp, _i, _len, _ref2; + _ref2 = this.expressions; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + exp = _ref2[_i]; + if (exp.isStatement(o)) { + return true; + } + } + return false; + }; + + Block.prototype.jumps = function(o) { + var exp, jumpNode, _i, _len, _ref2; + _ref2 = this.expressions; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + exp = _ref2[_i]; + if (jumpNode = exp.jumps(o)) { + return jumpNode; + } + } + }; + + Block.prototype.makeReturn = function(res) { + var expr, len; + len = this.expressions.length; + while (len--) { + expr = this.expressions[len]; + if (!(expr instanceof Comment)) { + this.expressions[len] = expr.makeReturn(res); + if (expr instanceof Return && !expr.expression) { + this.expressions.splice(len, 1); + } + break; + } + } + return this; + }; + + Block.prototype.compileToFragments = function(o, level) { + if (o == null) { + o = {}; + } + if (o.scope) { + return Block.__super__.compileToFragments.call(this, o, level); + } else { + return this.compileRoot(o); + } + }; + + Block.prototype.compileNode = function(o) { + var answer, compiledNodes, fragments, index, node, top, _i, _len, _ref2; + this.tab = o.indent; + top = o.level === LEVEL_TOP; + compiledNodes = []; + _ref2 = this.expressions; + for (index = _i = 0, _len = _ref2.length; _i < _len; index = ++_i) { + node = _ref2[index]; + node = node.unwrapAll(); + node = node.unfoldSoak(o) || node; + if (node instanceof Block) { + compiledNodes.push(node.compileNode(o)); + } else if (top) { + node.front = true; + fragments = node.compileToFragments(o); + if (!node.isStatement(o)) { + fragments.unshift(this.makeCode("" + this.tab)); + fragments.push(this.makeCode(";")); + } + compiledNodes.push(fragments); + } else { + compiledNodes.push(node.compileToFragments(o, LEVEL_LIST)); + } + } + if (top) { + if (this.spaced) { + return [].concat(this.joinFragmentArrays(compiledNodes, '\n\n'), this.makeCode("\n")); + } else { + return this.joinFragmentArrays(compiledNodes, '\n'); + } + } + if (compiledNodes.length) { + answer = this.joinFragmentArrays(compiledNodes, ', '); + } else { + answer = [this.makeCode("void 0")]; + } + if (compiledNodes.length > 1 && o.level >= LEVEL_LIST) { + return this.wrapInBraces(answer); + } else { + return answer; + } + }; + + Block.prototype.compileRoot = function(o) { + var exp, fragments, i, name, prelude, preludeExps, rest, _i, _len, _ref2; + o.indent = o.bare ? '' : TAB; + o.level = LEVEL_TOP; + this.spaced = true; + o.scope = new Scope(null, this, null); + _ref2 = o.locals || []; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + name = _ref2[_i]; + o.scope.parameter(name); + } + prelude = []; + if (!o.bare) { + preludeExps = (function() { + var _j, _len1, _ref3, _results; + _ref3 = this.expressions; + _results = []; + for (i = _j = 0, _len1 = _ref3.length; _j < _len1; i = ++_j) { + exp = _ref3[i]; + if (!(exp.unwrap() instanceof Comment)) { + break; + } + _results.push(exp); + } + return _results; + }).call(this); + rest = this.expressions.slice(preludeExps.length); + this.expressions = preludeExps; + if (preludeExps.length) { + prelude = this.compileNode(merge(o, { + indent: '' + })); + prelude.push(this.makeCode("\n")); + } + this.expressions = rest; + } + fragments = this.compileWithDeclarations(o); + if (o.bare) { + return fragments; + } + return [].concat(prelude, this.makeCode("(function() {\n"), fragments, this.makeCode("\n}).call(this);\n")); + }; + + Block.prototype.compileWithDeclarations = function(o) { + var assigns, declars, exp, fragments, i, post, rest, scope, spaced, _i, _len, _ref2, _ref3, _ref4; + fragments = []; + post = []; + _ref2 = this.expressions; + for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) { + exp = _ref2[i]; + exp = exp.unwrap(); + if (!(exp instanceof Comment || exp instanceof Literal)) { + break; + } + } + o = merge(o, { + level: LEVEL_TOP + }); + if (i) { + rest = this.expressions.splice(i, 9e9); + _ref3 = [this.spaced, false], spaced = _ref3[0], this.spaced = _ref3[1]; + _ref4 = [this.compileNode(o), spaced], fragments = _ref4[0], this.spaced = _ref4[1]; + this.expressions = rest; + } + post = this.compileNode(o); + scope = o.scope; + if (scope.expressions === this) { + declars = o.scope.hasDeclarations(); + assigns = scope.hasAssignments; + if (declars || assigns) { + if (i) { + fragments.push(this.makeCode('\n')); + } + fragments.push(this.makeCode("" + this.tab + "var ")); + if (declars) { + fragments.push(this.makeCode(scope.declaredVariables().join(', '))); + } + if (assigns) { + if (declars) { + fragments.push(this.makeCode(",\n" + (this.tab + TAB))); + } + fragments.push(this.makeCode(scope.assignedVariables().join(",\n" + (this.tab + TAB)))); + } + fragments.push(this.makeCode(";\n" + (this.spaced ? '\n' : ''))); + } else if (fragments.length && post.length) { + fragments.push(this.makeCode("\n")); + } + } + return fragments.concat(post); + }; + + Block.wrap = function(nodes) { + if (nodes.length === 1 && nodes[0] instanceof Block) { + return nodes[0]; + } + return new Block(nodes); + }; + + return Block; + + })(Base); + + exports.Literal = Literal = (function(_super) { + __extends(Literal, _super); + + function Literal(value) { + this.value = value; + } + + Literal.prototype.makeReturn = function() { + if (this.isStatement()) { + return this; + } else { + return Literal.__super__.makeReturn.apply(this, arguments); + } + }; + + Literal.prototype.isAssignable = function() { + return IDENTIFIER.test(this.value); + }; + + Literal.prototype.isStatement = function() { + var _ref2; + return (_ref2 = this.value) === 'break' || _ref2 === 'continue' || _ref2 === 'debugger'; + }; + + Literal.prototype.isComplex = NO; + + Literal.prototype.assigns = function(name) { + return name === this.value; + }; + + Literal.prototype.jumps = function(o) { + if (this.value === 'break' && !((o != null ? o.loop : void 0) || (o != null ? o.block : void 0))) { + return this; + } + if (this.value === 'continue' && !(o != null ? o.loop : void 0)) { + return this; + } + }; + + Literal.prototype.compileNode = function(o) { + var answer, code, _ref2; + code = this.value === 'this' ? ((_ref2 = o.scope.method) != null ? _ref2.bound : void 0) ? o.scope.method.context : this.value : this.value.reserved ? "\"" + this.value + "\"" : this.value; + answer = this.isStatement() ? "" + this.tab + code + ";" : code; + return [this.makeCode(answer)]; + }; + + Literal.prototype.toString = function() { + return ' "' + this.value + '"'; + }; + + return Literal; + + })(Base); + + exports.Undefined = (function(_super) { + __extends(Undefined, _super); + + function Undefined() { + return Undefined.__super__.constructor.apply(this, arguments); + } + + Undefined.prototype.isAssignable = NO; + + Undefined.prototype.isComplex = NO; + + Undefined.prototype.compileNode = function(o) { + return [this.makeCode(o.level >= LEVEL_ACCESS ? '(void 0)' : 'void 0')]; + }; + + return Undefined; + + })(Base); + + exports.Null = (function(_super) { + __extends(Null, _super); + + function Null() { + return Null.__super__.constructor.apply(this, arguments); + } + + Null.prototype.isAssignable = NO; + + Null.prototype.isComplex = NO; + + Null.prototype.compileNode = function() { + return [this.makeCode("null")]; + }; + + return Null; + + })(Base); + + exports.Bool = (function(_super) { + __extends(Bool, _super); + + Bool.prototype.isAssignable = NO; + + Bool.prototype.isComplex = NO; + + Bool.prototype.compileNode = function() { + return [this.makeCode(this.val)]; + }; + + function Bool(val) { + this.val = val; + } + + return Bool; + + })(Base); + + exports.Return = Return = (function(_super) { + __extends(Return, _super); + + function Return(expr) { + if (expr && !expr.unwrap().isUndefined) { + this.expression = expr; + } + } + + Return.prototype.children = ['expression']; + + Return.prototype.isStatement = YES; + + Return.prototype.makeReturn = THIS; + + Return.prototype.jumps = THIS; + + Return.prototype.compileToFragments = function(o, level) { + var expr, _ref2; + expr = (_ref2 = this.expression) != null ? _ref2.makeReturn() : void 0; + if (expr && !(expr instanceof Return)) { + return expr.compileToFragments(o, level); + } else { + return Return.__super__.compileToFragments.call(this, o, level); + } + }; + + Return.prototype.compileNode = function(o) { + var answer; + answer = []; + answer.push(this.makeCode(this.tab + ("return" + (this.expression ? " " : "")))); + if (this.expression) { + answer = answer.concat(this.expression.compileToFragments(o, LEVEL_PAREN)); + } + answer.push(this.makeCode(";")); + return answer; + }; + + return Return; + + })(Base); + + exports.Value = Value = (function(_super) { + __extends(Value, _super); + + function Value(base, props, tag) { + if (!props && base instanceof Value) { + return base; + } + this.base = base; + this.properties = props || []; + if (tag) { + this[tag] = true; + } + return this; + } + + Value.prototype.children = ['base', 'properties']; + + Value.prototype.add = function(props) { + this.properties = this.properties.concat(props); + return this; + }; + + Value.prototype.hasProperties = function() { + return !!this.properties.length; + }; + + Value.prototype.bareLiteral = function(type) { + return !this.properties.length && this.base instanceof type; + }; + + Value.prototype.isArray = function() { + return this.bareLiteral(Arr); + }; + + Value.prototype.isRange = function() { + return this.bareLiteral(Range); + }; + + Value.prototype.isComplex = function() { + return this.hasProperties() || this.base.isComplex(); + }; + + Value.prototype.isAssignable = function() { + return this.hasProperties() || this.base.isAssignable(); + }; + + Value.prototype.isSimpleNumber = function() { + return this.bareLiteral(Literal) && SIMPLENUM.test(this.base.value); + }; + + Value.prototype.isString = function() { + return this.bareLiteral(Literal) && IS_STRING.test(this.base.value); + }; + + Value.prototype.isRegex = function() { + return this.bareLiteral(Literal) && IS_REGEX.test(this.base.value); + }; + + Value.prototype.isAtomic = function() { + var node, _i, _len, _ref2; + _ref2 = this.properties.concat(this.base); + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + node = _ref2[_i]; + if (node.soak || node instanceof Call) { + return false; + } + } + return true; + }; + + Value.prototype.isNotCallable = function() { + return this.isSimpleNumber() || this.isString() || this.isRegex() || this.isArray() || this.isRange() || this.isSplice() || this.isObject(); + }; + + Value.prototype.isStatement = function(o) { + return !this.properties.length && this.base.isStatement(o); + }; + + Value.prototype.assigns = function(name) { + return !this.properties.length && this.base.assigns(name); + }; + + Value.prototype.jumps = function(o) { + return !this.properties.length && this.base.jumps(o); + }; + + Value.prototype.isObject = function(onlyGenerated) { + if (this.properties.length) { + return false; + } + return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated); + }; + + Value.prototype.isSplice = function() { + return last(this.properties) instanceof Slice; + }; + + Value.prototype.looksStatic = function(className) { + var _ref2; + return this.base.value === className && this.properties.length && ((_ref2 = this.properties[0].name) != null ? _ref2.value : void 0) !== 'prototype'; + }; + + Value.prototype.unwrap = function() { + if (this.properties.length) { + return this; + } else { + return this.base; + } + }; + + Value.prototype.cacheReference = function(o) { + var base, bref, name, nref; + name = last(this.properties); + if (this.properties.length < 2 && !this.base.isComplex() && !(name != null ? name.isComplex() : void 0)) { + return [this, this]; + } + base = new Value(this.base, this.properties.slice(0, -1)); + if (base.isComplex()) { + bref = new Literal(o.scope.freeVariable('base')); + base = new Value(new Parens(new Assign(bref, base))); + } + if (!name) { + return [base, bref]; + } + if (name.isComplex()) { + nref = new Literal(o.scope.freeVariable('name')); + name = new Index(new Assign(nref, name.index)); + nref = new Index(nref); + } + return [base.add(name), new Value(bref || base.base, [nref || name])]; + }; + + Value.prototype.compileNode = function(o) { + var fragments, prop, props, _i, _len; + this.base.front = this.front; + props = this.properties; + fragments = this.base.compileToFragments(o, (props.length ? LEVEL_ACCESS : null)); + if ((this.base instanceof Parens || props.length) && SIMPLENUM.test(fragmentsToText(fragments))) { + fragments.push(this.makeCode('.')); + } + for (_i = 0, _len = props.length; _i < _len; _i++) { + prop = props[_i]; + fragments.push.apply(fragments, prop.compileToFragments(o)); + } + return fragments; + }; + + Value.prototype.unfoldSoak = function(o) { + return this.unfoldedSoak != null ? this.unfoldedSoak : this.unfoldedSoak = (function(_this) { + return function() { + var fst, i, ifn, prop, ref, snd, _i, _len, _ref2, _ref3; + if (ifn = _this.base.unfoldSoak(o)) { + (_ref2 = ifn.body.properties).push.apply(_ref2, _this.properties); + return ifn; + } + _ref3 = _this.properties; + for (i = _i = 0, _len = _ref3.length; _i < _len; i = ++_i) { + prop = _ref3[i]; + if (!prop.soak) { + continue; + } + prop.soak = false; + fst = new Value(_this.base, _this.properties.slice(0, i)); + snd = new Value(_this.base, _this.properties.slice(i)); + if (fst.isComplex()) { + ref = new Literal(o.scope.freeVariable('ref')); + fst = new Parens(new Assign(ref, fst)); + snd.base = ref; + } + return new If(new Existence(fst), snd, { + soak: true + }); + } + return false; + }; + })(this)(); + }; + + return Value; + + })(Base); + + exports.Comment = Comment = (function(_super) { + __extends(Comment, _super); + + function Comment(comment) { + this.comment = comment; + } + + Comment.prototype.isStatement = YES; + + Comment.prototype.makeReturn = THIS; + + Comment.prototype.compileNode = function(o, level) { + var code, comment; + comment = this.comment.replace(/^(\s*)#/gm, "$1 *"); + code = "/*" + (multident(comment, this.tab)) + (__indexOf.call(comment, '\n') >= 0 ? "\n" + this.tab : '') + " */"; + if ((level || o.level) === LEVEL_TOP) { + code = o.indent + code; + } + return [this.makeCode("\n"), this.makeCode(code)]; + }; + + return Comment; + + })(Base); + + exports.Call = Call = (function(_super) { + __extends(Call, _super); + + function Call(variable, args, soak) { + this.args = args != null ? args : []; + this.soak = soak; + this.isNew = false; + this.isSuper = variable === 'super'; + this.variable = this.isSuper ? null : variable; + if (variable instanceof Value && variable.isNotCallable()) { + variable.error("literal is not a function"); + } + } + + Call.prototype.children = ['variable', 'args']; + + Call.prototype.newInstance = function() { + var base, _ref2; + base = ((_ref2 = this.variable) != null ? _ref2.base : void 0) || this.variable; + if (base instanceof Call && !base.isNew) { + base.newInstance(); + } else { + this.isNew = true; + } + return this; + }; + + Call.prototype.superReference = function(o) { + var accesses, method; + method = o.scope.namedMethod(); + if (method != null ? method.klass : void 0) { + accesses = [new Access(new Literal('__super__'))]; + if (method["static"]) { + accesses.push(new Access(new Literal('constructor'))); + } + accesses.push(new Access(new Literal(method.name))); + return (new Value(new Literal(method.klass), accesses)).compile(o); + } else if (method != null ? method.ctor : void 0) { + return "" + method.name + ".__super__.constructor"; + } else { + return this.error('cannot call super outside of an instance method.'); + } + }; + + Call.prototype.superThis = function(o) { + var method; + method = o.scope.method; + return (method && !method.klass && method.context) || "this"; + }; + + Call.prototype.unfoldSoak = function(o) { + var call, ifn, left, list, rite, _i, _len, _ref2, _ref3; + if (this.soak) { + if (this.variable) { + if (ifn = unfoldSoak(o, this, 'variable')) { + return ifn; + } + _ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1]; + } else { + left = new Literal(this.superReference(o)); + rite = new Value(left); + } + rite = new Call(rite, this.args); + rite.isNew = this.isNew; + left = new Literal("typeof " + (left.compile(o)) + " === \"function\""); + return new If(left, new Value(rite), { + soak: true + }); + } + call = this; + list = []; + while (true) { + if (call.variable instanceof Call) { + list.push(call); + call = call.variable; + continue; + } + if (!(call.variable instanceof Value)) { + break; + } + list.push(call); + if (!((call = call.variable.base) instanceof Call)) { + break; + } + } + _ref3 = list.reverse(); + for (_i = 0, _len = _ref3.length; _i < _len; _i++) { + call = _ref3[_i]; + if (ifn) { + if (call.variable instanceof Call) { + call.variable = ifn; + } else { + call.variable.base = ifn; + } + } + ifn = unfoldSoak(o, call, 'variable'); + } + return ifn; + }; + + Call.prototype.compileNode = function(o) { + var arg, argIndex, compiledArgs, compiledArray, fragments, preface, _i, _len, _ref2, _ref3; + if ((_ref2 = this.variable) != null) { + _ref2.front = this.front; + } + compiledArray = Splat.compileSplattedArray(o, this.args, true); + if (compiledArray.length) { + return this.compileSplat(o, compiledArray); + } + compiledArgs = []; + _ref3 = this.args; + for (argIndex = _i = 0, _len = _ref3.length; _i < _len; argIndex = ++_i) { + arg = _ref3[argIndex]; + if (argIndex) { + compiledArgs.push(this.makeCode(", ")); + } + compiledArgs.push.apply(compiledArgs, arg.compileToFragments(o, LEVEL_LIST)); + } + fragments = []; + if (this.isSuper) { + preface = this.superReference(o) + (".call(" + (this.superThis(o))); + if (compiledArgs.length) { + preface += ", "; + } + fragments.push(this.makeCode(preface)); + } else { + if (this.isNew) { + fragments.push(this.makeCode('new ')); + } + fragments.push.apply(fragments, this.variable.compileToFragments(o, LEVEL_ACCESS)); + fragments.push(this.makeCode("(")); + } + fragments.push.apply(fragments, compiledArgs); + fragments.push(this.makeCode(")")); + return fragments; + }; + + Call.prototype.compileSplat = function(o, splatArgs) { + var answer, base, fun, idt, name, ref; + if (this.isSuper) { + return [].concat(this.makeCode("" + (this.superReference(o)) + ".apply(" + (this.superThis(o)) + ", "), splatArgs, this.makeCode(")")); + } + if (this.isNew) { + idt = this.tab + TAB; + return [].concat(this.makeCode("(function(func, args, ctor) {\n" + idt + "ctor.prototype = func.prototype;\n" + idt + "var child = new ctor, result = func.apply(child, args);\n" + idt + "return Object(result) === result ? result : child;\n" + this.tab + "})("), this.variable.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), splatArgs, this.makeCode(", function(){})")); + } + answer = []; + base = new Value(this.variable); + if ((name = base.properties.pop()) && base.isComplex()) { + ref = o.scope.freeVariable('ref'); + answer = answer.concat(this.makeCode("(" + ref + " = "), base.compileToFragments(o, LEVEL_LIST), this.makeCode(")"), name.compileToFragments(o)); + } else { + fun = base.compileToFragments(o, LEVEL_ACCESS); + if (SIMPLENUM.test(fragmentsToText(fun))) { + fun = this.wrapInBraces(fun); + } + if (name) { + ref = fragmentsToText(fun); + fun.push.apply(fun, name.compileToFragments(o)); + } else { + ref = 'null'; + } + answer = answer.concat(fun); + } + return answer = answer.concat(this.makeCode(".apply(" + ref + ", "), splatArgs, this.makeCode(")")); + }; + + return Call; + + })(Base); + + exports.Extends = Extends = (function(_super) { + __extends(Extends, _super); + + function Extends(child, parent) { + this.child = child; + this.parent = parent; + } + + Extends.prototype.children = ['child', 'parent']; + + Extends.prototype.compileToFragments = function(o) { + return new Call(new Value(new Literal(utility('extends'))), [this.child, this.parent]).compileToFragments(o); + }; + + return Extends; + + })(Base); + + exports.Access = Access = (function(_super) { + __extends(Access, _super); + + function Access(name, tag) { + this.name = name; + this.name.asKey = true; + this.soak = tag === 'soak'; + } + + Access.prototype.children = ['name']; + + Access.prototype.compileToFragments = function(o) { + var name; + name = this.name.compileToFragments(o); + if (IDENTIFIER.test(fragmentsToText(name))) { + name.unshift(this.makeCode(".")); + } else { + name.unshift(this.makeCode("[")); + name.push(this.makeCode("]")); + } + return name; + }; + + Access.prototype.isComplex = NO; + + return Access; + + })(Base); + + exports.Index = Index = (function(_super) { + __extends(Index, _super); + + function Index(index) { + this.index = index; + } + + Index.prototype.children = ['index']; + + Index.prototype.compileToFragments = function(o) { + return [].concat(this.makeCode("["), this.index.compileToFragments(o, LEVEL_PAREN), this.makeCode("]")); + }; + + Index.prototype.isComplex = function() { + return this.index.isComplex(); + }; + + return Index; + + })(Base); + + exports.Range = Range = (function(_super) { + __extends(Range, _super); + + Range.prototype.children = ['from', 'to']; + + function Range(from, to, tag) { + this.from = from; + this.to = to; + this.exclusive = tag === 'exclusive'; + this.equals = this.exclusive ? '' : '='; + } + + Range.prototype.compileVariables = function(o) { + var step, _ref2, _ref3, _ref4, _ref5; + o = merge(o, { + top: true + }); + _ref2 = this.cacheToCodeFragments(this.from.cache(o, LEVEL_LIST)), this.fromC = _ref2[0], this.fromVar = _ref2[1]; + _ref3 = this.cacheToCodeFragments(this.to.cache(o, LEVEL_LIST)), this.toC = _ref3[0], this.toVar = _ref3[1]; + if (step = del(o, 'step')) { + _ref4 = this.cacheToCodeFragments(step.cache(o, LEVEL_LIST)), this.step = _ref4[0], this.stepVar = _ref4[1]; + } + _ref5 = [this.fromVar.match(NUMBER), this.toVar.match(NUMBER)], this.fromNum = _ref5[0], this.toNum = _ref5[1]; + if (this.stepVar) { + return this.stepNum = this.stepVar.match(NUMBER); + } + }; + + Range.prototype.compileNode = function(o) { + var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, stepPart, to, varPart, _ref2, _ref3; + if (!this.fromVar) { + this.compileVariables(o); + } + if (!o.index) { + return this.compileArray(o); + } + known = this.fromNum && this.toNum; + idx = del(o, 'index'); + idxName = del(o, 'name'); + namedIndex = idxName && idxName !== idx; + varPart = "" + idx + " = " + this.fromC; + if (this.toC !== this.toVar) { + varPart += ", " + this.toC; + } + if (this.step !== this.stepVar) { + varPart += ", " + this.step; + } + _ref2 = ["" + idx + " <" + this.equals, "" + idx + " >" + this.equals], lt = _ref2[0], gt = _ref2[1]; + condPart = this.stepNum ? parseNum(this.stepNum[0]) > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref3 = [parseNum(this.fromNum[0]), parseNum(this.toNum[0])], from = _ref3[0], to = _ref3[1], _ref3), from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = this.stepVar ? "" + this.stepVar + " > 0" : "" + this.fromVar + " <= " + this.toVar, "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar); + stepPart = this.stepVar ? "" + idx + " += " + this.stepVar : known ? namedIndex ? from <= to ? "++" + idx : "--" + idx : from <= to ? "" + idx + "++" : "" + idx + "--" : namedIndex ? "" + cond + " ? ++" + idx + " : --" + idx : "" + cond + " ? " + idx + "++ : " + idx + "--"; + if (namedIndex) { + varPart = "" + idxName + " = " + varPart; + } + if (namedIndex) { + stepPart = "" + idxName + " = " + stepPart; + } + return [this.makeCode("" + varPart + "; " + condPart + "; " + stepPart)]; + }; + + Range.prototype.compileArray = function(o) { + var args, body, cond, hasArgs, i, idt, post, pre, range, result, vars, _i, _ref2, _ref3, _results; + if (this.fromNum && this.toNum && Math.abs(this.fromNum - this.toNum) <= 20) { + range = (function() { + _results = []; + for (var _i = _ref2 = +this.fromNum, _ref3 = +this.toNum; _ref2 <= _ref3 ? _i <= _ref3 : _i >= _ref3; _ref2 <= _ref3 ? _i++ : _i--){ _results.push(_i); } + return _results; + }).apply(this); + if (this.exclusive) { + range.pop(); + } + return [this.makeCode("[" + (range.join(', ')) + "]")]; + } + idt = this.tab + TAB; + i = o.scope.freeVariable('i'); + result = o.scope.freeVariable('results'); + pre = "\n" + idt + result + " = [];"; + if (this.fromNum && this.toNum) { + o.index = i; + body = fragmentsToText(this.compileNode(o)); + } else { + vars = ("" + i + " = " + this.fromC) + (this.toC !== this.toVar ? ", " + this.toC : ''); + cond = "" + this.fromVar + " <= " + this.toVar; + body = "var " + vars + "; " + cond + " ? " + i + " <" + this.equals + " " + this.toVar + " : " + i + " >" + this.equals + " " + this.toVar + "; " + cond + " ? " + i + "++ : " + i + "--"; + } + post = "{ " + result + ".push(" + i + "); }\n" + idt + "return " + result + ";\n" + o.indent; + hasArgs = function(node) { + return node != null ? node.contains(isLiteralArguments) : void 0; + }; + if (hasArgs(this.from) || hasArgs(this.to)) { + args = ', arguments'; + } + return [this.makeCode("(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).apply(this" + (args != null ? args : '') + ")")]; + }; + + return Range; + + })(Base); + + exports.Slice = Slice = (function(_super) { + __extends(Slice, _super); + + Slice.prototype.children = ['range']; + + function Slice(range) { + this.range = range; + Slice.__super__.constructor.call(this); + } + + Slice.prototype.compileNode = function(o) { + var compiled, compiledText, from, fromCompiled, to, toStr, _ref2; + _ref2 = this.range, to = _ref2.to, from = _ref2.from; + fromCompiled = from && from.compileToFragments(o, LEVEL_PAREN) || [this.makeCode('0')]; + if (to) { + compiled = to.compileToFragments(o, LEVEL_PAREN); + compiledText = fragmentsToText(compiled); + if (!(!this.range.exclusive && +compiledText === -1)) { + toStr = ', ' + (this.range.exclusive ? compiledText : SIMPLENUM.test(compiledText) ? "" + (+compiledText + 1) : (compiled = to.compileToFragments(o, LEVEL_ACCESS), "+" + (fragmentsToText(compiled)) + " + 1 || 9e9")); + } + } + return [this.makeCode(".slice(" + (fragmentsToText(fromCompiled)) + (toStr || '') + ")")]; + }; + + return Slice; + + })(Base); + + exports.Obj = Obj = (function(_super) { + __extends(Obj, _super); + + function Obj(props, generated) { + this.generated = generated != null ? generated : false; + this.objects = this.properties = props || []; + } + + Obj.prototype.children = ['properties']; + + Obj.prototype.compileNode = function(o) { + var answer, i, idt, indent, join, lastNoncom, node, prop, props, _i, _j, _len, _len1; + props = this.properties; + if (!props.length) { + return [this.makeCode(this.front ? '({})' : '{}')]; + } + if (this.generated) { + for (_i = 0, _len = props.length; _i < _len; _i++) { + node = props[_i]; + if (node instanceof Value) { + node.error('cannot have an implicit value in an implicit object'); + } + } + } + idt = o.indent += TAB; + lastNoncom = this.lastNonComment(this.properties); + answer = []; + for (i = _j = 0, _len1 = props.length; _j < _len1; i = ++_j) { + prop = props[i]; + join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n'; + indent = prop instanceof Comment ? '' : idt; + if (prop instanceof Assign && prop.variable instanceof Value && prop.variable.hasProperties()) { + prop.variable.error('Invalid object key'); + } + if (prop instanceof Value && prop["this"]) { + prop = new Assign(prop.properties[0].name, prop, 'object'); + } + if (!(prop instanceof Comment)) { + if (!(prop instanceof Assign)) { + prop = new Assign(prop, prop, 'object'); + } + (prop.variable.base || prop.variable).asKey = true; + } + if (indent) { + answer.push(this.makeCode(indent)); + } + answer.push.apply(answer, prop.compileToFragments(o, LEVEL_TOP)); + if (join) { + answer.push(this.makeCode(join)); + } + } + answer.unshift(this.makeCode("{" + (props.length && '\n'))); + answer.push(this.makeCode("" + (props.length && '\n' + this.tab) + "}")); + if (this.front) { + return this.wrapInBraces(answer); + } else { + return answer; + } + }; + + Obj.prototype.assigns = function(name) { + var prop, _i, _len, _ref2; + _ref2 = this.properties; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + prop = _ref2[_i]; + if (prop.assigns(name)) { + return true; + } + } + return false; + }; + + return Obj; + + })(Base); + + exports.Arr = Arr = (function(_super) { + __extends(Arr, _super); + + function Arr(objs) { + this.objects = objs || []; + } + + Arr.prototype.children = ['objects']; + + Arr.prototype.compileNode = function(o) { + var answer, compiledObjs, fragments, index, obj, _i, _len; + if (!this.objects.length) { + return [this.makeCode('[]')]; + } + o.indent += TAB; + answer = Splat.compileSplattedArray(o, this.objects); + if (answer.length) { + return answer; + } + answer = []; + compiledObjs = (function() { + var _i, _len, _ref2, _results; + _ref2 = this.objects; + _results = []; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + obj = _ref2[_i]; + _results.push(obj.compileToFragments(o, LEVEL_LIST)); + } + return _results; + }).call(this); + for (index = _i = 0, _len = compiledObjs.length; _i < _len; index = ++_i) { + fragments = compiledObjs[index]; + if (index) { + answer.push(this.makeCode(", ")); + } + answer.push.apply(answer, fragments); + } + if (fragmentsToText(answer).indexOf('\n') >= 0) { + answer.unshift(this.makeCode("[\n" + o.indent)); + answer.push(this.makeCode("\n" + this.tab + "]")); + } else { + answer.unshift(this.makeCode("[")); + answer.push(this.makeCode("]")); + } + return answer; + }; + + Arr.prototype.assigns = function(name) { + var obj, _i, _len, _ref2; + _ref2 = this.objects; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + obj = _ref2[_i]; + if (obj.assigns(name)) { + return true; + } + } + return false; + }; + + return Arr; + + })(Base); + + exports.Class = Class = (function(_super) { + __extends(Class, _super); + + function Class(variable, parent, body) { + this.variable = variable; + this.parent = parent; + this.body = body != null ? body : new Block; + this.boundFuncs = []; + this.body.classBody = true; + } + + Class.prototype.children = ['variable', 'parent', 'body']; + + Class.prototype.determineName = function() { + var decl, tail; + if (!this.variable) { + return null; + } + decl = (tail = last(this.variable.properties)) ? tail instanceof Access && tail.name.value : this.variable.base.value; + if (__indexOf.call(STRICT_PROSCRIBED, decl) >= 0) { + this.variable.error("class variable name may not be " + decl); + } + return decl && (decl = IDENTIFIER.test(decl) && decl); + }; + + Class.prototype.setContext = function(name) { + return this.body.traverseChildren(false, function(node) { + if (node.classBody) { + return false; + } + if (node instanceof Literal && node.value === 'this') { + return node.value = name; + } else if (node instanceof Code) { + node.klass = name; + if (node.bound) { + return node.context = name; + } + } + }); + }; + + Class.prototype.addBoundFunctions = function(o) { + var bvar, lhs, _i, _len, _ref2; + _ref2 = this.boundFuncs; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + bvar = _ref2[_i]; + lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o); + this.ctor.body.unshift(new Literal("" + lhs + " = " + (utility('bind')) + "(" + lhs + ", this)")); + } + }; + + Class.prototype.addProperties = function(node, name, o) { + var assign, base, exprs, func, props; + props = node.base.properties.slice(0); + exprs = (function() { + var _results; + _results = []; + while (assign = props.shift()) { + if (assign instanceof Assign) { + base = assign.variable.base; + delete assign.context; + func = assign.value; + if (base.value === 'constructor') { + if (this.ctor) { + assign.error('cannot define more than one constructor in a class'); + } + if (func.bound) { + assign.error('cannot define a constructor as a bound function'); + } + if (func instanceof Code) { + assign = this.ctor = func; + } else { + this.externalCtor = o.classScope.freeVariable('class'); + assign = new Assign(new Literal(this.externalCtor), func); + } + } else { + if (assign.variable["this"]) { + func["static"] = true; + } else { + assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]); + if (func instanceof Code && func.bound) { + this.boundFuncs.push(base); + func.bound = false; + } + } + } + } + _results.push(assign); + } + return _results; + }).call(this); + return compact(exprs); + }; + + Class.prototype.walkBody = function(name, o) { + return this.traverseChildren(false, (function(_this) { + return function(child) { + var cont, exps, i, node, _i, _len, _ref2; + cont = true; + if (child instanceof Class) { + return false; + } + if (child instanceof Block) { + _ref2 = exps = child.expressions; + for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) { + node = _ref2[i]; + if (node instanceof Assign && node.variable.looksStatic(name)) { + node.value["static"] = true; + } else if (node instanceof Value && node.isObject(true)) { + cont = false; + exps[i] = _this.addProperties(node, name, o); + } + } + child.expressions = exps = flatten(exps); + } + return cont && !(child instanceof Class); + }; + })(this)); + }; + + Class.prototype.hoistDirectivePrologue = function() { + var expressions, index, node; + index = 0; + expressions = this.body.expressions; + while ((node = expressions[index]) && node instanceof Comment || node instanceof Value && node.isString()) { + ++index; + } + return this.directives = expressions.splice(0, index); + }; + + Class.prototype.ensureConstructor = function(name) { + if (!this.ctor) { + this.ctor = new Code; + if (this.externalCtor) { + this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)")); + } else if (this.parent) { + this.ctor.body.push(new Literal("" + name + ".__super__.constructor.apply(this, arguments)")); + } + this.ctor.body.makeReturn(); + this.body.expressions.unshift(this.ctor); + } + this.ctor.ctor = this.ctor.name = name; + this.ctor.klass = null; + return this.ctor.noReturn = true; + }; + + Class.prototype.compileNode = function(o) { + var args, argumentsNode, func, jumpNode, klass, lname, name, superClass, _ref2; + if (jumpNode = this.body.jumps()) { + jumpNode.error('Class bodies cannot contain pure statements'); + } + if (argumentsNode = this.body.contains(isLiteralArguments)) { + argumentsNode.error("Class bodies shouldn't reference arguments"); + } + name = this.determineName() || '_Class'; + if (name.reserved) { + name = "_" + name; + } + lname = new Literal(name); + func = new Code([], Block.wrap([this.body])); + args = []; + o.classScope = func.makeScope(o.scope); + this.hoistDirectivePrologue(); + this.setContext(name); + this.walkBody(name, o); + this.ensureConstructor(name); + this.addBoundFunctions(o); + this.body.spaced = true; + this.body.expressions.push(lname); + if (this.parent) { + superClass = new Literal(o.classScope.freeVariable('super', false)); + this.body.expressions.unshift(new Extends(lname, superClass)); + func.params.push(new Param(superClass)); + args.push(this.parent); + } + (_ref2 = this.body.expressions).unshift.apply(_ref2, this.directives); + klass = new Parens(new Call(func, args)); + if (this.variable) { + klass = new Assign(this.variable, klass); + } + return klass.compileToFragments(o); + }; + + return Class; + + })(Base); + + exports.Assign = Assign = (function(_super) { + __extends(Assign, _super); + + function Assign(variable, value, context, options) { + var forbidden, name, _ref2; + this.variable = variable; + this.value = value; + this.context = context; + this.param = options && options.param; + this.subpattern = options && options.subpattern; + forbidden = (_ref2 = (name = this.variable.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0); + if (forbidden && this.context !== 'object') { + this.variable.error("variable name may not be \"" + name + "\""); + } + } + + Assign.prototype.children = ['variable', 'value']; + + Assign.prototype.isStatement = function(o) { + return (o != null ? o.level : void 0) === LEVEL_TOP && (this.context != null) && __indexOf.call(this.context, "?") >= 0; + }; + + Assign.prototype.assigns = function(name) { + return this[this.context === 'object' ? 'value' : 'variable'].assigns(name); + }; + + Assign.prototype.unfoldSoak = function(o) { + return unfoldSoak(o, this, 'variable'); + }; + + Assign.prototype.compileNode = function(o) { + var answer, compiledName, isValue, match, name, val, varBase, _ref2, _ref3, _ref4; + if (isValue = this.variable instanceof Value) { + if (this.variable.isArray() || this.variable.isObject()) { + return this.compilePatternMatch(o); + } + if (this.variable.isSplice()) { + return this.compileSplice(o); + } + if ((_ref2 = this.context) === '||=' || _ref2 === '&&=' || _ref2 === '?=') { + return this.compileConditional(o); + } + } + compiledName = this.variable.compileToFragments(o, LEVEL_LIST); + name = fragmentsToText(compiledName); + if (!this.context) { + varBase = this.variable.unwrapAll(); + if (!varBase.isAssignable()) { + this.variable.error("\"" + (this.variable.compile(o)) + "\" cannot be assigned"); + } + if (!(typeof varBase.hasProperties === "function" ? varBase.hasProperties() : void 0)) { + if (this.param) { + o.scope.add(name, 'var'); + } else { + o.scope.find(name); + } + } + } + if (this.value instanceof Code && (match = METHOD_DEF.exec(name))) { + if (match[2]) { + this.value.klass = match[1]; + } + this.value.name = (_ref3 = (_ref4 = match[3]) != null ? _ref4 : match[4]) != null ? _ref3 : match[5]; + } + val = this.value.compileToFragments(o, LEVEL_LIST); + if (this.context === 'object') { + return compiledName.concat(this.makeCode(": "), val); + } + answer = compiledName.concat(this.makeCode(" " + (this.context || '=') + " "), val); + if (o.level <= LEVEL_LIST) { + return answer; + } else { + return this.wrapInBraces(answer); + } + }; + + Assign.prototype.compilePatternMatch = function(o) { + var acc, assigns, code, fragments, i, idx, isObject, ivar, name, obj, objects, olen, ref, rest, splat, top, val, value, vvar, vvarText, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7; + top = o.level === LEVEL_TOP; + value = this.value; + objects = this.variable.base.objects; + if (!(olen = objects.length)) { + code = value.compileToFragments(o); + if (o.level >= LEVEL_OP) { + return this.wrapInBraces(code); + } else { + return code; + } + } + isObject = this.variable.isObject(); + if (top && olen === 1 && !((obj = objects[0]) instanceof Splat)) { + if (obj instanceof Assign) { + _ref2 = obj, (_ref3 = _ref2.variable, idx = _ref3.base), obj = _ref2.value; + } else { + idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0); + } + acc = IDENTIFIER.test(idx.unwrap().value || 0); + value = new Value(value); + value.properties.push(new (acc ? Access : Index)(idx)); + if (_ref4 = obj.unwrap().value, __indexOf.call(RESERVED, _ref4) >= 0) { + obj.error("assignment to a reserved word: " + (obj.compile(o))); + } + return new Assign(obj, value, null, { + param: this.param + }).compileToFragments(o, LEVEL_TOP); + } + vvar = value.compileToFragments(o, LEVEL_LIST); + vvarText = fragmentsToText(vvar); + assigns = []; + splat = false; + if (!IDENTIFIER.test(vvarText) || this.variable.assigns(vvarText)) { + assigns.push([this.makeCode("" + (ref = o.scope.freeVariable('ref')) + " = ")].concat(__slice.call(vvar))); + vvar = [this.makeCode(ref)]; + vvarText = ref; + } + for (i = _i = 0, _len = objects.length; _i < _len; i = ++_i) { + obj = objects[i]; + idx = i; + if (isObject) { + if (obj instanceof Assign) { + _ref5 = obj, (_ref6 = _ref5.variable, idx = _ref6.base), obj = _ref5.value; + } else { + if (obj.base instanceof Parens) { + _ref7 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref7[0], idx = _ref7[1]; + } else { + idx = obj["this"] ? obj.properties[0].name : obj; + } + } + } + if (!splat && obj instanceof Splat) { + name = obj.name.unwrap().value; + obj = obj.unwrap(); + val = "" + olen + " <= " + vvarText + ".length ? " + (utility('slice')) + ".call(" + vvarText + ", " + i; + if (rest = olen - i - 1) { + ivar = o.scope.freeVariable('i'); + val += ", " + ivar + " = " + vvarText + ".length - " + rest + ") : (" + ivar + " = " + i + ", [])"; + } else { + val += ") : []"; + } + val = new Literal(val); + splat = "" + ivar + "++"; + } else { + name = obj.unwrap().value; + if (obj instanceof Splat) { + obj.error("multiple splats are disallowed in an assignment"); + } + if (typeof idx === 'number') { + idx = new Literal(splat || idx); + acc = false; + } else { + acc = isObject && IDENTIFIER.test(idx.unwrap().value || 0); + } + val = new Value(new Literal(vvarText), [new (acc ? Access : Index)(idx)]); + } + if ((name != null) && __indexOf.call(RESERVED, name) >= 0) { + obj.error("assignment to a reserved word: " + (obj.compile(o))); + } + assigns.push(new Assign(obj, val, null, { + param: this.param, + subpattern: true + }).compileToFragments(o, LEVEL_LIST)); + } + if (!(top || this.subpattern)) { + assigns.push(vvar); + } + fragments = this.joinFragmentArrays(assigns, ', '); + if (o.level < LEVEL_LIST) { + return fragments; + } else { + return this.wrapInBraces(fragments); + } + }; + + Assign.prototype.compileConditional = function(o) { + var fragments, left, right, _ref2; + _ref2 = this.variable.cacheReference(o), left = _ref2[0], right = _ref2[1]; + if (!left.properties.length && left.base instanceof Literal && left.base.value !== "this" && !o.scope.check(left.base.value)) { + this.variable.error("the variable \"" + left.base.value + "\" can't be assigned with " + this.context + " because it has not been declared before"); + } + if (__indexOf.call(this.context, "?") >= 0) { + o.isExistentialEquals = true; + return new If(new Existence(left), right, { + type: 'if' + }).addElse(new Assign(right, this.value, '=')).compileToFragments(o); + } else { + fragments = new Op(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compileToFragments(o); + if (o.level <= LEVEL_LIST) { + return fragments; + } else { + return this.wrapInBraces(fragments); + } + } + }; + + Assign.prototype.compileSplice = function(o) { + var answer, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef, _ref2, _ref3, _ref4; + _ref2 = this.variable.properties.pop().range, from = _ref2.from, to = _ref2.to, exclusive = _ref2.exclusive; + name = this.variable.compile(o); + if (from) { + _ref3 = this.cacheToCodeFragments(from.cache(o, LEVEL_OP)), fromDecl = _ref3[0], fromRef = _ref3[1]; + } else { + fromDecl = fromRef = '0'; + } + if (to) { + if (from instanceof Value && from.isSimpleNumber() && to instanceof Value && to.isSimpleNumber()) { + to = to.compile(o) - fromRef; + if (!exclusive) { + to += 1; + } + } else { + to = to.compile(o, LEVEL_ACCESS) + ' - ' + fromRef; + if (!exclusive) { + to += ' + 1'; + } + } + } else { + to = "9e9"; + } + _ref4 = this.value.cache(o, LEVEL_LIST), valDef = _ref4[0], valRef = _ref4[1]; + answer = [].concat(this.makeCode("[].splice.apply(" + name + ", [" + fromDecl + ", " + to + "].concat("), valDef, this.makeCode(")), "), valRef); + if (o.level > LEVEL_TOP) { + return this.wrapInBraces(answer); + } else { + return answer; + } + }; + + return Assign; + + })(Base); + + exports.Code = Code = (function(_super) { + __extends(Code, _super); + + function Code(params, body, tag) { + this.params = params || []; + this.body = body || new Block; + this.bound = tag === 'boundfunc'; + } + + Code.prototype.children = ['params', 'body']; + + Code.prototype.isStatement = function() { + return !!this.ctor; + }; + + Code.prototype.jumps = NO; + + Code.prototype.makeScope = function(parentScope) { + return new Scope(parentScope, this.body, this); + }; + + Code.prototype.compileNode = function(o) { + var answer, boundfunc, code, exprs, i, lit, p, param, params, ref, splats, uniqs, val, wasEmpty, wrapper, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _m, _n, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7; + if (this.bound && ((_ref2 = o.scope.method) != null ? _ref2.bound : void 0)) { + this.context = o.scope.method.context; + } + if (this.bound && !this.context) { + this.context = '_this'; + wrapper = new Code([new Param(new Literal(this.context))], new Block([this])); + boundfunc = new Call(wrapper, [new Literal('this')]); + boundfunc.updateLocationDataIfMissing(this.locationData); + return boundfunc.compileNode(o); + } + o.scope = del(o, 'classScope') || this.makeScope(o.scope); + o.scope.shared = del(o, 'sharedScope'); + o.indent += TAB; + delete o.bare; + delete o.isExistentialEquals; + params = []; + exprs = []; + _ref3 = this.params; + for (_i = 0, _len = _ref3.length; _i < _len; _i++) { + param = _ref3[_i]; + o.scope.parameter(param.asReference(o)); + } + _ref4 = this.params; + for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) { + param = _ref4[_j]; + if (!param.splat) { + continue; + } + _ref5 = this.params; + for (_k = 0, _len2 = _ref5.length; _k < _len2; _k++) { + p = _ref5[_k].name; + if (p["this"]) { + p = p.properties[0].name; + } + if (p.value) { + o.scope.add(p.value, 'var', true); + } + } + splats = new Assign(new Value(new Arr((function() { + var _l, _len3, _ref6, _results; + _ref6 = this.params; + _results = []; + for (_l = 0, _len3 = _ref6.length; _l < _len3; _l++) { + p = _ref6[_l]; + _results.push(p.asReference(o)); + } + return _results; + }).call(this))), new Value(new Literal('arguments'))); + break; + } + _ref6 = this.params; + for (_l = 0, _len3 = _ref6.length; _l < _len3; _l++) { + param = _ref6[_l]; + if (param.isComplex()) { + val = ref = param.asReference(o); + if (param.value) { + val = new Op('?', ref, param.value); + } + exprs.push(new Assign(new Value(param.name), val, '=', { + param: true + })); + } else { + ref = param; + if (param.value) { + lit = new Literal(ref.name.value + ' == null'); + val = new Assign(new Value(param.name), param.value, '='); + exprs.push(new If(lit, val)); + } + } + if (!splats) { + params.push(ref); + } + } + wasEmpty = this.body.isEmpty(); + if (splats) { + exprs.unshift(splats); + } + if (exprs.length) { + (_ref7 = this.body.expressions).unshift.apply(_ref7, exprs); + } + for (i = _m = 0, _len4 = params.length; _m < _len4; i = ++_m) { + p = params[i]; + params[i] = p.compileToFragments(o); + o.scope.parameter(fragmentsToText(params[i])); + } + uniqs = []; + this.eachParamName(function(name, node) { + if (__indexOf.call(uniqs, name) >= 0) { + node.error("multiple parameters named '" + name + "'"); + } + return uniqs.push(name); + }); + if (!(wasEmpty || this.noReturn)) { + this.body.makeReturn(); + } + code = 'function'; + if (this.ctor) { + code += ' ' + this.name; + } + code += '('; + answer = [this.makeCode(code)]; + for (i = _n = 0, _len5 = params.length; _n < _len5; i = ++_n) { + p = params[i]; + if (i) { + answer.push(this.makeCode(", ")); + } + answer.push.apply(answer, p); + } + answer.push(this.makeCode(') {')); + if (!this.body.isEmpty()) { + answer = answer.concat(this.makeCode("\n"), this.body.compileWithDeclarations(o), this.makeCode("\n" + this.tab)); + } + answer.push(this.makeCode('}')); + if (this.ctor) { + return [this.makeCode(this.tab)].concat(__slice.call(answer)); + } + if (this.front || (o.level >= LEVEL_ACCESS)) { + return this.wrapInBraces(answer); + } else { + return answer; + } + }; + + Code.prototype.eachParamName = function(iterator) { + var param, _i, _len, _ref2, _results; + _ref2 = this.params; + _results = []; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + param = _ref2[_i]; + _results.push(param.eachName(iterator)); + } + return _results; + }; + + Code.prototype.traverseChildren = function(crossScope, func) { + if (crossScope) { + return Code.__super__.traverseChildren.call(this, crossScope, func); + } + }; + + return Code; + + })(Base); + + exports.Param = Param = (function(_super) { + __extends(Param, _super); + + function Param(name, value, splat) { + var _ref2; + this.name = name; + this.value = value; + this.splat = splat; + if (_ref2 = (name = this.name.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) { + this.name.error("parameter name \"" + name + "\" is not allowed"); + } + } + + Param.prototype.children = ['name', 'value']; + + Param.prototype.compileToFragments = function(o) { + return this.name.compileToFragments(o, LEVEL_LIST); + }; + + Param.prototype.asReference = function(o) { + var node; + if (this.reference) { + return this.reference; + } + node = this.name; + if (node["this"]) { + node = node.properties[0].name; + if (node.value.reserved) { + node = new Literal(o.scope.freeVariable(node.value)); + } + } else if (node.isComplex()) { + node = new Literal(o.scope.freeVariable('arg')); + } + node = new Value(node); + if (this.splat) { + node = new Splat(node); + } + node.updateLocationDataIfMissing(this.locationData); + return this.reference = node; + }; + + Param.prototype.isComplex = function() { + return this.name.isComplex(); + }; + + Param.prototype.eachName = function(iterator, name) { + var atParam, node, obj, _i, _len, _ref2; + if (name == null) { + name = this.name; + } + atParam = function(obj) { + var node; + node = obj.properties[0].name; + if (!node.value.reserved) { + return iterator(node.value, node); + } + }; + if (name instanceof Literal) { + return iterator(name.value, name); + } + if (name instanceof Value) { + return atParam(name); + } + _ref2 = name.objects; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + obj = _ref2[_i]; + if (obj instanceof Assign) { + this.eachName(iterator, obj.value.unwrap()); + } else if (obj instanceof Splat) { + node = obj.name.unwrap(); + iterator(node.value, node); + } else if (obj instanceof Value) { + if (obj.isArray() || obj.isObject()) { + this.eachName(iterator, obj.base); + } else if (obj["this"]) { + atParam(obj); + } else { + iterator(obj.base.value, obj.base); + } + } else { + obj.error("illegal parameter " + (obj.compile())); + } + } + }; + + return Param; + + })(Base); + + exports.Splat = Splat = (function(_super) { + __extends(Splat, _super); + + Splat.prototype.children = ['name']; + + Splat.prototype.isAssignable = YES; + + function Splat(name) { + this.name = name.compile ? name : new Literal(name); + } + + Splat.prototype.assigns = function(name) { + return this.name.assigns(name); + }; + + Splat.prototype.compileToFragments = function(o) { + return this.name.compileToFragments(o); + }; + + Splat.prototype.unwrap = function() { + return this.name; + }; + + Splat.compileSplattedArray = function(o, list, apply) { + var args, base, compiledNode, concatPart, fragments, i, index, node, _i, _len; + index = -1; + while ((node = list[++index]) && !(node instanceof Splat)) { + continue; + } + if (index >= list.length) { + return []; + } + if (list.length === 1) { + node = list[0]; + fragments = node.compileToFragments(o, LEVEL_LIST); + if (apply) { + return fragments; + } + return [].concat(node.makeCode("" + (utility('slice')) + ".call("), fragments, node.makeCode(")")); + } + args = list.slice(index); + for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) { + node = args[i]; + compiledNode = node.compileToFragments(o, LEVEL_LIST); + args[i] = node instanceof Splat ? [].concat(node.makeCode("" + (utility('slice')) + ".call("), compiledNode, node.makeCode(")")) : [].concat(node.makeCode("["), compiledNode, node.makeCode("]")); + } + if (index === 0) { + node = list[0]; + concatPart = node.joinFragmentArrays(args.slice(1), ', '); + return args[0].concat(node.makeCode(".concat("), concatPart, node.makeCode(")")); + } + base = (function() { + var _j, _len1, _ref2, _results; + _ref2 = list.slice(0, index); + _results = []; + for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + node = _ref2[_j]; + _results.push(node.compileToFragments(o, LEVEL_LIST)); + } + return _results; + })(); + base = list[0].joinFragmentArrays(base, ', '); + concatPart = list[index].joinFragmentArrays(args, ', '); + return [].concat(list[0].makeCode("["), base, list[index].makeCode("].concat("), concatPart, (last(list)).makeCode(")")); + }; + + return Splat; + + })(Base); + + exports.While = While = (function(_super) { + __extends(While, _super); + + function While(condition, options) { + this.condition = (options != null ? options.invert : void 0) ? condition.invert() : condition; + this.guard = options != null ? options.guard : void 0; + } + + While.prototype.children = ['condition', 'guard', 'body']; + + While.prototype.isStatement = YES; + + While.prototype.makeReturn = function(res) { + if (res) { + return While.__super__.makeReturn.apply(this, arguments); + } else { + this.returns = !this.jumps({ + loop: true + }); + return this; + } + }; + + While.prototype.addBody = function(body) { + this.body = body; + return this; + }; + + While.prototype.jumps = function() { + var expressions, jumpNode, node, _i, _len; + expressions = this.body.expressions; + if (!expressions.length) { + return false; + } + for (_i = 0, _len = expressions.length; _i < _len; _i++) { + node = expressions[_i]; + if (jumpNode = node.jumps({ + loop: true + })) { + return jumpNode; + } + } + return false; + }; + + While.prototype.compileNode = function(o) { + var answer, body, rvar, set; + o.indent += TAB; + set = ''; + body = this.body; + if (body.isEmpty()) { + body = this.makeCode(''); + } else { + if (this.returns) { + body.makeReturn(rvar = o.scope.freeVariable('results')); + set = "" + this.tab + rvar + " = [];\n"; + } + if (this.guard) { + if (body.expressions.length > 1) { + body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue"))); + } else { + if (this.guard) { + body = Block.wrap([new If(this.guard, body)]); + } + } + } + body = [].concat(this.makeCode("\n"), body.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab)); + } + answer = [].concat(this.makeCode(set + this.tab + "while ("), this.condition.compileToFragments(o, LEVEL_PAREN), this.makeCode(") {"), body, this.makeCode("}")); + if (this.returns) { + answer.push(this.makeCode("\n" + this.tab + "return " + rvar + ";")); + } + return answer; + }; + + return While; + + })(Base); + + exports.Op = Op = (function(_super) { + var CONVERSIONS, INVERSIONS; + + __extends(Op, _super); + + function Op(op, first, second, flip) { + if (op === 'in') { + return new In(first, second); + } + if (op === 'do') { + return this.generateDo(first); + } + if (op === 'new') { + if (first instanceof Call && !first["do"] && !first.isNew) { + return first.newInstance(); + } + if (first instanceof Code && first.bound || first["do"]) { + first = new Parens(first); + } + } + this.operator = CONVERSIONS[op] || op; + this.first = first; + this.second = second; + this.flip = !!flip; + return this; + } + + CONVERSIONS = { + '==': '===', + '!=': '!==', + 'of': 'in' + }; + + INVERSIONS = { + '!==': '===', + '===': '!==' + }; + + Op.prototype.children = ['first', 'second']; + + Op.prototype.isSimpleNumber = NO; + + Op.prototype.isUnary = function() { + return !this.second; + }; + + Op.prototype.isComplex = function() { + var _ref2; + return !(this.isUnary() && ((_ref2 = this.operator) === '+' || _ref2 === '-')) || this.first.isComplex(); + }; + + Op.prototype.isChainable = function() { + var _ref2; + return (_ref2 = this.operator) === '<' || _ref2 === '>' || _ref2 === '>=' || _ref2 === '<=' || _ref2 === '===' || _ref2 === '!=='; + }; + + Op.prototype.invert = function() { + var allInvertable, curr, fst, op, _ref2; + if (this.isChainable() && this.first.isChainable()) { + allInvertable = true; + curr = this; + while (curr && curr.operator) { + allInvertable && (allInvertable = curr.operator in INVERSIONS); + curr = curr.first; + } + if (!allInvertable) { + return new Parens(this).invert(); + } + curr = this; + while (curr && curr.operator) { + curr.invert = !curr.invert; + curr.operator = INVERSIONS[curr.operator]; + curr = curr.first; + } + return this; + } else if (op = INVERSIONS[this.operator]) { + this.operator = op; + if (this.first.unwrap() instanceof Op) { + this.first.invert(); + } + return this; + } else if (this.second) { + return new Parens(this).invert(); + } else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref2 = fst.operator) === '!' || _ref2 === 'in' || _ref2 === 'instanceof')) { + return fst; + } else { + return new Op('!', this); + } + }; + + Op.prototype.unfoldSoak = function(o) { + var _ref2; + return ((_ref2 = this.operator) === '++' || _ref2 === '--' || _ref2 === 'delete') && unfoldSoak(o, this, 'first'); + }; + + Op.prototype.generateDo = function(exp) { + var call, func, param, passedParams, ref, _i, _len, _ref2; + passedParams = []; + func = exp instanceof Assign && (ref = exp.value.unwrap()) instanceof Code ? ref : exp; + _ref2 = func.params || []; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + param = _ref2[_i]; + if (param.value) { + passedParams.push(param.value); + delete param.value; + } else { + passedParams.push(param); + } + } + call = new Call(exp, passedParams); + call["do"] = true; + return call; + }; + + Op.prototype.compileNode = function(o) { + var answer, isChain, _ref2, _ref3; + isChain = this.isChainable() && this.first.isChainable(); + if (!isChain) { + this.first.front = this.front; + } + if (this.operator === 'delete' && o.scope.check(this.first.unwrapAll().value)) { + this.error('delete operand may not be argument or var'); + } + if (((_ref2 = this.operator) === '--' || _ref2 === '++') && (_ref3 = this.first.unwrapAll().value, __indexOf.call(STRICT_PROSCRIBED, _ref3) >= 0)) { + this.error("cannot increment/decrement \"" + (this.first.unwrapAll().value) + "\""); + } + if (this.isUnary()) { + return this.compileUnary(o); + } + if (isChain) { + return this.compileChain(o); + } + if (this.operator === '?') { + return this.compileExistence(o); + } + answer = [].concat(this.first.compileToFragments(o, LEVEL_OP), this.makeCode(' ' + this.operator + ' '), this.second.compileToFragments(o, LEVEL_OP)); + if (o.level <= LEVEL_OP) { + return answer; + } else { + return this.wrapInBraces(answer); + } + }; + + Op.prototype.compileChain = function(o) { + var fragments, fst, shared, _ref2; + _ref2 = this.first.second.cache(o), this.first.second = _ref2[0], shared = _ref2[1]; + fst = this.first.compileToFragments(o, LEVEL_OP); + fragments = fst.concat(this.makeCode(" " + (this.invert ? '&&' : '||') + " "), shared.compileToFragments(o), this.makeCode(" " + this.operator + " "), this.second.compileToFragments(o, LEVEL_OP)); + return this.wrapInBraces(fragments); + }; + + Op.prototype.compileExistence = function(o) { + var fst, ref; + if (this.first.isComplex()) { + ref = new Literal(o.scope.freeVariable('ref')); + fst = new Parens(new Assign(ref, this.first)); + } else { + fst = this.first; + ref = fst; + } + return new If(new Existence(fst), ref, { + type: 'if' + }).addElse(this.second).compileToFragments(o); + }; + + Op.prototype.compileUnary = function(o) { + var op, parts, plusMinus; + parts = []; + op = this.operator; + parts.push([this.makeCode(op)]); + if (op === '!' && this.first instanceof Existence) { + this.first.negated = !this.first.negated; + return this.first.compileToFragments(o); + } + if (o.level >= LEVEL_ACCESS) { + return (new Parens(this)).compileToFragments(o); + } + plusMinus = op === '+' || op === '-'; + if ((op === 'new' || op === 'typeof' || op === 'delete') || plusMinus && this.first instanceof Op && this.first.operator === op) { + parts.push([this.makeCode(' ')]); + } + if ((plusMinus && this.first instanceof Op) || (op === 'new' && this.first.isStatement(o))) { + this.first = new Parens(this.first); + } + parts.push(this.first.compileToFragments(o, LEVEL_OP)); + if (this.flip) { + parts.reverse(); + } + return this.joinFragmentArrays(parts, ''); + }; + + Op.prototype.toString = function(idt) { + return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator); + }; + + return Op; + + })(Base); + + exports.In = In = (function(_super) { + __extends(In, _super); + + function In(object, array) { + this.object = object; + this.array = array; + } + + In.prototype.children = ['object', 'array']; + + In.prototype.invert = NEGATE; + + In.prototype.compileNode = function(o) { + var hasSplat, obj, _i, _len, _ref2; + if (this.array instanceof Value && this.array.isArray()) { + _ref2 = this.array.base.objects; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + obj = _ref2[_i]; + if (!(obj instanceof Splat)) { + continue; + } + hasSplat = true; + break; + } + if (!hasSplat) { + return this.compileOrTest(o); + } + } + return this.compileLoopTest(o); + }; + + In.prototype.compileOrTest = function(o) { + var cmp, cnj, i, item, ref, sub, tests, _i, _len, _ref2, _ref3, _ref4; + if (this.array.base.objects.length === 0) { + return [this.makeCode("" + (!!this.negated))]; + } + _ref2 = this.object.cache(o, LEVEL_OP), sub = _ref2[0], ref = _ref2[1]; + _ref3 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref3[0], cnj = _ref3[1]; + tests = []; + _ref4 = this.array.base.objects; + for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) { + item = _ref4[i]; + if (i) { + tests.push(this.makeCode(cnj)); + } + tests = tests.concat((i ? ref : sub), this.makeCode(cmp), item.compileToFragments(o, LEVEL_ACCESS)); + } + if (o.level < LEVEL_OP) { + return tests; + } else { + return this.wrapInBraces(tests); + } + }; + + In.prototype.compileLoopTest = function(o) { + var fragments, ref, sub, _ref2; + _ref2 = this.object.cache(o, LEVEL_LIST), sub = _ref2[0], ref = _ref2[1]; + fragments = [].concat(this.makeCode(utility('indexOf') + ".call("), this.array.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), ref, this.makeCode(") " + (this.negated ? '< 0' : '>= 0'))); + if (fragmentsToText(sub) === fragmentsToText(ref)) { + return fragments; + } + fragments = sub.concat(this.makeCode(', '), fragments); + if (o.level < LEVEL_LIST) { + return fragments; + } else { + return this.wrapInBraces(fragments); + } + }; + + In.prototype.toString = function(idt) { + return In.__super__.toString.call(this, idt, this.constructor.name + (this.negated ? '!' : '')); + }; + + return In; + + })(Base); + + exports.Try = Try = (function(_super) { + __extends(Try, _super); + + function Try(attempt, errorVariable, recovery, ensure) { + this.attempt = attempt; + this.errorVariable = errorVariable; + this.recovery = recovery; + this.ensure = ensure; + } + + Try.prototype.children = ['attempt', 'recovery', 'ensure']; + + Try.prototype.isStatement = YES; + + Try.prototype.jumps = function(o) { + var _ref2; + return this.attempt.jumps(o) || ((_ref2 = this.recovery) != null ? _ref2.jumps(o) : void 0); + }; + + Try.prototype.makeReturn = function(res) { + if (this.attempt) { + this.attempt = this.attempt.makeReturn(res); + } + if (this.recovery) { + this.recovery = this.recovery.makeReturn(res); + } + return this; + }; + + Try.prototype.compileNode = function(o) { + var catchPart, ensurePart, placeholder, tryPart; + o.indent += TAB; + tryPart = this.attempt.compileToFragments(o, LEVEL_TOP); + catchPart = this.recovery ? (placeholder = new Literal('_error'), this.errorVariable ? this.recovery.unshift(new Assign(this.errorVariable, placeholder)) : void 0, [].concat(this.makeCode(" catch ("), placeholder.compileToFragments(o), this.makeCode(") {\n"), this.recovery.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}"))) : !(this.ensure || this.recovery) ? [this.makeCode(' catch (_error) {}')] : []; + ensurePart = this.ensure ? [].concat(this.makeCode(" finally {\n"), this.ensure.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}")) : []; + return [].concat(this.makeCode("" + this.tab + "try {\n"), tryPart, this.makeCode("\n" + this.tab + "}"), catchPart, ensurePart); + }; + + return Try; + + })(Base); + + exports.Throw = Throw = (function(_super) { + __extends(Throw, _super); + + function Throw(expression) { + this.expression = expression; + } + + Throw.prototype.children = ['expression']; + + Throw.prototype.isStatement = YES; + + Throw.prototype.jumps = NO; + + Throw.prototype.makeReturn = THIS; + + Throw.prototype.compileNode = function(o) { + return [].concat(this.makeCode(this.tab + "throw "), this.expression.compileToFragments(o), this.makeCode(";")); + }; + + return Throw; + + })(Base); + + exports.Existence = Existence = (function(_super) { + __extends(Existence, _super); + + function Existence(expression) { + this.expression = expression; + } + + Existence.prototype.children = ['expression']; + + Existence.prototype.invert = NEGATE; + + Existence.prototype.compileNode = function(o) { + var cmp, cnj, code, _ref2; + this.expression.front = this.front; + code = this.expression.compile(o, LEVEL_OP); + if (IDENTIFIER.test(code) && !o.scope.check(code)) { + _ref2 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = _ref2[0], cnj = _ref2[1]; + code = "typeof " + code + " " + cmp + " \"undefined\" " + cnj + " " + code + " " + cmp + " null"; + } else { + code = "" + code + " " + (this.negated ? '==' : '!=') + " null"; + } + return [this.makeCode(o.level <= LEVEL_COND ? code : "(" + code + ")")]; + }; + + return Existence; + + })(Base); + + exports.Parens = Parens = (function(_super) { + __extends(Parens, _super); + + function Parens(body) { + this.body = body; + } + + Parens.prototype.children = ['body']; + + Parens.prototype.unwrap = function() { + return this.body; + }; + + Parens.prototype.isComplex = function() { + return this.body.isComplex(); + }; + + Parens.prototype.compileNode = function(o) { + var bare, expr, fragments; + expr = this.body.unwrap(); + if (expr instanceof Value && expr.isAtomic()) { + expr.front = this.front; + return expr.compileToFragments(o); + } + fragments = expr.compileToFragments(o, LEVEL_PAREN); + bare = o.level < LEVEL_OP && (expr instanceof Op || expr instanceof Call || (expr instanceof For && expr.returns)); + if (bare) { + return fragments; + } else { + return this.wrapInBraces(fragments); + } + }; + + return Parens; + + })(Base); + + exports.For = For = (function(_super) { + __extends(For, _super); + + function For(body, source) { + var _ref2; + this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index; + this.body = Block.wrap([body]); + this.own = !!source.own; + this.object = !!source.object; + if (this.object) { + _ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1]; + } + if (this.index instanceof Value) { + this.index.error('index cannot be a pattern matching expression'); + } + this.range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length; + this.pattern = this.name instanceof Value; + if (this.range && this.index) { + this.index.error('indexes do not apply to range loops'); + } + if (this.range && this.pattern) { + this.name.error('cannot pattern match over range loops'); + } + if (this.own && !this.object) { + this.name.error('cannot use own with for-in'); + } + this.returns = false; + } + + For.prototype.children = ['body', 'source', 'guard', 'step']; + + For.prototype.compileNode = function(o) { + var body, bodyFragments, compare, compareDown, declare, declareDown, defPart, defPartFragments, down, forPartFragments, guardPart, idt1, increment, index, ivar, kvar, kvarAssign, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart, _ref2, _ref3; + body = Block.wrap([this.body]); + lastJumps = (_ref2 = last(body.expressions)) != null ? _ref2.jumps() : void 0; + if (lastJumps && lastJumps instanceof Return) { + this.returns = false; + } + source = this.range ? this.source.base : this.source; + scope = o.scope; + name = this.name && (this.name.compile(o, LEVEL_LIST)); + index = this.index && (this.index.compile(o, LEVEL_LIST)); + if (name && !this.pattern) { + scope.find(name); + } + if (index) { + scope.find(index); + } + if (this.returns) { + rvar = scope.freeVariable('results'); + } + ivar = (this.object && index) || scope.freeVariable('i'); + kvar = (this.range && name) || index || ivar; + kvarAssign = kvar !== ivar ? "" + kvar + " = " : ""; + if (this.step && !this.range) { + _ref3 = this.cacheToCodeFragments(this.step.cache(o, LEVEL_LIST)), step = _ref3[0], stepVar = _ref3[1]; + stepNum = stepVar.match(NUMBER); + } + if (this.pattern) { + name = ivar; + } + varPart = ''; + guardPart = ''; + defPart = ''; + idt1 = this.tab + TAB; + if (this.range) { + forPartFragments = source.compileToFragments(merge(o, { + index: ivar, + name: name, + step: this.step + })); + } else { + svar = this.source.compile(o, LEVEL_LIST); + if ((name || this.own) && !IDENTIFIER.test(svar)) { + defPart += "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n"; + svar = ref; + } + if (name && !this.pattern) { + namePart = "" + name + " = " + svar + "[" + kvar + "]"; + } + if (!this.object) { + if (step !== stepVar) { + defPart += "" + this.tab + step + ";\n"; + } + if (!(this.step && stepNum && (down = parseNum(stepNum[0]) < 0))) { + lvar = scope.freeVariable('len'); + } + declare = "" + kvarAssign + ivar + " = 0, " + lvar + " = " + svar + ".length"; + declareDown = "" + kvarAssign + ivar + " = " + svar + ".length - 1"; + compare = "" + ivar + " < " + lvar; + compareDown = "" + ivar + " >= 0"; + if (this.step) { + if (stepNum) { + if (down) { + compare = compareDown; + declare = declareDown; + } + } else { + compare = "" + stepVar + " > 0 ? " + compare + " : " + compareDown; + declare = "(" + stepVar + " > 0 ? (" + declare + ") : " + declareDown + ")"; + } + increment = "" + ivar + " += " + stepVar; + } else { + increment = "" + (kvar !== ivar ? "++" + ivar : "" + ivar + "++"); + } + forPartFragments = [this.makeCode("" + declare + "; " + compare + "; " + kvarAssign + increment)]; + } + } + if (this.returns) { + resultPart = "" + this.tab + rvar + " = [];\n"; + returnResult = "\n" + this.tab + "return " + rvar + ";"; + body.makeReturn(rvar); + } + if (this.guard) { + if (body.expressions.length > 1) { + body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue"))); + } else { + if (this.guard) { + body = Block.wrap([new If(this.guard, body)]); + } + } + } + if (this.pattern) { + body.expressions.unshift(new Assign(this.name, new Literal("" + svar + "[" + kvar + "]"))); + } + defPartFragments = [].concat(this.makeCode(defPart), this.pluckDirectCall(o, body)); + if (namePart) { + varPart = "\n" + idt1 + namePart + ";"; + } + if (this.object) { + forPartFragments = [this.makeCode("" + kvar + " in " + svar)]; + if (this.own) { + guardPart = "\n" + idt1 + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + kvar + ")) continue;"; + } + } + bodyFragments = body.compileToFragments(merge(o, { + indent: idt1 + }), LEVEL_TOP); + if (bodyFragments && (bodyFragments.length > 0)) { + bodyFragments = [].concat(this.makeCode("\n"), bodyFragments, this.makeCode("\n")); + } + return [].concat(defPartFragments, this.makeCode("" + (resultPart || '') + this.tab + "for ("), forPartFragments, this.makeCode(") {" + guardPart + varPart), bodyFragments, this.makeCode("" + this.tab + "}" + (returnResult || ''))); + }; + + For.prototype.pluckDirectCall = function(o, body) { + var base, defs, expr, fn, idx, ref, val, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8; + defs = []; + _ref2 = body.expressions; + for (idx = _i = 0, _len = _ref2.length; _i < _len; idx = ++_i) { + expr = _ref2[idx]; + expr = expr.unwrapAll(); + if (!(expr instanceof Call)) { + continue; + } + val = (_ref3 = expr.variable) != null ? _ref3.unwrapAll() : void 0; + if (!((val instanceof Code) || (val instanceof Value && ((_ref4 = val.base) != null ? _ref4.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((_ref5 = (_ref6 = val.properties[0].name) != null ? _ref6.value : void 0) === 'call' || _ref5 === 'apply')))) { + continue; + } + fn = ((_ref7 = val.base) != null ? _ref7.unwrapAll() : void 0) || val; + ref = new Literal(o.scope.freeVariable('fn')); + base = new Value(ref); + if (val.base) { + _ref8 = [base, val], val.base = _ref8[0], base = _ref8[1]; + } + body.expressions[idx] = new Call(base, expr.args); + defs = defs.concat(this.makeCode(this.tab), new Assign(ref, fn).compileToFragments(o, LEVEL_TOP), this.makeCode(';\n')); + } + return defs; + }; + + return For; + + })(While); + + exports.Switch = Switch = (function(_super) { + __extends(Switch, _super); + + function Switch(subject, cases, otherwise) { + this.subject = subject; + this.cases = cases; + this.otherwise = otherwise; + } + + Switch.prototype.children = ['subject', 'cases', 'otherwise']; + + Switch.prototype.isStatement = YES; + + Switch.prototype.jumps = function(o) { + var block, conds, jumpNode, _i, _len, _ref2, _ref3, _ref4; + if (o == null) { + o = { + block: true + }; + } + _ref2 = this.cases; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + _ref3 = _ref2[_i], conds = _ref3[0], block = _ref3[1]; + if (jumpNode = block.jumps(o)) { + return jumpNode; + } + } + return (_ref4 = this.otherwise) != null ? _ref4.jumps(o) : void 0; + }; + + Switch.prototype.makeReturn = function(res) { + var pair, _i, _len, _ref2, _ref3; + _ref2 = this.cases; + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + pair = _ref2[_i]; + pair[1].makeReturn(res); + } + if (res) { + this.otherwise || (this.otherwise = new Block([new Literal('void 0')])); + } + if ((_ref3 = this.otherwise) != null) { + _ref3.makeReturn(res); + } + return this; + }; + + Switch.prototype.compileNode = function(o) { + var block, body, cond, conditions, expr, fragments, i, idt1, idt2, _i, _j, _len, _len1, _ref2, _ref3, _ref4; + idt1 = o.indent + TAB; + idt2 = o.indent = idt1 + TAB; + fragments = [].concat(this.makeCode(this.tab + "switch ("), (this.subject ? this.subject.compileToFragments(o, LEVEL_PAREN) : this.makeCode("false")), this.makeCode(") {\n")); + _ref2 = this.cases; + for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) { + _ref3 = _ref2[i], conditions = _ref3[0], block = _ref3[1]; + _ref4 = flatten([conditions]); + for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) { + cond = _ref4[_j]; + if (!this.subject) { + cond = cond.invert(); + } + fragments = fragments.concat(this.makeCode(idt1 + "case "), cond.compileToFragments(o, LEVEL_PAREN), this.makeCode(":\n")); + } + if ((body = block.compileToFragments(o, LEVEL_TOP)).length > 0) { + fragments = fragments.concat(body, this.makeCode('\n')); + } + if (i === this.cases.length - 1 && !this.otherwise) { + break; + } + expr = this.lastNonComment(block.expressions); + if (expr instanceof Return || (expr instanceof Literal && expr.jumps() && expr.value !== 'debugger')) { + continue; + } + fragments.push(cond.makeCode(idt2 + 'break;\n')); + } + if (this.otherwise && this.otherwise.expressions.length) { + fragments.push.apply(fragments, [this.makeCode(idt1 + "default:\n")].concat(__slice.call(this.otherwise.compileToFragments(o, LEVEL_TOP)), [this.makeCode("\n")])); + } + fragments.push(this.makeCode(this.tab + '}')); + return fragments; + }; + + return Switch; + + })(Base); + + exports.If = If = (function(_super) { + __extends(If, _super); + + function If(condition, body, options) { + this.body = body; + if (options == null) { + options = {}; + } + this.condition = options.type === 'unless' ? condition.invert() : condition; + this.elseBody = null; + this.isChain = false; + this.soak = options.soak; + } + + If.prototype.children = ['condition', 'body', 'elseBody']; + + If.prototype.bodyNode = function() { + var _ref2; + return (_ref2 = this.body) != null ? _ref2.unwrap() : void 0; + }; + + If.prototype.elseBodyNode = function() { + var _ref2; + return (_ref2 = this.elseBody) != null ? _ref2.unwrap() : void 0; + }; + + If.prototype.addElse = function(elseBody) { + if (this.isChain) { + this.elseBodyNode().addElse(elseBody); + } else { + this.isChain = elseBody instanceof If; + this.elseBody = this.ensureBlock(elseBody); + this.elseBody.updateLocationDataIfMissing(elseBody.locationData); + } + return this; + }; + + If.prototype.isStatement = function(o) { + var _ref2; + return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((_ref2 = this.elseBodyNode()) != null ? _ref2.isStatement(o) : void 0); + }; + + If.prototype.jumps = function(o) { + var _ref2; + return this.body.jumps(o) || ((_ref2 = this.elseBody) != null ? _ref2.jumps(o) : void 0); + }; + + If.prototype.compileNode = function(o) { + if (this.isStatement(o)) { + return this.compileStatement(o); + } else { + return this.compileExpression(o); + } + }; + + If.prototype.makeReturn = function(res) { + if (res) { + this.elseBody || (this.elseBody = new Block([new Literal('void 0')])); + } + this.body && (this.body = new Block([this.body.makeReturn(res)])); + this.elseBody && (this.elseBody = new Block([this.elseBody.makeReturn(res)])); + return this; + }; + + If.prototype.ensureBlock = function(node) { + if (node instanceof Block) { + return node; + } else { + return new Block([node]); + } + }; + + If.prototype.compileStatement = function(o) { + var answer, body, child, cond, exeq, ifPart, indent; + child = del(o, 'chainChild'); + exeq = del(o, 'isExistentialEquals'); + if (exeq) { + return new If(this.condition.invert(), this.elseBodyNode(), { + type: 'if' + }).compileToFragments(o); + } + indent = o.indent + TAB; + cond = this.condition.compileToFragments(o, LEVEL_PAREN); + body = this.ensureBlock(this.body).compileToFragments(merge(o, { + indent: indent + })); + ifPart = [].concat(this.makeCode("if ("), cond, this.makeCode(") {\n"), body, this.makeCode("\n" + this.tab + "}")); + if (!child) { + ifPart.unshift(this.makeCode(this.tab)); + } + if (!this.elseBody) { + return ifPart; + } + answer = ifPart.concat(this.makeCode(' else ')); + if (this.isChain) { + o.chainChild = true; + answer = answer.concat(this.elseBody.unwrap().compileToFragments(o, LEVEL_TOP)); + } else { + answer = answer.concat(this.makeCode("{\n"), this.elseBody.compileToFragments(merge(o, { + indent: indent + }), LEVEL_TOP), this.makeCode("\n" + this.tab + "}")); + } + return answer; + }; + + If.prototype.compileExpression = function(o) { + var alt, body, cond, fragments; + cond = this.condition.compileToFragments(o, LEVEL_COND); + body = this.bodyNode().compileToFragments(o, LEVEL_LIST); + alt = this.elseBodyNode() ? this.elseBodyNode().compileToFragments(o, LEVEL_LIST) : [this.makeCode('void 0')]; + fragments = cond.concat(this.makeCode(" ? "), body, this.makeCode(" : "), alt); + if (o.level >= LEVEL_COND) { + return this.wrapInBraces(fragments); + } else { + return fragments; + } + }; + + If.prototype.unfoldSoak = function() { + return this.soak && this; + }; + + return If; + + })(Base); + + UTILITIES = { + "extends": function() { + return "function(child, parent) { for (var key in parent) { if (" + (utility('hasProp')) + ".call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }"; + }, + bind: function() { + return 'function(fn, me){ return function(){ return fn.apply(me, arguments); }; }'; + }, + indexOf: function() { + return "[].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }"; + }, + hasProp: function() { + return '{}.hasOwnProperty'; + }, + slice: function() { + return '[].slice'; + } + }; + + LEVEL_TOP = 1; + + LEVEL_PAREN = 2; + + LEVEL_LIST = 3; + + LEVEL_COND = 4; + + LEVEL_OP = 5; + + LEVEL_ACCESS = 6; + + TAB = ' '; + + IDENTIFIER_STR = "[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*"; + + IDENTIFIER = RegExp("^" + IDENTIFIER_STR + "$"); + + SIMPLENUM = /^[+-]?\d+$/; + + HEXNUM = /^[+-]?0x[\da-f]+/i; + + NUMBER = /^[+-]?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)$/i; + + METHOD_DEF = RegExp("^(" + IDENTIFIER_STR + ")(\\.prototype)?(?:\\.(" + IDENTIFIER_STR + ")|\\[(\"(?:[^\\\\\"\\r\\n]|\\\\.)*\"|'(?:[^\\\\'\\r\\n]|\\\\.)*')\\]|\\[(0x[\\da-fA-F]+|\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\])$"); + + IS_STRING = /^['"]/; + + IS_REGEX = /^\//; + + utility = function(name) { + var ref; + ref = "__" + name; + Scope.root.assign(ref, UTILITIES[name]()); + return ref; + }; + + multident = function(code, tab) { + code = code.replace(/\n/g, '$&' + tab); + return code.replace(/\s+$/, ''); + }; + + parseNum = function(x) { + if (x == null) { + return 0; + } else if (x.match(HEXNUM)) { + return parseInt(x, 16); + } else { + return parseFloat(x); + } + }; + + isLiteralArguments = function(node) { + return node instanceof Literal && node.value === 'arguments' && !node.asKey; + }; + + isLiteralThis = function(node) { + return (node instanceof Literal && node.value === 'this' && !node.asKey) || (node instanceof Code && node.bound) || (node instanceof Call && node.isSuper); + }; + + unfoldSoak = function(o, parent, name) { + var ifn; + if (!(ifn = parent[name].unfoldSoak(o))) { + return; + } + parent[name] = ifn.body; + ifn.body = new Value(parent); + return ifn; + }; + + +}); \ No newline at end of file diff --git a/lib/ace/mode/coffee/parser.js b/lib/ace/mode/coffee/parser.js new file mode 100644 index 00000000..00d1b723 --- /dev/null +++ b/lib/ace/mode/coffee/parser.js @@ -0,0 +1,724 @@ +/** + * Copyright (c) 2009-2013 Jeremy Ashkenas + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +define(function(require, exports, module) { +/* parser generated by jison 0.4.4 */ +/* + Returns a Parser object of the following structure: + + Parser: { + yy: {} + } + + Parser.prototype: { + yy: {}, + trace: function(), + symbols_: {associative list: name ==> number}, + terminals_: {associative list: number ==> name}, + productions_: [...], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), + table: [...], + defaultActions: {...}, + parseError: function(str, hash), + parse: function(input), + + lexer: { + EOF: 1, + parseError: function(str, hash), + setInput: function(input), + input: function(), + unput: function(str), + more: function(), + less: function(n), + pastInput: function(), + upcomingInput: function(), + showPosition: function(), + test_match: function(regex_match_array, rule_index), + next: function(), + lex: function(), + begin: function(condition), + popState: function(), + _currentRules: function(), + topState: function(), + pushState: function(condition), + + options: { + ranges: boolean (optional: true ==> token location info will include a .range[] member) + flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) + backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) + }, + + performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), + rules: [...], + conditions: {associative list: name ==> set}, + } + } + + + token location info (@$, _$, etc.): { + first_line: n, + last_line: n, + first_column: n, + last_column: n, + range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) + } + + + the parseError function receives a 'hash' object with these members for lexer and parser errors: { + text: (matched text) + token: (the produced terminal token, if any) + line: (yylineno) + } + while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { + loc: (yylloc) + expected: (string describing the set of expected tokens) + recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) + } +*/ + +var parser = {trace: function trace() { }, +yy: {}, +symbols_: {"error":2,"Root":3,"Body":4,"Line":5,"TERMINATOR":6,"Expression":7,"Statement":8,"Return":9,"Comment":10,"STATEMENT":11,"Value":12,"Invocation":13,"Code":14,"Operation":15,"Assign":16,"If":17,"Try":18,"While":19,"For":20,"Switch":21,"Class":22,"Throw":23,"Block":24,"INDENT":25,"OUTDENT":26,"Identifier":27,"IDENTIFIER":28,"AlphaNumeric":29,"NUMBER":30,"STRING":31,"Literal":32,"JS":33,"REGEX":34,"DEBUGGER":35,"UNDEFINED":36,"NULL":37,"BOOL":38,"Assignable":39,"=":40,"AssignObj":41,"ObjAssignable":42,":":43,"ThisProperty":44,"RETURN":45,"HERECOMMENT":46,"PARAM_START":47,"ParamList":48,"PARAM_END":49,"FuncGlyph":50,"->":51,"=>":52,"OptComma":53,",":54,"Param":55,"ParamVar":56,"...":57,"Array":58,"Object":59,"Splat":60,"SimpleAssignable":61,"Accessor":62,"Parenthetical":63,"Range":64,"This":65,".":66,"?.":67,"::":68,"?::":69,"Index":70,"INDEX_START":71,"IndexValue":72,"INDEX_END":73,"INDEX_SOAK":74,"Slice":75,"{":76,"AssignList":77,"}":78,"CLASS":79,"EXTENDS":80,"OptFuncExist":81,"Arguments":82,"SUPER":83,"FUNC_EXIST":84,"CALL_START":85,"CALL_END":86,"ArgList":87,"THIS":88,"@":89,"[":90,"]":91,"RangeDots":92,"..":93,"Arg":94,"SimpleArgs":95,"TRY":96,"Catch":97,"FINALLY":98,"CATCH":99,"THROW":100,"(":101,")":102,"WhileSource":103,"WHILE":104,"WHEN":105,"UNTIL":106,"Loop":107,"LOOP":108,"ForBody":109,"FOR":110,"ForStart":111,"ForSource":112,"ForVariables":113,"OWN":114,"ForValue":115,"FORIN":116,"FOROF":117,"BY":118,"SWITCH":119,"Whens":120,"ELSE":121,"When":122,"LEADING_WHEN":123,"IfBlock":124,"IF":125,"POST_IF":126,"UNARY":127,"-":128,"+":129,"--":130,"++":131,"?":132,"MATH":133,"SHIFT":134,"COMPARE":135,"LOGIC":136,"RELATION":137,"COMPOUND_ASSIGN":138,"$accept":0,"$end":1}, +terminals_: {2:"error",6:"TERMINATOR",11:"STATEMENT",25:"INDENT",26:"OUTDENT",28:"IDENTIFIER",30:"NUMBER",31:"STRING",33:"JS",34:"REGEX",35:"DEBUGGER",36:"UNDEFINED",37:"NULL",38:"BOOL",40:"=",43:":",45:"RETURN",46:"HERECOMMENT",47:"PARAM_START",49:"PARAM_END",51:"->",52:"=>",54:",",57:"...",66:".",67:"?.",68:"::",69:"?::",71:"INDEX_START",73:"INDEX_END",74:"INDEX_SOAK",76:"{",78:"}",79:"CLASS",80:"EXTENDS",83:"SUPER",84:"FUNC_EXIST",85:"CALL_START",86:"CALL_END",88:"THIS",89:"@",90:"[",91:"]",93:"..",96:"TRY",98:"FINALLY",99:"CATCH",100:"THROW",101:"(",102:")",104:"WHILE",105:"WHEN",106:"UNTIL",108:"LOOP",110:"FOR",114:"OWN",116:"FORIN",117:"FOROF",118:"BY",119:"SWITCH",121:"ELSE",123:"LEADING_WHEN",125:"IF",126:"POST_IF",127:"UNARY",128:"-",129:"+",130:"--",131:"++",132:"?",133:"MATH",134:"SHIFT",135:"COMPARE",136:"LOGIC",137:"RELATION",138:"COMPOUND_ASSIGN"}, +productions_: [0,[3,0],[3,1],[4,1],[4,3],[4,2],[5,1],[5,1],[8,1],[8,1],[8,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[24,2],[24,3],[27,1],[29,1],[29,1],[32,1],[32,1],[32,1],[32,1],[32,1],[32,1],[32,1],[16,3],[16,4],[16,5],[41,1],[41,3],[41,5],[41,1],[42,1],[42,1],[42,1],[9,2],[9,1],[10,1],[14,5],[14,2],[50,1],[50,1],[53,0],[53,1],[48,0],[48,1],[48,3],[48,4],[48,6],[55,1],[55,2],[55,3],[56,1],[56,1],[56,1],[56,1],[60,2],[61,1],[61,2],[61,2],[61,1],[39,1],[39,1],[39,1],[12,1],[12,1],[12,1],[12,1],[12,1],[62,2],[62,2],[62,2],[62,2],[62,1],[62,1],[70,3],[70,2],[72,1],[72,1],[59,4],[77,0],[77,1],[77,3],[77,4],[77,6],[22,1],[22,2],[22,3],[22,4],[22,2],[22,3],[22,4],[22,5],[13,3],[13,3],[13,1],[13,2],[81,0],[81,1],[82,2],[82,4],[65,1],[65,1],[44,2],[58,2],[58,4],[92,1],[92,1],[64,5],[75,3],[75,2],[75,2],[75,1],[87,1],[87,3],[87,4],[87,4],[87,6],[94,1],[94,1],[95,1],[95,3],[18,2],[18,3],[18,4],[18,5],[97,3],[97,3],[97,2],[23,2],[63,3],[63,5],[103,2],[103,4],[103,2],[103,4],[19,2],[19,2],[19,2],[19,1],[107,2],[107,2],[20,2],[20,2],[20,2],[109,2],[109,2],[111,2],[111,3],[115,1],[115,1],[115,1],[115,1],[113,1],[113,3],[112,2],[112,2],[112,4],[112,4],[112,4],[112,6],[112,6],[21,5],[21,7],[21,4],[21,6],[120,1],[120,2],[122,3],[122,4],[124,3],[124,5],[17,1],[17,3],[17,3],[17,3],[15,2],[15,2],[15,2],[15,2],[15,2],[15,2],[15,2],[15,2],[15,3],[15,3],[15,3],[15,3],[15,3],[15,3],[15,3],[15,3],[15,5],[15,4],[15,3]], +performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { +/* this == yyval */ + +var $0 = $$.length - 1; +switch (yystate) { +case 1:return this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Block); +break; +case 2:return this.$ = $$[$0]; +break; +case 3:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Block.wrap([$$[$0]])); +break; +case 4:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].push($$[$0])); +break; +case 5:this.$ = $$[$0-1]; +break; +case 6:this.$ = $$[$0]; +break; +case 7:this.$ = $$[$0]; +break; +case 8:this.$ = $$[$0]; +break; +case 9:this.$ = $$[$0]; +break; +case 10:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0])); +break; +case 11:this.$ = $$[$0]; +break; +case 12:this.$ = $$[$0]; +break; +case 13:this.$ = $$[$0]; +break; +case 14:this.$ = $$[$0]; +break; +case 15:this.$ = $$[$0]; +break; +case 16:this.$ = $$[$0]; +break; +case 17:this.$ = $$[$0]; +break; +case 18:this.$ = $$[$0]; +break; +case 19:this.$ = $$[$0]; +break; +case 20:this.$ = $$[$0]; +break; +case 21:this.$ = $$[$0]; +break; +case 22:this.$ = $$[$0]; +break; +case 23:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Block); +break; +case 24:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-1]); +break; +case 25:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0])); +break; +case 26:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0])); +break; +case 27:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0])); +break; +case 28:this.$ = $$[$0]; +break; +case 29:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0])); +break; +case 30:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0])); +break; +case 31:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0])); +break; +case 32:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Undefined); +break; +case 33:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Null); +break; +case 34:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Bool($$[$0])); +break; +case 35:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign($$[$0-2], $$[$0])); +break; +case 36:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Assign($$[$0-3], $$[$0])); +break; +case 37:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1])); +break; +case 38:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0])); +break; +case 39:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-2])(new yy.Value($$[$0-2])), $$[$0], 'object')); +break; +case 40:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-4])(new yy.Value($$[$0-4])), $$[$0-1], 'object')); +break; +case 41:this.$ = $$[$0]; +break; +case 42:this.$ = $$[$0]; +break; +case 43:this.$ = $$[$0]; +break; +case 44:this.$ = $$[$0]; +break; +case 45:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Return($$[$0])); +break; +case 46:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Return); +break; +case 47:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Comment($$[$0])); +break; +case 48:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Code($$[$0-3], $$[$0], $$[$0-1])); +break; +case 49:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Code([], $$[$0], $$[$0-1])); +break; +case 50:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('func'); +break; +case 51:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('boundfunc'); +break; +case 52:this.$ = $$[$0]; +break; +case 53:this.$ = $$[$0]; +break; +case 54:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([]); +break; +case 55:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]); +break; +case 56:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].concat($$[$0])); +break; +case 57:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-3].concat($$[$0])); +break; +case 58:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])($$[$0-5].concat($$[$0-2])); +break; +case 59:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Param($$[$0])); +break; +case 60:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Param($$[$0-1], null, true)); +break; +case 61:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Param($$[$0-2], $$[$0])); +break; +case 62:this.$ = $$[$0]; +break; +case 63:this.$ = $$[$0]; +break; +case 64:this.$ = $$[$0]; +break; +case 65:this.$ = $$[$0]; +break; +case 66:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Splat($$[$0-1])); +break; +case 67:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0])); +break; +case 68:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].add($$[$0])); +break; +case 69:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Value($$[$0-1], [].concat($$[$0]))); +break; +case 70:this.$ = $$[$0]; +break; +case 71:this.$ = $$[$0]; +break; +case 72:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0])); +break; +case 73:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0])); +break; +case 74:this.$ = $$[$0]; +break; +case 75:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0])); +break; +case 76:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0])); +break; +case 77:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0])); +break; +case 78:this.$ = $$[$0]; +break; +case 79:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Access($$[$0])); +break; +case 80:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Access($$[$0], 'soak')); +break; +case 81:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([yy.addLocationDataFn(_$[$0-1])(new yy.Access(new yy.Literal('prototype'))), yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))]); +break; +case 82:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([yy.addLocationDataFn(_$[$0-1])(new yy.Access(new yy.Literal('prototype'), 'soak')), yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))]); +break; +case 83:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Access(new yy.Literal('prototype'))); +break; +case 84:this.$ = $$[$0]; +break; +case 85:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-1]); +break; +case 86:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.extend($$[$0], { + soak: true + })); +break; +case 87:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Index($$[$0])); +break; +case 88:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Slice($$[$0])); +break; +case 89:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Obj($$[$0-2], $$[$0-3].generated)); +break; +case 90:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([]); +break; +case 91:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]); +break; +case 92:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].concat($$[$0])); +break; +case 93:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-3].concat($$[$0])); +break; +case 94:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])($$[$0-5].concat($$[$0-2])); +break; +case 95:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Class); +break; +case 96:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Class(null, null, $$[$0])); +break; +case 97:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Class(null, $$[$0])); +break; +case 98:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Class(null, $$[$0-1], $$[$0])); +break; +case 99:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Class($$[$0])); +break; +case 100:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Class($$[$0-1], null, $$[$0])); +break; +case 101:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Class($$[$0-2], $$[$0])); +break; +case 102:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Class($$[$0-3], $$[$0-1], $$[$0])); +break; +case 103:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Call($$[$0-2], $$[$0], $$[$0-1])); +break; +case 104:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Call($$[$0-2], $$[$0], $$[$0-1])); +break; +case 105:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Call('super', [new yy.Splat(new yy.Literal('arguments'))])); +break; +case 106:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Call('super', $$[$0])); +break; +case 107:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(false); +break; +case 108:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(true); +break; +case 109:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([]); +break; +case 110:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-2]); +break; +case 111:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value(new yy.Literal('this'))); +break; +case 112:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value(new yy.Literal('this'))); +break; +case 113:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Value(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('this')), [yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))], 'this')); +break; +case 114:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Arr([])); +break; +case 115:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Arr($$[$0-2])); +break; +case 116:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('inclusive'); +break; +case 117:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('exclusive'); +break; +case 118:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Range($$[$0-3], $$[$0-1], $$[$0-2])); +break; +case 119:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Range($$[$0-2], $$[$0], $$[$0-1])); +break; +case 120:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Range($$[$0-1], null, $$[$0])); +break; +case 121:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Range(null, $$[$0], $$[$0-1])); +break; +case 122:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Range(null, null, $$[$0])); +break; +case 123:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]); +break; +case 124:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].concat($$[$0])); +break; +case 125:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-3].concat($$[$0])); +break; +case 126:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-2]); +break; +case 127:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])($$[$0-5].concat($$[$0-2])); +break; +case 128:this.$ = $$[$0]; +break; +case 129:this.$ = $$[$0]; +break; +case 130:this.$ = $$[$0]; +break; +case 131:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([].concat($$[$0-2], $$[$0])); +break; +case 132:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Try($$[$0])); +break; +case 133:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Try($$[$0-1], $$[$0][0], $$[$0][1])); +break; +case 134:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Try($$[$0-2], null, null, $$[$0])); +break; +case 135:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Try($$[$0-3], $$[$0-2][0], $$[$0-2][1], $$[$0])); +break; +case 136:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([$$[$0-1], $$[$0]]); +break; +case 137:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([yy.addLocationDataFn(_$[$0-1])(new yy.Value($$[$0-1])), $$[$0]]); +break; +case 138:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([null, $$[$0]]); +break; +case 139:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Throw($$[$0])); +break; +case 140:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Parens($$[$0-1])); +break; +case 141:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Parens($$[$0-2])); +break; +case 142:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While($$[$0])); +break; +case 143:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.While($$[$0-2], { + guard: $$[$0] + })); +break; +case 144:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While($$[$0], { + invert: true + })); +break; +case 145:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.While($$[$0-2], { + invert: true, + guard: $$[$0] + })); +break; +case 146:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].addBody($$[$0])); +break; +case 147:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0].addBody(yy.addLocationDataFn(_$[$0-1])(yy.Block.wrap([$$[$0-1]])))); +break; +case 148:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0].addBody(yy.addLocationDataFn(_$[$0-1])(yy.Block.wrap([$$[$0-1]])))); +break; +case 149:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])($$[$0]); +break; +case 150:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('true'))).addBody($$[$0])); +break; +case 151:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('true'))).addBody(yy.addLocationDataFn(_$[$0])(yy.Block.wrap([$$[$0]])))); +break; +case 152:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0-1], $$[$0])); +break; +case 153:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0-1], $$[$0])); +break; +case 154:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0], $$[$0-1])); +break; +case 155:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({ + source: yy.addLocationDataFn(_$[$0])(new yy.Value($$[$0])) + }); +break; +case 156:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])((function () { + $$[$0].own = $$[$0-1].own; + $$[$0].name = $$[$0-1][0]; + $$[$0].index = $$[$0-1][1]; + return $$[$0]; + }())); +break; +case 157:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0]); +break; +case 158:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])((function () { + $$[$0].own = true; + return $$[$0]; + }())); +break; +case 159:this.$ = $$[$0]; +break; +case 160:this.$ = $$[$0]; +break; +case 161:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0])); +break; +case 162:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0])); +break; +case 163:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]); +break; +case 164:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([$$[$0-2], $$[$0]]); +break; +case 165:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({ + source: $$[$0] + }); +break; +case 166:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({ + source: $$[$0], + object: true + }); +break; +case 167:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({ + source: $$[$0-2], + guard: $$[$0] + }); +break; +case 168:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({ + source: $$[$0-2], + guard: $$[$0], + object: true + }); +break; +case 169:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({ + source: $$[$0-2], + step: $$[$0] + }); +break; +case 170:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])({ + source: $$[$0-4], + guard: $$[$0-2], + step: $$[$0] + }); +break; +case 171:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])({ + source: $$[$0-4], + step: $$[$0-2], + guard: $$[$0] + }); +break; +case 172:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Switch($$[$0-3], $$[$0-1])); +break; +case 173:this.$ = yy.addLocationDataFn(_$[$0-6], _$[$0])(new yy.Switch($$[$0-5], $$[$0-3], $$[$0-1])); +break; +case 174:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Switch(null, $$[$0-1])); +break; +case 175:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])(new yy.Switch(null, $$[$0-3], $$[$0-1])); +break; +case 176:this.$ = $$[$0]; +break; +case 177:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].concat($$[$0])); +break; +case 178:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([[$$[$0-1], $$[$0]]]); +break; +case 179:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])([[$$[$0-2], $$[$0-1]]]); +break; +case 180:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0-1], $$[$0], { + type: $$[$0-2] + })); +break; +case 181:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])($$[$0-4].addElse(yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0-1], $$[$0], { + type: $$[$0-2] + })))); +break; +case 182:this.$ = $$[$0]; +break; +case 183:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].addElse($$[$0])); +break; +case 184:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0], yy.addLocationDataFn(_$[$0-2])(yy.Block.wrap([$$[$0-2]])), { + type: $$[$0-1], + statement: true + })); +break; +case 185:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0], yy.addLocationDataFn(_$[$0-2])(yy.Block.wrap([$$[$0-2]])), { + type: $$[$0-1], + statement: true + })); +break; +case 186:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op($$[$0-1], $$[$0])); +break; +case 187:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('-', $$[$0])); +break; +case 188:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('+', $$[$0])); +break; +case 189:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('--', $$[$0])); +break; +case 190:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('++', $$[$0])); +break; +case 191:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('--', $$[$0-1], null, true)); +break; +case 192:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('++', $$[$0-1], null, true)); +break; +case 193:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Existence($$[$0-1])); +break; +case 194:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op('+', $$[$0-2], $$[$0])); +break; +case 195:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op('-', $$[$0-2], $$[$0])); +break; +case 196:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0])); +break; +case 197:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0])); +break; +case 198:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0])); +break; +case 199:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0])); +break; +case 200:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])((function () { + if ($$[$0-1].charAt(0) === '!') { + return new yy.Op($$[$0-1].slice(1), $$[$0-2], $$[$0]).invert(); + } else { + return new yy.Op($$[$0-1], $$[$0-2], $$[$0]); + } + }())); +break; +case 201:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign($$[$0-2], $$[$0], $$[$0-1])); +break; +case 202:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1], $$[$0-3])); +break; +case 203:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Assign($$[$0-3], $$[$0], $$[$0-2])); +break; +case 204:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Extends($$[$0-2], $$[$0])); +break; +} +}, +table: [{1:[2,1],3:1,4:2,5:3,7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[3]},{1:[2,2],6:[1,72]},{1:[2,3],6:[2,3],26:[2,3],102:[2,3]},{1:[2,6],6:[2,6],26:[2,6],102:[2,6],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,7],6:[2,7],26:[2,7],102:[2,7],103:85,104:[1,63],106:[1,64],109:86,110:[1,66],111:67,126:[1,84]},{1:[2,11],6:[2,11],25:[2,11],26:[2,11],49:[2,11],54:[2,11],57:[2,11],62:88,66:[1,90],67:[1,91],68:[1,92],69:[1,93],70:94,71:[1,95],73:[2,11],74:[1,96],78:[2,11],81:87,84:[1,89],85:[2,107],86:[2,11],91:[2,11],93:[2,11],102:[2,11],104:[2,11],105:[2,11],106:[2,11],110:[2,11],118:[2,11],126:[2,11],128:[2,11],129:[2,11],132:[2,11],133:[2,11],134:[2,11],135:[2,11],136:[2,11],137:[2,11]},{1:[2,12],6:[2,12],25:[2,12],26:[2,12],49:[2,12],54:[2,12],57:[2,12],62:98,66:[1,90],67:[1,91],68:[1,92],69:[1,93],70:94,71:[1,95],73:[2,12],74:[1,96],78:[2,12],81:97,84:[1,89],85:[2,107],86:[2,12],91:[2,12],93:[2,12],102:[2,12],104:[2,12],105:[2,12],106:[2,12],110:[2,12],118:[2,12],126:[2,12],128:[2,12],129:[2,12],132:[2,12],133:[2,12],134:[2,12],135:[2,12],136:[2,12],137:[2,12]},{1:[2,13],6:[2,13],25:[2,13],26:[2,13],49:[2,13],54:[2,13],57:[2,13],73:[2,13],78:[2,13],86:[2,13],91:[2,13],93:[2,13],102:[2,13],104:[2,13],105:[2,13],106:[2,13],110:[2,13],118:[2,13],126:[2,13],128:[2,13],129:[2,13],132:[2,13],133:[2,13],134:[2,13],135:[2,13],136:[2,13],137:[2,13]},{1:[2,14],6:[2,14],25:[2,14],26:[2,14],49:[2,14],54:[2,14],57:[2,14],73:[2,14],78:[2,14],86:[2,14],91:[2,14],93:[2,14],102:[2,14],104:[2,14],105:[2,14],106:[2,14],110:[2,14],118:[2,14],126:[2,14],128:[2,14],129:[2,14],132:[2,14],133:[2,14],134:[2,14],135:[2,14],136:[2,14],137:[2,14]},{1:[2,15],6:[2,15],25:[2,15],26:[2,15],49:[2,15],54:[2,15],57:[2,15],73:[2,15],78:[2,15],86:[2,15],91:[2,15],93:[2,15],102:[2,15],104:[2,15],105:[2,15],106:[2,15],110:[2,15],118:[2,15],126:[2,15],128:[2,15],129:[2,15],132:[2,15],133:[2,15],134:[2,15],135:[2,15],136:[2,15],137:[2,15]},{1:[2,16],6:[2,16],25:[2,16],26:[2,16],49:[2,16],54:[2,16],57:[2,16],73:[2,16],78:[2,16],86:[2,16],91:[2,16],93:[2,16],102:[2,16],104:[2,16],105:[2,16],106:[2,16],110:[2,16],118:[2,16],126:[2,16],128:[2,16],129:[2,16],132:[2,16],133:[2,16],134:[2,16],135:[2,16],136:[2,16],137:[2,16]},{1:[2,17],6:[2,17],25:[2,17],26:[2,17],49:[2,17],54:[2,17],57:[2,17],73:[2,17],78:[2,17],86:[2,17],91:[2,17],93:[2,17],102:[2,17],104:[2,17],105:[2,17],106:[2,17],110:[2,17],118:[2,17],126:[2,17],128:[2,17],129:[2,17],132:[2,17],133:[2,17],134:[2,17],135:[2,17],136:[2,17],137:[2,17]},{1:[2,18],6:[2,18],25:[2,18],26:[2,18],49:[2,18],54:[2,18],57:[2,18],73:[2,18],78:[2,18],86:[2,18],91:[2,18],93:[2,18],102:[2,18],104:[2,18],105:[2,18],106:[2,18],110:[2,18],118:[2,18],126:[2,18],128:[2,18],129:[2,18],132:[2,18],133:[2,18],134:[2,18],135:[2,18],136:[2,18],137:[2,18]},{1:[2,19],6:[2,19],25:[2,19],26:[2,19],49:[2,19],54:[2,19],57:[2,19],73:[2,19],78:[2,19],86:[2,19],91:[2,19],93:[2,19],102:[2,19],104:[2,19],105:[2,19],106:[2,19],110:[2,19],118:[2,19],126:[2,19],128:[2,19],129:[2,19],132:[2,19],133:[2,19],134:[2,19],135:[2,19],136:[2,19],137:[2,19]},{1:[2,20],6:[2,20],25:[2,20],26:[2,20],49:[2,20],54:[2,20],57:[2,20],73:[2,20],78:[2,20],86:[2,20],91:[2,20],93:[2,20],102:[2,20],104:[2,20],105:[2,20],106:[2,20],110:[2,20],118:[2,20],126:[2,20],128:[2,20],129:[2,20],132:[2,20],133:[2,20],134:[2,20],135:[2,20],136:[2,20],137:[2,20]},{1:[2,21],6:[2,21],25:[2,21],26:[2,21],49:[2,21],54:[2,21],57:[2,21],73:[2,21],78:[2,21],86:[2,21],91:[2,21],93:[2,21],102:[2,21],104:[2,21],105:[2,21],106:[2,21],110:[2,21],118:[2,21],126:[2,21],128:[2,21],129:[2,21],132:[2,21],133:[2,21],134:[2,21],135:[2,21],136:[2,21],137:[2,21]},{1:[2,22],6:[2,22],25:[2,22],26:[2,22],49:[2,22],54:[2,22],57:[2,22],73:[2,22],78:[2,22],86:[2,22],91:[2,22],93:[2,22],102:[2,22],104:[2,22],105:[2,22],106:[2,22],110:[2,22],118:[2,22],126:[2,22],128:[2,22],129:[2,22],132:[2,22],133:[2,22],134:[2,22],135:[2,22],136:[2,22],137:[2,22]},{1:[2,8],6:[2,8],26:[2,8],102:[2,8],104:[2,8],106:[2,8],110:[2,8],126:[2,8]},{1:[2,9],6:[2,9],26:[2,9],102:[2,9],104:[2,9],106:[2,9],110:[2,9],126:[2,9]},{1:[2,10],6:[2,10],26:[2,10],102:[2,10],104:[2,10],106:[2,10],110:[2,10],126:[2,10]},{1:[2,74],6:[2,74],25:[2,74],26:[2,74],40:[1,99],49:[2,74],54:[2,74],57:[2,74],66:[2,74],67:[2,74],68:[2,74],69:[2,74],71:[2,74],73:[2,74],74:[2,74],78:[2,74],84:[2,74],85:[2,74],86:[2,74],91:[2,74],93:[2,74],102:[2,74],104:[2,74],105:[2,74],106:[2,74],110:[2,74],118:[2,74],126:[2,74],128:[2,74],129:[2,74],132:[2,74],133:[2,74],134:[2,74],135:[2,74],136:[2,74],137:[2,74]},{1:[2,75],6:[2,75],25:[2,75],26:[2,75],49:[2,75],54:[2,75],57:[2,75],66:[2,75],67:[2,75],68:[2,75],69:[2,75],71:[2,75],73:[2,75],74:[2,75],78:[2,75],84:[2,75],85:[2,75],86:[2,75],91:[2,75],93:[2,75],102:[2,75],104:[2,75],105:[2,75],106:[2,75],110:[2,75],118:[2,75],126:[2,75],128:[2,75],129:[2,75],132:[2,75],133:[2,75],134:[2,75],135:[2,75],136:[2,75],137:[2,75]},{1:[2,76],6:[2,76],25:[2,76],26:[2,76],49:[2,76],54:[2,76],57:[2,76],66:[2,76],67:[2,76],68:[2,76],69:[2,76],71:[2,76],73:[2,76],74:[2,76],78:[2,76],84:[2,76],85:[2,76],86:[2,76],91:[2,76],93:[2,76],102:[2,76],104:[2,76],105:[2,76],106:[2,76],110:[2,76],118:[2,76],126:[2,76],128:[2,76],129:[2,76],132:[2,76],133:[2,76],134:[2,76],135:[2,76],136:[2,76],137:[2,76]},{1:[2,77],6:[2,77],25:[2,77],26:[2,77],49:[2,77],54:[2,77],57:[2,77],66:[2,77],67:[2,77],68:[2,77],69:[2,77],71:[2,77],73:[2,77],74:[2,77],78:[2,77],84:[2,77],85:[2,77],86:[2,77],91:[2,77],93:[2,77],102:[2,77],104:[2,77],105:[2,77],106:[2,77],110:[2,77],118:[2,77],126:[2,77],128:[2,77],129:[2,77],132:[2,77],133:[2,77],134:[2,77],135:[2,77],136:[2,77],137:[2,77]},{1:[2,78],6:[2,78],25:[2,78],26:[2,78],49:[2,78],54:[2,78],57:[2,78],66:[2,78],67:[2,78],68:[2,78],69:[2,78],71:[2,78],73:[2,78],74:[2,78],78:[2,78],84:[2,78],85:[2,78],86:[2,78],91:[2,78],93:[2,78],102:[2,78],104:[2,78],105:[2,78],106:[2,78],110:[2,78],118:[2,78],126:[2,78],128:[2,78],129:[2,78],132:[2,78],133:[2,78],134:[2,78],135:[2,78],136:[2,78],137:[2,78]},{1:[2,105],6:[2,105],25:[2,105],26:[2,105],49:[2,105],54:[2,105],57:[2,105],66:[2,105],67:[2,105],68:[2,105],69:[2,105],71:[2,105],73:[2,105],74:[2,105],78:[2,105],82:100,84:[2,105],85:[1,101],86:[2,105],91:[2,105],93:[2,105],102:[2,105],104:[2,105],105:[2,105],106:[2,105],110:[2,105],118:[2,105],126:[2,105],128:[2,105],129:[2,105],132:[2,105],133:[2,105],134:[2,105],135:[2,105],136:[2,105],137:[2,105]},{6:[2,54],25:[2,54],27:105,28:[1,71],44:106,48:102,49:[2,54],54:[2,54],55:103,56:104,58:107,59:108,76:[1,68],89:[1,109],90:[1,110]},{24:111,25:[1,112]},{7:113,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:115,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:116,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{12:118,13:119,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:120,44:61,58:45,59:46,61:117,63:23,64:24,65:25,76:[1,68],83:[1,26],88:[1,56],89:[1,57],90:[1,55],101:[1,54]},{12:118,13:119,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:120,44:61,58:45,59:46,61:121,63:23,64:24,65:25,76:[1,68],83:[1,26],88:[1,56],89:[1,57],90:[1,55],101:[1,54]},{1:[2,71],6:[2,71],25:[2,71],26:[2,71],40:[2,71],49:[2,71],54:[2,71],57:[2,71],66:[2,71],67:[2,71],68:[2,71],69:[2,71],71:[2,71],73:[2,71],74:[2,71],78:[2,71],80:[1,125],84:[2,71],85:[2,71],86:[2,71],91:[2,71],93:[2,71],102:[2,71],104:[2,71],105:[2,71],106:[2,71],110:[2,71],118:[2,71],126:[2,71],128:[2,71],129:[2,71],130:[1,122],131:[1,123],132:[2,71],133:[2,71],134:[2,71],135:[2,71],136:[2,71],137:[2,71],138:[1,124]},{1:[2,182],6:[2,182],25:[2,182],26:[2,182],49:[2,182],54:[2,182],57:[2,182],73:[2,182],78:[2,182],86:[2,182],91:[2,182],93:[2,182],102:[2,182],104:[2,182],105:[2,182],106:[2,182],110:[2,182],118:[2,182],121:[1,126],126:[2,182],128:[2,182],129:[2,182],132:[2,182],133:[2,182],134:[2,182],135:[2,182],136:[2,182],137:[2,182]},{24:127,25:[1,112]},{24:128,25:[1,112]},{1:[2,149],6:[2,149],25:[2,149],26:[2,149],49:[2,149],54:[2,149],57:[2,149],73:[2,149],78:[2,149],86:[2,149],91:[2,149],93:[2,149],102:[2,149],104:[2,149],105:[2,149],106:[2,149],110:[2,149],118:[2,149],126:[2,149],128:[2,149],129:[2,149],132:[2,149],133:[2,149],134:[2,149],135:[2,149],136:[2,149],137:[2,149]},{24:129,25:[1,112]},{7:130,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,131],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,95],6:[2,95],12:118,13:119,24:132,25:[1,112],26:[2,95],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:120,44:61,49:[2,95],54:[2,95],57:[2,95],58:45,59:46,61:134,63:23,64:24,65:25,73:[2,95],76:[1,68],78:[2,95],80:[1,133],83:[1,26],86:[2,95],88:[1,56],89:[1,57],90:[1,55],91:[2,95],93:[2,95],101:[1,54],102:[2,95],104:[2,95],105:[2,95],106:[2,95],110:[2,95],118:[2,95],126:[2,95],128:[2,95],129:[2,95],132:[2,95],133:[2,95],134:[2,95],135:[2,95],136:[2,95],137:[2,95]},{7:135,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,46],6:[2,46],7:136,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,26:[2,46],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],102:[2,46],103:37,104:[2,46],106:[2,46],107:38,108:[1,65],109:39,110:[2,46],111:67,119:[1,40],124:35,125:[1,62],126:[2,46],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,47],6:[2,47],25:[2,47],26:[2,47],54:[2,47],78:[2,47],102:[2,47],104:[2,47],106:[2,47],110:[2,47],126:[2,47]},{1:[2,72],6:[2,72],25:[2,72],26:[2,72],40:[2,72],49:[2,72],54:[2,72],57:[2,72],66:[2,72],67:[2,72],68:[2,72],69:[2,72],71:[2,72],73:[2,72],74:[2,72],78:[2,72],84:[2,72],85:[2,72],86:[2,72],91:[2,72],93:[2,72],102:[2,72],104:[2,72],105:[2,72],106:[2,72],110:[2,72],118:[2,72],126:[2,72],128:[2,72],129:[2,72],132:[2,72],133:[2,72],134:[2,72],135:[2,72],136:[2,72],137:[2,72]},{1:[2,73],6:[2,73],25:[2,73],26:[2,73],40:[2,73],49:[2,73],54:[2,73],57:[2,73],66:[2,73],67:[2,73],68:[2,73],69:[2,73],71:[2,73],73:[2,73],74:[2,73],78:[2,73],84:[2,73],85:[2,73],86:[2,73],91:[2,73],93:[2,73],102:[2,73],104:[2,73],105:[2,73],106:[2,73],110:[2,73],118:[2,73],126:[2,73],128:[2,73],129:[2,73],132:[2,73],133:[2,73],134:[2,73],135:[2,73],136:[2,73],137:[2,73]},{1:[2,28],6:[2,28],25:[2,28],26:[2,28],49:[2,28],54:[2,28],57:[2,28],66:[2,28],67:[2,28],68:[2,28],69:[2,28],71:[2,28],73:[2,28],74:[2,28],78:[2,28],84:[2,28],85:[2,28],86:[2,28],91:[2,28],93:[2,28],102:[2,28],104:[2,28],105:[2,28],106:[2,28],110:[2,28],118:[2,28],126:[2,28],128:[2,28],129:[2,28],132:[2,28],133:[2,28],134:[2,28],135:[2,28],136:[2,28],137:[2,28]},{1:[2,29],6:[2,29],25:[2,29],26:[2,29],49:[2,29],54:[2,29],57:[2,29],66:[2,29],67:[2,29],68:[2,29],69:[2,29],71:[2,29],73:[2,29],74:[2,29],78:[2,29],84:[2,29],85:[2,29],86:[2,29],91:[2,29],93:[2,29],102:[2,29],104:[2,29],105:[2,29],106:[2,29],110:[2,29],118:[2,29],126:[2,29],128:[2,29],129:[2,29],132:[2,29],133:[2,29],134:[2,29],135:[2,29],136:[2,29],137:[2,29]},{1:[2,30],6:[2,30],25:[2,30],26:[2,30],49:[2,30],54:[2,30],57:[2,30],66:[2,30],67:[2,30],68:[2,30],69:[2,30],71:[2,30],73:[2,30],74:[2,30],78:[2,30],84:[2,30],85:[2,30],86:[2,30],91:[2,30],93:[2,30],102:[2,30],104:[2,30],105:[2,30],106:[2,30],110:[2,30],118:[2,30],126:[2,30],128:[2,30],129:[2,30],132:[2,30],133:[2,30],134:[2,30],135:[2,30],136:[2,30],137:[2,30]},{1:[2,31],6:[2,31],25:[2,31],26:[2,31],49:[2,31],54:[2,31],57:[2,31],66:[2,31],67:[2,31],68:[2,31],69:[2,31],71:[2,31],73:[2,31],74:[2,31],78:[2,31],84:[2,31],85:[2,31],86:[2,31],91:[2,31],93:[2,31],102:[2,31],104:[2,31],105:[2,31],106:[2,31],110:[2,31],118:[2,31],126:[2,31],128:[2,31],129:[2,31],132:[2,31],133:[2,31],134:[2,31],135:[2,31],136:[2,31],137:[2,31]},{1:[2,32],6:[2,32],25:[2,32],26:[2,32],49:[2,32],54:[2,32],57:[2,32],66:[2,32],67:[2,32],68:[2,32],69:[2,32],71:[2,32],73:[2,32],74:[2,32],78:[2,32],84:[2,32],85:[2,32],86:[2,32],91:[2,32],93:[2,32],102:[2,32],104:[2,32],105:[2,32],106:[2,32],110:[2,32],118:[2,32],126:[2,32],128:[2,32],129:[2,32],132:[2,32],133:[2,32],134:[2,32],135:[2,32],136:[2,32],137:[2,32]},{1:[2,33],6:[2,33],25:[2,33],26:[2,33],49:[2,33],54:[2,33],57:[2,33],66:[2,33],67:[2,33],68:[2,33],69:[2,33],71:[2,33],73:[2,33],74:[2,33],78:[2,33],84:[2,33],85:[2,33],86:[2,33],91:[2,33],93:[2,33],102:[2,33],104:[2,33],105:[2,33],106:[2,33],110:[2,33],118:[2,33],126:[2,33],128:[2,33],129:[2,33],132:[2,33],133:[2,33],134:[2,33],135:[2,33],136:[2,33],137:[2,33]},{1:[2,34],6:[2,34],25:[2,34],26:[2,34],49:[2,34],54:[2,34],57:[2,34],66:[2,34],67:[2,34],68:[2,34],69:[2,34],71:[2,34],73:[2,34],74:[2,34],78:[2,34],84:[2,34],85:[2,34],86:[2,34],91:[2,34],93:[2,34],102:[2,34],104:[2,34],105:[2,34],106:[2,34],110:[2,34],118:[2,34],126:[2,34],128:[2,34],129:[2,34],132:[2,34],133:[2,34],134:[2,34],135:[2,34],136:[2,34],137:[2,34]},{4:137,5:3,7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,138],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:139,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,143],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,60:144,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],87:141,88:[1,56],89:[1,57],90:[1,55],91:[1,140],94:142,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,111],6:[2,111],25:[2,111],26:[2,111],49:[2,111],54:[2,111],57:[2,111],66:[2,111],67:[2,111],68:[2,111],69:[2,111],71:[2,111],73:[2,111],74:[2,111],78:[2,111],84:[2,111],85:[2,111],86:[2,111],91:[2,111],93:[2,111],102:[2,111],104:[2,111],105:[2,111],106:[2,111],110:[2,111],118:[2,111],126:[2,111],128:[2,111],129:[2,111],132:[2,111],133:[2,111],134:[2,111],135:[2,111],136:[2,111],137:[2,111]},{1:[2,112],6:[2,112],25:[2,112],26:[2,112],27:145,28:[1,71],49:[2,112],54:[2,112],57:[2,112],66:[2,112],67:[2,112],68:[2,112],69:[2,112],71:[2,112],73:[2,112],74:[2,112],78:[2,112],84:[2,112],85:[2,112],86:[2,112],91:[2,112],93:[2,112],102:[2,112],104:[2,112],105:[2,112],106:[2,112],110:[2,112],118:[2,112],126:[2,112],128:[2,112],129:[2,112],132:[2,112],133:[2,112],134:[2,112],135:[2,112],136:[2,112],137:[2,112]},{25:[2,50]},{25:[2,51]},{1:[2,67],6:[2,67],25:[2,67],26:[2,67],40:[2,67],49:[2,67],54:[2,67],57:[2,67],66:[2,67],67:[2,67],68:[2,67],69:[2,67],71:[2,67],73:[2,67],74:[2,67],78:[2,67],80:[2,67],84:[2,67],85:[2,67],86:[2,67],91:[2,67],93:[2,67],102:[2,67],104:[2,67],105:[2,67],106:[2,67],110:[2,67],118:[2,67],126:[2,67],128:[2,67],129:[2,67],130:[2,67],131:[2,67],132:[2,67],133:[2,67],134:[2,67],135:[2,67],136:[2,67],137:[2,67],138:[2,67]},{1:[2,70],6:[2,70],25:[2,70],26:[2,70],40:[2,70],49:[2,70],54:[2,70],57:[2,70],66:[2,70],67:[2,70],68:[2,70],69:[2,70],71:[2,70],73:[2,70],74:[2,70],78:[2,70],80:[2,70],84:[2,70],85:[2,70],86:[2,70],91:[2,70],93:[2,70],102:[2,70],104:[2,70],105:[2,70],106:[2,70],110:[2,70],118:[2,70],126:[2,70],128:[2,70],129:[2,70],130:[2,70],131:[2,70],132:[2,70],133:[2,70],134:[2,70],135:[2,70],136:[2,70],137:[2,70],138:[2,70]},{7:146,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:147,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:148,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:150,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:149,25:[1,112],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{27:155,28:[1,71],44:156,58:157,59:158,64:151,76:[1,68],89:[1,109],90:[1,55],113:152,114:[1,153],115:154},{112:159,116:[1,160],117:[1,161]},{6:[2,90],10:165,25:[2,90],27:166,28:[1,71],29:167,30:[1,69],31:[1,70],41:163,42:164,44:168,46:[1,44],54:[2,90],77:162,78:[2,90],89:[1,109]},{1:[2,26],6:[2,26],25:[2,26],26:[2,26],43:[2,26],49:[2,26],54:[2,26],57:[2,26],66:[2,26],67:[2,26],68:[2,26],69:[2,26],71:[2,26],73:[2,26],74:[2,26],78:[2,26],84:[2,26],85:[2,26],86:[2,26],91:[2,26],93:[2,26],102:[2,26],104:[2,26],105:[2,26],106:[2,26],110:[2,26],118:[2,26],126:[2,26],128:[2,26],129:[2,26],132:[2,26],133:[2,26],134:[2,26],135:[2,26],136:[2,26],137:[2,26]},{1:[2,27],6:[2,27],25:[2,27],26:[2,27],43:[2,27],49:[2,27],54:[2,27],57:[2,27],66:[2,27],67:[2,27],68:[2,27],69:[2,27],71:[2,27],73:[2,27],74:[2,27],78:[2,27],84:[2,27],85:[2,27],86:[2,27],91:[2,27],93:[2,27],102:[2,27],104:[2,27],105:[2,27],106:[2,27],110:[2,27],118:[2,27],126:[2,27],128:[2,27],129:[2,27],132:[2,27],133:[2,27],134:[2,27],135:[2,27],136:[2,27],137:[2,27]},{1:[2,25],6:[2,25],25:[2,25],26:[2,25],40:[2,25],43:[2,25],49:[2,25],54:[2,25],57:[2,25],66:[2,25],67:[2,25],68:[2,25],69:[2,25],71:[2,25],73:[2,25],74:[2,25],78:[2,25],80:[2,25],84:[2,25],85:[2,25],86:[2,25],91:[2,25],93:[2,25],102:[2,25],104:[2,25],105:[2,25],106:[2,25],110:[2,25],116:[2,25],117:[2,25],118:[2,25],126:[2,25],128:[2,25],129:[2,25],130:[2,25],131:[2,25],132:[2,25],133:[2,25],134:[2,25],135:[2,25],136:[2,25],137:[2,25],138:[2,25]},{1:[2,5],5:169,6:[2,5],7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,26:[2,5],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],102:[2,5],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,193],6:[2,193],25:[2,193],26:[2,193],49:[2,193],54:[2,193],57:[2,193],73:[2,193],78:[2,193],86:[2,193],91:[2,193],93:[2,193],102:[2,193],104:[2,193],105:[2,193],106:[2,193],110:[2,193],118:[2,193],126:[2,193],128:[2,193],129:[2,193],132:[2,193],133:[2,193],134:[2,193],135:[2,193],136:[2,193],137:[2,193]},{7:170,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:171,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:172,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:173,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:174,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:175,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:176,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:177,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,148],6:[2,148],25:[2,148],26:[2,148],49:[2,148],54:[2,148],57:[2,148],73:[2,148],78:[2,148],86:[2,148],91:[2,148],93:[2,148],102:[2,148],104:[2,148],105:[2,148],106:[2,148],110:[2,148],118:[2,148],126:[2,148],128:[2,148],129:[2,148],132:[2,148],133:[2,148],134:[2,148],135:[2,148],136:[2,148],137:[2,148]},{1:[2,153],6:[2,153],25:[2,153],26:[2,153],49:[2,153],54:[2,153],57:[2,153],73:[2,153],78:[2,153],86:[2,153],91:[2,153],93:[2,153],102:[2,153],104:[2,153],105:[2,153],106:[2,153],110:[2,153],118:[2,153],126:[2,153],128:[2,153],129:[2,153],132:[2,153],133:[2,153],134:[2,153],135:[2,153],136:[2,153],137:[2,153]},{7:178,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,147],6:[2,147],25:[2,147],26:[2,147],49:[2,147],54:[2,147],57:[2,147],73:[2,147],78:[2,147],86:[2,147],91:[2,147],93:[2,147],102:[2,147],104:[2,147],105:[2,147],106:[2,147],110:[2,147],118:[2,147],126:[2,147],128:[2,147],129:[2,147],132:[2,147],133:[2,147],134:[2,147],135:[2,147],136:[2,147],137:[2,147]},{1:[2,152],6:[2,152],25:[2,152],26:[2,152],49:[2,152],54:[2,152],57:[2,152],73:[2,152],78:[2,152],86:[2,152],91:[2,152],93:[2,152],102:[2,152],104:[2,152],105:[2,152],106:[2,152],110:[2,152],118:[2,152],126:[2,152],128:[2,152],129:[2,152],132:[2,152],133:[2,152],134:[2,152],135:[2,152],136:[2,152],137:[2,152]},{82:179,85:[1,101]},{1:[2,68],6:[2,68],25:[2,68],26:[2,68],40:[2,68],49:[2,68],54:[2,68],57:[2,68],66:[2,68],67:[2,68],68:[2,68],69:[2,68],71:[2,68],73:[2,68],74:[2,68],78:[2,68],80:[2,68],84:[2,68],85:[2,68],86:[2,68],91:[2,68],93:[2,68],102:[2,68],104:[2,68],105:[2,68],106:[2,68],110:[2,68],118:[2,68],126:[2,68],128:[2,68],129:[2,68],130:[2,68],131:[2,68],132:[2,68],133:[2,68],134:[2,68],135:[2,68],136:[2,68],137:[2,68],138:[2,68]},{85:[2,108]},{27:180,28:[1,71]},{27:181,28:[1,71]},{1:[2,83],6:[2,83],25:[2,83],26:[2,83],27:182,28:[1,71],40:[2,83],49:[2,83],54:[2,83],57:[2,83],66:[2,83],67:[2,83],68:[2,83],69:[2,83],71:[2,83],73:[2,83],74:[2,83],78:[2,83],80:[2,83],84:[2,83],85:[2,83],86:[2,83],91:[2,83],93:[2,83],102:[2,83],104:[2,83],105:[2,83],106:[2,83],110:[2,83],118:[2,83],126:[2,83],128:[2,83],129:[2,83],130:[2,83],131:[2,83],132:[2,83],133:[2,83],134:[2,83],135:[2,83],136:[2,83],137:[2,83],138:[2,83]},{27:183,28:[1,71]},{1:[2,84],6:[2,84],25:[2,84],26:[2,84],40:[2,84],49:[2,84],54:[2,84],57:[2,84],66:[2,84],67:[2,84],68:[2,84],69:[2,84],71:[2,84],73:[2,84],74:[2,84],78:[2,84],80:[2,84],84:[2,84],85:[2,84],86:[2,84],91:[2,84],93:[2,84],102:[2,84],104:[2,84],105:[2,84],106:[2,84],110:[2,84],118:[2,84],126:[2,84],128:[2,84],129:[2,84],130:[2,84],131:[2,84],132:[2,84],133:[2,84],134:[2,84],135:[2,84],136:[2,84],137:[2,84],138:[2,84]},{7:185,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],57:[1,189],58:45,59:46,61:34,63:23,64:24,65:25,72:184,75:186,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],92:187,93:[1,188],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{70:190,71:[1,95],74:[1,96]},{82:191,85:[1,101]},{1:[2,69],6:[2,69],25:[2,69],26:[2,69],40:[2,69],49:[2,69],54:[2,69],57:[2,69],66:[2,69],67:[2,69],68:[2,69],69:[2,69],71:[2,69],73:[2,69],74:[2,69],78:[2,69],80:[2,69],84:[2,69],85:[2,69],86:[2,69],91:[2,69],93:[2,69],102:[2,69],104:[2,69],105:[2,69],106:[2,69],110:[2,69],118:[2,69],126:[2,69],128:[2,69],129:[2,69],130:[2,69],131:[2,69],132:[2,69],133:[2,69],134:[2,69],135:[2,69],136:[2,69],137:[2,69],138:[2,69]},{6:[1,193],7:192,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,194],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,106],6:[2,106],25:[2,106],26:[2,106],49:[2,106],54:[2,106],57:[2,106],66:[2,106],67:[2,106],68:[2,106],69:[2,106],71:[2,106],73:[2,106],74:[2,106],78:[2,106],84:[2,106],85:[2,106],86:[2,106],91:[2,106],93:[2,106],102:[2,106],104:[2,106],105:[2,106],106:[2,106],110:[2,106],118:[2,106],126:[2,106],128:[2,106],129:[2,106],132:[2,106],133:[2,106],134:[2,106],135:[2,106],136:[2,106],137:[2,106]},{7:197,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,143],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,60:144,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],86:[1,195],87:196,88:[1,56],89:[1,57],90:[1,55],94:142,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[2,52],25:[2,52],49:[1,198],53:200,54:[1,199]},{6:[2,55],25:[2,55],26:[2,55],49:[2,55],54:[2,55]},{6:[2,59],25:[2,59],26:[2,59],40:[1,202],49:[2,59],54:[2,59],57:[1,201]},{6:[2,62],25:[2,62],26:[2,62],40:[2,62],49:[2,62],54:[2,62],57:[2,62]},{6:[2,63],25:[2,63],26:[2,63],40:[2,63],49:[2,63],54:[2,63],57:[2,63]},{6:[2,64],25:[2,64],26:[2,64],40:[2,64],49:[2,64],54:[2,64],57:[2,64]},{6:[2,65],25:[2,65],26:[2,65],40:[2,65],49:[2,65],54:[2,65],57:[2,65]},{27:145,28:[1,71]},{7:197,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,143],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,60:144,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],87:141,88:[1,56],89:[1,57],90:[1,55],91:[1,140],94:142,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,49],6:[2,49],25:[2,49],26:[2,49],49:[2,49],54:[2,49],57:[2,49],73:[2,49],78:[2,49],86:[2,49],91:[2,49],93:[2,49],102:[2,49],104:[2,49],105:[2,49],106:[2,49],110:[2,49],118:[2,49],126:[2,49],128:[2,49],129:[2,49],132:[2,49],133:[2,49],134:[2,49],135:[2,49],136:[2,49],137:[2,49]},{4:204,5:3,7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,26:[1,203],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,186],6:[2,186],25:[2,186],26:[2,186],49:[2,186],54:[2,186],57:[2,186],73:[2,186],78:[2,186],86:[2,186],91:[2,186],93:[2,186],102:[2,186],103:82,104:[2,186],105:[2,186],106:[2,186],109:83,110:[2,186],111:67,118:[2,186],126:[2,186],128:[2,186],129:[2,186],132:[1,73],133:[2,186],134:[2,186],135:[2,186],136:[2,186],137:[2,186]},{103:85,104:[1,63],106:[1,64],109:86,110:[1,66],111:67,126:[1,84]},{1:[2,187],6:[2,187],25:[2,187],26:[2,187],49:[2,187],54:[2,187],57:[2,187],73:[2,187],78:[2,187],86:[2,187],91:[2,187],93:[2,187],102:[2,187],103:82,104:[2,187],105:[2,187],106:[2,187],109:83,110:[2,187],111:67,118:[2,187],126:[2,187],128:[2,187],129:[2,187],132:[1,73],133:[2,187],134:[2,187],135:[2,187],136:[2,187],137:[2,187]},{1:[2,188],6:[2,188],25:[2,188],26:[2,188],49:[2,188],54:[2,188],57:[2,188],73:[2,188],78:[2,188],86:[2,188],91:[2,188],93:[2,188],102:[2,188],103:82,104:[2,188],105:[2,188],106:[2,188],109:83,110:[2,188],111:67,118:[2,188],126:[2,188],128:[2,188],129:[2,188],132:[1,73],133:[2,188],134:[2,188],135:[2,188],136:[2,188],137:[2,188]},{1:[2,189],6:[2,189],25:[2,189],26:[2,189],49:[2,189],54:[2,189],57:[2,189],66:[2,71],67:[2,71],68:[2,71],69:[2,71],71:[2,71],73:[2,189],74:[2,71],78:[2,189],84:[2,71],85:[2,71],86:[2,189],91:[2,189],93:[2,189],102:[2,189],104:[2,189],105:[2,189],106:[2,189],110:[2,189],118:[2,189],126:[2,189],128:[2,189],129:[2,189],132:[2,189],133:[2,189],134:[2,189],135:[2,189],136:[2,189],137:[2,189]},{62:88,66:[1,90],67:[1,91],68:[1,92],69:[1,93],70:94,71:[1,95],74:[1,96],81:87,84:[1,89],85:[2,107]},{62:98,66:[1,90],67:[1,91],68:[1,92],69:[1,93],70:94,71:[1,95],74:[1,96],81:97,84:[1,89],85:[2,107]},{66:[2,74],67:[2,74],68:[2,74],69:[2,74],71:[2,74],74:[2,74],84:[2,74],85:[2,74]},{1:[2,190],6:[2,190],25:[2,190],26:[2,190],49:[2,190],54:[2,190],57:[2,190],66:[2,71],67:[2,71],68:[2,71],69:[2,71],71:[2,71],73:[2,190],74:[2,71],78:[2,190],84:[2,71],85:[2,71],86:[2,190],91:[2,190],93:[2,190],102:[2,190],104:[2,190],105:[2,190],106:[2,190],110:[2,190],118:[2,190],126:[2,190],128:[2,190],129:[2,190],132:[2,190],133:[2,190],134:[2,190],135:[2,190],136:[2,190],137:[2,190]},{1:[2,191],6:[2,191],25:[2,191],26:[2,191],49:[2,191],54:[2,191],57:[2,191],73:[2,191],78:[2,191],86:[2,191],91:[2,191],93:[2,191],102:[2,191],104:[2,191],105:[2,191],106:[2,191],110:[2,191],118:[2,191],126:[2,191],128:[2,191],129:[2,191],132:[2,191],133:[2,191],134:[2,191],135:[2,191],136:[2,191],137:[2,191]},{1:[2,192],6:[2,192],25:[2,192],26:[2,192],49:[2,192],54:[2,192],57:[2,192],73:[2,192],78:[2,192],86:[2,192],91:[2,192],93:[2,192],102:[2,192],104:[2,192],105:[2,192],106:[2,192],110:[2,192],118:[2,192],126:[2,192],128:[2,192],129:[2,192],132:[2,192],133:[2,192],134:[2,192],135:[2,192],136:[2,192],137:[2,192]},{6:[1,207],7:205,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,206],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:208,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{24:209,25:[1,112],125:[1,210]},{1:[2,132],6:[2,132],25:[2,132],26:[2,132],49:[2,132],54:[2,132],57:[2,132],73:[2,132],78:[2,132],86:[2,132],91:[2,132],93:[2,132],97:211,98:[1,212],99:[1,213],102:[2,132],104:[2,132],105:[2,132],106:[2,132],110:[2,132],118:[2,132],126:[2,132],128:[2,132],129:[2,132],132:[2,132],133:[2,132],134:[2,132],135:[2,132],136:[2,132],137:[2,132]},{1:[2,146],6:[2,146],25:[2,146],26:[2,146],49:[2,146],54:[2,146],57:[2,146],73:[2,146],78:[2,146],86:[2,146],91:[2,146],93:[2,146],102:[2,146],104:[2,146],105:[2,146],106:[2,146],110:[2,146],118:[2,146],126:[2,146],128:[2,146],129:[2,146],132:[2,146],133:[2,146],134:[2,146],135:[2,146],136:[2,146],137:[2,146]},{1:[2,154],6:[2,154],25:[2,154],26:[2,154],49:[2,154],54:[2,154],57:[2,154],73:[2,154],78:[2,154],86:[2,154],91:[2,154],93:[2,154],102:[2,154],104:[2,154],105:[2,154],106:[2,154],110:[2,154],118:[2,154],126:[2,154],128:[2,154],129:[2,154],132:[2,154],133:[2,154],134:[2,154],135:[2,154],136:[2,154],137:[2,154]},{25:[1,214],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{120:215,122:216,123:[1,217]},{1:[2,96],6:[2,96],25:[2,96],26:[2,96],49:[2,96],54:[2,96],57:[2,96],73:[2,96],78:[2,96],86:[2,96],91:[2,96],93:[2,96],102:[2,96],104:[2,96],105:[2,96],106:[2,96],110:[2,96],118:[2,96],126:[2,96],128:[2,96],129:[2,96],132:[2,96],133:[2,96],134:[2,96],135:[2,96],136:[2,96],137:[2,96]},{7:218,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,99],6:[2,99],24:219,25:[1,112],26:[2,99],49:[2,99],54:[2,99],57:[2,99],66:[2,71],67:[2,71],68:[2,71],69:[2,71],71:[2,71],73:[2,99],74:[2,71],78:[2,99],80:[1,220],84:[2,71],85:[2,71],86:[2,99],91:[2,99],93:[2,99],102:[2,99],104:[2,99],105:[2,99],106:[2,99],110:[2,99],118:[2,99],126:[2,99],128:[2,99],129:[2,99],132:[2,99],133:[2,99],134:[2,99],135:[2,99],136:[2,99],137:[2,99]},{1:[2,139],6:[2,139],25:[2,139],26:[2,139],49:[2,139],54:[2,139],57:[2,139],73:[2,139],78:[2,139],86:[2,139],91:[2,139],93:[2,139],102:[2,139],103:82,104:[2,139],105:[2,139],106:[2,139],109:83,110:[2,139],111:67,118:[2,139],126:[2,139],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,45],6:[2,45],26:[2,45],102:[2,45],103:82,104:[2,45],106:[2,45],109:83,110:[2,45],111:67,126:[2,45],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{6:[1,72],102:[1,221]},{4:222,5:3,7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[2,128],25:[2,128],54:[2,128],57:[1,224],91:[2,128],92:223,93:[1,188],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,114],6:[2,114],25:[2,114],26:[2,114],40:[2,114],49:[2,114],54:[2,114],57:[2,114],66:[2,114],67:[2,114],68:[2,114],69:[2,114],71:[2,114],73:[2,114],74:[2,114],78:[2,114],84:[2,114],85:[2,114],86:[2,114],91:[2,114],93:[2,114],102:[2,114],104:[2,114],105:[2,114],106:[2,114],110:[2,114],116:[2,114],117:[2,114],118:[2,114],126:[2,114],128:[2,114],129:[2,114],132:[2,114],133:[2,114],134:[2,114],135:[2,114],136:[2,114],137:[2,114]},{6:[2,52],25:[2,52],53:225,54:[1,226],91:[2,52]},{6:[2,123],25:[2,123],26:[2,123],54:[2,123],86:[2,123],91:[2,123]},{7:197,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,143],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,60:144,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],87:227,88:[1,56],89:[1,57],90:[1,55],94:142,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[2,129],25:[2,129],26:[2,129],54:[2,129],86:[2,129],91:[2,129]},{1:[2,113],6:[2,113],25:[2,113],26:[2,113],40:[2,113],43:[2,113],49:[2,113],54:[2,113],57:[2,113],66:[2,113],67:[2,113],68:[2,113],69:[2,113],71:[2,113],73:[2,113],74:[2,113],78:[2,113],80:[2,113],84:[2,113],85:[2,113],86:[2,113],91:[2,113],93:[2,113],102:[2,113],104:[2,113],105:[2,113],106:[2,113],110:[2,113],116:[2,113],117:[2,113],118:[2,113],126:[2,113],128:[2,113],129:[2,113],130:[2,113],131:[2,113],132:[2,113],133:[2,113],134:[2,113],135:[2,113],136:[2,113],137:[2,113],138:[2,113]},{24:228,25:[1,112],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,142],6:[2,142],25:[2,142],26:[2,142],49:[2,142],54:[2,142],57:[2,142],73:[2,142],78:[2,142],86:[2,142],91:[2,142],93:[2,142],102:[2,142],103:82,104:[1,63],105:[1,229],106:[1,64],109:83,110:[1,66],111:67,118:[2,142],126:[2,142],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,144],6:[2,144],25:[2,144],26:[2,144],49:[2,144],54:[2,144],57:[2,144],73:[2,144],78:[2,144],86:[2,144],91:[2,144],93:[2,144],102:[2,144],103:82,104:[1,63],105:[1,230],106:[1,64],109:83,110:[1,66],111:67,118:[2,144],126:[2,144],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,150],6:[2,150],25:[2,150],26:[2,150],49:[2,150],54:[2,150],57:[2,150],73:[2,150],78:[2,150],86:[2,150],91:[2,150],93:[2,150],102:[2,150],104:[2,150],105:[2,150],106:[2,150],110:[2,150],118:[2,150],126:[2,150],128:[2,150],129:[2,150],132:[2,150],133:[2,150],134:[2,150],135:[2,150],136:[2,150],137:[2,150]},{1:[2,151],6:[2,151],25:[2,151],26:[2,151],49:[2,151],54:[2,151],57:[2,151],73:[2,151],78:[2,151],86:[2,151],91:[2,151],93:[2,151],102:[2,151],103:82,104:[1,63],105:[2,151],106:[1,64],109:83,110:[1,66],111:67,118:[2,151],126:[2,151],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,155],6:[2,155],25:[2,155],26:[2,155],49:[2,155],54:[2,155],57:[2,155],73:[2,155],78:[2,155],86:[2,155],91:[2,155],93:[2,155],102:[2,155],104:[2,155],105:[2,155],106:[2,155],110:[2,155],118:[2,155],126:[2,155],128:[2,155],129:[2,155],132:[2,155],133:[2,155],134:[2,155],135:[2,155],136:[2,155],137:[2,155]},{116:[2,157],117:[2,157]},{27:155,28:[1,71],44:156,58:157,59:158,76:[1,68],89:[1,109],90:[1,110],113:231,115:154},{54:[1,232],116:[2,163],117:[2,163]},{54:[2,159],116:[2,159],117:[2,159]},{54:[2,160],116:[2,160],117:[2,160]},{54:[2,161],116:[2,161],117:[2,161]},{54:[2,162],116:[2,162],117:[2,162]},{1:[2,156],6:[2,156],25:[2,156],26:[2,156],49:[2,156],54:[2,156],57:[2,156],73:[2,156],78:[2,156],86:[2,156],91:[2,156],93:[2,156],102:[2,156],104:[2,156],105:[2,156],106:[2,156],110:[2,156],118:[2,156],126:[2,156],128:[2,156],129:[2,156],132:[2,156],133:[2,156],134:[2,156],135:[2,156],136:[2,156],137:[2,156]},{7:233,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:234,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[2,52],25:[2,52],53:235,54:[1,236],78:[2,52]},{6:[2,91],25:[2,91],26:[2,91],54:[2,91],78:[2,91]},{6:[2,38],25:[2,38],26:[2,38],43:[1,237],54:[2,38],78:[2,38]},{6:[2,41],25:[2,41],26:[2,41],54:[2,41],78:[2,41]},{6:[2,42],25:[2,42],26:[2,42],43:[2,42],54:[2,42],78:[2,42]},{6:[2,43],25:[2,43],26:[2,43],43:[2,43],54:[2,43],78:[2,43]},{6:[2,44],25:[2,44],26:[2,44],43:[2,44],54:[2,44],78:[2,44]},{1:[2,4],6:[2,4],26:[2,4],102:[2,4]},{1:[2,194],6:[2,194],25:[2,194],26:[2,194],49:[2,194],54:[2,194],57:[2,194],73:[2,194],78:[2,194],86:[2,194],91:[2,194],93:[2,194],102:[2,194],103:82,104:[2,194],105:[2,194],106:[2,194],109:83,110:[2,194],111:67,118:[2,194],126:[2,194],128:[2,194],129:[2,194],132:[1,73],133:[1,76],134:[2,194],135:[2,194],136:[2,194],137:[2,194]},{1:[2,195],6:[2,195],25:[2,195],26:[2,195],49:[2,195],54:[2,195],57:[2,195],73:[2,195],78:[2,195],86:[2,195],91:[2,195],93:[2,195],102:[2,195],103:82,104:[2,195],105:[2,195],106:[2,195],109:83,110:[2,195],111:67,118:[2,195],126:[2,195],128:[2,195],129:[2,195],132:[1,73],133:[1,76],134:[2,195],135:[2,195],136:[2,195],137:[2,195]},{1:[2,196],6:[2,196],25:[2,196],26:[2,196],49:[2,196],54:[2,196],57:[2,196],73:[2,196],78:[2,196],86:[2,196],91:[2,196],93:[2,196],102:[2,196],103:82,104:[2,196],105:[2,196],106:[2,196],109:83,110:[2,196],111:67,118:[2,196],126:[2,196],128:[2,196],129:[2,196],132:[1,73],133:[2,196],134:[2,196],135:[2,196],136:[2,196],137:[2,196]},{1:[2,197],6:[2,197],25:[2,197],26:[2,197],49:[2,197],54:[2,197],57:[2,197],73:[2,197],78:[2,197],86:[2,197],91:[2,197],93:[2,197],102:[2,197],103:82,104:[2,197],105:[2,197],106:[2,197],109:83,110:[2,197],111:67,118:[2,197],126:[2,197],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[2,197],135:[2,197],136:[2,197],137:[2,197]},{1:[2,198],6:[2,198],25:[2,198],26:[2,198],49:[2,198],54:[2,198],57:[2,198],73:[2,198],78:[2,198],86:[2,198],91:[2,198],93:[2,198],102:[2,198],103:82,104:[2,198],105:[2,198],106:[2,198],109:83,110:[2,198],111:67,118:[2,198],126:[2,198],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[2,198],136:[2,198],137:[1,80]},{1:[2,199],6:[2,199],25:[2,199],26:[2,199],49:[2,199],54:[2,199],57:[2,199],73:[2,199],78:[2,199],86:[2,199],91:[2,199],93:[2,199],102:[2,199],103:82,104:[2,199],105:[2,199],106:[2,199],109:83,110:[2,199],111:67,118:[2,199],126:[2,199],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[2,199],137:[1,80]},{1:[2,200],6:[2,200],25:[2,200],26:[2,200],49:[2,200],54:[2,200],57:[2,200],73:[2,200],78:[2,200],86:[2,200],91:[2,200],93:[2,200],102:[2,200],103:82,104:[2,200],105:[2,200],106:[2,200],109:83,110:[2,200],111:67,118:[2,200],126:[2,200],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[2,200],136:[2,200],137:[2,200]},{1:[2,185],6:[2,185],25:[2,185],26:[2,185],49:[2,185],54:[2,185],57:[2,185],73:[2,185],78:[2,185],86:[2,185],91:[2,185],93:[2,185],102:[2,185],103:82,104:[1,63],105:[2,185],106:[1,64],109:83,110:[1,66],111:67,118:[2,185],126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,184],6:[2,184],25:[2,184],26:[2,184],49:[2,184],54:[2,184],57:[2,184],73:[2,184],78:[2,184],86:[2,184],91:[2,184],93:[2,184],102:[2,184],103:82,104:[1,63],105:[2,184],106:[1,64],109:83,110:[1,66],111:67,118:[2,184],126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,103],6:[2,103],25:[2,103],26:[2,103],49:[2,103],54:[2,103],57:[2,103],66:[2,103],67:[2,103],68:[2,103],69:[2,103],71:[2,103],73:[2,103],74:[2,103],78:[2,103],84:[2,103],85:[2,103],86:[2,103],91:[2,103],93:[2,103],102:[2,103],104:[2,103],105:[2,103],106:[2,103],110:[2,103],118:[2,103],126:[2,103],128:[2,103],129:[2,103],132:[2,103],133:[2,103],134:[2,103],135:[2,103],136:[2,103],137:[2,103]},{1:[2,79],6:[2,79],25:[2,79],26:[2,79],40:[2,79],49:[2,79],54:[2,79],57:[2,79],66:[2,79],67:[2,79],68:[2,79],69:[2,79],71:[2,79],73:[2,79],74:[2,79],78:[2,79],80:[2,79],84:[2,79],85:[2,79],86:[2,79],91:[2,79],93:[2,79],102:[2,79],104:[2,79],105:[2,79],106:[2,79],110:[2,79],118:[2,79],126:[2,79],128:[2,79],129:[2,79],130:[2,79],131:[2,79],132:[2,79],133:[2,79],134:[2,79],135:[2,79],136:[2,79],137:[2,79],138:[2,79]},{1:[2,80],6:[2,80],25:[2,80],26:[2,80],40:[2,80],49:[2,80],54:[2,80],57:[2,80],66:[2,80],67:[2,80],68:[2,80],69:[2,80],71:[2,80],73:[2,80],74:[2,80],78:[2,80],80:[2,80],84:[2,80],85:[2,80],86:[2,80],91:[2,80],93:[2,80],102:[2,80],104:[2,80],105:[2,80],106:[2,80],110:[2,80],118:[2,80],126:[2,80],128:[2,80],129:[2,80],130:[2,80],131:[2,80],132:[2,80],133:[2,80],134:[2,80],135:[2,80],136:[2,80],137:[2,80],138:[2,80]},{1:[2,81],6:[2,81],25:[2,81],26:[2,81],40:[2,81],49:[2,81],54:[2,81],57:[2,81],66:[2,81],67:[2,81],68:[2,81],69:[2,81],71:[2,81],73:[2,81],74:[2,81],78:[2,81],80:[2,81],84:[2,81],85:[2,81],86:[2,81],91:[2,81],93:[2,81],102:[2,81],104:[2,81],105:[2,81],106:[2,81],110:[2,81],118:[2,81],126:[2,81],128:[2,81],129:[2,81],130:[2,81],131:[2,81],132:[2,81],133:[2,81],134:[2,81],135:[2,81],136:[2,81],137:[2,81],138:[2,81]},{1:[2,82],6:[2,82],25:[2,82],26:[2,82],40:[2,82],49:[2,82],54:[2,82],57:[2,82],66:[2,82],67:[2,82],68:[2,82],69:[2,82],71:[2,82],73:[2,82],74:[2,82],78:[2,82],80:[2,82],84:[2,82],85:[2,82],86:[2,82],91:[2,82],93:[2,82],102:[2,82],104:[2,82],105:[2,82],106:[2,82],110:[2,82],118:[2,82],126:[2,82],128:[2,82],129:[2,82],130:[2,82],131:[2,82],132:[2,82],133:[2,82],134:[2,82],135:[2,82],136:[2,82],137:[2,82],138:[2,82]},{73:[1,238]},{57:[1,189],73:[2,87],92:239,93:[1,188],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{73:[2,88]},{7:240,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,73:[2,122],76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{11:[2,116],28:[2,116],30:[2,116],31:[2,116],33:[2,116],34:[2,116],35:[2,116],36:[2,116],37:[2,116],38:[2,116],45:[2,116],46:[2,116],47:[2,116],51:[2,116],52:[2,116],73:[2,116],76:[2,116],79:[2,116],83:[2,116],88:[2,116],89:[2,116],90:[2,116],96:[2,116],100:[2,116],101:[2,116],104:[2,116],106:[2,116],108:[2,116],110:[2,116],119:[2,116],125:[2,116],127:[2,116],128:[2,116],129:[2,116],130:[2,116],131:[2,116]},{11:[2,117],28:[2,117],30:[2,117],31:[2,117],33:[2,117],34:[2,117],35:[2,117],36:[2,117],37:[2,117],38:[2,117],45:[2,117],46:[2,117],47:[2,117],51:[2,117],52:[2,117],73:[2,117],76:[2,117],79:[2,117],83:[2,117],88:[2,117],89:[2,117],90:[2,117],96:[2,117],100:[2,117],101:[2,117],104:[2,117],106:[2,117],108:[2,117],110:[2,117],119:[2,117],125:[2,117],127:[2,117],128:[2,117],129:[2,117],130:[2,117],131:[2,117]},{1:[2,86],6:[2,86],25:[2,86],26:[2,86],40:[2,86],49:[2,86],54:[2,86],57:[2,86],66:[2,86],67:[2,86],68:[2,86],69:[2,86],71:[2,86],73:[2,86],74:[2,86],78:[2,86],80:[2,86],84:[2,86],85:[2,86],86:[2,86],91:[2,86],93:[2,86],102:[2,86],104:[2,86],105:[2,86],106:[2,86],110:[2,86],118:[2,86],126:[2,86],128:[2,86],129:[2,86],130:[2,86],131:[2,86],132:[2,86],133:[2,86],134:[2,86],135:[2,86],136:[2,86],137:[2,86],138:[2,86]},{1:[2,104],6:[2,104],25:[2,104],26:[2,104],49:[2,104],54:[2,104],57:[2,104],66:[2,104],67:[2,104],68:[2,104],69:[2,104],71:[2,104],73:[2,104],74:[2,104],78:[2,104],84:[2,104],85:[2,104],86:[2,104],91:[2,104],93:[2,104],102:[2,104],104:[2,104],105:[2,104],106:[2,104],110:[2,104],118:[2,104],126:[2,104],128:[2,104],129:[2,104],132:[2,104],133:[2,104],134:[2,104],135:[2,104],136:[2,104],137:[2,104]},{1:[2,35],6:[2,35],25:[2,35],26:[2,35],49:[2,35],54:[2,35],57:[2,35],73:[2,35],78:[2,35],86:[2,35],91:[2,35],93:[2,35],102:[2,35],103:82,104:[2,35],105:[2,35],106:[2,35],109:83,110:[2,35],111:67,118:[2,35],126:[2,35],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{7:241,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:242,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,109],6:[2,109],25:[2,109],26:[2,109],49:[2,109],54:[2,109],57:[2,109],66:[2,109],67:[2,109],68:[2,109],69:[2,109],71:[2,109],73:[2,109],74:[2,109],78:[2,109],84:[2,109],85:[2,109],86:[2,109],91:[2,109],93:[2,109],102:[2,109],104:[2,109],105:[2,109],106:[2,109],110:[2,109],118:[2,109],126:[2,109],128:[2,109],129:[2,109],132:[2,109],133:[2,109],134:[2,109],135:[2,109],136:[2,109],137:[2,109]},{6:[2,52],25:[2,52],53:243,54:[1,226],86:[2,52]},{6:[2,128],25:[2,128],26:[2,128],54:[2,128],57:[1,244],86:[2,128],91:[2,128],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{50:245,51:[1,58],52:[1,59]},{6:[2,53],25:[2,53],26:[2,53],27:105,28:[1,71],44:106,55:246,56:104,58:107,59:108,76:[1,68],89:[1,109],90:[1,110]},{6:[1,247],25:[1,248]},{6:[2,60],25:[2,60],26:[2,60],49:[2,60],54:[2,60]},{7:249,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,23],6:[2,23],25:[2,23],26:[2,23],49:[2,23],54:[2,23],57:[2,23],73:[2,23],78:[2,23],86:[2,23],91:[2,23],93:[2,23],98:[2,23],99:[2,23],102:[2,23],104:[2,23],105:[2,23],106:[2,23],110:[2,23],118:[2,23],121:[2,23],123:[2,23],126:[2,23],128:[2,23],129:[2,23],132:[2,23],133:[2,23],134:[2,23],135:[2,23],136:[2,23],137:[2,23]},{6:[1,72],26:[1,250]},{1:[2,201],6:[2,201],25:[2,201],26:[2,201],49:[2,201],54:[2,201],57:[2,201],73:[2,201],78:[2,201],86:[2,201],91:[2,201],93:[2,201],102:[2,201],103:82,104:[2,201],105:[2,201],106:[2,201],109:83,110:[2,201],111:67,118:[2,201],126:[2,201],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{7:251,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:252,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,204],6:[2,204],25:[2,204],26:[2,204],49:[2,204],54:[2,204],57:[2,204],73:[2,204],78:[2,204],86:[2,204],91:[2,204],93:[2,204],102:[2,204],103:82,104:[2,204],105:[2,204],106:[2,204],109:83,110:[2,204],111:67,118:[2,204],126:[2,204],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,183],6:[2,183],25:[2,183],26:[2,183],49:[2,183],54:[2,183],57:[2,183],73:[2,183],78:[2,183],86:[2,183],91:[2,183],93:[2,183],102:[2,183],104:[2,183],105:[2,183],106:[2,183],110:[2,183],118:[2,183],126:[2,183],128:[2,183],129:[2,183],132:[2,183],133:[2,183],134:[2,183],135:[2,183],136:[2,183],137:[2,183]},{7:253,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,133],6:[2,133],25:[2,133],26:[2,133],49:[2,133],54:[2,133],57:[2,133],73:[2,133],78:[2,133],86:[2,133],91:[2,133],93:[2,133],98:[1,254],102:[2,133],104:[2,133],105:[2,133],106:[2,133],110:[2,133],118:[2,133],126:[2,133],128:[2,133],129:[2,133],132:[2,133],133:[2,133],134:[2,133],135:[2,133],136:[2,133],137:[2,133]},{24:255,25:[1,112]},{24:258,25:[1,112],27:256,28:[1,71],59:257,76:[1,68]},{120:259,122:216,123:[1,217]},{26:[1,260],121:[1,261],122:262,123:[1,217]},{26:[2,176],121:[2,176],123:[2,176]},{7:264,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],95:263,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,97],6:[2,97],24:265,25:[1,112],26:[2,97],49:[2,97],54:[2,97],57:[2,97],73:[2,97],78:[2,97],86:[2,97],91:[2,97],93:[2,97],102:[2,97],103:82,104:[1,63],105:[2,97],106:[1,64],109:83,110:[1,66],111:67,118:[2,97],126:[2,97],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,100],6:[2,100],25:[2,100],26:[2,100],49:[2,100],54:[2,100],57:[2,100],73:[2,100],78:[2,100],86:[2,100],91:[2,100],93:[2,100],102:[2,100],104:[2,100],105:[2,100],106:[2,100],110:[2,100],118:[2,100],126:[2,100],128:[2,100],129:[2,100],132:[2,100],133:[2,100],134:[2,100],135:[2,100],136:[2,100],137:[2,100]},{7:266,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,140],6:[2,140],25:[2,140],26:[2,140],49:[2,140],54:[2,140],57:[2,140],66:[2,140],67:[2,140],68:[2,140],69:[2,140],71:[2,140],73:[2,140],74:[2,140],78:[2,140],84:[2,140],85:[2,140],86:[2,140],91:[2,140],93:[2,140],102:[2,140],104:[2,140],105:[2,140],106:[2,140],110:[2,140],118:[2,140],126:[2,140],128:[2,140],129:[2,140],132:[2,140],133:[2,140],134:[2,140],135:[2,140],136:[2,140],137:[2,140]},{6:[1,72],26:[1,267]},{7:268,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[2,66],11:[2,117],25:[2,66],28:[2,117],30:[2,117],31:[2,117],33:[2,117],34:[2,117],35:[2,117],36:[2,117],37:[2,117],38:[2,117],45:[2,117],46:[2,117],47:[2,117],51:[2,117],52:[2,117],54:[2,66],76:[2,117],79:[2,117],83:[2,117],88:[2,117],89:[2,117],90:[2,117],91:[2,66],96:[2,117],100:[2,117],101:[2,117],104:[2,117],106:[2,117],108:[2,117],110:[2,117],119:[2,117],125:[2,117],127:[2,117],128:[2,117],129:[2,117],130:[2,117],131:[2,117]},{6:[1,270],25:[1,271],91:[1,269]},{6:[2,53],7:197,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[2,53],26:[2,53],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,60:144,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],86:[2,53],88:[1,56],89:[1,57],90:[1,55],91:[2,53],94:272,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[2,52],25:[2,52],26:[2,52],53:273,54:[1,226]},{1:[2,180],6:[2,180],25:[2,180],26:[2,180],49:[2,180],54:[2,180],57:[2,180],73:[2,180],78:[2,180],86:[2,180],91:[2,180],93:[2,180],102:[2,180],104:[2,180],105:[2,180],106:[2,180],110:[2,180],118:[2,180],121:[2,180],126:[2,180],128:[2,180],129:[2,180],132:[2,180],133:[2,180],134:[2,180],135:[2,180],136:[2,180],137:[2,180]},{7:274,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:275,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{116:[2,158],117:[2,158]},{27:155,28:[1,71],44:156,58:157,59:158,76:[1,68],89:[1,109],90:[1,110],115:276},{1:[2,165],6:[2,165],25:[2,165],26:[2,165],49:[2,165],54:[2,165],57:[2,165],73:[2,165],78:[2,165],86:[2,165],91:[2,165],93:[2,165],102:[2,165],103:82,104:[2,165],105:[1,277],106:[2,165],109:83,110:[2,165],111:67,118:[1,278],126:[2,165],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,166],6:[2,166],25:[2,166],26:[2,166],49:[2,166],54:[2,166],57:[2,166],73:[2,166],78:[2,166],86:[2,166],91:[2,166],93:[2,166],102:[2,166],103:82,104:[2,166],105:[1,279],106:[2,166],109:83,110:[2,166],111:67,118:[2,166],126:[2,166],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{6:[1,281],25:[1,282],78:[1,280]},{6:[2,53],10:165,25:[2,53],26:[2,53],27:166,28:[1,71],29:167,30:[1,69],31:[1,70],41:283,42:164,44:168,46:[1,44],78:[2,53],89:[1,109]},{7:284,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,285],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,85],6:[2,85],25:[2,85],26:[2,85],40:[2,85],49:[2,85],54:[2,85],57:[2,85],66:[2,85],67:[2,85],68:[2,85],69:[2,85],71:[2,85],73:[2,85],74:[2,85],78:[2,85],80:[2,85],84:[2,85],85:[2,85],86:[2,85],91:[2,85],93:[2,85],102:[2,85],104:[2,85],105:[2,85],106:[2,85],110:[2,85],118:[2,85],126:[2,85],128:[2,85],129:[2,85],130:[2,85],131:[2,85],132:[2,85],133:[2,85],134:[2,85],135:[2,85],136:[2,85],137:[2,85],138:[2,85]},{7:286,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,73:[2,120],76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{73:[2,121],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,36],6:[2,36],25:[2,36],26:[2,36],49:[2,36],54:[2,36],57:[2,36],73:[2,36],78:[2,36],86:[2,36],91:[2,36],93:[2,36],102:[2,36],103:82,104:[2,36],105:[2,36],106:[2,36],109:83,110:[2,36],111:67,118:[2,36],126:[2,36],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{26:[1,287],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{6:[1,270],25:[1,271],86:[1,288]},{6:[2,66],25:[2,66],26:[2,66],54:[2,66],86:[2,66],91:[2,66]},{24:289,25:[1,112]},{6:[2,56],25:[2,56],26:[2,56],49:[2,56],54:[2,56]},{27:105,28:[1,71],44:106,55:290,56:104,58:107,59:108,76:[1,68],89:[1,109],90:[1,110]},{6:[2,54],25:[2,54],26:[2,54],27:105,28:[1,71],44:106,48:291,54:[2,54],55:103,56:104,58:107,59:108,76:[1,68],89:[1,109],90:[1,110]},{6:[2,61],25:[2,61],26:[2,61],49:[2,61],54:[2,61],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,24],6:[2,24],25:[2,24],26:[2,24],49:[2,24],54:[2,24],57:[2,24],73:[2,24],78:[2,24],86:[2,24],91:[2,24],93:[2,24],98:[2,24],99:[2,24],102:[2,24],104:[2,24],105:[2,24],106:[2,24],110:[2,24],118:[2,24],121:[2,24],123:[2,24],126:[2,24],128:[2,24],129:[2,24],132:[2,24],133:[2,24],134:[2,24],135:[2,24],136:[2,24],137:[2,24]},{26:[1,292],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,203],6:[2,203],25:[2,203],26:[2,203],49:[2,203],54:[2,203],57:[2,203],73:[2,203],78:[2,203],86:[2,203],91:[2,203],93:[2,203],102:[2,203],103:82,104:[2,203],105:[2,203],106:[2,203],109:83,110:[2,203],111:67,118:[2,203],126:[2,203],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{24:293,25:[1,112],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{24:294,25:[1,112]},{1:[2,134],6:[2,134],25:[2,134],26:[2,134],49:[2,134],54:[2,134],57:[2,134],73:[2,134],78:[2,134],86:[2,134],91:[2,134],93:[2,134],102:[2,134],104:[2,134],105:[2,134],106:[2,134],110:[2,134],118:[2,134],126:[2,134],128:[2,134],129:[2,134],132:[2,134],133:[2,134],134:[2,134],135:[2,134],136:[2,134],137:[2,134]},{24:295,25:[1,112]},{24:296,25:[1,112]},{1:[2,138],6:[2,138],25:[2,138],26:[2,138],49:[2,138],54:[2,138],57:[2,138],73:[2,138],78:[2,138],86:[2,138],91:[2,138],93:[2,138],98:[2,138],102:[2,138],104:[2,138],105:[2,138],106:[2,138],110:[2,138],118:[2,138],126:[2,138],128:[2,138],129:[2,138],132:[2,138],133:[2,138],134:[2,138],135:[2,138],136:[2,138],137:[2,138]},{26:[1,297],121:[1,298],122:262,123:[1,217]},{1:[2,174],6:[2,174],25:[2,174],26:[2,174],49:[2,174],54:[2,174],57:[2,174],73:[2,174],78:[2,174],86:[2,174],91:[2,174],93:[2,174],102:[2,174],104:[2,174],105:[2,174],106:[2,174],110:[2,174],118:[2,174],126:[2,174],128:[2,174],129:[2,174],132:[2,174],133:[2,174],134:[2,174],135:[2,174],136:[2,174],137:[2,174]},{24:299,25:[1,112]},{26:[2,177],121:[2,177],123:[2,177]},{24:300,25:[1,112],54:[1,301]},{25:[2,130],54:[2,130],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,98],6:[2,98],25:[2,98],26:[2,98],49:[2,98],54:[2,98],57:[2,98],73:[2,98],78:[2,98],86:[2,98],91:[2,98],93:[2,98],102:[2,98],104:[2,98],105:[2,98],106:[2,98],110:[2,98],118:[2,98],126:[2,98],128:[2,98],129:[2,98],132:[2,98],133:[2,98],134:[2,98],135:[2,98],136:[2,98],137:[2,98]},{1:[2,101],6:[2,101],24:302,25:[1,112],26:[2,101],49:[2,101],54:[2,101],57:[2,101],73:[2,101],78:[2,101],86:[2,101],91:[2,101],93:[2,101],102:[2,101],103:82,104:[1,63],105:[2,101],106:[1,64],109:83,110:[1,66],111:67,118:[2,101],126:[2,101],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{102:[1,303]},{91:[1,304],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,115],6:[2,115],25:[2,115],26:[2,115],40:[2,115],49:[2,115],54:[2,115],57:[2,115],66:[2,115],67:[2,115],68:[2,115],69:[2,115],71:[2,115],73:[2,115],74:[2,115],78:[2,115],84:[2,115],85:[2,115],86:[2,115],91:[2,115],93:[2,115],102:[2,115],104:[2,115],105:[2,115],106:[2,115],110:[2,115],116:[2,115],117:[2,115],118:[2,115],126:[2,115],128:[2,115],129:[2,115],132:[2,115],133:[2,115],134:[2,115],135:[2,115],136:[2,115],137:[2,115]},{7:197,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,60:144,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],94:305,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:197,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,143],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,60:144,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],87:306,88:[1,56],89:[1,57],90:[1,55],94:142,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[2,124],25:[2,124],26:[2,124],54:[2,124],86:[2,124],91:[2,124]},{6:[1,270],25:[1,271],26:[1,307]},{1:[2,143],6:[2,143],25:[2,143],26:[2,143],49:[2,143],54:[2,143],57:[2,143],73:[2,143],78:[2,143],86:[2,143],91:[2,143],93:[2,143],102:[2,143],103:82,104:[1,63],105:[2,143],106:[1,64],109:83,110:[1,66],111:67,118:[2,143],126:[2,143],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,145],6:[2,145],25:[2,145],26:[2,145],49:[2,145],54:[2,145],57:[2,145],73:[2,145],78:[2,145],86:[2,145],91:[2,145],93:[2,145],102:[2,145],103:82,104:[1,63],105:[2,145],106:[1,64],109:83,110:[1,66],111:67,118:[2,145],126:[2,145],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{116:[2,164],117:[2,164]},{7:308,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:309,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:310,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,89],6:[2,89],25:[2,89],26:[2,89],40:[2,89],49:[2,89],54:[2,89],57:[2,89],66:[2,89],67:[2,89],68:[2,89],69:[2,89],71:[2,89],73:[2,89],74:[2,89],78:[2,89],84:[2,89],85:[2,89],86:[2,89],91:[2,89],93:[2,89],102:[2,89],104:[2,89],105:[2,89],106:[2,89],110:[2,89],116:[2,89],117:[2,89],118:[2,89],126:[2,89],128:[2,89],129:[2,89],132:[2,89],133:[2,89],134:[2,89],135:[2,89],136:[2,89],137:[2,89]},{10:165,27:166,28:[1,71],29:167,30:[1,69],31:[1,70],41:311,42:164,44:168,46:[1,44],89:[1,109]},{6:[2,90],10:165,25:[2,90],26:[2,90],27:166,28:[1,71],29:167,30:[1,69],31:[1,70],41:163,42:164,44:168,46:[1,44],54:[2,90],77:312,89:[1,109]},{6:[2,92],25:[2,92],26:[2,92],54:[2,92],78:[2,92]},{6:[2,39],25:[2,39],26:[2,39],54:[2,39],78:[2,39],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{7:313,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{73:[2,119],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,37],6:[2,37],25:[2,37],26:[2,37],49:[2,37],54:[2,37],57:[2,37],73:[2,37],78:[2,37],86:[2,37],91:[2,37],93:[2,37],102:[2,37],104:[2,37],105:[2,37],106:[2,37],110:[2,37],118:[2,37],126:[2,37],128:[2,37],129:[2,37],132:[2,37],133:[2,37],134:[2,37],135:[2,37],136:[2,37],137:[2,37]},{1:[2,110],6:[2,110],25:[2,110],26:[2,110],49:[2,110],54:[2,110],57:[2,110],66:[2,110],67:[2,110],68:[2,110],69:[2,110],71:[2,110],73:[2,110],74:[2,110],78:[2,110],84:[2,110],85:[2,110],86:[2,110],91:[2,110],93:[2,110],102:[2,110],104:[2,110],105:[2,110],106:[2,110],110:[2,110],118:[2,110],126:[2,110],128:[2,110],129:[2,110],132:[2,110],133:[2,110],134:[2,110],135:[2,110],136:[2,110],137:[2,110]},{1:[2,48],6:[2,48],25:[2,48],26:[2,48],49:[2,48],54:[2,48],57:[2,48],73:[2,48],78:[2,48],86:[2,48],91:[2,48],93:[2,48],102:[2,48],104:[2,48],105:[2,48],106:[2,48],110:[2,48],118:[2,48],126:[2,48],128:[2,48],129:[2,48],132:[2,48],133:[2,48],134:[2,48],135:[2,48],136:[2,48],137:[2,48]},{6:[2,57],25:[2,57],26:[2,57],49:[2,57],54:[2,57]},{6:[2,52],25:[2,52],26:[2,52],53:314,54:[1,199]},{1:[2,202],6:[2,202],25:[2,202],26:[2,202],49:[2,202],54:[2,202],57:[2,202],73:[2,202],78:[2,202],86:[2,202],91:[2,202],93:[2,202],102:[2,202],104:[2,202],105:[2,202],106:[2,202],110:[2,202],118:[2,202],126:[2,202],128:[2,202],129:[2,202],132:[2,202],133:[2,202],134:[2,202],135:[2,202],136:[2,202],137:[2,202]},{1:[2,181],6:[2,181],25:[2,181],26:[2,181],49:[2,181],54:[2,181],57:[2,181],73:[2,181],78:[2,181],86:[2,181],91:[2,181],93:[2,181],102:[2,181],104:[2,181],105:[2,181],106:[2,181],110:[2,181],118:[2,181],121:[2,181],126:[2,181],128:[2,181],129:[2,181],132:[2,181],133:[2,181],134:[2,181],135:[2,181],136:[2,181],137:[2,181]},{1:[2,135],6:[2,135],25:[2,135],26:[2,135],49:[2,135],54:[2,135],57:[2,135],73:[2,135],78:[2,135],86:[2,135],91:[2,135],93:[2,135],102:[2,135],104:[2,135],105:[2,135],106:[2,135],110:[2,135],118:[2,135],126:[2,135],128:[2,135],129:[2,135],132:[2,135],133:[2,135],134:[2,135],135:[2,135],136:[2,135],137:[2,135]},{1:[2,136],6:[2,136],25:[2,136],26:[2,136],49:[2,136],54:[2,136],57:[2,136],73:[2,136],78:[2,136],86:[2,136],91:[2,136],93:[2,136],98:[2,136],102:[2,136],104:[2,136],105:[2,136],106:[2,136],110:[2,136],118:[2,136],126:[2,136],128:[2,136],129:[2,136],132:[2,136],133:[2,136],134:[2,136],135:[2,136],136:[2,136],137:[2,136]},{1:[2,137],6:[2,137],25:[2,137],26:[2,137],49:[2,137],54:[2,137],57:[2,137],73:[2,137],78:[2,137],86:[2,137],91:[2,137],93:[2,137],98:[2,137],102:[2,137],104:[2,137],105:[2,137],106:[2,137],110:[2,137],118:[2,137],126:[2,137],128:[2,137],129:[2,137],132:[2,137],133:[2,137],134:[2,137],135:[2,137],136:[2,137],137:[2,137]},{1:[2,172],6:[2,172],25:[2,172],26:[2,172],49:[2,172],54:[2,172],57:[2,172],73:[2,172],78:[2,172],86:[2,172],91:[2,172],93:[2,172],102:[2,172],104:[2,172],105:[2,172],106:[2,172],110:[2,172],118:[2,172],126:[2,172],128:[2,172],129:[2,172],132:[2,172],133:[2,172],134:[2,172],135:[2,172],136:[2,172],137:[2,172]},{24:315,25:[1,112]},{26:[1,316]},{6:[1,317],26:[2,178],121:[2,178],123:[2,178]},{7:318,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,102],6:[2,102],25:[2,102],26:[2,102],49:[2,102],54:[2,102],57:[2,102],73:[2,102],78:[2,102],86:[2,102],91:[2,102],93:[2,102],102:[2,102],104:[2,102],105:[2,102],106:[2,102],110:[2,102],118:[2,102],126:[2,102],128:[2,102],129:[2,102],132:[2,102],133:[2,102],134:[2,102],135:[2,102],136:[2,102],137:[2,102]},{1:[2,141],6:[2,141],25:[2,141],26:[2,141],49:[2,141],54:[2,141],57:[2,141],66:[2,141],67:[2,141],68:[2,141],69:[2,141],71:[2,141],73:[2,141],74:[2,141],78:[2,141],84:[2,141],85:[2,141],86:[2,141],91:[2,141],93:[2,141],102:[2,141],104:[2,141],105:[2,141],106:[2,141],110:[2,141],118:[2,141],126:[2,141],128:[2,141],129:[2,141],132:[2,141],133:[2,141],134:[2,141],135:[2,141],136:[2,141],137:[2,141]},{1:[2,118],6:[2,118],25:[2,118],26:[2,118],49:[2,118],54:[2,118],57:[2,118],66:[2,118],67:[2,118],68:[2,118],69:[2,118],71:[2,118],73:[2,118],74:[2,118],78:[2,118],84:[2,118],85:[2,118],86:[2,118],91:[2,118],93:[2,118],102:[2,118],104:[2,118],105:[2,118],106:[2,118],110:[2,118],118:[2,118],126:[2,118],128:[2,118],129:[2,118],132:[2,118],133:[2,118],134:[2,118],135:[2,118],136:[2,118],137:[2,118]},{6:[2,125],25:[2,125],26:[2,125],54:[2,125],86:[2,125],91:[2,125]},{6:[2,52],25:[2,52],26:[2,52],53:319,54:[1,226]},{6:[2,126],25:[2,126],26:[2,126],54:[2,126],86:[2,126],91:[2,126]},{1:[2,167],6:[2,167],25:[2,167],26:[2,167],49:[2,167],54:[2,167],57:[2,167],73:[2,167],78:[2,167],86:[2,167],91:[2,167],93:[2,167],102:[2,167],103:82,104:[2,167],105:[2,167],106:[2,167],109:83,110:[2,167],111:67,118:[1,320],126:[2,167],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,169],6:[2,169],25:[2,169],26:[2,169],49:[2,169],54:[2,169],57:[2,169],73:[2,169],78:[2,169],86:[2,169],91:[2,169],93:[2,169],102:[2,169],103:82,104:[2,169],105:[1,321],106:[2,169],109:83,110:[2,169],111:67,118:[2,169],126:[2,169],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,168],6:[2,168],25:[2,168],26:[2,168],49:[2,168],54:[2,168],57:[2,168],73:[2,168],78:[2,168],86:[2,168],91:[2,168],93:[2,168],102:[2,168],103:82,104:[2,168],105:[2,168],106:[2,168],109:83,110:[2,168],111:67,118:[2,168],126:[2,168],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{6:[2,93],25:[2,93],26:[2,93],54:[2,93],78:[2,93]},{6:[2,52],25:[2,52],26:[2,52],53:322,54:[1,236]},{26:[1,323],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{6:[1,247],25:[1,248],26:[1,324]},{26:[1,325]},{1:[2,175],6:[2,175],25:[2,175],26:[2,175],49:[2,175],54:[2,175],57:[2,175],73:[2,175],78:[2,175],86:[2,175],91:[2,175],93:[2,175],102:[2,175],104:[2,175],105:[2,175],106:[2,175],110:[2,175],118:[2,175],126:[2,175],128:[2,175],129:[2,175],132:[2,175],133:[2,175],134:[2,175],135:[2,175],136:[2,175],137:[2,175]},{26:[2,179],121:[2,179],123:[2,179]},{25:[2,131],54:[2,131],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{6:[1,270],25:[1,271],26:[1,326]},{7:327,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:328,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[1,281],25:[1,282],26:[1,329]},{6:[2,40],25:[2,40],26:[2,40],54:[2,40],78:[2,40]},{6:[2,58],25:[2,58],26:[2,58],49:[2,58],54:[2,58]},{1:[2,173],6:[2,173],25:[2,173],26:[2,173],49:[2,173],54:[2,173],57:[2,173],73:[2,173],78:[2,173],86:[2,173],91:[2,173],93:[2,173],102:[2,173],104:[2,173],105:[2,173],106:[2,173],110:[2,173],118:[2,173],126:[2,173],128:[2,173],129:[2,173],132:[2,173],133:[2,173],134:[2,173],135:[2,173],136:[2,173],137:[2,173]},{6:[2,127],25:[2,127],26:[2,127],54:[2,127],86:[2,127],91:[2,127]},{1:[2,170],6:[2,170],25:[2,170],26:[2,170],49:[2,170],54:[2,170],57:[2,170],73:[2,170],78:[2,170],86:[2,170],91:[2,170],93:[2,170],102:[2,170],103:82,104:[2,170],105:[2,170],106:[2,170],109:83,110:[2,170],111:67,118:[2,170],126:[2,170],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,171],6:[2,171],25:[2,171],26:[2,171],49:[2,171],54:[2,171],57:[2,171],73:[2,171],78:[2,171],86:[2,171],91:[2,171],93:[2,171],102:[2,171],103:82,104:[2,171],105:[2,171],106:[2,171],109:83,110:[2,171],111:67,118:[2,171],126:[2,171],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{6:[2,94],25:[2,94],26:[2,94],54:[2,94],78:[2,94]}], +defaultActions: {58:[2,50],59:[2,51],89:[2,108],186:[2,88]}, +parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + // ace_mod + var e = new Error(str) + e.location = hash.loc + throw e; + } +}, +parse: function parse(input) { + var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; + this.lexer.setInput(input); + this.lexer.yy = this.yy; + this.yy.lexer = this.lexer; + this.yy.parser = this; + if (typeof this.lexer.yylloc == 'undefined') { + this.lexer.yylloc = {}; + } + var yyloc = this.lexer.yylloc; + lstack.push(yyloc); + var ranges = this.lexer.options && this.lexer.options.ranges; + if (typeof this.yy.parseError === 'function') { + this.parseError = this.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function popStack(n) { + stack.length = stack.length - 2 * n; + vstack.length = vstack.length - n; + lstack.length = lstack.length - n; + } + function lex() { + var token; + token = self.lexer.lex() || EOF; + if (typeof token !== 'number') { + token = self.symbols_[token] || token; + } + return token; + } + var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == 'undefined') { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === 'undefined' || !action.length || !action[0]) { + var errStr = ''; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push('\'' + this.terminals_[p] + '\''); + } + } + if (this.lexer.showPosition) { + errStr = 'Expecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; + } else { + errStr = 'Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); + } + // ace_mod + if (this.lexer.yylloc.first_line !== yyloc.first_line) yyloc = this.lexer.yylloc; + this.parseError(errStr, { + text: this.lexer.match, + token: this.terminals_[symbol] || symbol, + line: this.lexer.yylineno, + loc: yyloc, + expected: expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(this.lexer.yytext); + lstack.push(this.lexer.yylloc); + stack.push(action[1]); + symbol = null; + if (!preErrorSymbol) { + yyleng = this.lexer.yyleng; + yytext = this.lexer.yytext; + yylineno = this.lexer.yylineno; + yyloc = this.lexer.yylloc; + if (recovering > 0) { + recovering--; + } + } else { + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack); + if (typeof r !== 'undefined') { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; +}}; +undefined +function Parser () { + this.yy = {}; +} +Parser.prototype = parser;parser.Parser = Parser; + +module.exports = new 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 new file mode 100644 index 00000000..001262b6 --- /dev/null +++ b/lib/ace/mode/coffee/parser_test.js @@ -0,0 +1,88 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { +"use strict"; + +var assert = require("../../test/assertions"); +var coffee = require("../coffee/coffee-script"); + +function assertLocation(e, sl, sc, el, ec) { + assert.equal(e.location.first_line, sl); + assert.equal(e.location.first_column, sc); + assert.equal(e.location.last_line, el); + assert.equal(e.location.last_column, ec); +} + +function parse(str) { + try { + coffee.parse(str).compile(); + } catch (e) { + return e; + } +} + +module.exports = { + "test parse valid coffee script": function() { + coffee.parse("square = (x) -> x * x"); + }, + + "test parse invalid coffee script": function() { + var e = parse("a = 12 f"); + assert.equal(e.message, "Unexpected 'IDENTIFIER'"); + assertLocation(e, 0, 4, 0, 5); + }, + + "test parse missing bracket": function() { + var e = parse("a = 12 f {\n\n"); + assert.equal(e.message, "missing }"); + assertLocation(e, 0, 10, 0, 10); + }, + "test unexpected indent": function() { + var e = parse("a\n a\n"); + assert.equal(e.message, "Unexpected 'INDENT'"); + assertLocation(e, 1, 0, 1, 1); + }, + "test invalid destructuring": function() { + var e = parse("\n{b: 5} = {}"); + assert.equal(e.message, '"5" cannot be assigned'); + assertLocation(e, 1, 4, 1, 4); + } +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec(); +} diff --git a/lib/ace/mode/coffee/rewriter.js b/lib/ace/mode/coffee/rewriter.js new file mode 100644 index 00000000..acb5c420 --- /dev/null +++ b/lib/ace/mode/coffee/rewriter.js @@ -0,0 +1,516 @@ +/** + * Copyright (c) 2009-2013 Jeremy Ashkenas + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +define(function(require, exports, module) { +// Generated by CoffeeScript 1.6.3 + + var BALANCED_PAIRS, CALL_CLOSERS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, generate, left, rite, _i, _len, _ref, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, + __slice = [].slice; + + generate = function(tag, value) { + var tok; + tok = [tag, value]; + tok.generated = true; + return tok; + }; + + exports.Rewriter = (function() { + function Rewriter() {} + + Rewriter.prototype.rewrite = function(tokens) { + this.tokens = tokens; + this.removeLeadingNewlines(); + this.closeOpenCalls(); + this.closeOpenIndexes(); + this.normalizeLines(); + this.tagPostfixConditionals(); + this.addImplicitBracesAndParens(); + this.addLocationDataToGeneratedTokens(); + return this.tokens; + }; + + Rewriter.prototype.scanTokens = function(block) { + var i, token, tokens; + tokens = this.tokens; + i = 0; + while (token = tokens[i]) { + i += block.call(this, token, i, tokens); + } + return true; + }; + + Rewriter.prototype.detectEnd = function(i, condition, action) { + var levels, token, tokens, _ref, _ref1; + tokens = this.tokens; + levels = 0; + while (token = tokens[i]) { + if (levels === 0 && condition.call(this, token, i)) { + return action.call(this, token, i); + } + if (!token || levels < 0) { + return action.call(this, token, i - 1); + } + if (_ref = token[0], __indexOf.call(EXPRESSION_START, _ref) >= 0) { + levels += 1; + } else if (_ref1 = token[0], __indexOf.call(EXPRESSION_END, _ref1) >= 0) { + levels -= 1; + } + i += 1; + } + return i - 1; + }; + + Rewriter.prototype.removeLeadingNewlines = function() { + var i, tag, _i, _len, _ref; + _ref = this.tokens; + for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { + tag = _ref[i][0]; + if (tag !== 'TERMINATOR') { + break; + } + } + if (i) { + return this.tokens.splice(0, i); + } + }; + + Rewriter.prototype.closeOpenCalls = function() { + var action, condition; + condition = function(token, i) { + var _ref; + return ((_ref = token[0]) === ')' || _ref === 'CALL_END') || token[0] === 'OUTDENT' && this.tag(i - 1) === ')'; + }; + action = function(token, i) { + return this.tokens[token[0] === 'OUTDENT' ? i - 1 : i][0] = 'CALL_END'; + }; + return this.scanTokens(function(token, i) { + if (token[0] === 'CALL_START') { + this.detectEnd(i + 1, condition, action); + } + return 1; + }); + }; + + Rewriter.prototype.closeOpenIndexes = function() { + var action, condition; + condition = function(token, i) { + var _ref; + return (_ref = token[0]) === ']' || _ref === 'INDEX_END'; + }; + action = function(token, i) { + return token[0] = 'INDEX_END'; + }; + return this.scanTokens(function(token, i) { + if (token[0] === 'INDEX_START') { + this.detectEnd(i + 1, condition, action); + } + return 1; + }); + }; + + Rewriter.prototype.matchTags = function() { + var fuzz, i, j, pattern, _i, _ref, _ref1; + i = arguments[0], pattern = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + fuzz = 0; + for (j = _i = 0, _ref = pattern.length; 0 <= _ref ? _i < _ref : _i > _ref; j = 0 <= _ref ? ++_i : --_i) { + while (this.tag(i + j + fuzz) === 'HERECOMMENT') { + fuzz += 2; + } + if (pattern[j] == null) { + continue; + } + if (typeof pattern[j] === 'string') { + pattern[j] = [pattern[j]]; + } + if (_ref1 = this.tag(i + j + fuzz), __indexOf.call(pattern[j], _ref1) < 0) { + return false; + } + } + return true; + }; + + Rewriter.prototype.looksObjectish = function(j) { + return this.matchTags(j, '@', null, ':') || this.matchTags(j, null, ':'); + }; + + Rewriter.prototype.findTagsBackwards = function(i, tags) { + var backStack, _ref, _ref1, _ref2, _ref3, _ref4, _ref5; + backStack = []; + while (i >= 0 && (backStack.length || (_ref2 = this.tag(i), __indexOf.call(tags, _ref2) < 0) && ((_ref3 = this.tag(i), __indexOf.call(EXPRESSION_START, _ref3) < 0) || this.tokens[i].generated) && (_ref4 = this.tag(i), __indexOf.call(LINEBREAKS, _ref4) < 0))) { + if (_ref = this.tag(i), __indexOf.call(EXPRESSION_END, _ref) >= 0) { + backStack.push(this.tag(i)); + } + if ((_ref1 = this.tag(i), __indexOf.call(EXPRESSION_START, _ref1) >= 0) && backStack.length) { + backStack.pop(); + } + i -= 1; + } + return _ref5 = this.tag(i), __indexOf.call(tags, _ref5) >= 0; + }; + + Rewriter.prototype.addImplicitBracesAndParens = function() { + var stack; + stack = []; + return this.scanTokens(function(token, i, tokens) { + var endAllImplicitCalls, endImplicitCall, endImplicitObject, forward, inImplicit, inImplicitCall, inImplicitControl, inImplicitObject, nextTag, offset, prevTag, prevToken, s, sameLine, stackIdx, stackTag, stackTop, startIdx, startImplicitCall, startImplicitObject, startsLine, tag, _ref, _ref1, _ref2, _ref3, _ref4, _ref5; + tag = token[0]; + prevTag = (prevToken = i > 0 ? tokens[i - 1] : [])[0]; + nextTag = (i < tokens.length - 1 ? tokens[i + 1] : [])[0]; + stackTop = function() { + return stack[stack.length - 1]; + }; + startIdx = i; + forward = function(n) { + return i - startIdx + n; + }; + inImplicit = function() { + var _ref, _ref1; + return (_ref = stackTop()) != null ? (_ref1 = _ref[2]) != null ? _ref1.ours : void 0 : void 0; + }; + inImplicitCall = function() { + var _ref; + return inImplicit() && ((_ref = stackTop()) != null ? _ref[0] : void 0) === '('; + }; + inImplicitObject = function() { + var _ref; + return inImplicit() && ((_ref = stackTop()) != null ? _ref[0] : void 0) === '{'; + }; + inImplicitControl = function() { + var _ref; + return inImplicit && ((_ref = stackTop()) != null ? _ref[0] : void 0) === 'CONTROL'; + }; + startImplicitCall = function(j) { + var idx; + idx = j != null ? j : i; + stack.push([ + '(', idx, { + ours: true + } + ]); + tokens.splice(idx, 0, generate('CALL_START', '(')); + if (j == null) { + return i += 1; + } + }; + endImplicitCall = function() { + stack.pop(); + tokens.splice(i, 0, generate('CALL_END', ')')); + return i += 1; + }; + endAllImplicitCalls = function() { + while (inImplicitCall()) { + endImplicitCall(); + } + }; + startImplicitObject = function(j, startsLine) { + var idx; + if (startsLine == null) { + startsLine = true; + } + idx = j != null ? j : i; + stack.push([ + '{', idx, { + sameLine: true, + startsLine: startsLine, + ours: true + } + ]); + tokens.splice(idx, 0, generate('{', generate(new String('{')))); + if (j == null) { + return i += 1; + } + }; + endImplicitObject = function(j) { + j = j != null ? j : i; + stack.pop(); + tokens.splice(j, 0, generate('}', '}')); + return i += 1; + }; + if (inImplicitCall() && (tag === 'IF' || tag === 'TRY' || tag === 'FINALLY' || tag === 'CATCH' || tag === 'CLASS' || tag === 'SWITCH')) { + stack.push([ + 'CONTROL', i, { + ours: true + } + ]); + return forward(1); + } + if (tag === 'INDENT' && inImplicit()) { + if (prevTag !== '=>' && prevTag !== '->' && prevTag !== '[' && prevTag !== '(' && prevTag !== ',' && prevTag !== '{' && prevTag !== 'TRY' && prevTag !== 'ELSE' && prevTag !== '=') { + while (inImplicitCall()) { + endImplicitCall(); + } + } + if (inImplicitControl()) { + stack.pop(); + } + stack.push([tag, i]); + return forward(1); + } + if (__indexOf.call(EXPRESSION_START, tag) >= 0) { + stack.push([tag, i]); + return forward(1); + } + if (__indexOf.call(EXPRESSION_END, tag) >= 0) { + while (inImplicit()) { + if (inImplicitCall()) { + endImplicitCall(); + } else if (inImplicitObject()) { + endImplicitObject(); + } else { + stack.pop(); + } + } + stack.pop(); + } + if ((__indexOf.call(IMPLICIT_FUNC, tag) >= 0 && token.spaced && !token.stringEnd || tag === '?' && i > 0 && !tokens[i - 1].spaced) && (__indexOf.call(IMPLICIT_CALL, nextTag) >= 0 || __indexOf.call(IMPLICIT_UNSPACED_CALL, nextTag) >= 0 && !((_ref = tokens[i + 1]) != null ? _ref.spaced : void 0) && !((_ref1 = tokens[i + 1]) != null ? _ref1.newLine : void 0))) { + if (tag === '?') { + tag = token[0] = 'FUNC_EXIST'; + } + startImplicitCall(i + 1); + return forward(2); + } + if (__indexOf.call(IMPLICIT_FUNC, tag) >= 0 && this.matchTags(i + 1, 'INDENT', null, ':') && !this.findTagsBackwards(i, ['CLASS', 'EXTENDS', 'IF', 'CATCH', 'SWITCH', 'LEADING_WHEN', 'FOR', 'WHILE', 'UNTIL'])) { + startImplicitCall(i + 1); + stack.push(['INDENT', i + 2]); + return forward(3); + } + if (tag === ':') { + if (this.tag(i - 2) === '@') { + s = i - 2; + } else { + s = i - 1; + } + while (this.tag(s - 2) === 'HERECOMMENT') { + s -= 2; + } + startsLine = s === 0 || (_ref2 = this.tag(s - 1), __indexOf.call(LINEBREAKS, _ref2) >= 0) || tokens[s - 1].newLine; + if (stackTop()) { + _ref3 = stackTop(), stackTag = _ref3[0], stackIdx = _ref3[1]; + if ((stackTag === '{' || stackTag === 'INDENT' && this.tag(stackIdx - 1) === '{') && (startsLine || this.tag(s - 1) === ',' || this.tag(s - 1) === '{')) { + return forward(1); + } + } + startImplicitObject(s, !!startsLine); + return forward(2); + } + if (inImplicitCall() && __indexOf.call(CALL_CLOSERS, tag) >= 0) { + if (prevTag === 'OUTDENT') { + endImplicitCall(); + return forward(1); + } + if (prevToken.newLine) { + endAllImplicitCalls(); + return forward(1); + } + } + if (inImplicitObject() && __indexOf.call(LINEBREAKS, tag) >= 0) { + stackTop()[2].sameLine = false; + } + if (__indexOf.call(IMPLICIT_END, tag) >= 0) { + while (inImplicit()) { + _ref4 = stackTop(), stackTag = _ref4[0], stackIdx = _ref4[1], (_ref5 = _ref4[2], sameLine = _ref5.sameLine, startsLine = _ref5.startsLine); + if (inImplicitCall() && prevTag !== ',') { + endImplicitCall(); + } else if (inImplicitObject() && sameLine && !startsLine) { + endImplicitObject(); + } else if (inImplicitObject() && tag === 'TERMINATOR' && prevTag !== ',' && !(startsLine && this.looksObjectish(i + 1))) { + endImplicitObject(); + } else { + break; + } + } + } + if (tag === ',' && !this.looksObjectish(i + 1) && inImplicitObject() && (nextTag !== 'TERMINATOR' || !this.looksObjectish(i + 2))) { + offset = nextTag === 'OUTDENT' ? 1 : 0; + while (inImplicitObject()) { + endImplicitObject(i + offset); + } + } + return forward(1); + }); + }; + + Rewriter.prototype.addLocationDataToGeneratedTokens = function() { + return this.scanTokens(function(token, i, tokens) { + var column, line, nextLocation, prevLocation, _ref, _ref1; + if (token[2]) { + return 1; + } + if (!(token.generated || token.explicit)) { + return 1; + } + if (token[0] === '{' && (nextLocation = (_ref = tokens[i + 1]) != null ? _ref[2] : void 0)) { + line = nextLocation.first_line, column = nextLocation.first_column; + } else if (prevLocation = (_ref1 = tokens[i - 1]) != null ? _ref1[2] : void 0) { + line = prevLocation.last_line, column = prevLocation.last_column; + } else { + line = column = 0; + } + token[2] = { + first_line: line, + first_column: column, + last_line: line, + last_column: column + }; + return 1; + }); + }; + + Rewriter.prototype.normalizeLines = function() { + var action, condition, indent, outdent, starter; + starter = indent = outdent = null; + condition = function(token, i) { + var _ref, _ref1, _ref2, _ref3; + return token[1] !== ';' && (_ref = token[0], __indexOf.call(SINGLE_CLOSERS, _ref) >= 0) && !(token[0] === 'TERMINATOR' && (_ref1 = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref1) >= 0)) && !(token[0] === 'ELSE' && starter !== 'THEN') && !(((_ref2 = token[0]) === 'CATCH' || _ref2 === 'FINALLY') && (starter === '->' || starter === '=>')) || (_ref3 = token[0], __indexOf.call(CALL_CLOSERS, _ref3) >= 0) && this.tokens[i - 1].newLine; + }; + action = function(token, i) { + return this.tokens.splice((this.tag(i - 1) === ',' ? i - 1 : i), 0, outdent); + }; + return this.scanTokens(function(token, i, tokens) { + var j, tag, _i, _ref, _ref1, _ref2; + tag = token[0]; + if (tag === 'TERMINATOR') { + if (this.tag(i + 1) === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') { + tokens.splice.apply(tokens, [i, 1].concat(__slice.call(this.indentation()))); + return 1; + } + if (_ref = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref) >= 0) { + tokens.splice(i, 1); + return 0; + } + } + if (tag === 'CATCH') { + for (j = _i = 1; _i <= 2; j = ++_i) { + if (!((_ref1 = this.tag(i + j)) === 'OUTDENT' || _ref1 === 'TERMINATOR' || _ref1 === 'FINALLY')) { + continue; + } + tokens.splice.apply(tokens, [i + j, 0].concat(__slice.call(this.indentation()))); + return 2 + j; + } + } + if (__indexOf.call(SINGLE_LINERS, tag) >= 0 && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) { + starter = tag; + _ref2 = this.indentation(true), indent = _ref2[0], outdent = _ref2[1]; + if (starter === 'THEN') { + indent.fromThen = true; + } + tokens.splice(i + 1, 0, indent); + this.detectEnd(i + 2, condition, action); + if (tag === 'THEN') { + tokens.splice(i, 1); + } + return 1; + } + return 1; + }); + }; + + Rewriter.prototype.tagPostfixConditionals = function() { + var action, condition, original; + original = null; + condition = function(token, i) { + var prevTag, tag; + tag = token[0]; + prevTag = this.tokens[i - 1][0]; + return tag === 'TERMINATOR' || (tag === 'INDENT' && __indexOf.call(SINGLE_LINERS, prevTag) < 0); + }; + action = function(token, i) { + if (token[0] !== 'INDENT' || (token.generated && !token.fromThen)) { + return original[0] = 'POST_' + original[0]; + } + }; + return this.scanTokens(function(token, i) { + if (token[0] !== 'IF') { + return 1; + } + original = token; + this.detectEnd(i + 1, condition, action); + return 1; + }); + }; + + Rewriter.prototype.indentation = function(implicit) { + var indent, outdent; + if (implicit == null) { + implicit = false; + } + indent = ['INDENT', 2]; + outdent = ['OUTDENT', 2]; + if (implicit) { + indent.generated = outdent.generated = true; + } + if (!implicit) { + indent.explicit = outdent.explicit = true; + } + return [indent, outdent]; + }; + + Rewriter.prototype.generate = generate; + + Rewriter.prototype.tag = function(i) { + var _ref; + return (_ref = this.tokens[i]) != null ? _ref[0] : void 0; + }; + + return Rewriter; + + })(); + + BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['CALL_START', 'CALL_END'], ['PARAM_START', 'PARAM_END'], ['INDEX_START', 'INDEX_END']]; + + exports.INVERSES = INVERSES = {}; + + EXPRESSION_START = []; + + EXPRESSION_END = []; + + for (_i = 0, _len = BALANCED_PAIRS.length; _i < _len; _i++) { + _ref = BALANCED_PAIRS[_i], left = _ref[0], rite = _ref[1]; + EXPRESSION_START.push(INVERSES[rite] = left); + EXPRESSION_END.push(INVERSES[left] = rite); + } + + EXPRESSION_CLOSE = ['CATCH', 'THEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END); + + IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS']; + + IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++']; + + IMPLICIT_UNSPACED_CALL = ['+', '-']; + + IMPLICIT_END = ['POST_IF', 'FOR', 'WHILE', 'UNTIL', 'WHEN', 'BY', 'LOOP', 'TERMINATOR']; + + SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN']; + + SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN']; + + LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT']; + + CALL_CLOSERS = ['.', '?.', '::', '?::']; + + +}); \ No newline at end of file diff --git a/lib/ace/mode/coffee/scope.js b/lib/ace/mode/coffee/scope.js new file mode 100644 index 00000000..5834963b --- /dev/null +++ b/lib/ace/mode/coffee/scope.js @@ -0,0 +1,174 @@ +/** + * Copyright (c) 2009-2013 Jeremy Ashkenas + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +define(function(require, exports, module) { +// Generated by CoffeeScript 1.6.3 + + var Scope, extend, last, _ref; + + _ref = require('./helpers'), extend = _ref.extend, last = _ref.last; + + exports.Scope = Scope = (function() { + Scope.root = null; + + function Scope(parent, expressions, method) { + this.parent = parent; + this.expressions = expressions; + this.method = method; + this.variables = [ + { + name: 'arguments', + type: 'arguments' + } + ]; + this.positions = {}; + if (!this.parent) { + Scope.root = this; + } + } + + Scope.prototype.add = function(name, type, immediate) { + if (this.shared && !immediate) { + return this.parent.add(name, type, immediate); + } + if (Object.prototype.hasOwnProperty.call(this.positions, name)) { + return this.variables[this.positions[name]].type = type; + } else { + return this.positions[name] = this.variables.push({ + name: name, + type: type + }) - 1; + } + }; + + Scope.prototype.namedMethod = function() { + var _ref1; + if (((_ref1 = this.method) != null ? _ref1.name : void 0) || !this.parent) { + return this.method; + } + return this.parent.namedMethod(); + }; + + Scope.prototype.find = function(name) { + if (this.check(name)) { + return true; + } + this.add(name, 'var'); + return false; + }; + + Scope.prototype.parameter = function(name) { + if (this.shared && this.parent.check(name, true)) { + return; + } + return this.add(name, 'param'); + }; + + Scope.prototype.check = function(name) { + var _ref1; + return !!(this.type(name) || ((_ref1 = this.parent) != null ? _ref1.check(name) : void 0)); + }; + + Scope.prototype.temporary = function(name, index) { + if (name.length > 1) { + return '_' + name + (index > 1 ? index - 1 : ''); + } else { + return '_' + (index + parseInt(name, 36)).toString(36).replace(/\d/g, 'a'); + } + }; + + Scope.prototype.type = function(name) { + var v, _i, _len, _ref1; + _ref1 = this.variables; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + v = _ref1[_i]; + if (v.name === name) { + return v.type; + } + } + return null; + }; + + Scope.prototype.freeVariable = function(name, reserve) { + var index, temp; + if (reserve == null) { + reserve = true; + } + index = 0; + while (this.check((temp = this.temporary(name, index)))) { + index++; + } + if (reserve) { + this.add(temp, 'var', true); + } + return temp; + }; + + Scope.prototype.assign = function(name, value) { + this.add(name, { + value: value, + assigned: true + }, true); + return this.hasAssignments = true; + }; + + Scope.prototype.hasDeclarations = function() { + return !!this.declaredVariables().length; + }; + + Scope.prototype.declaredVariables = function() { + var realVars, tempVars, v, _i, _len, _ref1; + realVars = []; + tempVars = []; + _ref1 = this.variables; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + v = _ref1[_i]; + if (v.type === 'var') { + (v.name.charAt(0) === '_' ? tempVars : realVars).push(v.name); + } + } + return realVars.sort().concat(tempVars.sort()); + }; + + Scope.prototype.assignedVariables = function() { + var v, _i, _len, _ref1, _results; + _ref1 = this.variables; + _results = []; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + v = _ref1[_i]; + if (v.type.assigned) { + _results.push("" + v.name + " = " + v.type.value); + } + } + return _results; + }; + + return Scope; + + })(); + + +}); \ No newline at end of file diff --git a/lib/ace/mode/coffee_highlight_rules.js b/lib/ace/mode/coffee_highlight_rules.js index c28fd8f9..94c9476f 100644 --- a/lib/ace/mode/coffee_highlight_rules.js +++ b/lib/ace/mode/coffee_highlight_rules.js @@ -1,182 +1,233 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Satoshi Murakami - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -require("pilot/oop").inherits( - CoffeeHighlightRules, - require("ace/mode/text_highlight_rules").TextHighlightRules); + var oop = require("../lib/oop"); + var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; -function CoffeeHighlightRules() { -var identifier = "[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*" - , keywordend = "(?![$\\w]|\\s*:)" - , stringfill = {token: "string", regex: ".+"} -; -this.$rules = - { start: - [ { token: "identifier" - , regex: "(?:@|(?:\\.|::)\\s*)" + identifier - } - , { token: "keyword" - , regex: "(?:t(?:h(?:is|row|en)|ry|ypeof)|s(?:uper|witch)|return|b(?:reak|y)|c(?:ontinue|atch|lass)|i(?:n(?:stanceof)?|s(?:nt)?|f)|e(?:lse|xtends)|f(?:or (?:own)?|inally|unction)|wh(?:ile|en)|n(?:ew|ot?)|d(?:e(?:lete|bugger)|o)|loop|o(?:ff?|[rn])|un(?:less|til)|and|yes)" + keywordend - } - , { token: "constant.language" - , regex: "(?:true|false|null|undefined)" + keywordend - } - , { token: "invalid.illegal" - , regex: "(?:c(?:ase|onst)|default|function|v(?:ar|oid)|with|e(?:num|xport)|i(?:mplements|nterface)|let|p(?:ackage|r(?:ivate|otected)|ublic)|static|yield|__(?:hasProp|extends|slice|bind|indexOf))" + keywordend - } - , { token: "language.support.class" - , regex: "(?:Array|Boolean|Date|Function|Number|Object|R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|TypeError|URIError)" + keywordend - } - , { token: "language.support.function" - , regex: "(?:Math|JSON|is(?:NaN|Finite)|parse(?:Int|Float)|encodeURI(?:Component)?|decodeURI(?:Component)?)" + keywordend - } - , { token: "identifier" - , regex: identifier - } - , { token: "constant.numeric" - , regex: "(?:0x[\\da-fA-F]+|(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:[eE][+-]?\\d+)?)" - } - , { token: "string" - , regex: "'''" - , next : "qdoc" - } - , { token: "string" - , regex: '"""' - , next : "qqdoc" - } - , { token: "string" - , regex: "'" - , next : "qstring" - } - , { token: "string" - , regex: '"' - , next : "qqstring" - } - , { token: "string" - , regex: "`" - , next : "js" - } - , { token: "string.regex" - , regex: "///" - , next : "heregex" - } - , { token: "string.regex" - , regex: "/(?!\\s)[^[/\\n\\\\]*(?: (?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[/\\n\\\\]*)*/[imgy]{0,4}(?!\\w)" - } - , { token: "comment" - , regex: "###(?!#)" - , next : "comment" - } - , { token: "comment" - , regex: "#.*" - } - , { token: "lparen" - , regex: "[({[]" - } - , { token: "rparen" - , regex: "[\\]})]" - } - , { token: "keyword.operator" - , regex: "\\S+" - } - , { token: "text" - , regex: "\\s+" - } - ] - , qdoc: - [ { token: "string" - , regex: ".*?'''" - , next : "start" - } - , stringfill - ] - , qqdoc: - [ { token: "string" - , regex: '.*?"""' - , next : "start" - } - , stringfill - ] - , qstring: - [ { token: "string" - , regex: "[^\\\\']*(?:\\\\.[^\\\\']*)*'" - , next : "start" - } - , stringfill - ] - , qqstring: - [ { token: "string" - , regex: '[^\\\\"]*(?:\\\\.[^\\\\"]*)*"' - , next : "start" - } - , stringfill - ] - , js: - [ { token: "string" - , regex: "[^\\\\`]*(?:\\\\.[^\\\\`]*)*`" - , next : "start" - } - , stringfill - ] - , heregex: - [ { token: "string.regex" - , regex: '.*?///[imgy]{0,4}' - , next : "start" - } - , { token: "comment.regex" - , regex: "\\s+(?:#.*)?" - } - , { token: "string.regex" - , regex: "\\S+" - } - ] - , comment: - [ { token: "comment" - , regex: '.*?###' - , next : "start" - } - , { token: "comment" - , regex: ".+" - } - ] - }; -} + oop.inherits(CoffeeHighlightRules, TextHighlightRules); -exports.CoffeeHighlightRules = CoffeeHighlightRules; + function CoffeeHighlightRules() { + var identifier = "[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*"; + + var keywords = ( + "this|throw|then|try|typeof|super|switch|return|break|by|continue|" + + "catch|class|in|instanceof|is|isnt|if|else|extends|for|own|" + + "finally|function|while|when|new|no|not|delete|debugger|do|loop|of|off|" + + "or|on|unless|until|and|yes" + ); + + var langConstant = ( + "true|false|null|undefined|NaN|Infinity" + ); + + var illegal = ( + "case|const|default|function|var|void|with|enum|export|implements|" + + "interface|let|package|private|protected|public|static|yield|" + + "__hasProp|slice|bind|indexOf" + ); + + var supportClass = ( + "Array|Boolean|Date|Function|Number|Object|RegExp|ReferenceError|String|" + + "Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|" + + "SyntaxError|TypeError|URIError|" + + "ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|" + + "Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray" + ); + + var supportFunction = ( + "Math|JSON|isNaN|isFinite|parseInt|parseFloat|encodeURI|" + + "encodeURIComponent|decodeURI|decodeURIComponent|String|" + ); + + var variableLanguage = ( + "window|arguments|prototype|document" + ); + + var keywordMapper = this.createKeywordMapper({ + "keyword": keywords, + "constant.language": langConstant, + "invalid.illegal": illegal, + "language.support.class": supportClass, + "language.support.function": supportFunction, + "variable.language": variableLanguage + }, "identifier"); + + var functionRule = { + token: ["paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type"], + regex: /(?:(\()((?:"[^")]*?"|'[^')]*?'|\/[^\/)]*?\/|[^()\"'\/])*?)(\))(\s*))?([\-=]>)/.source + }; + + var stringEscape = /\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)/; + + this.$rules = { + start : [ + { + token : "constant.numeric", + regex : "(?:0x[\\da-fA-F]+|(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:[eE][+-]?\\d+)?)" + }, { + stateName: "qdoc", + token : "string", regex : "'''", next : [ + {token : "string", regex : "'''", next : "start"}, + {token : "constant.language.escape", regex : stringEscape}, + {defaultToken: "string"} + ] + }, { + stateName: "qqdoc", + token : "string", + regex : '"""', + next : [ + {token : "string", regex : '"""', next : "start"}, + {token : "paren.string", regex : '#{', push : "start"}, + {token : "constant.language.escape", regex : stringEscape}, + {defaultToken: "string"} + ] + }, { + stateName: "qstring", + token : "string", regex : "'", next : [ + {token : "string", regex : "'", next : "start"}, + {token : "constant.language.escape", regex : stringEscape}, + {defaultToken: "string"} + ] + }, { + stateName: "qqstring", + token : "string.start", regex : '"', next : [ + {token : "string.end", regex : '"', next : "start"}, + {token : "paren.string", regex : '#{', push : "start"}, + {token : "constant.language.escape", regex : stringEscape}, + {defaultToken: "string"} + ] + }, { + stateName: "js", + token : "string", regex : "`", next : [ + {token : "string", regex : "`", next : "start"}, + {token : "constant.language.escape", regex : stringEscape}, + {defaultToken: "string"} + ] + }, { + regex: "[{}]", onMatch: function(val, state, stack) { + this.next = ""; + if (val == "{" && stack.length) { + stack.unshift("start", state); + return "paren"; + } + if (val == "}" && stack.length) { + stack.shift(); + this.next = stack.shift() || ""; + if (this.next.indexOf("string") != -1) + return "paren.string"; + } + return "paren"; + } + }, { + token : "string.regex", + regex : "///", + next : "heregex" + }, { + token : "string.regex", + regex : /(?:\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)(?:[imgy]{0,4})(?!\w)/ + }, { + token : "comment", + regex : "###(?!#)", + next : "comment" + }, { + token : "comment", + regex : "#.*" + }, { + token : ["punctuation.operator", "text", "identifier"], + regex : "(\\.)(\\s*)(" + illegal + ")" + }, { + token : "punctuation.operator", + regex : "\\." + }, { + //class A extends B + token : ["keyword", "text", "language.support.class", + "text", "keyword", "text", "language.support.class"], + regex : "(class)(\\s+)(" + identifier + ")(?:(\\s+)(extends)(\\s+)(" + identifier + "))?" + }, { + //play = (...) -> + token : ["entity.name.function", "text", "keyword.operator", "text"].concat(functionRule.token), + regex : "(" + identifier + ")(\\s*)([=:])(\\s*)" + functionRule.regex + }, + functionRule, + { + token : "variable", + regex : "@(?:" + identifier + ")?" + }, { + token: keywordMapper, + regex : identifier + }, { + token : "punctuation.operator", + regex : "\\,|\\." + }, { + token : "storage.type", + regex : "[\\-=]>" + }, { + token : "keyword.operator", + regex : "(?:[-+*/%<>&|^!?=]=|>>>=?|\\-\\-|\\+\\+|::|&&=|\\|\\|=|<<=|>>=|\\?\\.|\\.{2,3}|[!*+-=><])" + }, { + token : "paren.lparen", + regex : "[({[]" + }, { + token : "paren.rparen", + regex : "[\\]})]" + }, { + token : "text", + regex : "\\s+" + }], + + + heregex : [{ + token : "string.regex", + regex : '.*?///[imgy]{0,4}', + next : "start" + }, { + token : "comment.regex", + regex : "\\s+(?:#.*)?" + }, { + token : "string.regex", + regex : "\\S+" + }], + + comment : [{ + token : "comment", + regex : '###', + next : "start" + }, { + defaultToken : "comment" + }] + }; + this.normalizeRules(); + } + + exports.CoffeeHighlightRules = CoffeeHighlightRules; }); diff --git a/lib/ace/mode/coffee_worker.js b/lib/ace/mode/coffee_worker.js new file mode 100644 index 00000000..d68f1296 --- /dev/null +++ b/lib/ace/mode/coffee_worker.js @@ -0,0 +1,73 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var Mirror = require("../worker/mirror").Mirror; +var coffee = require("../mode/coffee/coffee-script"); + +window.addEventListener = function() {}; + + +var Worker = exports.Worker = function(sender) { + Mirror.call(this, sender); + this.setTimeout(250); +}; + +oop.inherits(Worker, Mirror); + +(function() { + + this.onUpdate = function() { + var value = this.doc.getValue(); + var errors = []; + try { + coffee.parse(value).compile(); + } catch(e) { + var loc = e.location; + if (loc) { + errors.push({ + row: loc.first_line, + column: loc.first_column, + endRow: loc.last_line, + endColumn: loc.last_column, + text: e.message, + type: "error" + }); + } + } + this.sender.emit("annotate", errors); + }; + +}).call(Worker.prototype); + +}); diff --git a/lib/ace/mode/coldfusion.js b/lib/ace/mode/coldfusion.js new file mode 100644 index 00000000..0b4ea449 --- /dev/null +++ b/lib/ace/mode/coldfusion.js @@ -0,0 +1,61 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var lang = require("../lib/lang"); +var HtmlMode = require("./html").Mode; +var ColdfusionHighlightRules = require("./coldfusion_highlight_rules").ColdfusionHighlightRules; + +var voidElements = "cfabort|cfapplication|cfargument|cfassociate|cfbreak|cfcache|cfcollection|cfcookie|cfdbinfo|cfdirectory|cfdump|cfelse|cfelseif|cferror|cfexchangecalendar|cfexchangeconnection|cfexchangecontact|cfexchangefilter|cfexchangetask|cfexit|cffeed|cffile|cfflush|cfftp|cfheader|cfhtmlhead|cfhttpparam|cfimage|cfimport|cfinclude|cfindex|cfinsert|cfinvokeargument|cflocation|cflog|cfmailparam|cfNTauthenticate|cfobject|cfobjectcache|cfparam|cfpdfformparam|cfprint|cfprocparam|cfprocresult|cfproperty|cfqueryparam|cfregistry|cfreportparam|cfrethrow|cfreturn|cfschedule|cfsearch|cfset|cfsetting|cfthrow|cfzipparam)".split("|"); + +var Mode = function() { + HtmlMode.call(this); + + this.HighlightRules = ColdfusionHighlightRules; +}; +oop.inherits(Mode, HtmlMode); + +(function() { + + // mix with html void elements + this.voidElements = oop.mixin(lang.arrayToMap(voidElements), this.voidElements); + + this.getNextLineIndent = function(state, line, tab) { + return this.$getIndent(line); + }; + + this.$id = "ace/mode/coldfusion"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); diff --git a/lib/ace/mode/coldfusion_highlight_rules.js b/lib/ace/mode/coldfusion_highlight_rules.js new file mode 100644 index 00000000..5feff6d6 --- /dev/null +++ b/lib/ace/mode/coldfusion_highlight_rules.js @@ -0,0 +1,49 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; +var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; + +var ColdfusionHighlightRules = function() { + HtmlHighlightRules.call(this); + + this.embedTagRules(JavaScriptHighlightRules, "cfjs-", "cfscript"); + + this.normalizeRules(); +}; + +oop.inherits(ColdfusionHighlightRules, HtmlHighlightRules); + +exports.ColdfusionHighlightRules = ColdfusionHighlightRules; +}); diff --git a/lib/ace/mode/coldfusion_test.js b/lib/ace/mode/coldfusion_test.js new file mode 100644 index 00000000..b55fb1c5 --- /dev/null +++ b/lib/ace/mode/coldfusion_test.js @@ -0,0 +1,67 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { +"use strict"; + +var EditSession = require("../edit_session").EditSession; +var Range = require("../range").Range; +var ColdfusionMode = require("./coldfusion").Mode; +var assert = require("../test/assertions"); + +module.exports = { + setUp : function() { + this.mode = new ColdfusionMode(); + }, + + "test: toggle comment lines" : function() { + var session = new EditSession([" abc", " cde", "fg"]); + + var range = new Range(0, 3, 1, 1); + var comment = this.mode.toggleCommentLines("start", session, 0, 1); + assert.equal([" ", " ", "fg"].join("\n"), session.toString()); + }, + + "test: next line indent should be the same as the current line indent" : function() { + assert.equal(" ", this.mode.getNextLineIndent("start", " abc")); + assert.equal("", this.mode.getNextLineIndent("start", "abc")); + assert.equal("\t", this.mode.getNextLineIndent("start", "\tabc")); + } +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} diff --git a/lib/ace/mode/csharp.js b/lib/ace/mode/csharp.js index 1d164340..a3b2964f 100644 --- a/lib/ace/mode/csharp.js +++ b/lib/ace/mode/csharp.js @@ -1,53 +1,60 @@ define(function(require, exports, module) { +"use strict"; -var oop = require("pilot/oop"); -var TextMode = require("ace/mode/text").Mode; -var Tokenizer = require("ace/tokenizer").Tokenizer; -var CSharpHighlightRules = require("ace/mode/csharp_highlight_rules").CSharpHighlightRules; -var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent; +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var CSharpHighlightRules = require("./csharp_highlight_rules").CSharpHighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; +var CStyleFoldMode = require("./folding/csharp").FoldMode; var Mode = function() { - this.$tokenizer = new Tokenizer(new CSharpHighlightRules().getRules()); + this.HighlightRules = CSharpHighlightRules; this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CstyleBehaviour(); + this.foldingRules = new CStyleFoldMode(); }; oop.inherits(Mode, TextMode); (function() { - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); + this.lineCommentStart = "//"; + this.blockComment = {start: "/*", end: "*/"}; + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + + var tokenizedLine = this.getTokenizer().getLineTokens(line, state); + var tokens = tokenizedLine.tokens; + + if (tokens.length && tokens[tokens.length-1].type == "comment") { + return indent; + } + + if (state == "start") { + var match = line.match(/^.*[\{\(\[]\s*$/); + if (match) { + indent += tab; + } + } + + return indent; + }; - var tokenizedLine = this.$tokenizer.getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - var endState = tokenizedLine.state; - - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - if (state == "start") { - var match = line.match(/^.*[\{\(\[]\s*$/); - if (match) { - indent += tab; - } - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; + this.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); + }; + + this.autoOutdent = function(state, doc, row) { + this.$outdent.autoOutdent(doc, row); + }; this.createWorker = function(session) { return null; }; + this.$id = "ace/mode/csharp"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/lib/ace/mode/csharp_highlight_rules.js b/lib/ace/mode/csharp_highlight_rules.js index 8a7cd2cf..6e7ba5d4 100644 --- a/lib/ace/mode/csharp_highlight_rules.js +++ b/lib/ace/mode/csharp_highlight_rules.js @@ -1,120 +1,90 @@ define(function(require, exports, module) { +"use strict"; -var oop = require("pilot/oop"); -var lang = require("pilot/lang"); -var DocCommentHighlightRules = require("ace/mode/doc_comment_highlight_rules").DocCommentHighlightRules; -var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules; +var oop = require("../lib/oop"); +var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var CSharpHighlightRules = function() { - - var docComment = new DocCommentHighlightRules(); - var keywords = lang.arrayToMap( - ("abstract|event|new|struct|as|explicit|null|switch|base|extern|object|this|bool|false|operator|throw|break|finally|out|true|byte|fixed|override|try|case|float|params|typeof|catch|for|private|uint|char|foreach|protected|ulong|checked|goto|public|unchecked|class|if|readonly|unsafe|const|implicit|ref|ushort|continue|in|return|using|decimal|int|sbyte|virtual|default|interface|sealed|volatile|delegate|internal|short|void|do|is|sizeof|while|double|lock|stackalloc|else|long|static|enum|namespace|string|var|dynamic").split("|") - ); - - var buildinConstants = lang.arrayToMap( - ("null|true|false").split("|") - ); - + var keywordMapper = this.createKeywordMapper({ + "variable.language": "this", + "keyword": "abstract|event|new|struct|as|explicit|null|switch|base|extern|object|this|bool|false|operator|throw|break|finally|out|true|byte|fixed|override|try|case|float|params|typeof|catch|for|private|uint|char|foreach|protected|ulong|checked|goto|public|unchecked|class|if|readonly|unsafe|const|implicit|ref|ushort|continue|in|return|using|decimal|int|sbyte|virtual|default|interface|sealed|volatile|delegate|internal|short|void|do|is|sizeof|while|double|lock|stackalloc|else|long|static|enum|namespace|string|var|dynamic", + "constant.language": "null|true|false" + }, "identifier"); // regexp must not have capturing parentheses. Use (?:) instead. // regexps are ordered -> the first match is used this.$rules = { "start" : [ - { - token : "comment", - regex : "\\/\\/.*$" - }, - docComment.getStartRule("doc-start"), + { + token : "comment", + regex : "\\/\\/.*$" + }, + DocCommentHighlightRules.getStartRule("doc-start"), { token : "comment", // multi line comment regex : "\\/\\*", next : "comment" }, { - token : "comment", // multi line comment - regex : "\\/\\*\\*", - next : "comment" - }, { - token : "string.regexp", - regex : "[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)" - }, { - token : "string", // single line - regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' - }, { - token : "string", // single line - regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" - }, { - token : "constant.numeric", // hex - regex : "0[xX][0-9a-fA-F]+\\b" - }, { - token : "constant.numeric", // float - regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" - }, { - token : "constant.language.boolean", - regex : "(?:true|false)\\b" - }, { - token : function(value) { - if (value == "this") - return "variable.language"; - else if (keywords.hasOwnProperty(value)) - return "keyword"; - else if (buildinConstants.hasOwnProperty(value)) - return "constant.language"; - else - return "identifier"; - }, - // TODO: Unicode escape sequences - // TODO: Unicode identifiers - regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" - }, { - token : "keyword.operator", - regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" - }, { - token : "lparen", - regex : "[[({]" - }, { - token : "rparen", - regex : "[\\])}]" - }, { - token : "text", - regex : "\\s+" - } + token : "string", // character + regex : /'(?:.|\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n]))'/ + }, { + token : "string", start : '"', end : '"|$', next: [ + {token: "constant.language.escape", regex: /\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n])/}, + {token: "invalid", regex: /\\./} + ] + }, { + token : "string", start : '@"', end : '"', next:[ + {token: "constant.language.escape", regex: '""'} + ] + }, { + token : "constant.numeric", // hex + regex : "0[xX][0-9a-fA-F]+\\b" + }, { + token : "constant.numeric", // float + regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" + }, { + token : "constant.language.boolean", + regex : "(?:true|false)\\b" + }, { + token : keywordMapper, + regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + }, { + token : "keyword.operator", + regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)" + }, { + token : "keyword", + regex : "^\\s*#(if|else|elif|endif|define|undef|warning|error|line|region|endregion|pragma)" + }, { + token : "punctuation.operator", + regex : "\\?|\\:|\\,|\\;|\\." + }, { + token : "paren.lparen", + regex : "[[({]" + }, { + token : "paren.rparen", + regex : "[\\])}]" + }, { + token : "text", + regex : "\\s+" + } ], "comment" : [ - { - token : "comment", // closing comment - regex : ".*?\\*\\/", - next : "start" - }, { - token : "comment", // comment spanning whole line - regex : ".+" - } - ], - "qqstring" : [ { - token : "string", - regex : '(?:(?:\\\\.)|(?:[^"\\\\]))*?"', - next : "start" - }, { - token : "string", - regex : '.+' - } - ], - "qstring" : [ - { - token : "string", - regex : "(?:(?:\\\\.)|(?:[^'\\\\]))*?'", - next : "start" - }, { - token : "string", - regex : '.+' - } + token : "comment", // closing comment + regex : ".*?\\*\\/", + next : "start" + }, { + token : "comment", // comment spanning whole line + regex : ".+" + } ] }; - this.addRules(docComment.getRules(), "doc-"); - this.$rules["doc-start"][0].next = "start"; + this.embedRules(DocCommentHighlightRules, "doc-", + [ DocCommentHighlightRules.getEndRule("start") ]); + this.normalizeRules(); }; oop.inherits(CSharpHighlightRules, TextHighlightRules); diff --git a/lib/ace/mode/css.js b/lib/ace/mode/css.js index d8878bda..6fef5ccd 100644 --- a/lib/ace/mode/css.js +++ b/lib/ace/mode/css.js @@ -1,61 +1,62 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var oop = require("pilot/oop"); -var TextMode = require("ace/mode/text").Mode; -var Tokenizer = require("ace/tokenizer").Tokenizer; -var CssHighlightRules = require("ace/mode/css_highlight_rules").CssHighlightRules; -var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent; +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var CssHighlightRules = require("./css_highlight_rules").CssHighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var WorkerClient = require("../worker/worker_client").WorkerClient; +var CssBehaviour = require("./behaviour/css").CssBehaviour; +var CStyleFoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { - this.$tokenizer = new Tokenizer(new CssHighlightRules().getRules()); + this.HighlightRules = CssHighlightRules; this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CssBehaviour(); + this.foldingRules = new CStyleFoldMode(); }; oop.inherits(Mode, TextMode); (function() { + this.foldingRules = "cStyle"; + this.blockComment = {start: "/*", end: "*/"}; + this.getNextLineIndent = function(state, line, tab) { var indent = this.$getIndent(line); // ignore braces in comments - var tokens = this.$tokenizer.getLineTokens(line, state).tokens; + var tokens = this.getTokenizer().getLineTokens(line, state).tokens; if (tokens.length && tokens[tokens.length-1].type == "comment") { return indent; } @@ -76,6 +77,22 @@ oop.inherits(Mode, TextMode); this.$outdent.autoOutdent(doc, row); }; + this.createWorker = function(session) { + var worker = new WorkerClient(["ace"], "ace/mode/css_worker", "Worker"); + worker.attachToDocument(session.getDocument()); + + worker.on("annotate", function(e) { + session.setAnnotations(e.data); + }); + + worker.on("terminate", function() { + session.clearAnnotations(); + }); + + return worker; + }; + + this.$id = "ace/mode/css"; }).call(Mode.prototype); exports.Mode = Mode; diff --git a/lib/ace/mode/css/csslint.js b/lib/ace/mode/css/csslint.js new file mode 100644 index 00000000..c3c79a80 --- /dev/null +++ b/lib/ace/mode/css/csslint.js @@ -0,0 +1,9628 @@ +define(function(require, exports, module) { +/*! +CSSLint +Copyright (c) 2014 Nicole Sullivan and Nicholas C. Zakas. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the 'Software'), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ +/* Build: v0.10.0 22-July-2014 01:17:52 */ +/*! +Parser-Lib +Copyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ +/* Version v0.2.5, Build time: 7-May-2014 03:37:38 */ +var parserlib = {}; +(function(){ + +/** + * A generic base to inherit from for any object + * that needs event handling. + * @class EventTarget + * @constructor + */ +function EventTarget(){ + + /** + * The array of listeners for various events. + * @type Object + * @property _listeners + * @private + */ + this._listeners = {}; +} + +EventTarget.prototype = { + + //restore constructor + constructor: EventTarget, + + /** + * Adds a listener for a given event type. + * @param {String} type The type of event to add a listener for. + * @param {Function} listener The function to call when the event occurs. + * @return {void} + * @method addListener + */ + addListener: function(type, listener){ + if (!this._listeners[type]){ + this._listeners[type] = []; + } + + this._listeners[type].push(listener); + }, + + /** + * Fires an event based on the passed-in object. + * @param {Object|String} event An object with at least a 'type' attribute + * or a string indicating the event name. + * @return {void} + * @method fire + */ + fire: function(event){ + if (typeof event == "string"){ + event = { type: event }; + } + if (typeof event.target != "undefined"){ + event.target = this; + } + + if (typeof event.type == "undefined"){ + throw new Error("Event object missing 'type' property."); + } + + if (this._listeners[event.type]){ + + //create a copy of the array and use that so listeners can't chane + var listeners = this._listeners[event.type].concat(); + for (var i=0, len=listeners.length; i < len; i++){ + listeners[i].call(this, event); + } + } + }, + + /** + * Removes a listener for a given event type. + * @param {String} type The type of event to remove a listener from. + * @param {Function} listener The function to remove from the event. + * @return {void} + * @method removeListener + */ + removeListener: function(type, listener){ + if (this._listeners[type]){ + var listeners = this._listeners[type]; + for (var i=0, len=listeners.length; i < len; i++){ + if (listeners[i] === listener){ + listeners.splice(i, 1); + break; + } + } + + + } + } +}; +/** + * Convenient way to read through strings. + * @namespace parserlib.util + * @class StringReader + * @constructor + * @param {String} text The text to read. + */ +function StringReader(text){ + + /** + * The input text with line endings normalized. + * @property _input + * @type String + * @private + */ + this._input = text.replace(/\n\r?/g, "\n"); + + + /** + * The row for the character to be read next. + * @property _line + * @type int + * @private + */ + this._line = 1; + + + /** + * The column for the character to be read next. + * @property _col + * @type int + * @private + */ + this._col = 1; + + /** + * The index of the character in the input to be read next. + * @property _cursor + * @type int + * @private + */ + this._cursor = 0; +} + +StringReader.prototype = { + + //restore constructor + constructor: StringReader, + + //------------------------------------------------------------------------- + // Position info + //------------------------------------------------------------------------- + + /** + * Returns the column of the character to be read next. + * @return {int} The column of the character to be read next. + * @method getCol + */ + getCol: function(){ + return this._col; + }, + + /** + * Returns the row of the character to be read next. + * @return {int} The row of the character to be read next. + * @method getLine + */ + getLine: function(){ + return this._line ; + }, + + /** + * Determines if you're at the end of the input. + * @return {Boolean} True if there's no more input, false otherwise. + * @method eof + */ + eof: function(){ + return (this._cursor == this._input.length); + }, + + //------------------------------------------------------------------------- + // Basic reading + //------------------------------------------------------------------------- + + /** + * Reads the next character without advancing the cursor. + * @param {int} count How many characters to look ahead (default is 1). + * @return {String} The next character or null if there is no next character. + * @method peek + */ + peek: function(count){ + var c = null; + count = (typeof count == "undefined" ? 1 : count); + + //if we're not at the end of the input... + if (this._cursor < this._input.length){ + + //get character and increment cursor and column + c = this._input.charAt(this._cursor + count - 1); + } + + return c; + }, + + /** + * Reads the next character from the input and adjusts the row and column + * accordingly. + * @return {String} The next character or null if there is no next character. + * @method read + */ + read: function(){ + var c = null; + + //if we're not at the end of the input... + if (this._cursor < this._input.length){ + + //if the last character was a newline, increment row count + //and reset column count + if (this._input.charAt(this._cursor) == "\n"){ + this._line++; + this._col=1; + } else { + this._col++; + } + + //get character and increment cursor and column + c = this._input.charAt(this._cursor++); + } + + return c; + }, + + //------------------------------------------------------------------------- + // Misc + //------------------------------------------------------------------------- + + /** + * Saves the current location so it can be returned to later. + * @method mark + * @return {void} + */ + mark: function(){ + this._bookmark = { + cursor: this._cursor, + line: this._line, + col: this._col + }; + }, + + reset: function(){ + if (this._bookmark){ + this._cursor = this._bookmark.cursor; + this._line = this._bookmark.line; + this._col = this._bookmark.col; + delete this._bookmark; + } + }, + + //------------------------------------------------------------------------- + // Advanced reading + //------------------------------------------------------------------------- + + /** + * Reads up to and including the given string. Throws an error if that + * string is not found. + * @param {String} pattern The string to read. + * @return {String} The string when it is found. + * @throws Error when the string pattern is not found. + * @method readTo + */ + readTo: function(pattern){ + + var buffer = "", + c; + + /* + * First, buffer must be the same length as the pattern. + * Then, buffer must end with the pattern or else reach the + * end of the input. + */ + while (buffer.length < pattern.length || buffer.lastIndexOf(pattern) != buffer.length - pattern.length){ + c = this.read(); + if (c){ + buffer += c; + } else { + throw new Error("Expected \"" + pattern + "\" at line " + this._line + ", col " + this._col + "."); + } + } + + return buffer; + + }, + + /** + * Reads characters while each character causes the given + * filter function to return true. The function is passed + * in each character and either returns true to continue + * reading or false to stop. + * @param {Function} filter The function to read on each character. + * @return {String} The string made up of all characters that passed the + * filter check. + * @method readWhile + */ + readWhile: function(filter){ + + var buffer = "", + c = this.read(); + + while(c !== null && filter(c)){ + buffer += c; + c = this.read(); + } + + return buffer; + + }, + + /** + * Reads characters that match either text or a regular expression and + * returns those characters. If a match is found, the row and column + * are adjusted; if no match is found, the reader's state is unchanged. + * reading or false to stop. + * @param {String|RegExp} matchter If a string, then the literal string + * value is searched for. If a regular expression, then any string + * matching the pattern is search for. + * @return {String} The string made up of all characters that matched or + * null if there was no match. + * @method readMatch + */ + readMatch: function(matcher){ + + var source = this._input.substring(this._cursor), + value = null; + + //if it's a string, just do a straight match + if (typeof matcher == "string"){ + if (source.indexOf(matcher) === 0){ + value = this.readCount(matcher.length); + } + } else if (matcher instanceof RegExp){ + if (matcher.test(source)){ + value = this.readCount(RegExp.lastMatch.length); + } + } + + return value; + }, + + + /** + * Reads a given number of characters. If the end of the input is reached, + * it reads only the remaining characters and does not throw an error. + * @param {int} count The number of characters to read. + * @return {String} The string made up the read characters. + * @method readCount + */ + readCount: function(count){ + var buffer = ""; + + while(count--){ + buffer += this.read(); + } + + return buffer; + } + +}; +/** + * Type to use when a syntax error occurs. + * @class SyntaxError + * @namespace parserlib.util + * @constructor + * @param {String} message The error message. + * @param {int} line The line at which the error occurred. + * @param {int} col The column at which the error occurred. + */ +function SyntaxError(message, line, col){ + + /** + * The column at which the error occurred. + * @type int + * @property col + */ + this.col = col; + + /** + * The line at which the error occurred. + * @type int + * @property line + */ + this.line = line; + + /** + * The text representation of the unit. + * @type String + * @property text + */ + this.message = message; + +} + +//inherit from Error +SyntaxError.prototype = new Error(); +/** + * Base type to represent a single syntactic unit. + * @class SyntaxUnit + * @namespace parserlib.util + * @constructor + * @param {String} text The text of the unit. + * @param {int} line The line of text on which the unit resides. + * @param {int} col The column of text on which the unit resides. + */ +function SyntaxUnit(text, line, col, type){ + + + /** + * The column of text on which the unit resides. + * @type int + * @property col + */ + this.col = col; + + /** + * The line of text on which the unit resides. + * @type int + * @property line + */ + this.line = line; + + /** + * The text representation of the unit. + * @type String + * @property text + */ + this.text = text; + + /** + * The type of syntax unit. + * @type int + * @property type + */ + this.type = type; +} + +/** + * Create a new syntax unit based solely on the given token. + * Convenience method for creating a new syntax unit when + * it represents a single token instead of multiple. + * @param {Object} token The token object to represent. + * @return {parserlib.util.SyntaxUnit} The object representing the token. + * @static + * @method fromToken + */ +SyntaxUnit.fromToken = function(token){ + return new SyntaxUnit(token.value, token.startLine, token.startCol); +}; + +SyntaxUnit.prototype = { + + //restore constructor + constructor: SyntaxUnit, + + /** + * Returns the text representation of the unit. + * @return {String} The text representation of the unit. + * @method valueOf + */ + valueOf: function(){ + return this.text; + }, + + /** + * Returns the text representation of the unit. + * @return {String} The text representation of the unit. + * @method toString + */ + toString: function(){ + return this.text; + } + +}; +/*global StringReader, SyntaxError*/ + +/** + * Generic TokenStream providing base functionality. + * @class TokenStreamBase + * @namespace parserlib.util + * @constructor + * @param {String|StringReader} input The text to tokenize or a reader from + * which to read the input. + */ +function TokenStreamBase(input, tokenData){ + + /** + * The string reader for easy access to the text. + * @type StringReader + * @property _reader + * @private + */ + this._reader = input ? new StringReader(input.toString()) : null; + + /** + * Token object for the last consumed token. + * @type Token + * @property _token + * @private + */ + this._token = null; + + /** + * The array of token information. + * @type Array + * @property _tokenData + * @private + */ + this._tokenData = tokenData; + + /** + * Lookahead token buffer. + * @type Array + * @property _lt + * @private + */ + this._lt = []; + + /** + * Lookahead token buffer index. + * @type int + * @property _ltIndex + * @private + */ + this._ltIndex = 0; + + this._ltIndexCache = []; +} + +/** + * Accepts an array of token information and outputs + * an array of token data containing key-value mappings + * and matching functions that the TokenStream needs. + * @param {Array} tokens An array of token descriptors. + * @return {Array} An array of processed token data. + * @method createTokenData + * @static + */ +TokenStreamBase.createTokenData = function(tokens){ + + var nameMap = [], + typeMap = {}, + tokenData = tokens.concat([]), + i = 0, + len = tokenData.length+1; + + tokenData.UNKNOWN = -1; + tokenData.unshift({name:"EOF"}); + + for (; i < len; i++){ + nameMap.push(tokenData[i].name); + tokenData[tokenData[i].name] = i; + if (tokenData[i].text){ + typeMap[tokenData[i].text] = i; + } + } + + tokenData.name = function(tt){ + return nameMap[tt]; + }; + + tokenData.type = function(c){ + return typeMap[c]; + }; + + return tokenData; +}; + +TokenStreamBase.prototype = { + + //restore constructor + constructor: TokenStreamBase, + + //------------------------------------------------------------------------- + // Matching methods + //------------------------------------------------------------------------- + + /** + * Determines if the next token matches the given token type. + * If so, that token is consumed; if not, the token is placed + * back onto the token stream. You can pass in any number of + * token types and this will return true if any of the token + * types is found. + * @param {int|int[]} tokenTypes Either a single token type or an array of + * token types that the next token might be. If an array is passed, + * it's assumed that the token can be any of these. + * @param {variant} channel (Optional) The channel to read from. If not + * provided, reads from the default (unnamed) channel. + * @return {Boolean} True if the token type matches, false if not. + * @method match + */ + match: function(tokenTypes, channel){ + + //always convert to an array, makes things easier + if (!(tokenTypes instanceof Array)){ + tokenTypes = [tokenTypes]; + } + + var tt = this.get(channel), + i = 0, + len = tokenTypes.length; + + while(i < len){ + if (tt == tokenTypes[i++]){ + return true; + } + } + + //no match found, put the token back + this.unget(); + return false; + }, + + /** + * Determines if the next token matches the given token type. + * If so, that token is consumed; if not, an error is thrown. + * @param {int|int[]} tokenTypes Either a single token type or an array of + * token types that the next token should be. If an array is passed, + * it's assumed that the token must be one of these. + * @param {variant} channel (Optional) The channel to read from. If not + * provided, reads from the default (unnamed) channel. + * @return {void} + * @method mustMatch + */ + mustMatch: function(tokenTypes, channel){ + + var token; + + //always convert to an array, makes things easier + if (!(tokenTypes instanceof Array)){ + tokenTypes = [tokenTypes]; + } + + if (!this.match.apply(this, arguments)){ + token = this.LT(1); + throw new SyntaxError("Expected " + this._tokenData[tokenTypes[0]].name + + " at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); + } + }, + + //------------------------------------------------------------------------- + // Consuming methods + //------------------------------------------------------------------------- + + /** + * Keeps reading from the token stream until either one of the specified + * token types is found or until the end of the input is reached. + * @param {int|int[]} tokenTypes Either a single token type or an array of + * token types that the next token should be. If an array is passed, + * it's assumed that the token must be one of these. + * @param {variant} channel (Optional) The channel to read from. If not + * provided, reads from the default (unnamed) channel. + * @return {void} + * @method advance + */ + advance: function(tokenTypes, channel){ + + while(this.LA(0) !== 0 && !this.match(tokenTypes, channel)){ + this.get(); + } + + return this.LA(0); + }, + + /** + * Consumes the next token from the token stream. + * @return {int} The token type of the token that was just consumed. + * @method get + */ + get: function(channel){ + + var tokenInfo = this._tokenData, + reader = this._reader, + value, + i =0, + len = tokenInfo.length, + found = false, + token, + info; + + //check the lookahead buffer first + if (this._lt.length && this._ltIndex >= 0 && this._ltIndex < this._lt.length){ + + i++; + this._token = this._lt[this._ltIndex++]; + info = tokenInfo[this._token.type]; + + //obey channels logic + while((info.channel !== undefined && channel !== info.channel) && + this._ltIndex < this._lt.length){ + this._token = this._lt[this._ltIndex++]; + info = tokenInfo[this._token.type]; + i++; + } + + //here be dragons + if ((info.channel === undefined || channel === info.channel) && + this._ltIndex <= this._lt.length){ + this._ltIndexCache.push(i); + return this._token.type; + } + } + + //call token retriever method + token = this._getToken(); + + //if it should be hidden, don't save a token + if (token.type > -1 && !tokenInfo[token.type].hide){ + + //apply token channel + token.channel = tokenInfo[token.type].channel; + + //save for later + this._token = token; + this._lt.push(token); + + //save space that will be moved (must be done before array is truncated) + this._ltIndexCache.push(this._lt.length - this._ltIndex + i); + + //keep the buffer under 5 items + if (this._lt.length > 5){ + this._lt.shift(); + } + + //also keep the shift buffer under 5 items + if (this._ltIndexCache.length > 5){ + this._ltIndexCache.shift(); + } + + //update lookahead index + this._ltIndex = this._lt.length; + } + + /* + * Skip to the next token if: + * 1. The token type is marked as hidden. + * 2. The token type has a channel specified and it isn't the current channel. + */ + info = tokenInfo[token.type]; + if (info && + (info.hide || + (info.channel !== undefined && channel !== info.channel))){ + return this.get(channel); + } else { + //return just the type + return token.type; + } + }, + + /** + * Looks ahead a certain number of tokens and returns the token type at + * that position. This will throw an error if you lookahead past the + * end of input, past the size of the lookahead buffer, or back past + * the first token in the lookahead buffer. + * @param {int} The index of the token type to retrieve. 0 for the + * current token, 1 for the next, -1 for the previous, etc. + * @return {int} The token type of the token in the given position. + * @method LA + */ + LA: function(index){ + var total = index, + tt; + if (index > 0){ + //TODO: Store 5 somewhere + if (index > 5){ + throw new Error("Too much lookahead."); + } + + //get all those tokens + while(total){ + tt = this.get(); + total--; + } + + //unget all those tokens + while(total < index){ + this.unget(); + total++; + } + } else if (index < 0){ + + if(this._lt[this._ltIndex+index]){ + tt = this._lt[this._ltIndex+index].type; + } else { + throw new Error("Too much lookbehind."); + } + + } else { + tt = this._token.type; + } + + return tt; + + }, + + /** + * Looks ahead a certain number of tokens and returns the token at + * that position. This will throw an error if you lookahead past the + * end of input, past the size of the lookahead buffer, or back past + * the first token in the lookahead buffer. + * @param {int} The index of the token type to retrieve. 0 for the + * current token, 1 for the next, -1 for the previous, etc. + * @return {Object} The token of the token in the given position. + * @method LA + */ + LT: function(index){ + + //lookahead first to prime the token buffer + this.LA(index); + + //now find the token, subtract one because _ltIndex is already at the next index + return this._lt[this._ltIndex+index-1]; + }, + + /** + * Returns the token type for the next token in the stream without + * consuming it. + * @return {int} The token type of the next token in the stream. + * @method peek + */ + peek: function(){ + return this.LA(1); + }, + + /** + * Returns the actual token object for the last consumed token. + * @return {Token} The token object for the last consumed token. + * @method token + */ + token: function(){ + return this._token; + }, + + /** + * Returns the name of the token for the given token type. + * @param {int} tokenType The type of token to get the name of. + * @return {String} The name of the token or "UNKNOWN_TOKEN" for any + * invalid token type. + * @method tokenName + */ + tokenName: function(tokenType){ + if (tokenType < 0 || tokenType > this._tokenData.length){ + return "UNKNOWN_TOKEN"; + } else { + return this._tokenData[tokenType].name; + } + }, + + /** + * Returns the token type value for the given token name. + * @param {String} tokenName The name of the token whose value should be returned. + * @return {int} The token type value for the given token name or -1 + * for an unknown token. + * @method tokenName + */ + tokenType: function(tokenName){ + return this._tokenData[tokenName] || -1; + }, + + /** + * Returns the last consumed token to the token stream. + * @method unget + */ + unget: function(){ + //if (this._ltIndex > -1){ + if (this._ltIndexCache.length){ + this._ltIndex -= this._ltIndexCache.pop();//--; + this._token = this._lt[this._ltIndex - 1]; + } else { + throw new Error("Too much lookahead."); + } + } + +}; + + +parserlib.util = { +StringReader: StringReader, +SyntaxError : SyntaxError, +SyntaxUnit : SyntaxUnit, +EventTarget : EventTarget, +TokenStreamBase : TokenStreamBase +}; +})(); +/* +Parser-Lib +Copyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ +/* Version v0.2.5, Build time: 7-May-2014 03:37:38 */ +(function(){ +var EventTarget = parserlib.util.EventTarget, +TokenStreamBase = parserlib.util.TokenStreamBase, +StringReader = parserlib.util.StringReader, +SyntaxError = parserlib.util.SyntaxError, +SyntaxUnit = parserlib.util.SyntaxUnit; + +var Colors = { + aliceblue :"#f0f8ff", + antiquewhite :"#faebd7", + aqua :"#00ffff", + aquamarine :"#7fffd4", + azure :"#f0ffff", + beige :"#f5f5dc", + bisque :"#ffe4c4", + black :"#000000", + blanchedalmond :"#ffebcd", + blue :"#0000ff", + blueviolet :"#8a2be2", + brown :"#a52a2a", + burlywood :"#deb887", + cadetblue :"#5f9ea0", + chartreuse :"#7fff00", + chocolate :"#d2691e", + coral :"#ff7f50", + cornflowerblue :"#6495ed", + cornsilk :"#fff8dc", + crimson :"#dc143c", + cyan :"#00ffff", + darkblue :"#00008b", + darkcyan :"#008b8b", + darkgoldenrod :"#b8860b", + darkgray :"#a9a9a9", + darkgrey :"#a9a9a9", + darkgreen :"#006400", + darkkhaki :"#bdb76b", + darkmagenta :"#8b008b", + darkolivegreen :"#556b2f", + darkorange :"#ff8c00", + darkorchid :"#9932cc", + darkred :"#8b0000", + darksalmon :"#e9967a", + darkseagreen :"#8fbc8f", + darkslateblue :"#483d8b", + darkslategray :"#2f4f4f", + darkslategrey :"#2f4f4f", + darkturquoise :"#00ced1", + darkviolet :"#9400d3", + deeppink :"#ff1493", + deepskyblue :"#00bfff", + dimgray :"#696969", + dimgrey :"#696969", + dodgerblue :"#1e90ff", + firebrick :"#b22222", + floralwhite :"#fffaf0", + forestgreen :"#228b22", + fuchsia :"#ff00ff", + gainsboro :"#dcdcdc", + ghostwhite :"#f8f8ff", + gold :"#ffd700", + goldenrod :"#daa520", + gray :"#808080", + grey :"#808080", + green :"#008000", + greenyellow :"#adff2f", + honeydew :"#f0fff0", + hotpink :"#ff69b4", + indianred :"#cd5c5c", + indigo :"#4b0082", + ivory :"#fffff0", + khaki :"#f0e68c", + lavender :"#e6e6fa", + lavenderblush :"#fff0f5", + lawngreen :"#7cfc00", + lemonchiffon :"#fffacd", + lightblue :"#add8e6", + lightcoral :"#f08080", + lightcyan :"#e0ffff", + lightgoldenrodyellow :"#fafad2", + lightgray :"#d3d3d3", + lightgrey :"#d3d3d3", + lightgreen :"#90ee90", + lightpink :"#ffb6c1", + lightsalmon :"#ffa07a", + lightseagreen :"#20b2aa", + lightskyblue :"#87cefa", + lightslategray :"#778899", + lightslategrey :"#778899", + lightsteelblue :"#b0c4de", + lightyellow :"#ffffe0", + lime :"#00ff00", + limegreen :"#32cd32", + linen :"#faf0e6", + magenta :"#ff00ff", + maroon :"#800000", + mediumaquamarine:"#66cdaa", + mediumblue :"#0000cd", + mediumorchid :"#ba55d3", + mediumpurple :"#9370d8", + mediumseagreen :"#3cb371", + mediumslateblue :"#7b68ee", + mediumspringgreen :"#00fa9a", + mediumturquoise :"#48d1cc", + mediumvioletred :"#c71585", + midnightblue :"#191970", + mintcream :"#f5fffa", + mistyrose :"#ffe4e1", + moccasin :"#ffe4b5", + navajowhite :"#ffdead", + navy :"#000080", + oldlace :"#fdf5e6", + olive :"#808000", + olivedrab :"#6b8e23", + orange :"#ffa500", + orangered :"#ff4500", + orchid :"#da70d6", + palegoldenrod :"#eee8aa", + palegreen :"#98fb98", + paleturquoise :"#afeeee", + palevioletred :"#d87093", + papayawhip :"#ffefd5", + peachpuff :"#ffdab9", + peru :"#cd853f", + pink :"#ffc0cb", + plum :"#dda0dd", + powderblue :"#b0e0e6", + purple :"#800080", + red :"#ff0000", + rosybrown :"#bc8f8f", + royalblue :"#4169e1", + saddlebrown :"#8b4513", + salmon :"#fa8072", + sandybrown :"#f4a460", + seagreen :"#2e8b57", + seashell :"#fff5ee", + sienna :"#a0522d", + silver :"#c0c0c0", + skyblue :"#87ceeb", + slateblue :"#6a5acd", + slategray :"#708090", + slategrey :"#708090", + snow :"#fffafa", + springgreen :"#00ff7f", + steelblue :"#4682b4", + tan :"#d2b48c", + teal :"#008080", + thistle :"#d8bfd8", + tomato :"#ff6347", + turquoise :"#40e0d0", + violet :"#ee82ee", + wheat :"#f5deb3", + white :"#ffffff", + whitesmoke :"#f5f5f5", + yellow :"#ffff00", + yellowgreen :"#9acd32", + //CSS2 system colors http://www.w3.org/TR/css3-color/#css2-system + activeBorder :"Active window border.", + activecaption :"Active window caption.", + appworkspace :"Background color of multiple document interface.", + background :"Desktop background.", + buttonface :"The face background color for 3-D elements that appear 3-D due to one layer of surrounding border.", + buttonhighlight :"The color of the border facing the light source for 3-D elements that appear 3-D due to one layer of surrounding border.", + buttonshadow :"The color of the border away from the light source for 3-D elements that appear 3-D due to one layer of surrounding border.", + buttontext :"Text on push buttons.", + captiontext :"Text in caption, size box, and scrollbar arrow box.", + graytext :"Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color.", + greytext :"Greyed (disabled) text. This color is set to #000 if the current display driver does not support a solid grey color.", + highlight :"Item(s) selected in a control.", + highlighttext :"Text of item(s) selected in a control.", + inactiveborder :"Inactive window border.", + inactivecaption :"Inactive window caption.", + inactivecaptiontext :"Color of text in an inactive caption.", + infobackground :"Background color for tooltip controls.", + infotext :"Text color for tooltip controls.", + menu :"Menu background.", + menutext :"Text in menus.", + scrollbar :"Scroll bar gray area.", + threeddarkshadow :"The color of the darker (generally outer) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", + threedface :"The face background color for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", + threedhighlight :"The color of the lighter (generally outer) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", + threedlightshadow :"The color of the darker (generally inner) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", + threedshadow :"The color of the lighter (generally inner) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.", + window :"Window background.", + windowframe :"Window frame.", + windowtext :"Text in windows." +}; +/*global SyntaxUnit, Parser*/ +/** + * Represents a selector combinator (whitespace, +, >). + * @namespace parserlib.css + * @class Combinator + * @extends parserlib.util.SyntaxUnit + * @constructor + * @param {String} text The text representation of the unit. + * @param {int} line The line of text on which the unit resides. + * @param {int} col The column of text on which the unit resides. + */ +function Combinator(text, line, col){ + + SyntaxUnit.call(this, text, line, col, Parser.COMBINATOR_TYPE); + + /** + * The type of modifier. + * @type String + * @property type + */ + this.type = "unknown"; + + //pretty simple + if (/^\s+$/.test(text)){ + this.type = "descendant"; + } else if (text == ">"){ + this.type = "child"; + } else if (text == "+"){ + this.type = "adjacent-sibling"; + } else if (text == "~"){ + this.type = "sibling"; + } + +} + +Combinator.prototype = new SyntaxUnit(); +Combinator.prototype.constructor = Combinator; + +/*global SyntaxUnit, Parser*/ +/** + * Represents a media feature, such as max-width:500. + * @namespace parserlib.css + * @class MediaFeature + * @extends parserlib.util.SyntaxUnit + * @constructor + * @param {SyntaxUnit} name The name of the feature. + * @param {SyntaxUnit} value The value of the feature or null if none. + */ +function MediaFeature(name, value){ + + SyntaxUnit.call(this, "(" + name + (value !== null ? ":" + value : "") + ")", name.startLine, name.startCol, Parser.MEDIA_FEATURE_TYPE); + + /** + * The name of the media feature + * @type String + * @property name + */ + this.name = name; + + /** + * The value for the feature or null if there is none. + * @type SyntaxUnit + * @property value + */ + this.value = value; +} + +MediaFeature.prototype = new SyntaxUnit(); +MediaFeature.prototype.constructor = MediaFeature; + +/*global SyntaxUnit, Parser*/ +/** + * Represents an individual media query. + * @namespace parserlib.css + * @class MediaQuery + * @extends parserlib.util.SyntaxUnit + * @constructor + * @param {String} modifier The modifier "not" or "only" (or null). + * @param {String} mediaType The type of media (i.e., "print"). + * @param {Array} parts Array of selectors parts making up this selector. + * @param {int} line The line of text on which the unit resides. + * @param {int} col The column of text on which the unit resides. + */ +function MediaQuery(modifier, mediaType, features, line, col){ + + SyntaxUnit.call(this, (modifier ? modifier + " ": "") + (mediaType ? mediaType : "") + (mediaType && features.length > 0 ? " and " : "") + features.join(" and "), line, col, Parser.MEDIA_QUERY_TYPE); + + /** + * The media modifier ("not" or "only") + * @type String + * @property modifier + */ + this.modifier = modifier; + + /** + * The mediaType (i.e., "print") + * @type String + * @property mediaType + */ + this.mediaType = mediaType; + + /** + * The parts that make up the selector. + * @type Array + * @property features + */ + this.features = features; + +} + +MediaQuery.prototype = new SyntaxUnit(); +MediaQuery.prototype.constructor = MediaQuery; + +/*global Tokens, TokenStream, SyntaxError, Properties, Validation, ValidationError, SyntaxUnit, + PropertyValue, PropertyValuePart, SelectorPart, SelectorSubPart, Selector, + PropertyName, Combinator, MediaFeature, MediaQuery, EventTarget */ + +/** + * A CSS3 parser. + * @namespace parserlib.css + * @class Parser + * @constructor + * @param {Object} options (Optional) Various options for the parser: + * starHack (true|false) to allow IE6 star hack as valid, + * underscoreHack (true|false) to interpret leading underscores + * as IE6-7 targeting for known properties, ieFilters (true|false) + * to indicate that IE < 8 filters should be accepted and not throw + * syntax errors. + */ +function Parser(options){ + + //inherit event functionality + EventTarget.call(this); + + + this.options = options || {}; + + this._tokenStream = null; +} + +//Static constants +Parser.DEFAULT_TYPE = 0; +Parser.COMBINATOR_TYPE = 1; +Parser.MEDIA_FEATURE_TYPE = 2; +Parser.MEDIA_QUERY_TYPE = 3; +Parser.PROPERTY_NAME_TYPE = 4; +Parser.PROPERTY_VALUE_TYPE = 5; +Parser.PROPERTY_VALUE_PART_TYPE = 6; +Parser.SELECTOR_TYPE = 7; +Parser.SELECTOR_PART_TYPE = 8; +Parser.SELECTOR_SUB_PART_TYPE = 9; + +Parser.prototype = function(){ + + var proto = new EventTarget(), //new prototype + prop, + additions = { + + //restore constructor + constructor: Parser, + + //instance constants - yuck + DEFAULT_TYPE : 0, + COMBINATOR_TYPE : 1, + MEDIA_FEATURE_TYPE : 2, + MEDIA_QUERY_TYPE : 3, + PROPERTY_NAME_TYPE : 4, + PROPERTY_VALUE_TYPE : 5, + PROPERTY_VALUE_PART_TYPE : 6, + SELECTOR_TYPE : 7, + SELECTOR_PART_TYPE : 8, + SELECTOR_SUB_PART_TYPE : 9, + + //----------------------------------------------------------------- + // Grammar + //----------------------------------------------------------------- + + _stylesheet: function(){ + + /* + * stylesheet + * : [ CHARSET_SYM S* STRING S* ';' ]? + * [S|CDO|CDC]* [ import [S|CDO|CDC]* ]* + * [ namespace [S|CDO|CDC]* ]* + * [ [ ruleset | media | page | font_face | keyframes ] [S|CDO|CDC]* ]* + * ; + */ + + var tokenStream = this._tokenStream, + charset = null, + count, + token, + tt; + + this.fire("startstylesheet"); + + //try to read character set + this._charset(); + + this._skipCruft(); + + //try to read imports - may be more than one + while (tokenStream.peek() == Tokens.IMPORT_SYM){ + this._import(); + this._skipCruft(); + } + + //try to read namespaces - may be more than one + while (tokenStream.peek() == Tokens.NAMESPACE_SYM){ + this._namespace(); + this._skipCruft(); + } + + //get the next token + tt = tokenStream.peek(); + + //try to read the rest + while(tt > Tokens.EOF){ + + try { + + switch(tt){ + case Tokens.MEDIA_SYM: + this._media(); + this._skipCruft(); + break; + case Tokens.PAGE_SYM: + this._page(); + this._skipCruft(); + break; + case Tokens.FONT_FACE_SYM: + this._font_face(); + this._skipCruft(); + break; + case Tokens.KEYFRAMES_SYM: + this._keyframes(); + this._skipCruft(); + break; + case Tokens.VIEWPORT_SYM: + this._viewport(); + this._skipCruft(); + break; + case Tokens.UNKNOWN_SYM: //unknown @ rule + tokenStream.get(); + if (!this.options.strict){ + + //fire error event + this.fire({ + type: "error", + error: null, + message: "Unknown @ rule: " + tokenStream.LT(0).value + ".", + line: tokenStream.LT(0).startLine, + col: tokenStream.LT(0).startCol + }); + + //skip braces + count=0; + while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) == Tokens.LBRACE){ + count++; //keep track of nesting depth + } + + while(count){ + tokenStream.advance([Tokens.RBRACE]); + count--; + } + + } else { + //not a syntax error, rethrow it + throw new SyntaxError("Unknown @ rule.", tokenStream.LT(0).startLine, tokenStream.LT(0).startCol); + } + break; + case Tokens.S: + this._readWhitespace(); + break; + default: + if(!this._ruleset()){ + + //error handling for known issues + switch(tt){ + case Tokens.CHARSET_SYM: + token = tokenStream.LT(1); + this._charset(false); + throw new SyntaxError("@charset not allowed here.", token.startLine, token.startCol); + case Tokens.IMPORT_SYM: + token = tokenStream.LT(1); + this._import(false); + throw new SyntaxError("@import not allowed here.", token.startLine, token.startCol); + case Tokens.NAMESPACE_SYM: + token = tokenStream.LT(1); + this._namespace(false); + throw new SyntaxError("@namespace not allowed here.", token.startLine, token.startCol); + default: + tokenStream.get(); //get the last token + this._unexpectedToken(tokenStream.token()); + } + + } + } + } catch(ex) { + if (ex instanceof SyntaxError && !this.options.strict){ + this.fire({ + type: "error", + error: ex, + message: ex.message, + line: ex.line, + col: ex.col + }); + } else { + throw ex; + } + } + + tt = tokenStream.peek(); + } + + if (tt != Tokens.EOF){ + this._unexpectedToken(tokenStream.token()); + } + + this.fire("endstylesheet"); + }, + + _charset: function(emit){ + var tokenStream = this._tokenStream, + charset, + token, + line, + col; + + if (tokenStream.match(Tokens.CHARSET_SYM)){ + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + + this._readWhitespace(); + tokenStream.mustMatch(Tokens.STRING); + + token = tokenStream.token(); + charset = token.value; + + this._readWhitespace(); + tokenStream.mustMatch(Tokens.SEMICOLON); + + if (emit !== false){ + this.fire({ + type: "charset", + charset:charset, + line: line, + col: col + }); + } + } + }, + + _import: function(emit){ + /* + * import + * : IMPORT_SYM S* + * [STRING|URI] S* media_query_list? ';' S* + */ + + var tokenStream = this._tokenStream, + tt, + uri, + importToken, + mediaList = []; + + //read import symbol + tokenStream.mustMatch(Tokens.IMPORT_SYM); + importToken = tokenStream.token(); + this._readWhitespace(); + + tokenStream.mustMatch([Tokens.STRING, Tokens.URI]); + + //grab the URI value + uri = tokenStream.token().value.replace(/^(?:url\()?["']?([^"']+?)["']?\)?$/, "$1"); + + this._readWhitespace(); + + mediaList = this._media_query_list(); + + //must end with a semicolon + tokenStream.mustMatch(Tokens.SEMICOLON); + this._readWhitespace(); + + if (emit !== false){ + this.fire({ + type: "import", + uri: uri, + media: mediaList, + line: importToken.startLine, + col: importToken.startCol + }); + } + + }, + + _namespace: function(emit){ + /* + * namespace + * : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S* + */ + + var tokenStream = this._tokenStream, + line, + col, + prefix, + uri; + + //read import symbol + tokenStream.mustMatch(Tokens.NAMESPACE_SYM); + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + this._readWhitespace(); + + //it's a namespace prefix - no _namespace_prefix() method because it's just an IDENT + if (tokenStream.match(Tokens.IDENT)){ + prefix = tokenStream.token().value; + this._readWhitespace(); + } + + tokenStream.mustMatch([Tokens.STRING, Tokens.URI]); + /*if (!tokenStream.match(Tokens.STRING)){ + tokenStream.mustMatch(Tokens.URI); + }*/ + + //grab the URI value + uri = tokenStream.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/, "$1"); + + this._readWhitespace(); + + //must end with a semicolon + tokenStream.mustMatch(Tokens.SEMICOLON); + this._readWhitespace(); + + if (emit !== false){ + this.fire({ + type: "namespace", + prefix: prefix, + uri: uri, + line: line, + col: col + }); + } + + }, + + _media: function(){ + /* + * media + * : MEDIA_SYM S* media_query_list S* '{' S* ruleset* '}' S* + * ; + */ + var tokenStream = this._tokenStream, + line, + col, + mediaList;// = []; + + //look for @media + tokenStream.mustMatch(Tokens.MEDIA_SYM); + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + + this._readWhitespace(); + + mediaList = this._media_query_list(); + + tokenStream.mustMatch(Tokens.LBRACE); + this._readWhitespace(); + + this.fire({ + type: "startmedia", + media: mediaList, + line: line, + col: col + }); + + while(true) { + if (tokenStream.peek() == Tokens.PAGE_SYM){ + this._page(); + } else if (tokenStream.peek() == Tokens.FONT_FACE_SYM){ + this._font_face(); + } else if (tokenStream.peek() == Tokens.VIEWPORT_SYM){ + this._viewport(); + } else if (!this._ruleset()){ + break; + } + } + + tokenStream.mustMatch(Tokens.RBRACE); + this._readWhitespace(); + + this.fire({ + type: "endmedia", + media: mediaList, + line: line, + col: col + }); + }, + + + //CSS3 Media Queries + _media_query_list: function(){ + /* + * media_query_list + * : S* [media_query [ ',' S* media_query ]* ]? + * ; + */ + var tokenStream = this._tokenStream, + mediaList = []; + + + this._readWhitespace(); + + if (tokenStream.peek() == Tokens.IDENT || tokenStream.peek() == Tokens.LPAREN){ + mediaList.push(this._media_query()); + } + + while(tokenStream.match(Tokens.COMMA)){ + this._readWhitespace(); + mediaList.push(this._media_query()); + } + + return mediaList; + }, + + /* + * Note: "expression" in the grammar maps to the _media_expression + * method. + + */ + _media_query: function(){ + /* + * media_query + * : [ONLY | NOT]? S* media_type S* [ AND S* expression ]* + * | expression [ AND S* expression ]* + * ; + */ + var tokenStream = this._tokenStream, + type = null, + ident = null, + token = null, + expressions = []; + + if (tokenStream.match(Tokens.IDENT)){ + ident = tokenStream.token().value.toLowerCase(); + + //since there's no custom tokens for these, need to manually check + if (ident != "only" && ident != "not"){ + tokenStream.unget(); + ident = null; + } else { + token = tokenStream.token(); + } + } + + this._readWhitespace(); + + if (tokenStream.peek() == Tokens.IDENT){ + type = this._media_type(); + if (token === null){ + token = tokenStream.token(); + } + } else if (tokenStream.peek() == Tokens.LPAREN){ + if (token === null){ + token = tokenStream.LT(1); + } + expressions.push(this._media_expression()); + } + + if (type === null && expressions.length === 0){ + return null; + } else { + this._readWhitespace(); + while (tokenStream.match(Tokens.IDENT)){ + if (tokenStream.token().value.toLowerCase() != "and"){ + this._unexpectedToken(tokenStream.token()); + } + + this._readWhitespace(); + expressions.push(this._media_expression()); + } + } + + return new MediaQuery(ident, type, expressions, token.startLine, token.startCol); + }, + + //CSS3 Media Queries + _media_type: function(){ + /* + * media_type + * : IDENT + * ; + */ + return this._media_feature(); + }, + + /** + * Note: in CSS3 Media Queries, this is called "expression". + * Renamed here to avoid conflict with CSS3 Selectors + * definition of "expression". Also note that "expr" in the + * grammar now maps to "expression" from CSS3 selectors. + * @method _media_expression + * @private + */ + _media_expression: function(){ + /* + * expression + * : '(' S* media_feature S* [ ':' S* expr ]? ')' S* + * ; + */ + var tokenStream = this._tokenStream, + feature = null, + token, + expression = null; + + tokenStream.mustMatch(Tokens.LPAREN); + + feature = this._media_feature(); + this._readWhitespace(); + + if (tokenStream.match(Tokens.COLON)){ + this._readWhitespace(); + token = tokenStream.LT(1); + expression = this._expression(); + } + + tokenStream.mustMatch(Tokens.RPAREN); + this._readWhitespace(); + + return new MediaFeature(feature, (expression ? new SyntaxUnit(expression, token.startLine, token.startCol) : null)); + }, + + //CSS3 Media Queries + _media_feature: function(){ + /* + * media_feature + * : IDENT + * ; + */ + var tokenStream = this._tokenStream; + + tokenStream.mustMatch(Tokens.IDENT); + + return SyntaxUnit.fromToken(tokenStream.token()); + }, + + //CSS3 Paged Media + _page: function(){ + /* + * page: + * PAGE_SYM S* IDENT? pseudo_page? S* + * '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S* + * ; + */ + var tokenStream = this._tokenStream, + line, + col, + identifier = null, + pseudoPage = null; + + //look for @page + tokenStream.mustMatch(Tokens.PAGE_SYM); + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + + this._readWhitespace(); + + if (tokenStream.match(Tokens.IDENT)){ + identifier = tokenStream.token().value; + + //The value 'auto' may not be used as a page name and MUST be treated as a syntax error. + if (identifier.toLowerCase() === "auto"){ + this._unexpectedToken(tokenStream.token()); + } + } + + //see if there's a colon upcoming + if (tokenStream.peek() == Tokens.COLON){ + pseudoPage = this._pseudo_page(); + } + + this._readWhitespace(); + + this.fire({ + type: "startpage", + id: identifier, + pseudo: pseudoPage, + line: line, + col: col + }); + + this._readDeclarations(true, true); + + this.fire({ + type: "endpage", + id: identifier, + pseudo: pseudoPage, + line: line, + col: col + }); + + }, + + //CSS3 Paged Media + _margin: function(){ + /* + * margin : + * margin_sym S* '{' declaration [ ';' S* declaration? ]* '}' S* + * ; + */ + var tokenStream = this._tokenStream, + line, + col, + marginSym = this._margin_sym(); + + if (marginSym){ + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + + this.fire({ + type: "startpagemargin", + margin: marginSym, + line: line, + col: col + }); + + this._readDeclarations(true); + + this.fire({ + type: "endpagemargin", + margin: marginSym, + line: line, + col: col + }); + return true; + } else { + return false; + } + }, + + //CSS3 Paged Media + _margin_sym: function(){ + + /* + * margin_sym : + * TOPLEFTCORNER_SYM | + * TOPLEFT_SYM | + * TOPCENTER_SYM | + * TOPRIGHT_SYM | + * TOPRIGHTCORNER_SYM | + * BOTTOMLEFTCORNER_SYM | + * BOTTOMLEFT_SYM | + * BOTTOMCENTER_SYM | + * BOTTOMRIGHT_SYM | + * BOTTOMRIGHTCORNER_SYM | + * LEFTTOP_SYM | + * LEFTMIDDLE_SYM | + * LEFTBOTTOM_SYM | + * RIGHTTOP_SYM | + * RIGHTMIDDLE_SYM | + * RIGHTBOTTOM_SYM + * ; + */ + + var tokenStream = this._tokenStream; + + if(tokenStream.match([Tokens.TOPLEFTCORNER_SYM, Tokens.TOPLEFT_SYM, + Tokens.TOPCENTER_SYM, Tokens.TOPRIGHT_SYM, Tokens.TOPRIGHTCORNER_SYM, + Tokens.BOTTOMLEFTCORNER_SYM, Tokens.BOTTOMLEFT_SYM, + Tokens.BOTTOMCENTER_SYM, Tokens.BOTTOMRIGHT_SYM, + Tokens.BOTTOMRIGHTCORNER_SYM, Tokens.LEFTTOP_SYM, + Tokens.LEFTMIDDLE_SYM, Tokens.LEFTBOTTOM_SYM, Tokens.RIGHTTOP_SYM, + Tokens.RIGHTMIDDLE_SYM, Tokens.RIGHTBOTTOM_SYM])) + { + return SyntaxUnit.fromToken(tokenStream.token()); + } else { + return null; + } + + }, + + _pseudo_page: function(){ + /* + * pseudo_page + * : ':' IDENT + * ; + */ + + var tokenStream = this._tokenStream; + + tokenStream.mustMatch(Tokens.COLON); + tokenStream.mustMatch(Tokens.IDENT); + + //TODO: CSS3 Paged Media says only "left", "center", and "right" are allowed + + return tokenStream.token().value; + }, + + _font_face: function(){ + /* + * font_face + * : FONT_FACE_SYM S* + * '{' S* declaration [ ';' S* declaration ]* '}' S* + * ; + */ + var tokenStream = this._tokenStream, + line, + col; + + //look for @page + tokenStream.mustMatch(Tokens.FONT_FACE_SYM); + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + + this._readWhitespace(); + + this.fire({ + type: "startfontface", + line: line, + col: col + }); + + this._readDeclarations(true); + + this.fire({ + type: "endfontface", + line: line, + col: col + }); + }, + + _viewport: function(){ + /* + * viewport + * : VIEWPORT_SYM S* + * '{' S* declaration? [ ';' S* declaration? ]* '}' S* + * ; + */ + var tokenStream = this._tokenStream, + line, + col; + + tokenStream.mustMatch(Tokens.VIEWPORT_SYM); + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + + this._readWhitespace(); + + this.fire({ + type: "startviewport", + line: line, + col: col + }); + + this._readDeclarations(true); + + this.fire({ + type: "endviewport", + line: line, + col: col + }); + + }, + + _operator: function(inFunction){ + + /* + * operator (outside function) + * : '/' S* | ',' S* | /( empty )/ + * operator (inside function) + * : '/' S* | '+' S* | '*' S* | '-' S* /( empty )/ + * ; + */ + + var tokenStream = this._tokenStream, + token = null; + + if (tokenStream.match([Tokens.SLASH, Tokens.COMMA]) || + (inFunction && tokenStream.match([Tokens.PLUS, Tokens.STAR, Tokens.MINUS]))){ + token = tokenStream.token(); + this._readWhitespace(); + } + return token ? PropertyValuePart.fromToken(token) : null; + + }, + + _combinator: function(){ + + /* + * combinator + * : PLUS S* | GREATER S* | TILDE S* | S+ + * ; + */ + + var tokenStream = this._tokenStream, + value = null, + token; + + if(tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE])){ + token = tokenStream.token(); + value = new Combinator(token.value, token.startLine, token.startCol); + this._readWhitespace(); + } + + return value; + }, + + _unary_operator: function(){ + + /* + * unary_operator + * : '-' | '+' + * ; + */ + + var tokenStream = this._tokenStream; + + if (tokenStream.match([Tokens.MINUS, Tokens.PLUS])){ + return tokenStream.token().value; + } else { + return null; + } + }, + + _property: function(){ + + /* + * property + * : IDENT S* + * ; + */ + + var tokenStream = this._tokenStream, + value = null, + hack = null, + tokenValue, + token, + line, + col; + + //check for star hack - throws error if not allowed + if (tokenStream.peek() == Tokens.STAR && this.options.starHack){ + tokenStream.get(); + token = tokenStream.token(); + hack = token.value; + line = token.startLine; + col = token.startCol; + } + + if(tokenStream.match(Tokens.IDENT)){ + token = tokenStream.token(); + tokenValue = token.value; + + //check for underscore hack - no error if not allowed because it's valid CSS syntax + if (tokenValue.charAt(0) == "_" && this.options.underscoreHack){ + hack = "_"; + tokenValue = tokenValue.substring(1); + } + + value = new PropertyName(tokenValue, hack, (line||token.startLine), (col||token.startCol)); + this._readWhitespace(); + } + + return value; + }, + + //Augmented with CSS3 Selectors + _ruleset: function(){ + /* + * ruleset + * : selectors_group + * '{' S* declaration? [ ';' S* declaration? ]* '}' S* + * ; + */ + + var tokenStream = this._tokenStream, + tt, + selectors; + + + /* + * Error Recovery: If even a single selector fails to parse, + * then the entire ruleset should be thrown away. + */ + try { + selectors = this._selectors_group(); + } catch (ex){ + if (ex instanceof SyntaxError && !this.options.strict){ + + //fire error event + this.fire({ + type: "error", + error: ex, + message: ex.message, + line: ex.line, + col: ex.col + }); + + //skip over everything until closing brace + tt = tokenStream.advance([Tokens.RBRACE]); + if (tt == Tokens.RBRACE){ + //if there's a right brace, the rule is finished so don't do anything + } else { + //otherwise, rethrow the error because it wasn't handled properly + throw ex; + } + + } else { + //not a syntax error, rethrow it + throw ex; + } + + //trigger parser to continue + return true; + } + + //if it got here, all selectors parsed + if (selectors){ + + this.fire({ + type: "startrule", + selectors: selectors, + line: selectors[0].line, + col: selectors[0].col + }); + + this._readDeclarations(true); + + this.fire({ + type: "endrule", + selectors: selectors, + line: selectors[0].line, + col: selectors[0].col + }); + + } + + return selectors; + + }, + + //CSS3 Selectors + _selectors_group: function(){ + + /* + * selectors_group + * : selector [ COMMA S* selector ]* + * ; + */ + var tokenStream = this._tokenStream, + selectors = [], + selector; + + selector = this._selector(); + if (selector !== null){ + + selectors.push(selector); + while(tokenStream.match(Tokens.COMMA)){ + this._readWhitespace(); + selector = this._selector(); + if (selector !== null){ + selectors.push(selector); + } else { + this._unexpectedToken(tokenStream.LT(1)); + } + } + } + + return selectors.length ? selectors : null; + }, + + //CSS3 Selectors + _selector: function(){ + /* + * selector + * : simple_selector_sequence [ combinator simple_selector_sequence ]* + * ; + */ + + var tokenStream = this._tokenStream, + selector = [], + nextSelector = null, + combinator = null, + ws = null; + + //if there's no simple selector, then there's no selector + nextSelector = this._simple_selector_sequence(); + if (nextSelector === null){ + return null; + } + + selector.push(nextSelector); + + do { + + //look for a combinator + combinator = this._combinator(); + + if (combinator !== null){ + selector.push(combinator); + nextSelector = this._simple_selector_sequence(); + + //there must be a next selector + if (nextSelector === null){ + this._unexpectedToken(tokenStream.LT(1)); + } else { + + //nextSelector is an instance of SelectorPart + selector.push(nextSelector); + } + } else { + + //if there's not whitespace, we're done + if (this._readWhitespace()){ + + //add whitespace separator + ws = new Combinator(tokenStream.token().value, tokenStream.token().startLine, tokenStream.token().startCol); + + //combinator is not required + combinator = this._combinator(); + + //selector is required if there's a combinator + nextSelector = this._simple_selector_sequence(); + if (nextSelector === null){ + if (combinator !== null){ + this._unexpectedToken(tokenStream.LT(1)); + } + } else { + + if (combinator !== null){ + selector.push(combinator); + } else { + selector.push(ws); + } + + selector.push(nextSelector); + } + } else { + break; + } + + } + } while(true); + + return new Selector(selector, selector[0].line, selector[0].col); + }, + + //CSS3 Selectors + _simple_selector_sequence: function(){ + /* + * simple_selector_sequence + * : [ type_selector | universal ] + * [ HASH | class | attrib | pseudo | negation ]* + * | [ HASH | class | attrib | pseudo | negation ]+ + * ; + */ + + var tokenStream = this._tokenStream, + + //parts of a simple selector + elementName = null, + modifiers = [], + + //complete selector text + selectorText= "", + + //the different parts after the element name to search for + components = [ + //HASH + function(){ + return tokenStream.match(Tokens.HASH) ? + new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) : + null; + }, + this._class, + this._attrib, + this._pseudo, + this._negation + ], + i = 0, + len = components.length, + component = null, + found = false, + line, + col; + + + //get starting line and column for the selector + line = tokenStream.LT(1).startLine; + col = tokenStream.LT(1).startCol; + + elementName = this._type_selector(); + if (!elementName){ + elementName = this._universal(); + } + + if (elementName !== null){ + selectorText += elementName; + } + + while(true){ + + //whitespace means we're done + if (tokenStream.peek() === Tokens.S){ + break; + } + + //check for each component + while(i < len && component === null){ + component = components[i++].call(this); + } + + if (component === null){ + + //we don't have a selector + if (selectorText === ""){ + return null; + } else { + break; + } + } else { + i = 0; + modifiers.push(component); + selectorText += component.toString(); + component = null; + } + } + + + return selectorText !== "" ? + new SelectorPart(elementName, modifiers, selectorText, line, col) : + null; + }, + + //CSS3 Selectors + _type_selector: function(){ + /* + * type_selector + * : [ namespace_prefix ]? element_name + * ; + */ + + var tokenStream = this._tokenStream, + ns = this._namespace_prefix(), + elementName = this._element_name(); + + if (!elementName){ + /* + * Need to back out the namespace that was read due to both + * type_selector and universal reading namespace_prefix + * first. Kind of hacky, but only way I can figure out + * right now how to not change the grammar. + */ + if (ns){ + tokenStream.unget(); + if (ns.length > 1){ + tokenStream.unget(); + } + } + + return null; + } else { + if (ns){ + elementName.text = ns + elementName.text; + elementName.col -= ns.length; + } + return elementName; + } + }, + + //CSS3 Selectors + _class: function(){ + /* + * class + * : '.' IDENT + * ; + */ + + var tokenStream = this._tokenStream, + token; + + if (tokenStream.match(Tokens.DOT)){ + tokenStream.mustMatch(Tokens.IDENT); + token = tokenStream.token(); + return new SelectorSubPart("." + token.value, "class", token.startLine, token.startCol - 1); + } else { + return null; + } + + }, + + //CSS3 Selectors + _element_name: function(){ + /* + * element_name + * : IDENT + * ; + */ + + var tokenStream = this._tokenStream, + token; + + if (tokenStream.match(Tokens.IDENT)){ + token = tokenStream.token(); + return new SelectorSubPart(token.value, "elementName", token.startLine, token.startCol); + + } else { + return null; + } + }, + + //CSS3 Selectors + _namespace_prefix: function(){ + /* + * namespace_prefix + * : [ IDENT | '*' ]? '|' + * ; + */ + var tokenStream = this._tokenStream, + value = ""; + + //verify that this is a namespace prefix + if (tokenStream.LA(1) === Tokens.PIPE || tokenStream.LA(2) === Tokens.PIPE){ + + if(tokenStream.match([Tokens.IDENT, Tokens.STAR])){ + value += tokenStream.token().value; + } + + tokenStream.mustMatch(Tokens.PIPE); + value += "|"; + + } + + return value.length ? value : null; + }, + + //CSS3 Selectors + _universal: function(){ + /* + * universal + * : [ namespace_prefix ]? '*' + * ; + */ + var tokenStream = this._tokenStream, + value = "", + ns; + + ns = this._namespace_prefix(); + if(ns){ + value += ns; + } + + if(tokenStream.match(Tokens.STAR)){ + value += "*"; + } + + return value.length ? value : null; + + }, + + //CSS3 Selectors + _attrib: function(){ + /* + * attrib + * : '[' S* [ namespace_prefix ]? IDENT S* + * [ [ PREFIXMATCH | + * SUFFIXMATCH | + * SUBSTRINGMATCH | + * '=' | + * INCLUDES | + * DASHMATCH ] S* [ IDENT | STRING ] S* + * ]? ']' + * ; + */ + + var tokenStream = this._tokenStream, + value = null, + ns, + token; + + if (tokenStream.match(Tokens.LBRACKET)){ + token = tokenStream.token(); + value = token.value; + value += this._readWhitespace(); + + ns = this._namespace_prefix(); + + if (ns){ + value += ns; + } + + tokenStream.mustMatch(Tokens.IDENT); + value += tokenStream.token().value; + value += this._readWhitespace(); + + if(tokenStream.match([Tokens.PREFIXMATCH, Tokens.SUFFIXMATCH, Tokens.SUBSTRINGMATCH, + Tokens.EQUALS, Tokens.INCLUDES, Tokens.DASHMATCH])){ + + value += tokenStream.token().value; + value += this._readWhitespace(); + + tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]); + value += tokenStream.token().value; + value += this._readWhitespace(); + } + + tokenStream.mustMatch(Tokens.RBRACKET); + + return new SelectorSubPart(value + "]", "attribute", token.startLine, token.startCol); + } else { + return null; + } + }, + + //CSS3 Selectors + _pseudo: function(){ + + /* + * pseudo + * : ':' ':'? [ IDENT | functional_pseudo ] + * ; + */ + + var tokenStream = this._tokenStream, + pseudo = null, + colons = ":", + line, + col; + + if (tokenStream.match(Tokens.COLON)){ + + if (tokenStream.match(Tokens.COLON)){ + colons += ":"; + } + + if (tokenStream.match(Tokens.IDENT)){ + pseudo = tokenStream.token().value; + line = tokenStream.token().startLine; + col = tokenStream.token().startCol - colons.length; + } else if (tokenStream.peek() == Tokens.FUNCTION){ + line = tokenStream.LT(1).startLine; + col = tokenStream.LT(1).startCol - colons.length; + pseudo = this._functional_pseudo(); + } + + if (pseudo){ + pseudo = new SelectorSubPart(colons + pseudo, "pseudo", line, col); + } + } + + return pseudo; + }, + + //CSS3 Selectors + _functional_pseudo: function(){ + /* + * functional_pseudo + * : FUNCTION S* expression ')' + * ; + */ + + var tokenStream = this._tokenStream, + value = null; + + if(tokenStream.match(Tokens.FUNCTION)){ + value = tokenStream.token().value; + value += this._readWhitespace(); + value += this._expression(); + tokenStream.mustMatch(Tokens.RPAREN); + value += ")"; + } + + return value; + }, + + //CSS3 Selectors + _expression: function(){ + /* + * expression + * : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+ + * ; + */ + + var tokenStream = this._tokenStream, + value = ""; + + while(tokenStream.match([Tokens.PLUS, Tokens.MINUS, Tokens.DIMENSION, + Tokens.NUMBER, Tokens.STRING, Tokens.IDENT, Tokens.LENGTH, + Tokens.FREQ, Tokens.ANGLE, Tokens.TIME, + Tokens.RESOLUTION, Tokens.SLASH])){ + + value += tokenStream.token().value; + value += this._readWhitespace(); + } + + return value.length ? value : null; + + }, + + //CSS3 Selectors + _negation: function(){ + /* + * negation + * : NOT S* negation_arg S* ')' + * ; + */ + + var tokenStream = this._tokenStream, + line, + col, + value = "", + arg, + subpart = null; + + if (tokenStream.match(Tokens.NOT)){ + value = tokenStream.token().value; + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + value += this._readWhitespace(); + arg = this._negation_arg(); + value += arg; + value += this._readWhitespace(); + tokenStream.match(Tokens.RPAREN); + value += tokenStream.token().value; + + subpart = new SelectorSubPart(value, "not", line, col); + subpart.args.push(arg); + } + + return subpart; + }, + + //CSS3 Selectors + _negation_arg: function(){ + /* + * negation_arg + * : type_selector | universal | HASH | class | attrib | pseudo + * ; + */ + + var tokenStream = this._tokenStream, + args = [ + this._type_selector, + this._universal, + function(){ + return tokenStream.match(Tokens.HASH) ? + new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) : + null; + }, + this._class, + this._attrib, + this._pseudo + ], + arg = null, + i = 0, + len = args.length, + elementName, + line, + col, + part; + + line = tokenStream.LT(1).startLine; + col = tokenStream.LT(1).startCol; + + while(i < len && arg === null){ + + arg = args[i].call(this); + i++; + } + + //must be a negation arg + if (arg === null){ + this._unexpectedToken(tokenStream.LT(1)); + } + + //it's an element name + if (arg.type == "elementName"){ + part = new SelectorPart(arg, [], arg.toString(), line, col); + } else { + part = new SelectorPart(null, [arg], arg.toString(), line, col); + } + + return part; + }, + + _declaration: function(){ + + /* + * declaration + * : property ':' S* expr prio? + * | /( empty )/ + * ; + */ + + var tokenStream = this._tokenStream, + property = null, + expr = null, + prio = null, + error = null, + invalid = null, + propertyName= ""; + + property = this._property(); + if (property !== null){ + + tokenStream.mustMatch(Tokens.COLON); + this._readWhitespace(); + + expr = this._expr(); + + //if there's no parts for the value, it's an error + if (!expr || expr.length === 0){ + this._unexpectedToken(tokenStream.LT(1)); + } + + prio = this._prio(); + + /* + * If hacks should be allowed, then only check the root + * property. If hacks should not be allowed, treat + * _property or *property as invalid properties. + */ + propertyName = property.toString(); + if (this.options.starHack && property.hack == "*" || + this.options.underscoreHack && property.hack == "_") { + + propertyName = property.text; + } + + try { + this._validateProperty(propertyName, expr); + } catch (ex) { + invalid = ex; + } + + this.fire({ + type: "property", + property: property, + value: expr, + important: prio, + line: property.line, + col: property.col, + invalid: invalid + }); + + return true; + } else { + return false; + } + }, + + _prio: function(){ + /* + * prio + * : IMPORTANT_SYM S* + * ; + */ + + var tokenStream = this._tokenStream, + result = tokenStream.match(Tokens.IMPORTANT_SYM); + + this._readWhitespace(); + return result; + }, + + _expr: function(inFunction){ + /* + * expr + * : term [ operator term ]* + * ; + */ + + var tokenStream = this._tokenStream, + values = [], + //valueParts = [], + value = null, + operator = null; + + value = this._term(inFunction); + if (value !== null){ + + values.push(value); + + do { + operator = this._operator(inFunction); + + //if there's an operator, keep building up the value parts + if (operator){ + values.push(operator); + } /*else { + //if there's not an operator, you have a full value + values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col)); + valueParts = []; + }*/ + + value = this._term(inFunction); + + if (value === null){ + break; + } else { + values.push(value); + } + } while(true); + } + + //cleanup + /*if (valueParts.length){ + values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col)); + }*/ + + return values.length > 0 ? new PropertyValue(values, values[0].line, values[0].col) : null; + }, + + _term: function(inFunction){ + + /* + * term + * : unary_operator? + * [ NUMBER S* | PERCENTAGE S* | LENGTH S* | ANGLE S* | + * TIME S* | FREQ S* | function | ie_function ] + * | STRING S* | IDENT S* | URI S* | UNICODERANGE S* | hexcolor + * ; + */ + + var tokenStream = this._tokenStream, + unary = null, + value = null, + endChar = null, + token, + line, + col; + + //returns the operator or null + unary = this._unary_operator(); + if (unary !== null){ + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + } + + //exception for IE filters + if (tokenStream.peek() == Tokens.IE_FUNCTION && this.options.ieFilters){ + + value = this._ie_function(); + if (unary === null){ + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + } + + //see if it's a simple block + } else if (inFunction && tokenStream.match([Tokens.LPAREN, Tokens.LBRACE, Tokens.LBRACKET])){ + + token = tokenStream.token(); + endChar = token.endChar; + value = token.value + this._expr(inFunction).text; + if (unary === null){ + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + } + tokenStream.mustMatch(Tokens.type(endChar)); + value += endChar; + this._readWhitespace(); + + //see if there's a simple match + } else if (tokenStream.match([Tokens.NUMBER, Tokens.PERCENTAGE, Tokens.LENGTH, + Tokens.ANGLE, Tokens.TIME, + Tokens.FREQ, Tokens.STRING, Tokens.IDENT, Tokens.URI, Tokens.UNICODE_RANGE])){ + + value = tokenStream.token().value; + if (unary === null){ + line = tokenStream.token().startLine; + col = tokenStream.token().startCol; + } + this._readWhitespace(); + } else { + + //see if it's a color + token = this._hexcolor(); + if (token === null){ + + //if there's no unary, get the start of the next token for line/col info + if (unary === null){ + line = tokenStream.LT(1).startLine; + col = tokenStream.LT(1).startCol; + } + + //has to be a function + if (value === null){ + + /* + * This checks for alpha(opacity=0) style of IE + * functions. IE_FUNCTION only presents progid: style. + */ + if (tokenStream.LA(3) == Tokens.EQUALS && this.options.ieFilters){ + value = this._ie_function(); + } else { + value = this._function(); + } + } + + /*if (value === null){ + return null; + //throw new Error("Expected identifier at line " + tokenStream.token().startLine + ", character " + tokenStream.token().startCol + "."); + }*/ + + } else { + value = token.value; + if (unary === null){ + line = token.startLine; + col = token.startCol; + } + } + + } + + return value !== null ? + new PropertyValuePart(unary !== null ? unary + value : value, line, col) : + null; + + }, + + _function: function(){ + + /* + * function + * : FUNCTION S* expr ')' S* + * ; + */ + + var tokenStream = this._tokenStream, + functionText = null, + expr = null, + lt; + + if (tokenStream.match(Tokens.FUNCTION)){ + functionText = tokenStream.token().value; + this._readWhitespace(); + expr = this._expr(true); + functionText += expr; + + //START: Horrible hack in case it's an IE filter + if (this.options.ieFilters && tokenStream.peek() == Tokens.EQUALS){ + do { + + if (this._readWhitespace()){ + functionText += tokenStream.token().value; + } + + //might be second time in the loop + if (tokenStream.LA(0) == Tokens.COMMA){ + functionText += tokenStream.token().value; + } + + tokenStream.match(Tokens.IDENT); + functionText += tokenStream.token().value; + + tokenStream.match(Tokens.EQUALS); + functionText += tokenStream.token().value; + + //functionText += this._term(); + lt = tokenStream.peek(); + while(lt != Tokens.COMMA && lt != Tokens.S && lt != Tokens.RPAREN){ + tokenStream.get(); + functionText += tokenStream.token().value; + lt = tokenStream.peek(); + } + } while(tokenStream.match([Tokens.COMMA, Tokens.S])); + } + + //END: Horrible Hack + + tokenStream.match(Tokens.RPAREN); + functionText += ")"; + this._readWhitespace(); + } + + return functionText; + }, + + _ie_function: function(){ + + /* (My own extension) + * ie_function + * : IE_FUNCTION S* IDENT '=' term [S* ','? IDENT '=' term]+ ')' S* + * ; + */ + + var tokenStream = this._tokenStream, + functionText = null, + expr = null, + lt; + + //IE function can begin like a regular function, too + if (tokenStream.match([Tokens.IE_FUNCTION, Tokens.FUNCTION])){ + functionText = tokenStream.token().value; + + do { + + if (this._readWhitespace()){ + functionText += tokenStream.token().value; + } + + //might be second time in the loop + if (tokenStream.LA(0) == Tokens.COMMA){ + functionText += tokenStream.token().value; + } + + tokenStream.match(Tokens.IDENT); + functionText += tokenStream.token().value; + + tokenStream.match(Tokens.EQUALS); + functionText += tokenStream.token().value; + + //functionText += this._term(); + lt = tokenStream.peek(); + while(lt != Tokens.COMMA && lt != Tokens.S && lt != Tokens.RPAREN){ + tokenStream.get(); + functionText += tokenStream.token().value; + lt = tokenStream.peek(); + } + } while(tokenStream.match([Tokens.COMMA, Tokens.S])); + + tokenStream.match(Tokens.RPAREN); + functionText += ")"; + this._readWhitespace(); + } + + return functionText; + }, + + _hexcolor: function(){ + /* + * There is a constraint on the color that it must + * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F]) + * after the "#"; e.g., "#000" is OK, but "#abcd" is not. + * + * hexcolor + * : HASH S* + * ; + */ + + var tokenStream = this._tokenStream, + token = null, + color; + + if(tokenStream.match(Tokens.HASH)){ + + //need to do some validation here + + token = tokenStream.token(); + color = token.value; + if (!/#[a-f0-9]{3,6}/i.test(color)){ + throw new SyntaxError("Expected a hex color but found '" + color + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); + } + this._readWhitespace(); + } + + return token; + }, + + //----------------------------------------------------------------- + // Animations methods + //----------------------------------------------------------------- + + _keyframes: function(){ + + /* + * keyframes: + * : KEYFRAMES_SYM S* keyframe_name S* '{' S* keyframe_rule* '}' { + * ; + */ + var tokenStream = this._tokenStream, + token, + tt, + name, + prefix = ""; + + tokenStream.mustMatch(Tokens.KEYFRAMES_SYM); + token = tokenStream.token(); + if (/^@\-([^\-]+)\-/.test(token.value)) { + prefix = RegExp.$1; + } + + this._readWhitespace(); + name = this._keyframe_name(); + + this._readWhitespace(); + tokenStream.mustMatch(Tokens.LBRACE); + + this.fire({ + type: "startkeyframes", + name: name, + prefix: prefix, + line: token.startLine, + col: token.startCol + }); + + this._readWhitespace(); + tt = tokenStream.peek(); + + //check for key + while(tt == Tokens.IDENT || tt == Tokens.PERCENTAGE) { + this._keyframe_rule(); + this._readWhitespace(); + tt = tokenStream.peek(); + } + + this.fire({ + type: "endkeyframes", + name: name, + prefix: prefix, + line: token.startLine, + col: token.startCol + }); + + this._readWhitespace(); + tokenStream.mustMatch(Tokens.RBRACE); + + }, + + _keyframe_name: function(){ + + /* + * keyframe_name: + * : IDENT + * | STRING + * ; + */ + var tokenStream = this._tokenStream, + token; + + tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]); + return SyntaxUnit.fromToken(tokenStream.token()); + }, + + _keyframe_rule: function(){ + + /* + * keyframe_rule: + * : key_list S* + * '{' S* declaration [ ';' S* declaration ]* '}' S* + * ; + */ + var tokenStream = this._tokenStream, + token, + keyList = this._key_list(); + + this.fire({ + type: "startkeyframerule", + keys: keyList, + line: keyList[0].line, + col: keyList[0].col + }); + + this._readDeclarations(true); + + this.fire({ + type: "endkeyframerule", + keys: keyList, + line: keyList[0].line, + col: keyList[0].col + }); + + }, + + _key_list: function(){ + + /* + * key_list: + * : key [ S* ',' S* key]* + * ; + */ + var tokenStream = this._tokenStream, + token, + key, + keyList = []; + + //must be least one key + keyList.push(this._key()); + + this._readWhitespace(); + + while(tokenStream.match(Tokens.COMMA)){ + this._readWhitespace(); + keyList.push(this._key()); + this._readWhitespace(); + } + + return keyList; + }, + + _key: function(){ + /* + * There is a restriction that IDENT can be only "from" or "to". + * + * key + * : PERCENTAGE + * | IDENT + * ; + */ + + var tokenStream = this._tokenStream, + token; + + if (tokenStream.match(Tokens.PERCENTAGE)){ + return SyntaxUnit.fromToken(tokenStream.token()); + } else if (tokenStream.match(Tokens.IDENT)){ + token = tokenStream.token(); + + if (/from|to/i.test(token.value)){ + return SyntaxUnit.fromToken(token); + } + + tokenStream.unget(); + } + + //if it gets here, there wasn't a valid token, so time to explode + this._unexpectedToken(tokenStream.LT(1)); + }, + + //----------------------------------------------------------------- + // Helper methods + //----------------------------------------------------------------- + + /** + * Not part of CSS grammar, but useful for skipping over + * combination of white space and HTML-style comments. + * @return {void} + * @method _skipCruft + * @private + */ + _skipCruft: function(){ + while(this._tokenStream.match([Tokens.S, Tokens.CDO, Tokens.CDC])){ + //noop + } + }, + + /** + * Not part of CSS grammar, but this pattern occurs frequently + * in the official CSS grammar. Split out here to eliminate + * duplicate code. + * @param {Boolean} checkStart Indicates if the rule should check + * for the left brace at the beginning. + * @param {Boolean} readMargins Indicates if the rule should check + * for margin patterns. + * @return {void} + * @method _readDeclarations + * @private + */ + _readDeclarations: function(checkStart, readMargins){ + /* + * Reads the pattern + * S* '{' S* declaration [ ';' S* declaration ]* '}' S* + * or + * S* '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S* + * Note that this is how it is described in CSS3 Paged Media, but is actually incorrect. + * A semicolon is only necessary following a declaration is there's another declaration + * or margin afterwards. + */ + var tokenStream = this._tokenStream, + tt; + + + this._readWhitespace(); + + if (checkStart){ + tokenStream.mustMatch(Tokens.LBRACE); + } + + this._readWhitespace(); + + try { + + while(true){ + + if (tokenStream.match(Tokens.SEMICOLON) || (readMargins && this._margin())){ + //noop + } else if (this._declaration()){ + if (!tokenStream.match(Tokens.SEMICOLON)){ + break; + } + } else { + break; + } + + //if ((!this._margin() && !this._declaration()) || !tokenStream.match(Tokens.SEMICOLON)){ + // break; + //} + this._readWhitespace(); + } + + tokenStream.mustMatch(Tokens.RBRACE); + this._readWhitespace(); + + } catch (ex) { + if (ex instanceof SyntaxError && !this.options.strict){ + + //fire error event + this.fire({ + type: "error", + error: ex, + message: ex.message, + line: ex.line, + col: ex.col + }); + + //see if there's another declaration + tt = tokenStream.advance([Tokens.SEMICOLON, Tokens.RBRACE]); + if (tt == Tokens.SEMICOLON){ + //if there's a semicolon, then there might be another declaration + this._readDeclarations(false, readMargins); + } else if (tt != Tokens.RBRACE){ + //if there's a right brace, the rule is finished so don't do anything + //otherwise, rethrow the error because it wasn't handled properly + throw ex; + } + + } else { + //not a syntax error, rethrow it + throw ex; + } + } + + }, + + /** + * In some cases, you can end up with two white space tokens in a + * row. Instead of making a change in every function that looks for + * white space, this function is used to match as much white space + * as necessary. + * @method _readWhitespace + * @return {String} The white space if found, empty string if not. + * @private + */ + _readWhitespace: function(){ + + var tokenStream = this._tokenStream, + ws = ""; + + while(tokenStream.match(Tokens.S)){ + ws += tokenStream.token().value; + } + + return ws; + }, + + + /** + * Throws an error when an unexpected token is found. + * @param {Object} token The token that was found. + * @method _unexpectedToken + * @return {void} + * @private + */ + _unexpectedToken: function(token){ + throw new SyntaxError("Unexpected token '" + token.value + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); + }, + + /** + * Helper method used for parsing subparts of a style sheet. + * @return {void} + * @method _verifyEnd + * @private + */ + _verifyEnd: function(){ + if (this._tokenStream.LA(1) != Tokens.EOF){ + this._unexpectedToken(this._tokenStream.LT(1)); + } + }, + + //----------------------------------------------------------------- + // Validation methods + //----------------------------------------------------------------- + _validateProperty: function(property, value){ + Validation.validate(property, value); + }, + + //----------------------------------------------------------------- + // Parsing methods + //----------------------------------------------------------------- + + parse: function(input){ + this._tokenStream = new TokenStream(input, Tokens); + this._stylesheet(); + }, + + parseStyleSheet: function(input){ + //just passthrough + return this.parse(input); + }, + + parseMediaQuery: function(input){ + this._tokenStream = new TokenStream(input, Tokens); + var result = this._media_query(); + + //if there's anything more, then it's an invalid selector + this._verifyEnd(); + + //otherwise return result + return result; + }, + + /** + * Parses a property value (everything after the semicolon). + * @return {parserlib.css.PropertyValue} The property value. + * @throws parserlib.util.SyntaxError If an unexpected token is found. + * @method parserPropertyValue + */ + parsePropertyValue: function(input){ + + this._tokenStream = new TokenStream(input, Tokens); + this._readWhitespace(); + + var result = this._expr(); + + //okay to have a trailing white space + this._readWhitespace(); + + //if there's anything more, then it's an invalid selector + this._verifyEnd(); + + //otherwise return result + return result; + }, + + /** + * Parses a complete CSS rule, including selectors and + * properties. + * @param {String} input The text to parser. + * @return {Boolean} True if the parse completed successfully, false if not. + * @method parseRule + */ + parseRule: function(input){ + this._tokenStream = new TokenStream(input, Tokens); + + //skip any leading white space + this._readWhitespace(); + + var result = this._ruleset(); + + //skip any trailing white space + this._readWhitespace(); + + //if there's anything more, then it's an invalid selector + this._verifyEnd(); + + //otherwise return result + return result; + }, + + /** + * Parses a single CSS selector (no comma) + * @param {String} input The text to parse as a CSS selector. + * @return {Selector} An object representing the selector. + * @throws parserlib.util.SyntaxError If an unexpected token is found. + * @method parseSelector + */ + parseSelector: function(input){ + + this._tokenStream = new TokenStream(input, Tokens); + + //skip any leading white space + this._readWhitespace(); + + var result = this._selector(); + + //skip any trailing white space + this._readWhitespace(); + + //if there's anything more, then it's an invalid selector + this._verifyEnd(); + + //otherwise return result + return result; + }, + + /** + * Parses an HTML style attribute: a set of CSS declarations + * separated by semicolons. + * @param {String} input The text to parse as a style attribute + * @return {void} + * @method parseStyleAttribute + */ + parseStyleAttribute: function(input){ + input += "}"; // for error recovery in _readDeclarations() + this._tokenStream = new TokenStream(input, Tokens); + this._readDeclarations(); + } + }; + + //copy over onto prototype + for (prop in additions){ + if (additions.hasOwnProperty(prop)){ + proto[prop] = additions[prop]; + } + } + + return proto; +}(); + + +/* +nth + : S* [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]? | + ['-'|'+']? INTEGER | {O}{D}{D} | {E}{V}{E}{N} ] S* + ; +*/ +/*global Validation, ValidationTypes, ValidationError*/ +var Properties = { + + //A + "align-items" : "flex-start | flex-end | center | baseline | stretch", + "align-content" : "flex-start | flex-end | center | space-between | space-around | stretch", + "align-self" : "auto | flex-start | flex-end | center | baseline | stretch", + "-webkit-align-items" : "flex-start | flex-end | center | baseline | stretch", + "-webkit-align-content" : "flex-start | flex-end | center | space-between | space-around | stretch", + "-webkit-align-self" : "auto | flex-start | flex-end | center | baseline | stretch", + "alignment-adjust" : "auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | | ", + "alignment-baseline" : "baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical", + "animation" : 1, + "animation-delay" : { multi: "
  • element + tree.insertElement(name, attributes); + tree.framesetOk = false; + }; + + modes.inBody.startTagPlaintext = function(name, attributes) { + if (tree.openElements.inButtonScope('p')) + this.endTagP('p'); + tree.insertElement(name, attributes); + tree.tokenizer.setState(Tokenizer.PLAINTEXT); + }; + + modes.inBody.startTagHeading = function(name, attributes) { + if (tree.openElements.inButtonScope('p')) + this.endTagP('p'); + if (tree.currentStackItem().isNumberedHeader()) { + tree.parseError('unexpected-start-tag', {name: name}); + tree.popElement(); + } + tree.insertElement(name, attributes); + }; + + modes.inBody.startTagA = function(name, attributes) { + var activeA = tree.elementInActiveFormattingElements('a'); + if (activeA) { + tree.parseError("unexpected-start-tag-implies-end-tag", {startName: "a", endName: "a"}); + tree.adoptionAgencyEndTag('a'); + if (tree.openElements.contains(activeA)) + tree.openElements.remove(activeA); + tree.removeElementFromActiveFormattingElements(activeA); + } + tree.reconstructActiveFormattingElements(); + tree.insertFormattingElement(name, attributes); + }; + + modes.inBody.startTagFormatting = function(name, attributes) { + tree.reconstructActiveFormattingElements(); + tree.insertFormattingElement(name, attributes); + }; + + modes.inBody.startTagNobr = function(name, attributes) { + tree.reconstructActiveFormattingElements(); + if (tree.openElements.inScope('nobr')) { + tree.parseError("unexpected-start-tag-implies-end-tag", {startName: 'nobr', endName: 'nobr'}); + this.processEndTag('nobr'); + // XXX Need tests that trigger the following + tree.reconstructActiveFormattingElements(); + } + tree.insertFormattingElement(name, attributes); + }; + + modes.inBody.startTagButton = function(name, attributes) { + if (tree.openElements.inScope('button')) { + tree.parseError('unexpected-start-tag-implies-end-tag', {startName: 'button', endName: 'button'}); + this.processEndTag('button'); + tree.insertionMode.processStartTag(name, attributes); + } else { + tree.framesetOk = false; + tree.reconstructActiveFormattingElements(); + tree.insertElement(name, attributes); + } + }; + + modes.inBody.startTagAppletMarqueeObject = function(name, attributes) { + tree.reconstructActiveFormattingElements(); + tree.insertElement(name, attributes); + tree.activeFormattingElements.push(Marker); + tree.framesetOk = false; + }; + + modes.inBody.endTagAppletMarqueeObject = function(name) { + if (!tree.openElements.inScope(name)) { + tree.parseError("unexpected-end-tag", {name: name}); + } else { + tree.generateImpliedEndTags(); + if (tree.currentStackItem().localName != name) { + tree.parseError('end-tag-too-early', {name: name}); + } + tree.openElements.popUntilPopped(name); + tree.clearActiveFormattingElements(); + } + }; + + modes.inBody.startTagXmp = function(name, attributes) { + if (tree.openElements.inButtonScope('p')) + this.processEndTag('p'); + tree.reconstructActiveFormattingElements(); + tree.processGenericRawTextStartTag(name, attributes); + tree.framesetOk = false; + }; + + modes.inBody.startTagTable = function(name, attributes) { + if (tree.compatMode !== "quirks") + if (tree.openElements.inButtonScope('p')) + this.processEndTag('p'); + tree.insertElement(name, attributes); + tree.setInsertionMode('inTable'); + tree.framesetOk = false; + }; + + modes.inBody.startTagVoidFormatting = function(name, attributes) { + tree.reconstructActiveFormattingElements(); + tree.insertSelfClosingElement(name, attributes); + tree.framesetOk = false; + }; + + modes.inBody.startTagParamSourceTrack = function(name, attributes) { + tree.insertSelfClosingElement(name, attributes); + }; + + modes.inBody.startTagHr = function(name, attributes) { + if (tree.openElements.inButtonScope('p')) + this.endTagP('p'); + tree.insertSelfClosingElement(name, attributes); + tree.framesetOk = false; + }; + + modes.inBody.startTagImage = function(name, attributes) { + // No, really... + tree.parseError('unexpected-start-tag-treated-as', {originalName: 'image', newName: 'img'}); + this.processStartTag('img', attributes); + }; + + modes.inBody.startTagInput = function(name, attributes) { + var currentFramesetOk = tree.framesetOk; + this.startTagVoidFormatting(name, attributes); + for (var key in attributes) { + // input type=hidden doesn't change framesetOk + if (attributes[key].nodeName == 'type') { + if (attributes[key].nodeValue.toLowerCase() == 'hidden') + tree.framesetOk = currentFramesetOk; + break; + } + } + }; + + modes.inBody.startTagIsindex = function(name, attributes) { + tree.parseError('deprecated-tag', {name: 'isindex'}); + tree.selfClosingFlagAcknowledged = true; + if (tree.form) + return; + var formAttributes = []; + var inputAttributes = []; + var prompt = "This is a searchable index. Enter search keywords: "; + for (var key in attributes) { + switch (attributes[key].nodeName) { + case 'action': + formAttributes.push({nodeName: 'action', + nodeValue: attributes[key].nodeValue}); + break; + case 'prompt': + prompt = attributes[key].nodeValue; + break; + case 'name': + break; + default: + inputAttributes.push({nodeName: attributes[key].nodeName, + nodeValue: attributes[key].nodeValue}); + } + } + inputAttributes.push({nodeName: 'name', nodeValue: 'isindex'}); + this.processStartTag('form', formAttributes); + this.processStartTag('hr'); + this.processStartTag('label'); + this.processCharacters(new CharacterBuffer(prompt)); + this.processStartTag('input', inputAttributes); + this.processEndTag('label'); + this.processStartTag('hr'); + this.processEndTag('form'); + }; + + modes.inBody.startTagTextarea = function(name, attributes) { + // XXX Form element pointer checking here as well... + tree.insertElement(name, attributes); + tree.tokenizer.setState(Tokenizer.RCDATA); + tree.originalInsertionMode = tree.insertionModeName; + tree.shouldSkipLeadingNewline = true; + tree.framesetOk = false; + tree.setInsertionMode('text'); + }; + + modes.inBody.startTagIFrame = function(name, attributes) { + tree.framesetOk = false; + this.startTagRawText(name, attributes); + }; + + modes.inBody.startTagRawText = function(name, attributes) { + tree.processGenericRawTextStartTag(name, attributes); + }; + + modes.inBody.startTagSelect = function(name, attributes) { + tree.reconstructActiveFormattingElements(); + tree.insertElement(name, attributes); + tree.framesetOk = false; + var insertionModeName = tree.insertionModeName; + if (insertionModeName == 'inTable' || + insertionModeName == 'inCaption' || + insertionModeName == 'inColumnGroup' || + insertionModeName == 'inTableBody' || + insertionModeName == 'inRow' || + insertionModeName == 'inCell') { + tree.setInsertionMode('inSelectInTable'); + } else { + tree.setInsertionMode('inSelect'); + } + }; + + modes.inBody.startTagMisplaced = function(name, attributes) { + tree.parseError('unexpected-start-tag-ignored', {name: name}); + }; + + modes.inBody.endTagMisplaced = function(name) { + // This handles elements with end tags in other insertion modes. + tree.parseError("unexpected-end-tag", {name: name}); + }; + + modes.inBody.endTagBr = function(name) { + tree.parseError("unexpected-end-tag-treated-as", {originalName: "br", newName: "br element"}); + tree.reconstructActiveFormattingElements(); + tree.insertElement(name, []); + tree.popElement(); + }; + + modes.inBody.startTagOptionOptgroup = function(name, attributes) { + if (tree.currentStackItem().localName == 'option') + tree.popElement(); + tree.reconstructActiveFormattingElements(); + tree.insertElement(name, attributes); + }; + + modes.inBody.startTagOther = function(name, attributes) { + tree.reconstructActiveFormattingElements(); + tree.insertElement(name, attributes); + }; + + modes.inBody.endTagOther = function(name) { + var node; + for (var i = tree.openElements.length - 1; i > 0; i--) { + node = tree.openElements.item(i); + if (node.localName == name) { + tree.generateImpliedEndTags(name); + if (tree.currentStackItem().localName != name) + tree.parseError('unexpected-end-tag', {name: name}); + // todo optimize + tree.openElements.remove_openElements_until(function(x) {return x === node;}); + break; + } + if (node.isSpecial()) { + tree.parseError('unexpected-end-tag', {name: name}); + break; + } + } + }; + + modes.inBody.startTagMath = function(name, attributes, selfClosing) { + tree.reconstructActiveFormattingElements(); + attributes = tree.adjustMathMLAttributes(attributes); + attributes = tree.adjustForeignAttributes(attributes); + tree.insertForeignElement(name, attributes, "http://www.w3.org/1998/Math/MathML", selfClosing); + // Need to get the parse error right for the case where the token + // has a namespace not equal to the xmlns attribute + }; + + modes.inBody.startTagSVG = function(name, attributes, selfClosing) { + tree.reconstructActiveFormattingElements(); + attributes = tree.adjustSVGAttributes(attributes); + attributes = tree.adjustForeignAttributes(attributes); + tree.insertForeignElement(name, attributes, "http://www.w3.org/2000/svg", selfClosing); + // Need to get the parse error right for the case where the token + // has a namespace not equal to the xmlns attribute + }; + + modes.inBody.endTagP = function(name) { + if (!tree.openElements.inButtonScope('p')) { + tree.parseError('unexpected-end-tag', {name: 'p'}); + this.startTagCloseP('p', []); + this.endTagP('p'); + } else { + tree.generateImpliedEndTags('p'); + if (tree.currentStackItem().localName != 'p') + tree.parseError('unexpected-implied-end-tag', {name: 'p'}); + tree.openElements.popUntilPopped(name); + } + }; + + modes.inBody.endTagBody = function(name) { + if (!tree.openElements.inScope('body')) { + tree.parseError('unexpected-end-tag', {name: name}); + return; + } + + /// @todo Emit parse error on end tags other than the ones listed in http://www.w3.org/TR/html5/tree-construction.html#parsing-main-inbody + // ['dd', 'dt', 'li', 'optgroup', 'option', 'p', 'rp', 'rt', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'body', 'html'] + if (tree.currentStackItem().localName != 'body') { + tree.parseError('expected-one-end-tag-but-got-another', { + expectedName: tree.currentStackItem().localName, + gotName: name + }); + } + tree.setInsertionMode('afterBody'); + }; + + modes.inBody.endTagHtml = function(name) { + if (!tree.openElements.inScope('body')) { + tree.parseError('unexpected-end-tag', {name: name}); + return; + } + + /// @todo Emit parse error on end tags other than the ones listed in http://www.w3.org/TR/html5/tree-construction.html#parsing-main-inbody + // ['dd', 'dt', 'li', 'optgroup', 'option', 'p', 'rp', 'rt', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'body', 'html'] + if (tree.currentStackItem().localName != 'body') { + tree.parseError('expected-one-end-tag-but-got-another', { + expectedName: tree.currentStackItem().localName, + gotName: name + }); + } + tree.setInsertionMode('afterBody'); + tree.insertionMode.processEndTag(name); + }; + + modes.inBody.endTagBlock = function(name) { + if (!tree.openElements.inScope(name)) { + tree.parseError('unexpected-end-tag', {name: name}); + } else { + tree.generateImpliedEndTags(); + if (tree.currentStackItem().localName != name) { + tree.parseError('end-tag-too-early', {name: name}); + } + tree.openElements.popUntilPopped(name); + } + }; + + modes.inBody.endTagForm = function(name) { + var node = tree.form; + tree.form = null; + if (!node || !tree.openElements.inScope(name)) { + tree.parseError('unexpected-end-tag', {name: name}); + } else { + tree.generateImpliedEndTags(); + if (tree.currentStackItem() != node) { + tree.parseError('end-tag-too-early-ignored', {name: 'form'}); + } + tree.openElements.remove(node); + } + }; + + modes.inBody.endTagListItem = function(name) { + if (!tree.openElements.inListItemScope(name)) { + tree.parseError('unexpected-end-tag', {name: name}); + } else { + tree.generateImpliedEndTags(name); + if (tree.currentStackItem().localName != name) + tree.parseError('end-tag-too-early', {name: name}); + tree.openElements.popUntilPopped(name); + } + }; + + modes.inBody.endTagHeading = function(name) { + if (!tree.openElements.hasNumberedHeaderElementInScope()) { + tree.parseError('unexpected-end-tag', {name: name}); + return; + } + tree.generateImpliedEndTags(); + if (tree.currentStackItem().localName != name) + tree.parseError('end-tag-too-early', {name: name}); + + tree.openElements.remove_openElements_until(function(e) { + return e.isNumberedHeader(); + }); + }; + + modes.inBody.endTagFormatting = function(name, attributes) { + if (!tree.adoptionAgencyEndTag(name)) + this.endTagOther(name, attributes); + }; + + modes.inCaption = Object.create(modes.base); + + modes.inCaption.start_tag_handlers = { + html: 'startTagHtml', + caption: 'startTagTableElement', + col: 'startTagTableElement', + colgroup: 'startTagTableElement', + tbody: 'startTagTableElement', + td: 'startTagTableElement', + tfoot: 'startTagTableElement', + thead: 'startTagTableElement', + tr: 'startTagTableElement', + '-default': 'startTagOther' + }; + + modes.inCaption.end_tag_handlers = { + caption: 'endTagCaption', + table: 'endTagTable', + body: 'endTagIgnore', + col: 'endTagIgnore', + colgroup: 'endTagIgnore', + html: 'endTagIgnore', + tbody: 'endTagIgnore', + td: 'endTagIgnore', + tfood: 'endTagIgnore', + thead: 'endTagIgnore', + tr: 'endTagIgnore', + '-default': 'endTagOther' + }; + + modes.inCaption.processCharacters = function(data) { + modes.inBody.processCharacters(data); + }; + + modes.inCaption.startTagTableElement = function(name, attributes) { + tree.parseError('unexpected-end-tag', {name: name}); + var ignoreEndTag = !tree.openElements.inTableScope('caption'); + tree.insertionMode.processEndTag('caption'); + if (!ignoreEndTag) tree.insertionMode.processStartTag(name, attributes); + }; + + modes.inCaption.startTagOther = function(name, attributes, selfClosing) { + modes.inBody.processStartTag(name, attributes, selfClosing); + }; + + modes.inCaption.endTagCaption = function(name) { + if (!tree.openElements.inTableScope('caption')) { + // context case + assert.ok(tree.context); + tree.parseError('unexpected-end-tag', {name: name}); + } else { + // AT this code is quite similar to endTagTable in inTable + tree.generateImpliedEndTags(); + if (tree.currentStackItem().localName != 'caption') { + // @todo this is confusing for implied end tag + tree.parseError('expected-one-end-tag-but-got-another', { + gotName: "caption", + expectedName: tree.currentStackItem().localName + }); + } + tree.openElements.popUntilPopped('caption'); + tree.clearActiveFormattingElements(); + tree.setInsertionMode('inTable'); + } + }; + + modes.inCaption.endTagTable = function(name) { + tree.parseError("unexpected-end-table-in-caption"); + var ignoreEndTag = !tree.openElements.inTableScope('caption'); + tree.insertionMode.processEndTag('caption'); + if (!ignoreEndTag) tree.insertionMode.processEndTag(name); + }; + + modes.inCaption.endTagIgnore = function(name) { + tree.parseError('unexpected-end-tag', {name: name}); + }; + + modes.inCaption.endTagOther = function(name) { + modes.inBody.processEndTag(name); + }; + + modes.inCell = Object.create(modes.base); + + modes.inCell.start_tag_handlers = { + html: 'startTagHtml', + caption: 'startTagTableOther', + col: 'startTagTableOther', + colgroup: 'startTagTableOther', + tbody: 'startTagTableOther', + td: 'startTagTableOther', + tfoot: 'startTagTableOther', + th: 'startTagTableOther', + thead: 'startTagTableOther', + tr: 'startTagTableOther', + '-default': 'startTagOther' + }; + + modes.inCell.end_tag_handlers = { + td: 'endTagTableCell', + th: 'endTagTableCell', + body: 'endTagIgnore', + caption: 'endTagIgnore', + col: 'endTagIgnore', + colgroup: 'endTagIgnore', + html: 'endTagIgnore', + table: 'endTagImply', + tbody: 'endTagImply', + tfoot: 'endTagImply', + thead: 'endTagImply', + tr: 'endTagImply', + '-default': 'endTagOther' + }; + + modes.inCell.processCharacters = function(data) { + modes.inBody.processCharacters(data); + }; + + modes.inCell.startTagTableOther = function(name, attributes, selfClosing) { + if (tree.openElements.inTableScope('td') || tree.openElements.inTableScope('th')) { + this.closeCell(); + tree.insertionMode.processStartTag(name, attributes, selfClosing); + } else { + // context case + tree.parseError('unexpected-start-tag', {name: name}); + } + }; + + modes.inCell.startTagOther = function(name, attributes, selfClosing) { + modes.inBody.processStartTag(name, attributes, selfClosing); + }; + + modes.inCell.endTagTableCell = function(name) { + if (tree.openElements.inTableScope(name)) { + tree.generateImpliedEndTags(name); + if (tree.currentStackItem().localName != name.toLowerCase()) { + tree.parseError('unexpected-cell-end-tag', {name: name}); + tree.openElements.popUntilPopped(name); + } else { + tree.popElement(); + } + tree.clearActiveFormattingElements(); + tree.setInsertionMode('inRow'); + } else { + tree.parseError('unexpected-end-tag', {name: name}); + } + }; + + modes.inCell.endTagIgnore = function(name) { + tree.parseError('unexpected-end-tag', {name: name}); + }; + + modes.inCell.endTagImply = function(name) { + if (tree.openElements.inTableScope(name)) { + this.closeCell(); + tree.insertionMode.processEndTag(name); + } else { + // sometimes context case + tree.parseError('unexpected-end-tag', {name: name}); + } + }; + + modes.inCell.endTagOther = function(name) { + modes.inBody.processEndTag(name); + }; + + modes.inCell.closeCell = function() { + if (tree.openElements.inTableScope('td')) { + this.endTagTableCell('td'); + } else if (tree.openElements.inTableScope('th')) { + this.endTagTableCell('th'); + } + }; + + + modes.inColumnGroup = Object.create(modes.base); + + modes.inColumnGroup.start_tag_handlers = { + html: 'startTagHtml', + col: 'startTagCol', + '-default': 'startTagOther' + }; + + modes.inColumnGroup.end_tag_handlers = { + colgroup: 'endTagColgroup', + col: 'endTagCol', + '-default': 'endTagOther' + }; + + modes.inColumnGroup.ignoreEndTagColgroup = function() { + return tree.currentStackItem().localName == 'html'; + }; + + modes.inColumnGroup.processCharacters = function(buffer) { + var leadingWhitespace = buffer.takeLeadingWhitespace(); + if (leadingWhitespace) + tree.insertText(leadingWhitespace); + if (!buffer.length) + return; + var ignoreEndTag = this.ignoreEndTagColgroup(); + this.endTagColgroup('colgroup'); + if (!ignoreEndTag) tree.insertionMode.processCharacters(buffer); + }; + + modes.inColumnGroup.startTagCol = function(name, attributes) { + tree.insertSelfClosingElement(name, attributes); + }; + + modes.inColumnGroup.startTagOther = function(name, attributes, selfClosing) { + var ignoreEndTag = this.ignoreEndTagColgroup(); + this.endTagColgroup('colgroup'); + if (!ignoreEndTag) tree.insertionMode.processStartTag(name, attributes, selfClosing); + }; + + modes.inColumnGroup.endTagColgroup = function(name) { + if (this.ignoreEndTagColgroup()) { + // context case + assert.ok(tree.context); + tree.parseError('unexpected-end-tag', {name: name}); + } else { + tree.popElement(); + tree.setInsertionMode('inTable'); + } + }; + + modes.inColumnGroup.endTagCol = function(name) { + tree.parseError("no-end-tag", {name: 'col'}); + }; + + modes.inColumnGroup.endTagOther = function(name) { + var ignoreEndTag = this.ignoreEndTagColgroup(); + this.endTagColgroup('colgroup'); + if (!ignoreEndTag) tree.insertionMode.processEndTag(name) ; + }; + + modes.inForeignContent = Object.create(modes.base); + + modes.inForeignContent.processStartTag = function(name, attributes, selfClosing) { + if (['b', 'big', 'blockquote', 'body', 'br', 'center', 'code', 'dd', 'div', 'dl', 'dt', 'em', 'embed', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'i', 'img', 'li', 'listing', 'menu', 'meta', 'nobr', 'ol', 'p', 'pre', 'ruby', 's', 'small', 'span', 'strong', 'strike', 'sub', 'sup', 'table', 'tt', 'u', 'ul', 'var'].indexOf(name) != -1 + || (name == 'font' && attributes.some(function(attr){ return ['color', 'face', 'size'].indexOf(attr.nodeName) >= 0 }))) { + tree.parseError('unexpected-html-element-in-foreign-content', {name: name}); + while (tree.currentStackItem().isForeign() + && !tree.currentStackItem().isHtmlIntegrationPoint() + && !tree.currentStackItem().isMathMLTextIntegrationPoint()) { + tree.openElements.pop(); + } + tree.insertionMode.processStartTag(name, attributes, selfClosing); + return; + } + if (tree.currentStackItem().namespaceURI == "http://www.w3.org/1998/Math/MathML") { + attributes = tree.adjustMathMLAttributes(attributes); + } + if (tree.currentStackItem().namespaceURI == "http://www.w3.org/2000/svg") { + name = tree.adjustSVGTagNameCase(name); + attributes = tree.adjustSVGAttributes(attributes); + } + attributes = tree.adjustForeignAttributes(attributes); + tree.insertForeignElement(name, attributes, tree.currentStackItem().namespaceURI, selfClosing); + }; + + modes.inForeignContent.processEndTag = function(name) { + var node = tree.currentStackItem(); + var index = tree.openElements.length - 1; + if (node.localName.toLowerCase() != name) + tree.parseError("unexpected-end-tag", {name: name}); + + while (true) { + if (index === 0) + break; + if (node.localName.toLowerCase() == name) { + while (tree.openElements.pop() != node); + break; + } + index -= 1; + node = tree.openElements.item(index); + if (node.isForeign()) { + continue; + } else { + tree.insertionMode.processEndTag(name); + break; + } + } + }; + + modes.inForeignContent.processCharacters = function(buffer) { + var characters = buffer.takeRemaining(); + characters = characters.replace(/\u0000/g, function(match, index){ + // @todo position + tree.parseError('invalid-codepoint'); + return '\uFFFD'; + }); + if (tree.framesetOk && !isAllWhitespaceOrReplacementCharacters(characters)) + tree.framesetOk = false; + tree.insertText(characters); + }; + + modes.inHeadNoscript = Object.create(modes.base); + + modes.inHeadNoscript.start_tag_handlers = { + html: 'startTagHtml', + basefont: 'startTagBasefontBgsoundLinkMetaNoframesStyle', + bgsound: 'startTagBasefontBgsoundLinkMetaNoframesStyle', + link: 'startTagBasefontBgsoundLinkMetaNoframesStyle', + meta: 'startTagBasefontBgsoundLinkMetaNoframesStyle', + noframes: 'startTagBasefontBgsoundLinkMetaNoframesStyle', + style: 'startTagBasefontBgsoundLinkMetaNoframesStyle', + head: 'startTagHeadNoscript', + noscript: 'startTagHeadNoscript', + "-default": 'startTagOther' + }; + + modes.inHeadNoscript.end_tag_handlers = { + noscript: 'endTagNoscript', + br: 'endTagBr', + '-default': 'endTagOther' + }; + + modes.inHeadNoscript.processCharacters = function(buffer) { + var leadingWhitespace = buffer.takeLeadingWhitespace(); + if (leadingWhitespace) + tree.insertText(leadingWhitespace); + if (!buffer.length) + return; + // FIXME error message + tree.parseError("unexpected-char-in-frameset"); + this.anythingElse(); + tree.insertionMode.processCharacters(buffer); + }; + + modes.inHeadNoscript.processComment = function(data) { + modes.inHead.processComment(data); + }; + + modes.inHeadNoscript.startTagBasefontBgsoundLinkMetaNoframesStyle = function(name, attributes) { + modes.inHead.processStartTag(name, attributes); + }; + + modes.inHeadNoscript.startTagHeadNoscript = function(name, attributes) { + // FIXME error message + tree.parseError("unexpected-start-tag-in-frameset", {name: name}); + }; + + modes.inHeadNoscript.startTagOther = function(name, attributes) { + // FIXME error message + tree.parseError("unexpected-start-tag-in-frameset", {name: name}); + this.anythingElse(); + tree.insertionMode.processStartTag(name, attributes); + }; + + modes.inHeadNoscript.endTagBr = function(name, attributes) { + // FIXME error message + tree.parseError("unexpected-end-tag-in-frameset", {name: name}); + this.anythingElse(); + tree.insertionMode.processEndTag(name, attributes); + }; + + modes.inHeadNoscript.endTagNoscript = function(name, attributes) { + tree.popElement(); + tree.setInsertionMode('inHead'); + }; + + modes.inHeadNoscript.endTagOther = function(name, attributes) { + // FIXME error message + tree.parseError("unexpected-end-tag-in-frameset", {name: name}); + }; + + modes.inHeadNoscript.anythingElse = function() { + tree.popElement(); + tree.setInsertionMode('inHead'); + }; + + + modes.inFrameset = Object.create(modes.base); + + modes.inFrameset.start_tag_handlers = { + html: 'startTagHtml', + frameset: 'startTagFrameset', + frame: 'startTagFrame', + noframes: 'startTagNoframes', + "-default": 'startTagOther' + }; + + modes.inFrameset.end_tag_handlers = { + frameset: 'endTagFrameset', + noframes: 'endTagNoframes', + '-default': 'endTagOther' + }; + + modes.inFrameset.processCharacters = function(data) { + tree.parseError("unexpected-char-in-frameset"); + }; + + modes.inFrameset.startTagFrameset = function(name, attributes) { + tree.insertElement(name, attributes); + }; + + modes.inFrameset.startTagFrame = function(name, attributes) { + tree.insertSelfClosingElement(name, attributes); + }; + + modes.inFrameset.startTagNoframes = function(name, attributes) { + modes.inBody.processStartTag(name, attributes); + }; + + modes.inFrameset.startTagOther = function(name, attributes) { + tree.parseError("unexpected-start-tag-in-frameset", {name: name}); + }; + + modes.inFrameset.endTagFrameset = function(name, attributes) { + if (tree.currentStackItem().localName == 'html') { + // context case + tree.parseError("unexpected-frameset-in-frameset-innerhtml"); + } else { + tree.popElement(); + } + + if (!tree.context && tree.currentStackItem().localName != 'frameset') { + // If we're not in context mode an the current node is not a "frameset" element (anymore) then switch + tree.setInsertionMode('afterFrameset'); + } + }; + + modes.inFrameset.endTagNoframes = function(name) { + modes.inBody.processEndTag(name); + }; + + modes.inFrameset.endTagOther = function(name) { + tree.parseError("unexpected-end-tag-in-frameset", {name: name}); + }; + + modes.inTable = Object.create(modes.base); + + modes.inTable.start_tag_handlers = { + html: 'startTagHtml', + caption: 'startTagCaption', + colgroup: 'startTagColgroup', + col: 'startTagCol', + table: 'startTagTable', + tbody: 'startTagRowGroup', + tfoot: 'startTagRowGroup', + thead: 'startTagRowGroup', + td: 'startTagImplyTbody', + th: 'startTagImplyTbody', + tr: 'startTagImplyTbody', + style: 'startTagStyleScript', + script: 'startTagStyleScript', + input: 'startTagInput', + form: 'startTagForm', + '-default': 'startTagOther' + }; + + modes.inTable.end_tag_handlers = { + table: 'endTagTable', + body: 'endTagIgnore', + caption: 'endTagIgnore', + col: 'endTagIgnore', + colgroup: 'endTagIgnore', + html: 'endTagIgnore', + tbody: 'endTagIgnore', + td: 'endTagIgnore', + tfoot: 'endTagIgnore', + th: 'endTagIgnore', + thead: 'endTagIgnore', + tr: 'endTagIgnore', + '-default': 'endTagOther' + }; + + modes.inTable.processCharacters = function(data) { + if (tree.currentStackItem().isFosterParenting()) { + var originalInsertionMode = tree.insertionModeName; + tree.setInsertionMode('inTableText'); + tree.originalInsertionMode = originalInsertionMode; + tree.insertionMode.processCharacters(data); + } else { + tree.redirectAttachToFosterParent = true; + modes.inBody.processCharacters(data); + tree.redirectAttachToFosterParent = false; + } + }; + + modes.inTable.startTagCaption = function(name, attributes) { + tree.openElements.popUntilTableScopeMarker(); + tree.activeFormattingElements.push(Marker); + tree.insertElement(name, attributes); + tree.setInsertionMode('inCaption'); + }; + + modes.inTable.startTagColgroup = function(name, attributes) { + tree.openElements.popUntilTableScopeMarker(); + tree.insertElement(name, attributes); + tree.setInsertionMode('inColumnGroup'); + }; + + modes.inTable.startTagCol = function(name, attributes) { + this.startTagColgroup('colgroup', []); + tree.insertionMode.processStartTag(name, attributes); + }; + + modes.inTable.startTagRowGroup = function(name, attributes) { + tree.openElements.popUntilTableScopeMarker(); + tree.insertElement(name, attributes); + tree.setInsertionMode('inTableBody'); + }; + + modes.inTable.startTagImplyTbody = function(name, attributes) { + this.startTagRowGroup('tbody', []); + tree.insertionMode.processStartTag(name, attributes); + }; + + modes.inTable.startTagTable = function(name, attributes) { + tree.parseError("unexpected-start-tag-implies-end-tag", + {startName: "table", endName: "table"}); + tree.insertionMode.processEndTag('table'); + if (!tree.context) tree.insertionMode.processStartTag(name, attributes); + }; + + modes.inTable.startTagStyleScript = function(name, attributes) { + modes.inHead.processStartTag(name, attributes); + }; + + modes.inTable.startTagInput = function(name, attributes) { + for (var key in attributes) { + if (attributes[key].nodeName.toLowerCase() == 'type') { + if (attributes[key].nodeValue.toLowerCase() == 'hidden') { + tree.parseError("unexpected-hidden-input-in-table"); + tree.insertElement(name, attributes); + // XXX associate with form + tree.openElements.pop(); + return; + } + break; + } + } + this.startTagOther(name, attributes); + }; + + modes.inTable.startTagForm = function(name, attributes) { + tree.parseError("unexpected-form-in-table"); + if (!tree.form) { + tree.insertElement(name, attributes); + tree.form = tree.currentStackItem(); + tree.openElements.pop(); + } + }; + + modes.inTable.startTagOther = function(name, attributes, selfClosing) { + tree.parseError("unexpected-start-tag-implies-table-voodoo", {name: name}); + tree.redirectAttachToFosterParent = true; + modes.inBody.processStartTag(name, attributes, selfClosing); + tree.redirectAttachToFosterParent = false; + }; + + modes.inTable.endTagTable = function(name) { + if (tree.openElements.inTableScope(name)) { + tree.generateImpliedEndTags(); + if (tree.currentStackItem().localName != name) { + tree.parseError("end-tag-too-early-named", {gotName: 'table', expectedName: tree.currentStackItem().localName}); + } + + tree.openElements.popUntilPopped('table'); + tree.resetInsertionMode(); + } else { + assert.ok(tree.context); + tree.parseError('unexpected-end-tag', {name: name}); + } + }; + + modes.inTable.endTagIgnore = function(name) { + tree.parseError("unexpected-end-tag", {name: name}); + }; + + modes.inTable.endTagOther = function(name) { + tree.parseError("unexpected-end-tag-implies-table-voodoo", {name: name}); + // Make all the special element rearranging voodoo kick in + tree.redirectAttachToFosterParent = true; + // Process the end tag in the "in body" mode + modes.inBody.processEndTag(name); + tree.redirectAttachToFosterParent = false; + }; + + modes.inTableText = Object.create(modes.base); + + modes.inTableText.flushCharacters = function() { + var characters = tree.pendingTableCharacters.join(''); + if (!isAllWhitespace(characters)) { + tree.redirectAttachToFosterParent = true; + tree.reconstructActiveFormattingElements(); + tree.insertText(characters); + tree.framesetOk = false; + tree.redirectAttachToFosterParent = false; + } else { + tree.insertText(characters); + } + tree.pendingTableCharacters = []; + }; + + modes.inTableText.processComment = function(data) { + this.flushCharacters(); + tree.setInsertionMode(tree.originalInsertionMode); + tree.insertionMode.processComment(data); + }; + + modes.inTableText.processEOF = function(data) { + this.flushCharacters(); + tree.setInsertionMode(tree.originalInsertionMode); + tree.insertionMode.processEOF(); + }; + + modes.inTableText.processCharacters = function(buffer) { + var characters = buffer.takeRemaining(); + characters = characters.replace(/\u0000/g, function(match, index){ + // @todo position + tree.parseError("invalid-codepoint"); + return ''; + }); + if (!characters) + return; + tree.pendingTableCharacters.push(characters); + }; + + modes.inTableText.processStartTag = function(name, attributes, selfClosing) { + this.flushCharacters(); + tree.setInsertionMode(tree.originalInsertionMode); + tree.insertionMode.processStartTag(name, attributes, selfClosing); + }; + + modes.inTableText.processEndTag = function(name, attributes) { + this.flushCharacters(); + tree.setInsertionMode(tree.originalInsertionMode); + tree.insertionMode.processEndTag(name, attributes); + }; + + modes.inTableBody = Object.create(modes.base); + + modes.inTableBody.start_tag_handlers = { + html: 'startTagHtml', + tr: 'startTagTr', + td: 'startTagTableCell', + th: 'startTagTableCell', + caption: 'startTagTableOther', + col: 'startTagTableOther', + colgroup: 'startTagTableOther', + tbody: 'startTagTableOther', + tfoot: 'startTagTableOther', + thead: 'startTagTableOther', + '-default': 'startTagOther' + }; + + modes.inTableBody.end_tag_handlers = { + table: 'endTagTable', + tbody: 'endTagTableRowGroup', + tfoot: 'endTagTableRowGroup', + thead: 'endTagTableRowGroup', + body: 'endTagIgnore', + caption: 'endTagIgnore', + col: 'endTagIgnore', + colgroup: 'endTagIgnore', + html: 'endTagIgnore', + td: 'endTagIgnore', + th: 'endTagIgnore', + tr: 'endTagIgnore', + '-default': 'endTagOther' + }; + + modes.inTableBody.processCharacters = function(data) { + modes.inTable.processCharacters(data); + }; + + modes.inTableBody.startTagTr = function(name, attributes) { + tree.openElements.popUntilTableBodyScopeMarker(); + tree.insertElement(name, attributes); + tree.setInsertionMode('inRow'); + }; + + modes.inTableBody.startTagTableCell = function(name, attributes) { + tree.parseError("unexpected-cell-in-table-body", {name: name}); + this.startTagTr('tr', []); + tree.insertionMode.processStartTag(name, attributes); + }; + + modes.inTableBody.startTagTableOther = function(name, attributes) { + // XXX any ideas on how to share this with endTagTable + if (tree.openElements.inTableScope('tbody') || tree.openElements.inTableScope('thead') || tree.openElements.inTableScope('tfoot')) { + tree.openElements.popUntilTableBodyScopeMarker(); + this.endTagTableRowGroup(tree.currentStackItem().localName); + tree.insertionMode.processStartTag(name, attributes); + } else { + // context case + tree.parseError('unexpected-start-tag', {name: name}); + } + }; + + modes.inTableBody.startTagOther = function(name, attributes) { + modes.inTable.processStartTag(name, attributes); + }; + + modes.inTableBody.endTagTableRowGroup = function(name) { + if (tree.openElements.inTableScope(name)) { + tree.openElements.popUntilTableBodyScopeMarker(); + tree.popElement(); + tree.setInsertionMode('inTable'); + } else { + tree.parseError('unexpected-end-tag-in-table-body', {name: name}); + } + }; + + modes.inTableBody.endTagTable = function(name) { + if (tree.openElements.inTableScope('tbody') || tree.openElements.inTableScope('thead') || tree.openElements.inTableScope('tfoot')) { + tree.openElements.popUntilTableBodyScopeMarker(); + this.endTagTableRowGroup(tree.currentStackItem().localName); + tree.insertionMode.processEndTag(name); + } else { + // context case + tree.parseError('unexpected-end-tag', {name: name}); + } + }; + + modes.inTableBody.endTagIgnore = function(name) { + tree.parseError("unexpected-end-tag-in-table-body", {name: name}); + }; + + modes.inTableBody.endTagOther = function(name) { + modes.inTable.processEndTag(name); + }; + + modes.inSelect = Object.create(modes.base); + + modes.inSelect.start_tag_handlers = { + html: 'startTagHtml', + option: 'startTagOption', + optgroup: 'startTagOptgroup', + select: 'startTagSelect', + input: 'startTagInput', + keygen: 'startTagInput', + textarea: 'startTagInput', + script: 'startTagScript', + '-default': 'startTagOther' + }; + + modes.inSelect.end_tag_handlers = { + option: 'endTagOption', + optgroup: 'endTagOptgroup', + select: 'endTagSelect', + caption: 'endTagTableElements', + table: 'endTagTableElements', + tbody: 'endTagTableElements', + tfoot: 'endTagTableElements', + thead: 'endTagTableElements', + tr: 'endTagTableElements', + td: 'endTagTableElements', + th: 'endTagTableElements', + '-default': 'endTagOther' + }; + + modes.inSelect.processCharacters = function(buffer) { + var data = buffer.takeRemaining(); + data = data.replace(/\u0000/g, function(match, index){ + // @todo position + tree.parseError("invalid-codepoint"); + return ''; + }); + if (!data) + return; + tree.insertText(data); + }; + + modes.inSelect.startTagOption = function(name, attributes) { + // we need to imply if ${3} +snippet curl+ + + + cparam+${6} + + ${3} +snippet credirect + +snippet contains + ${fn:contains(${1:string}, ${2:substr})} +snippet contains:i + ${fn:containsIgnoreCase(${1:string}, ${2:substr})} +snippet endswith + ${fn:endsWith(${1:string}, ${2:suffix})} +snippet escape + ${fn:escapeXml(${1:string})} +snippet indexof + ${fn:indexOf(${1:string}, ${2:substr})} +snippet join + ${fn:join(${1:collection}, ${2:delims})} +snippet length + ${fn:length(${1:collection_or_string})} +snippet replace + ${fn:replace(${1:string}, ${2:substr}, ${3:replace})} +snippet split + ${fn:split(${1:string}, ${2:delims})} +snippet startswith + ${fn:startsWith(${1:string}, ${2:prefix})} +snippet substr + ${fn:substring(${1:string}, ${2:begin}, ${3:end})} +snippet substr:a + ${fn:substringAfter(${1:string}, ${2:substr})} +snippet substr:b + ${fn:substringBefore(${1:string}, ${2:substr})} +snippet lc + ${fn:toLowerCase(${1:string})} +snippet uc + ${fn:toUpperCase(${1:string})} +snippet trim + ${fn:trim(${1:string})} diff --git a/lib/ace/snippets/jsx.js b/lib/ace/snippets/jsx.js new file mode 100644 index 00000000..9792a7a0 --- /dev/null +++ b/lib/ace/snippets/jsx.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./jsx.snippets"); +exports.scope = "jsx"; + +}); diff --git a/lib/ace/snippets/jsx.snippets b/lib/ace/snippets/jsx.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/julia.js b/lib/ace/snippets/julia.js new file mode 100644 index 00000000..f83777ef --- /dev/null +++ b/lib/ace/snippets/julia.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./julia.snippets"); +exports.scope = "julia"; + +}); diff --git a/lib/ace/snippets/julia.snippets b/lib/ace/snippets/julia.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/latex.js b/lib/ace/snippets/latex.js new file mode 100644 index 00000000..44bef369 --- /dev/null +++ b/lib/ace/snippets/latex.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./latex.snippets"); +exports.scope = "latex"; + +}); diff --git a/lib/ace/snippets/latex.snippets b/lib/ace/snippets/latex.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/lean.js b/lib/ace/snippets/lean.js new file mode 100644 index 00000000..a3c01639 --- /dev/null +++ b/lib/ace/snippets/lean.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./lean.snippets"); +exports.scope = "lean"; + +}); diff --git a/lib/ace/snippets/lean.snippets b/lib/ace/snippets/lean.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/ledger.snippets b/lib/ace/snippets/ledger.snippets new file mode 100644 index 00000000..293d4b65 --- /dev/null +++ b/lib/ace/snippets/ledger.snippets @@ -0,0 +1,5 @@ +# Ledger +snippet ent + `strftime("%Y/%m/%d")` ${1:transaction} + ${2:account} ${3:value} + ${4:account} diff --git a/lib/ace/snippets/less.js b/lib/ace/snippets/less.js new file mode 100644 index 00000000..7acf02f2 --- /dev/null +++ b/lib/ace/snippets/less.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./less.snippets"); +exports.scope = "less"; + +}); diff --git a/lib/ace/snippets/less.snippets b/lib/ace/snippets/less.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/liquid.js b/lib/ace/snippets/liquid.js new file mode 100644 index 00000000..2e320755 --- /dev/null +++ b/lib/ace/snippets/liquid.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./liquid.snippets"); +exports.scope = "liquid"; + +}); diff --git a/lib/ace/snippets/liquid.snippets b/lib/ace/snippets/liquid.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/lisp.js b/lib/ace/snippets/lisp.js new file mode 100644 index 00000000..2b6870bc --- /dev/null +++ b/lib/ace/snippets/lisp.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./lisp.snippets"); +exports.scope = "lisp"; + +}); diff --git a/lib/ace/snippets/lisp.snippets b/lib/ace/snippets/lisp.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/livescript.js b/lib/ace/snippets/livescript.js new file mode 100644 index 00000000..ba20e7e4 --- /dev/null +++ b/lib/ace/snippets/livescript.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./livescript.snippets"); +exports.scope = "livescript"; + +}); diff --git a/lib/ace/snippets/livescript.snippets b/lib/ace/snippets/livescript.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/logiql.js b/lib/ace/snippets/logiql.js new file mode 100644 index 00000000..7d0167da --- /dev/null +++ b/lib/ace/snippets/logiql.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./logiql.snippets"); +exports.scope = "logiql"; + +}); diff --git a/lib/ace/snippets/logiql.snippets b/lib/ace/snippets/logiql.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/lsl.js b/lib/ace/snippets/lsl.js new file mode 100644 index 00000000..678ba41f --- /dev/null +++ b/lib/ace/snippets/lsl.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./lsl.snippets"); +exports.scope = "lsl"; + +}); diff --git a/lib/ace/snippets/lsl.snippets b/lib/ace/snippets/lsl.snippets new file mode 100644 index 00000000..bc0d2eb9 --- /dev/null +++ b/lib/ace/snippets/lsl.snippets @@ -0,0 +1,1066 @@ +snippet @ + @${1:label}; +snippet CAMERA_ACTIVE + CAMERA_ACTIVE, ${1:integer isActive}, $0 +snippet CAMERA_BEHINDNESS_ANGLE + CAMERA_BEHINDNESS_ANGLE, ${1:float degrees}, $0 +snippet CAMERA_BEHINDNESS_LAG + CAMERA_BEHINDNESS_LAG, ${1:float seconds}, $0 +snippet CAMERA_DISTANCE + CAMERA_DISTANCE, ${1:float meters}, $0 +snippet CAMERA_FOCUS + CAMERA_FOCUS, ${1:vector position}, $0 +snippet CAMERA_FOCUS_LAG + CAMERA_FOCUS_LAG, ${1:float seconds}, $0 +snippet CAMERA_FOCUS_LOCKED + CAMERA_FOCUS_LOCKED, ${1:integer isLocked}, $0 +snippet CAMERA_FOCUS_OFFSET + CAMERA_FOCUS_OFFSET, ${1:vector meters}, $0 +snippet CAMERA_FOCUS_THRESHOLD + CAMERA_FOCUS_THRESHOLD, ${1:float meters}, $0 +snippet CAMERA_PITCH + CAMERA_PITCH, ${1:float degrees}, $0 +snippet CAMERA_POSITION + CAMERA_POSITION, ${1:vector position}, $0 +snippet CAMERA_POSITION_LAG + CAMERA_POSITION_LAG, ${1:float seconds}, $0 +snippet CAMERA_POSITION_LOCKED + CAMERA_POSITION_LOCKED, ${1:integer isLocked}, $0 +snippet CAMERA_POSITION_THRESHOLD + CAMERA_POSITION_THRESHOLD, ${1:float meters}, $0 +snippet CHARACTER_AVOIDANCE_MODE + CHARACTER_AVOIDANCE_MODE, ${1:integer flags}, $0 +snippet CHARACTER_DESIRED_SPEED + CHARACTER_DESIRED_SPEED, ${1:float speed}, $0 +snippet CHARACTER_DESIRED_TURN_SPEED + CHARACTER_DESIRED_TURN_SPEED, ${1:float speed}, $0 +snippet CHARACTER_LENGTH + CHARACTER_LENGTH, ${1:float length}, $0 +snippet CHARACTER_MAX_TURN_RADIUS + CHARACTER_MAX_TURN_RADIUS, ${1:float radius}, $0 +snippet CHARACTER_ORIENTATION + CHARACTER_ORIENTATION, ${1:integer orientation}, $0 +snippet CHARACTER_RADIUS + CHARACTER_RADIUS, ${1:float radius}, $0 +snippet CHARACTER_STAY_WITHIN_PARCEL + CHARACTER_STAY_WITHIN_PARCEL, ${1:boolean stay}, $0 +snippet CHARACTER_TYPE + CHARACTER_TYPE, ${1:integer type}, $0 +snippet HTTP_BODY_MAXLENGTH + HTTP_BODY_MAXLENGTH, ${1:integer length}, $0 +snippet HTTP_CUSTOM_HEADER + HTTP_CUSTOM_HEADER, ${1:string name}, ${2:string value}, $0 +snippet HTTP_METHOD + HTTP_METHOD, ${1:string method}, $0 +snippet HTTP_MIMETYPE + HTTP_MIMETYPE, ${1:string mimeType}, $0 +snippet HTTP_PRAGMA_NO_CACHE + HTTP_PRAGMA_NO_CACHE, ${1:integer send_header}, $0 +snippet HTTP_VERBOSE_THROTTLE + HTTP_VERBOSE_THROTTLE, ${1:integer noisy}, $0 +snippet HTTP_VERIFY_CERT + HTTP_VERIFY_CERT, ${1:integer verify}, $0 +snippet RC_DATA_FLAGS + RC_DATA_FLAGS, ${1:integer flags}, $0 +snippet RC_DETECT_PHANTOM + RC_DETECT_PHANTOM, ${1:integer dectedPhantom}, $0 +snippet RC_MAX_HITS + RC_MAX_HITS, ${1:integer maxHits}, $0 +snippet RC_REJECT_TYPES + RC_REJECT_TYPES, ${1:integer filterMask}, $0 +snippet at_rot_target + at_rot_target(${1:integer handle}, ${2:rotation targetrot}, ${3:rotation ourrot}) + { + $0 + } +snippet at_target + at_target(${1:integer tnum}, ${2:vector targetpos}, ${3:vector ourpos}) + { + $0 + } +snippet attach + attach(${1:key id}) + { + $0 + } +snippet changed + changed(${1:integer change}) + { + $0 + } +snippet collision + collision(${1:integer index}) + { + $0 + } +snippet collision_end + collision_end(${1:integer index}) + { + $0 + } +snippet collision_start + collision_start(${1:integer index}) + { + $0 + } +snippet control + control(${1:key id}, ${2:integer level}, ${3:integer edge}) + { + $0 + } +snippet dataserver + dataserver(${1:key query_id}, ${2:string data}) + { + $0 + } +snippet do + do + { + $0 + } + while (${1:condition}); +snippet else + else + { + $0 + } +snippet email + email(${1:string time}, ${2:string address}, ${3:string subject}, ${4:string message}, ${5:integer num_left}) + { + $0 + } +snippet experience_permissions + experience_permissions(${1:key agent_id}) + { + $0 + } +snippet experience_permissions_denied + experience_permissions_denied(${1:key agent_id}, ${2:integer reason}) + { + $0 + } +snippet for + for (${1:start}; ${3:condition}; ${3:step}) + { + $0 + } +snippet http_request + http_request(${1:key request_id}, ${2:string method}, ${3:string body}) + { + $0 + } +snippet http_response + http_response(${1:key request_id}, ${2:integer status}, ${3:list metadata}, ${4:string body}) + { + $0 + } +snippet if + if (${1:condition}) + { + $0 + } +snippet jump + jump ${1:label}; +snippet land_collision + land_collision(${1:vector pos}) + { + $0 + } +snippet land_collision_end + land_collision_end(${1:vector pos}) + { + $0 + } +snippet land_collision_start + land_collision_start(${1:vector pos}) + { + $0 + } +snippet link_message + link_message(${1:integer sender_num}, ${2:integer num}, ${3:string str}, ${4:key id}) + { + $0 + } +snippet listen + listen(${1:integer channel}, ${2:string name}, ${3:key id}, ${4:string message}) + { + $0 + } +snippet llAbs + llAbs(${1:integer val}) +snippet llAcos + llAcos(${1:float val}) +snippet llAddToLandBanList + llAddToLandBanList(${1:key agent}, ${2:float hours}); +snippet llAddToLandPassList + llAddToLandPassList(${1:key agent}, ${2:float hours}); +snippet llAdjustSoundVolume + llAdjustSoundVolume(${1:float volume}); +snippet llAgentInExperience + llAgentInExperience(${1:key agent}) +snippet llAllowInventoryDrop + llAllowInventoryDrop(${1:integer add}); +snippet llAngleBetween + llAngleBetween(${1:rotation a}, ${2:rotation b}) +snippet llApplyImpulse + llApplyImpulse(${1:vector force}, ${2:integer local}); +snippet llApplyRotationalImpulse + llApplyRotationalImpulse(${1:vector force}, ${2:integer local}); +snippet llAsin + llAsin(${1:float val}) +snippet llAtan2 + llAtan2(${1:float y}, ${2:float x}) +snippet llAttachToAvatar + llAttachToAvatar(${1:integer attach_point}); +snippet llAttachToAvatarTemp + llAttachToAvatarTemp(${1:integer attach_point}); +snippet llAvatarOnLinkSitTarget + llAvatarOnLinkSitTarget(${1:integer link}) +snippet llAvatarOnSitTarget + llAvatarOnSitTarget() +snippet llAxes2Rot + llAxes2Rot(${1:vector fwd}, ${2:vector left}, ${3:vector up}) +snippet llAxisAngle2Rot + llAxisAngle2Rot(${1:vector axis}, ${2:float angle}) +snippet llBase64ToInteger + llBase64ToInteger(${1:string str}) +snippet llBase64ToString + llBase64ToString(${1:string str}) +snippet llBreakAllLinks + llBreakAllLinks(); +snippet llBreakLink + llBreakLink(${1:integer link}); +snippet llCastRay + llCastRay(${1:vector start}, ${2:vector end}, ${3:list options}); +snippet llCeil + llCeil(${1:float val}) +snippet llClearCameraParams + llClearCameraParams(); +snippet llClearLinkMedia + llClearLinkMedia(${1:integer link}, ${2:integer face}); +snippet llClearPrimMedia + llClearPrimMedia(${1:integer face}); +snippet llCloseRemoteDataChannel + llCloseRemoteDataChannel(${1:key channel}); +snippet llCollisionFilter + llCollisionFilter(${1:string name}, ${2:key id}, ${3:integer accept}); +snippet llCollisionSound + llCollisionSound(${1:string impact_sound}, ${2:float impact_volume}); +snippet llCos + llCos(${1:float theta}) +snippet llCreateCharacter + llCreateCharacter(${1:list options}); +snippet llCreateKeyValue + llCreateKeyValue(${1:string k}) +snippet llCreateLink + llCreateLink(${1:key target}, ${2:integer parent}); +snippet llCSV2List + llCSV2List(${1:string src}) +snippet llDataSizeKeyValue + llDataSizeKeyValue() +snippet llDeleteCharacter + llDeleteCharacter(); +snippet llDeleteKeyValue + llDeleteKeyValue(${1:string k}) +snippet llDeleteSubList + llDeleteSubList(${1:list src}, ${2:integer start}, ${3:integer end}) +snippet llDeleteSubString + llDeleteSubString(${1:string src}, ${2:integer start}, ${3:integer end}) +snippet llDetachFromAvatar + llDetachFromAvatar(); +snippet llDetectedGrab + llDetectedGrab(${1:integer number}) +snippet llDetectedGroup + llDetectedGroup(${1:integer number}) +snippet llDetectedKey + llDetectedKey(${1:integer number}) +snippet llDetectedLinkNumber + llDetectedLinkNumber(${1:integer number}) +snippet llDetectedName + llDetectedName(${1:integer number}) +snippet llDetectedOwner + llDetectedOwner(${1:integer number}) +snippet llDetectedPos + llDetectedPosl(${1:integer number}) +snippet llDetectedRot + llDetectedRot(${1:integer number}) +snippet llDetectedTouchBinormal + llDetectedTouchBinormal(${1:integer number}) +snippet llDetectedTouchFace + llDetectedTouchFace(${1:integer number}) +snippet llDetectedTouchNormal + llDetectedTouchNormal(${1:integer number}) +snippet llDetectedTouchPos + llDetectedTouchPos(${1:integer number}) +snippet llDetectedTouchST + llDetectedTouchST(${1:integer number}) +snippet llDetectedTouchUV + llDetectedTouchUV(${1:integer number}) +snippet llDetectedType + llDetectedType(${1:integer number}) +snippet llDetectedVel + llDetectedVel(${1:integer number}) +snippet llDialog + llDialog(${1:key agent}, ${2:string message}, ${3:list buttons}, ${4:integer channel}); +snippet llDie + llDie(); +snippet llDumpList2String + llDumpList2String(${1:list src}, ${2:string separator}) +snippet llEdgeOfWorld + llEdgeOfWorld(${1:vector pos}, ${2:vector dir}) +snippet llEjectFromLand + llEjectFromLand(${1:key agent}); +snippet llEmail + llEmail(${1:string address}, ${2:string subject}, ${3:string message}); +snippet llEscapeURL + llEscapeURL(${1:string url}) +snippet llEuler2Rot + llEuler2Rot(${1:vector v}) +snippet llExecCharacterCmd + llExecCharacterCmd(${1:integer command}, ${2:list options}); +snippet llEvade + llEvade(${1:key target}, ${2:list options}); +snippet llFabs + llFabs(${1:float val}) +snippet llFleeFrom + llFleeFrom(${1:vector position}, ${2:float distance}, ${3:list options}); +snippet llFloor + llFloor(${1:float val}) +snippet llForceMouselook + llForceMouselook(${1:integer mouselook}); +snippet llFrand + llFrand(${1:float mag}) +snippet llGenerateKey + llGenerateKey() +snippet llGetAccel + llGetAccel() +snippet llGetAgentInfo + llGetAgentInfo(${1:key id}) +snippet llGetAgentLanguage + llGetAgentLanguage(${1:key agent}) +snippet llGetAgentList + llGetAgentList(${1:integer scope}, ${2:list options}) +snippet llGetAgentSize + llGetAgentSize(${1:key agent}) +snippet llGetAlpha + llGetAlpha(${1:integer face}) +snippet llGetAndResetTime + llGetAndResetTime() +snippet llGetAnimation + llGetAnimation(${1:key id}) +snippet llGetAnimationList + llGetAnimationList(${1:key agent}) +snippet llGetAnimationOverride + llGetAnimationOverride(${1:string anim_state}) +snippet llGetAttached + llGetAttached() +snippet llGetBoundingBox + llGetBoundingBox(${1:key object}) +snippet llGetCameraPos + llGetCameraPos() +snippet llGetCameraRot + llGetCameraRot() +snippet llGetCenterOfMass + llGetCenterOfMass() +snippet llGetClosestNavPoint + llGetClosestNavPoint(${1:vector point}, ${2:list options}) +snippet llGetColor + llGetColor(${1:integer face}) +snippet llGetCreator + llGetCreator() +snippet llGetDate + llGetDate() +snippet llGetDisplayName + llGetDisplayName(${1:key id}) +snippet llGetEnergy + llGetEnergy() +snippet llGetEnv + llGetEnv(${1:string name}) +snippet llGetExperienceDetails + llGetExperienceDetails(${1:key experience_id}) +snippet llGetExperienceErrorMessage + llGetExperienceErrorMessage(${1:integer error}) +snippet llGetForce + llGetForce() +snippet llGetFreeMemory + llGetFreeMemory() +snippet llGetFreeURLs + llGetFreeURLs() +snippet llGetGeometricCenter + llGetGeometricCenter() +snippet llGetGMTclock + llGetGMTclock() +snippet llGetHTTPHeader + llGetHTTPHeader(${1:key request_id}, ${2:string header}) +snippet llGetInventoryCreator + llGetInventoryCreator(${1:string item}) +snippet llGetInventoryKey + llGetInventoryKey(${1:string name}) +snippet llGetInventoryName + llGetInventoryName(${1:integer type}, ${2:integer number}) +snippet llGetInventoryNumber + llGetInventoryNumber(${1:integer type}) +snippet llGetInventoryPermMask + llGetInventoryPermMask(${1:string item}, ${2:integer mask}) +snippet llGetInventoryType + llGetInventoryType(${1:string name}) +snippet llGetKey + llGetKey() +snippet llGetLandOwnerAt + llGetLandOwnerAt(${1:vector pos}) +snippet llGetLinkKey + llGetLinkKey(${1:integer link}) +snippet llGetLinkMedia + llGetLinkMedia(${1:integer link}, ${2:integer face}, ${3:list params}) +snippet llGetLinkName + llGetLinkName(${1:integer link}) +snippet llGetLinkNumber + llGetLinkNumber() +snippet llGetLinkNumberOfSides + llGetLinkNumberOfSides(${1:integer link}) +snippet llGetLinkPrimitiveParams + llGetLinkPrimitiveParams(${1:integer link}, ${2:list params}) +snippet llGetListEntryType + llGetListEntryType(${1:list src}, ${2:integer index}) +snippet llGetListLength + llGetListLength(${1:list src}) +snippet llGetLocalPos + llGetLocalPos() +snippet llGetLocalRot + llGetLocalRot() +snippet llGetMass + llGetMass() +snippet llGetMassMKS + llGetMassMKS() +snippet llGetMaxScaleFactor + llGetMaxScaleFactor() +snippet llGetMemoryLimit + llGetMemoryLimit() +snippet llGetMinScaleFactor + llGetMinScaleFactor() +snippet llGetNextEmail + llGetNextEmail(${1:string address}, ${2:string subject}); +snippet llGetNotecardLine + llGetNotecardLine(${1:string name}, ${2:integer line}) +snippet llGetNumberOfNotecardLines + llGetNumberOfNotecardLines(${1:string name}) +snippet llGetNumberOfPrims + llGetNumberOfPrims() +snippet llGetNumberOfSides + llGetNumberOfSides() +snippet llGetObjectDesc + llGetObjectDesc() +snippet llGetObjectDetails + llGetObjectDetails(${1:key id}, ${2:list params}) +snippet llGetObjectMass + llGetObjectMass(${1:key id}) +snippet llGetObjectName + llGetObjectName() +snippet llGetObjectPermMask + llGetObjectPermMask(${1:integer mask}) +snippet llGetObjectPrimCount + llGetObjectPrimCount(${1:key prim}) +snippet llGetOmega + llGetOmega() +snippet llGetOwner + llGetOwner() +snippet llGetOwnerKey + llGetOwnerKey(${1:key id}) +snippet llGetParcelDetails + llGetParcelDetails(${1:vector pos}, ${2:list params}) +snippet llGetParcelFlags + llGetParcelFlags(${1:vector pos}) +snippet llGetParcelMaxPrims + llGetParcelMaxPrims(${1:vector pos}, ${2:integer sim_wide}) +snippet llGetParcelMusicURL + llGetParcelMusicURL() +snippet llGetParcelPrimCount + llGetParcelPrimCount(${1:vector pos}, ${2:integer category}, ${3:integer sim_wide}) +snippet llGetParcelPrimOwners + llGetParcelPrimOwners(${1:vector pos}) +snippet llGetPermissions + llGetPermissions() +snippet llGetPermissionsKey + llGetPermissionsKey() +snippet llGetPhysicsMaterial + llGetPhysicsMaterial() +snippet llGetPos + llGetPos() +snippet llGetPrimitiveParams + llGetPrimitiveParams(${1:list params}) +snippet llGetPrimMediaParams + llGetPrimMediaParams(${1:integer face}, ${2:list params}) +snippet llGetRegionAgentCount + llGetRegionAgentCount() +snippet llGetRegionCorner + llGetRegionCorner() +snippet llGetRegionFlags + llGetRegionFlags() +snippet llGetRegionFPS + llGetRegionFPS() +snippet llGetRegionName + llGetRegionName() +snippet llGetRegionTimeDilation + llGetRegionTimeDilation() +snippet llGetRootPosition + llGetRootPosition() +snippet llGetRootRotation + llGetRootRotation() +snippet llGetRot + llGetRot() +snippet llGetScale + llGetScale() +snippet llGetScriptName + llGetScriptName() +snippet llGetScriptState + llGetScriptState(${1:string script}) +snippet llGetSimStats + llGetSimStats(${1:integer stat_type}) +snippet llGetSimulatorHostname + llGetSimulatorHostname() +snippet llGetSPMaxMemory + llGetSPMaxMemory() +snippet llGetStartParameter + llGetStartParameter() +snippet llGetStaticPath + llGetStaticPath(${1:vector start}, ${2:vector end}, ${3:float radius}, ${4:list params}) +snippet llGetStatus + llGetStatus(${1:integer status}) +snippet llGetSubString + llGetSubString(${1:string src}, ${2:integer start}, ${3:integer end}) +snippet llGetSunDirection + llGetSunDirection() +snippet llGetTexture + llGetTexture(${1:integer face}) +snippet llGetTextureOffset + llGetTextureOffset(${1:integer face}) +snippet llGetTextureRot + llGetTextureRot(${1:integer face}) +snippet llGetTextureScale + llGetTextureScale(${1:integer face}) +snippet llGetTime + llGetTime() +snippet llGetTimeOfDay + llGetTimeOfDay() +snippet llGetTimestamp + llGetTimestamp() +snippet llGetTorque + llGetTorque() +snippet llGetUnixTime + llGetUnixTime() +snippet llGetUsedMemory + llGetUsedMemory() +snippet llGetUsername + llGetUsername(${1:key id}) +snippet llGetVel + llGetVel() +snippet llGetWallclock + llGetWallclock() +snippet llGiveInventory + llGiveInventory(${1:key destination}, ${2:string inventory}); +snippet llGiveInventoryList + llGiveInventoryList(${1:key target}, ${2:string folder}, ${3:list inventory}); +snippet llGiveMoney + llGiveMoney(${1:key destination}, ${2:integer amount}) +snippet llGround + llGround(${1:vector offset}) +snippet llGroundContour + llGroundContour(${1:vector offset}) +snippet llGroundNormal + llGroundNormal(${1:vector offset}) +snippet llGroundRepel + llGroundRepel(${1:float height}, ${2:integer water}, ${3:float tau}); +snippet llGroundSlope + llGroundSlope(${1:vector offset}) +snippet llHTTPRequest + llHTTPRequest(${1:string url}, ${2:list parameters}, ${3:string body}) +snippet llHTTPResponse + llHTTPResponse(${1:key request_id}, ${2:integer status}, ${3:string body}); +snippet llInsertString + llInsertString(${1:string dst}, ${2:integer pos}, ${3:string src}) +snippet llInstantMessage + llInstantMessage(${1:key user}, ${2:string message}); +snippet llIntegerToBase64 + llIntegerToBase64(${1:integer number}) +snippet llJson2List + llJson2List(${1:string json}) +snippet llJsonGetValue + llJsonGetValue(${1:string json}, ${2:list specifiers}) +snippet llJsonSetValue + llJsonSetValue(${1:string json}, ${2:list specifiers}, ${3:string newValue}) +snippet llJsonValueType + llJsonValueType(${1:string json}, ${2:list specifiers}) +snippet llKey2Name + llKey2Name(${1:key id}) +snippet llKeyCountKeyValue + llKeyCountKeyValue() +snippet llKeysKeyValue + llKeysKeyValue(${1:integer first}, ${2:integer count}) +snippet llLinkParticleSystem + llLinkParticleSystem(${1:integer link}, ${2:list rules}); +snippet llLinkSitTarget + llLinkSitTarget(${1:integer link}, ${2:vector offset}, ${3:rotation rot}); +snippet llList2CSV + llList2CSV(${1:list src}) +snippet llList2Float + llList2Float(${1:list src}, ${2:integer index}) +snippet llList2Integer + llList2Integer(${1:list src}, ${2:integer index}) +snippet llList2Json + llList2Json(${1:string type}, ${2:list values}) +snippet llList2Key + llList2Key(${1:list src}, ${2:integer index}) +snippet llList2List + llList2List(${1:list src}, ${2:integer start}, ${3:integer end}) +snippet llList2ListStrided + llList2ListStrided(${1:list src}, ${2:integer start}, ${3:integer end}, ${4:integer stride}) +snippet llList2Rot + llList2Rot(${1:list src}, ${2:integer index}) +snippet llList2String + llList2String(${1:list src}, ${2:integer index}) +snippet llList2Vector + llList2Vector(${1:list src}, ${2:integer index}) +snippet llListen + llListen(${1:integer channel}, ${2:string name}, ${3:key id}, ${4:string msg}) +snippet llListenControl + llListenControl(${1:integer handle}, ${2:integer active}); +snippet llListenRemove + llListenRemove(${1:integer handle}); +snippet llListFindList + llListFindList(${1:list src}, ${2:list test}) +snippet llListInsertList + llListInsertList(${1:list dest}, ${2:list src}, ${3:integer start}) +snippet llListRandomize + llListRandomize(${1:list src}, ${2:integer stride}) +snippet llListReplaceList + llListReplaceList(${1:list dest}, ${2:list src}, ${3:integer start}, ${4:integer end}) +snippet llListSort + llListSort(${1:list src}, ${2:integer stride}, ${3:integer ascending}) +snippet llListStatistics + llListStatistics(${1:integer operation}, ${2:list src}) +snippet llLoadURL + llLoadURL(${1:key agent}, ${2:string message}, ${3:string url}); +snippet llLog + llLog(${1:float val}) +snippet llLog10 + llLog10(${1:float val}) +snippet llLookAt + llLookAt(${1:vector target}, ${2:float strength}, ${3:float damping}); +snippet llLoopSound + llLoopSound(${1:string sound}, ${2:float volume}); +snippet llLoopSoundMaster + llLoopSoundMaster(${1:string sound}, ${2:float volume}); +snippet llLoopSoundSlave + llLoopSoundSlave(${1:string sound}, ${2:float volume}); +snippet llManageEstateAccess + llManageEstateAccess(${1:integer action}, ${2:key agent}) +snippet llMapDestination + llMapDestination(${1:string simname}, ${2:vector pos}, ${3:vector look_at}); +snippet llMD5String + llMD5String(${1:string src}, ${2:integer nonce}) +snippet llMessageLinked + llMessageLinked(${1:integer link}, ${2:integer num}, ${3:string str}, ${4:key id}); +snippet llMinEventDelay + llMinEventDelay(${1:float delay}); +snippet llModifyLand + llModifyLand(${1:integer action}, ${2:integer brush}); +snippet llModPow + llModPow(${1:integer a}, ${2:integer b}, ${3:integer c}) +snippet llMoveToTarget + llMoveToTarget(${1:vector target}, ${2:float tau}); +snippet llNavigateTo + llNavigateTo(${1:vector pos}, ${2:list options}); +snippet llOffsetTexture + llOffsetTexture(${1:float u}, ${2:float v}, ${3:integer face}); +snippet llOpenRemoteDataChannel + llOpenRemoteDataChannel(); +snippet llOverMyLand + llOverMyLand(${1:key id}) +snippet llOwnerSay + llOwnerSay(${1:string msg}); +snippet llParcelMediaCommandList + llParcelMediaCommandList(${1:list commandList}); +snippet llParcelMediaQuery + llParcelMediaQuery(${1:list query}) +snippet llParseString2List + llParseString2List(${1:string src}, ${2:list separators}, ${3:list spacers}) +snippet llParseStringKeepNulls + llParseStringKeepNulls(${1:string src}, ${2:list separators}, ${3:list spacers}) +snippet llParticleSystem + llParticleSystem(${1:list rules}); +snippet llPassCollisions + llPassCollisions(${1:integer pass}); +snippet llPassTouches + llPassTouches(${1:integer pass}); +snippet llPatrolPoints + llPatrolPoints(${1:list patrolPoints}, ${2:list options}); +snippet llPlaySound + llPlaySound(${1:string sound}, ${2:float volume}); +snippet llPlaySoundSlave + llPlaySoundSlave(${1:string sound}, ${2:float volume}); +snippet llPow + llPow(${1:float base}, ${2:float exponent}) +snippet llPreloadSound + llPreloadSound(${1:string sound}); +snippet llPursue + llPursue(${1:key target}, ${2:list options}); +snippet llPushObject + llPushObject(${1:key target}, ${2:vector impulse}, ${3:vector ang_impulse}, ${4:integer local}); +snippet llReadKeyValue + llReadKeyValue(${1:string k}) +snippet llRegionSay + llRegionSay(${1:integer channel}, ${2:string msg}); +snippet llRegionSayTo + llRegionSayTo(${1:key target}, ${2:integer channel}, ${3:string msg}); +snippet llReleaseControls + llReleaseControls(); +snippet llReleaseURL + llReleaseURL(${1:string url}); +snippet llRemoteDataReply + llRemoteDataReply(${1:key channel}, ${2:key message_id}, ${3:string sdata}, ${4:integer idata}); +snippet llRemoteLoadScriptPin + llRemoteLoadScriptPin(${1:key target}, ${2:string name}, ${3:integer pin}, ${4:integer running}, ${5:integer start_param}); +snippet llRemoveFromLandBanList + llRemoveFromLandBanList(${1:key agent}); +snippet llRemoveFromLandPassList + llRemoveFromLandPassList(${1:key agent}); +snippet llRemoveInventory + llRemoveInventory(${1:string item}); +snippet llRemoveVehicleFlags + llRemoveVehicleFlags(${1:integer flags}); +snippet llRequestAgentData + llRequestAgentData(${1:key id}, ${2:integer data}) +snippet llRequestDisplayName + llRequestDisplayName(${1:key id}) +snippet llRequestExperiencePermissions + llRequestExperiencePermissions(${1:key agent}, ${2:string name}) +snippet llRequestInventoryData + llRequestInventoryData(${1:string name}) +snippet llRequestPermissions + llRequestPermissions(${1:key agent}, ${2:integer permissions}) +snippet llRequestSecureURL + llRequestSecureURL() +snippet llRequestSimulatorData + llRequestSimulatorData(${1:string region}, ${2:integer data}) +snippet llRequestURL + llRequestURL() +snippet llRequestUsername + llRequestUsername(${1:key id}) +snippet llResetAnimationOverride + llResetAnimationOverride(${1:string anim_state}); +snippet llResetLandBanList + llResetLandBanList(); +snippet llResetLandPassList + llResetLandPassList(); +snippet llResetOtherScript + llResetOtherScript(${1:string name}); +snippet llResetScript + llResetScript(); +snippet llResetTime + llResetTime(); +snippet llReturnObjectsByID + llReturnObjectsByID(${1:list objects}) +snippet llReturnObjectsByOwner + llReturnObjectsByOwner(${1:key owner}, ${2:integer scope}) +snippet llRezAtRoot + llRezAtRoot(${1:string inventory}, ${2:vector position}, ${3:vector velocity}, ${4:rotation rot}, ${5:integer param}); +snippet llRezObject + llRezObject(${1:string inventory}, ${2:vector pos}, ${3:vector vel}, ${4:rotation rot}, ${5:integer param}); +snippet llRot2Angle + llRot2Angle(${1:rotation rot}) +snippet llRot2Axis + llRot2Axis(${1:rotation rot}) +snippet llRot2Euler + llRot2Euler(${1:rotation quat}) +snippet llRot2Fwd + llRot2Fwd(${1:rotation q}) +snippet llRot2Left + llRot2Left(${1:rotation q}) +snippet llRot2Up + llRot2Up(${1:rotation q}) +snippet llRotateTexture + llRotateTexture(${1:float angle}, ${2:integer face}); +snippet llRotBetween + llRotBetween(${1:vector start}, ${2:vector end}) +snippet llRotLookAt + llRotLookAt(${1:rotation target_direction}, ${2:float strength}, ${3:float damping}); +snippet llRotTarget + llRotTarget(${1:rotation rot}, ${2:float error}) +snippet llRotTargetRemove + llRotTargetRemove(${1:integer handle}); +snippet llRound + llRound(${1:float val}) +snippet llSameGroup + llSameGroup(${1:key group}) +snippet llSay + llSay(${1:integer channel}, ${2:string msg}); +snippet llScaleByFactor + llScaleByFactor(${1:float scaling_factor}) +snippet llScaleTexture + llScaleTexture(${1:float u}, ${2:float v}, ${3:integer face}); +snippet llScriptDanger + llScriptDanger(${1:vector pos}) +snippet llScriptProfiler + llScriptProfiler(${1:integer flags}); +snippet llSendRemoteData + llSendRemoteData(${1:key channel}, ${2:string dest}, ${3:integer idata}, ${4:string sdata}) +snippet llSensor + llSensor(${1:string name}, ${2:key id}, ${3:integer type}, ${4:float range}, ${5:float arc}); +snippet llSensorRepeat + llSensorRepeat(${1:string name}, ${2:key id}, ${3:integer type}, ${4:float range}, ${5:float arc}, ${6:float rate}); +snippet llSetAlpha + llSetAlpha(${1:float alpha}, ${2:integer face}); +snippet llSetAngularVelocity + llSetAngularVelocity(${1:vector force}, ${2:integer local}); +snippet llSetAnimationOverride + llSetAnimationOverride(${1:string anim_state}, ${2:string anim}) +snippet llSetBuoyancy + llSetBuoyancy(${1:float buoyancy}); +snippet llSetCameraAtOffset + llSetCameraAtOffset(${1:vector offset}); +snippet llSetCameraEyeOffset + llSetCameraEyeOffset(${1:vector offset}); +snippet llSetCameraParams + llSetCameraParams(${1:list rules}); +snippet llSetClickAction + llSetClickAction(${1:integer action}); +snippet llSetColor + llSetColor(${1:vector color}, ${2:integer face}); +snippet llSetContentType + llSetContentType(${1:key request_id}, ${2:integer content_type}); +snippet llSetDamage + llSetDamage(${1:float damage}); +snippet llSetForce + llSetForce(${1:vector force}, ${2:integer local}); +snippet llSetForceAndTorque + llSetForceAndTorque(${1:vector force}, ${2:vector torque}, ${3:integer local}); +snippet llSetHoverHeight + llSetHoverHeight(${1:float height}, ${2:integer water}, ${3:float tau}); +snippet llSetKeyframedMotion + llSetKeyframedMotion(${1:list keyframes}, ${2:list options}); +snippet llSetLinkAlpha + llSetLinkAlpha(${1:integer link}, ${2:float alpha}, ${3:integer face}); +snippet llSetLinkCamera + llSetLinkCamera(${1:integer link}, ${2:vector eye}, ${3:vector at}); +snippet llSetLinkColor + llSetLinkColor(${1:integer link}, ${2:vector color}, ${3:integer face}); +snippet llSetLinkMedia + llSetLinkMedia(${1:integer link}, ${2:integer face}, ${3:list params}); +snippet llSetLinkPrimitiveParams + llSetLinkPrimitiveParams(${1:integer link}, ${2:list rules}); +snippet llSetLinkPrimitiveParamsFast + llSetLinkPrimitiveParamsFast(${1:integer link}, ${2:list rules}); +snippet llSetLinkTexture + llSetLinkTexture(${1:integer link}, ${2:string texture}, ${3:integer face}); +snippet llSetLinkTextureAnim + llSetLinkTextureAnim(${1:integer link}, ${2:integer mode}, ${3:integer face}, ${4:integer sizex}, ${5:integer sizey}, ${6:float start}, ${7:float length}, ${8:float rate}); +snippet llSetLocalRot + llSetLocalRot(${1:rotation rot}); +snippet llSetMemoryLimit + llSetMemoryLimit(${1:integer limit}) +snippet llSetObjectDesc + llSetObjectDesc(${1:string description}); +snippet llSetObjectName + llSetObjectName(${1:string name}); +snippet llSetParcelMusicURL + llSetParcelMusicURL(${1:string url}); +snippet llSetPayPrice + llSetPayPrice(${1:integer price}, [${2:integer price_button_a}, ${3:integer price_button_b}, ${4:integer price_button_c}, ${5:integer price_button_d}]); +snippet llSetPhysicsMaterial + llSetPhysicsMaterial(${1:integer mask}, ${2:float gravity_multiplier}, ${3:float restitution}, ${4:float friction}, ${5:float density}); +snippet llSetPos + llSetPos(${1:vector pos}); +snippet llSetPrimitiveParams + llSetPrimitiveParams(${1:list rules}); +snippet llSetPrimMediaParams + llSetPrimMediaParams(${1:integer face}, ${2:list params}); +snippet llSetRegionPos + llSetRegionPos(${1:vector position}) +snippet llSetRemoteScriptAccessPin + llSetRemoteScriptAccessPin(${1:integer pin}); +snippet llSetRot + llSetRot(${1:rotation rot}); +snippet llSetScale + llSetScale(${1:vector size}); +snippet llSetScriptState + llSetScriptState(${1:string name}, ${2:integer run}); +snippet llSetSitText + llSetSitText(${1:string text}); +snippet llSetSoundQueueing + llSetSoundQueueing(${1:integer queue}); +snippet llSetSoundRadius + llSetSoundRadius(${1:float radius}); +snippet llSetStatus + llSetStatus(${1:integer status}, ${2:integer value}); +snippet llSetText + llSetText(${1:string text}, ${2:vector color}, ${3:float alpha}); +snippet llSetTexture + llSetTexture(${1:string texture}, ${2:integer face}); +snippet llSetTextureAnim + llSetTextureAnim(${1:integer mode}, ${2:integer face}, ${3:integer sizex}, ${4:integer sizey}, ${5:float start}, ${6:float length}, ${7:float rate}); +snippet llSetTimerEvent + llSetTimerEvent(${1:float sec}); +snippet llSetTorque + llSetTorque(${1:vector torque}, ${2:integer local}); +snippet llSetTouchText + llSetTouchText(${1:string text}); +snippet llSetVehicleFlags + llSetVehicleFlags(${1:integer flags}); +snippet llSetVehicleFloatParam + llSetVehicleFloatParam(${1:integer param}, ${2:float value}); +snippet llSetVehicleRotationParam + llSetVehicleRotationParam(${1:integer param}, ${2:rotation rot}); +snippet llSetVehicleType + llSetVehicleType(${1:integer type}); +snippet llSetVehicleVectorParam + llSetVehicleVectorParam(${1:integer param}, ${2:vector vec}); +snippet llSetVelocity + llSetVelocity(${1:vector force}, ${2:integer local}); +snippet llSHA1String + llSHA1String(${1:string src}) +snippet llShout + llShout(${1:integer channel}, ${2:string msg}); +snippet llSin + llSin(${1:float theta}) +snippet llSitTarget + llSitTarget(${1:vector offset}, ${2:rotation rot}); +snippet llSleep + llSleep(${1:float sec}); +snippet llSqrt + llSqrt(${1:float val}) +snippet llStartAnimation + llStartAnimation(${1:string anim}); +snippet llStopAnimation + llStopAnimation(${1:string anim}); +snippet llStopHover + llStopHover(); +snippet llStopLookAt + llStopLookAt(); +snippet llStopMoveToTarget + llStopMoveToTarget(); +snippet llStopSound + llStopSound(); +snippet llStringLength + llStringLength(${1:string str}) +snippet llStringToBase64 + llStringToBase64(${1:string str}) +snippet llStringTrim + llStringTrim(${1:string src}, ${2:integer type}) +snippet llSubStringIndex + llSubStringIndex(${1:string source}, ${2:string pattern}) +snippet llTakeControls + llTakeControls(${1:integer controls}, ${2:integer accept}, ${3:integer pass_on}); +snippet llTan + llTan(${1:float theta}) +snippet llTarget + llTarget(${1:vector position}, ${2:float range}) +snippet llTargetOmega + llTargetOmega(${1:vector axis}, ${2:float spinrate}, ${3:float gain}); +snippet llTargetRemove + llTargetRemove(${1:integer handle}); +snippet llTeleportAgent + llTeleportAgent(${1:key agent}, ${2:string landmark}, ${3:vector position}, ${4:vector look_at}); +snippet llTeleportAgentGlobalCoords + llTeleportAgentGlobalCoords(${1:key agent}, ${2:vector global_coordinates}, ${3:vector region_coordinates}, ${4:vector look_at}); +snippet llTeleportAgentHome + llTeleportAgentHome(${1:key agent}); +snippet llTextBox + llTextBox(${1:key agent}, ${2:string message}, ${3:integer channel}); +snippet llToLower + llToLower(${1:string src}) +snippet llToUpper + llToUpper(${1:string src}) +snippet llTransferLindenDollars + llTransferLindenDollars(${1:key destination}, ${2:integer amount}) +snippet llTriggerSound + llTriggerSound(${1:string sound}, ${2:float volume}); +snippet llTriggerSoundLimited + llTriggerSoundLimited(${1:string sound}, ${2:float volume}, ${3:vector top_north_east}, ${4:vector bottom_south_west}); +snippet llUnescapeURL + llUnescapeURL(${1:string url}) +snippet llUnSit + llUnSit(${1:key id}); +snippet llUpdateCharacter + llUpdateCharacter(${1:list options}) +snippet llUpdateKeyValue + llUpdateKeyValue(${1:string k}, ${2:string v}, ${3:integer checked}, ${4:string ov}) +snippet llVecDist + llVecDist(${1:vector vec_a}, ${2:vector vec_b}) +snippet llVecMag + llVecMag(${1:vector vec}) +snippet llVecNorm + llVecNorm(${1:vector vec}) +snippet llVolumeDetect + llVolumeDetect(${1:integer detect}); +snippet llWanderWithin + llWanderWithin(${1:vector origin}, ${2:vector dist}, ${3:list options}); +snippet llWater + llWater(${1:vector offset}); +snippet llWhisper + llWhisper(${1:integer channel}, ${2:string msg}); +snippet llWind + llWind(${1:vector offset}); +snippet llXorBase64 + llXorBase64(${1:string str1}, ${2:string str2}) +snippet money + money(${1:key id}, ${2:integer amount}) + { + $0 + } +snippet object_rez + object_rez(${1:key id}) + { + $0 + } +snippet on_rez + on_rez(${1:integer start_param}) + { + $0 + } +snippet path_update + path_update(${1:integer type}, ${2:list reserved}) + { + $0 + } +snippet remote_data + remote_data(${1:integer event_type}, ${2:key channel}, ${3:key message_id}, ${4:string sender}, ${5:integer idata}, ${6:string sdata}) + { + $0 + } +snippet run_time_permissions + run_time_permissions(${1:integer perm}) + { + $0 + } +snippet sensor + sensor(${1:integer index}) + { + $0 + } +snippet state + state ${1:name} +snippet touch + touch(${1:integer index}) + { + $0 + } +snippet touch_end + touch_end(${1:integer index}) + { + $0 + } +snippet touch_start + touch_start(${1:integer index}) + { + $0 + } +snippet transaction_result + transaction_result(${1:key id}, ${2:integer success}, ${3:string data}) + { + $0 + } +snippet while + while (${1:condition}) + { + $0 + } diff --git a/lib/ace/snippets/lua.js b/lib/ace/snippets/lua.js new file mode 100644 index 00000000..0ab6fdcd --- /dev/null +++ b/lib/ace/snippets/lua.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./lua.snippets"); +exports.scope = "lua"; + +}); diff --git a/lib/ace/snippets/lua.snippets b/lib/ace/snippets/lua.snippets new file mode 100644 index 00000000..34ae25eb --- /dev/null +++ b/lib/ace/snippets/lua.snippets @@ -0,0 +1,21 @@ +snippet #! + #!/usr/bin/env lua + $1 +snippet local + local ${1:x} = ${2:1} +snippet fun + function ${1:fname}(${2:...}) + ${3:-- body} + end +snippet for + for ${1:i}=${2:1},${3:10} do + ${4:print(i)} + end +snippet forp + for ${1:i},${2:v} in pairs(${3:table_name}) do + ${4:-- body} + end +snippet fori + for ${1:i},${2:v} in ipairs(${3:table_name}) do + ${4:-- body} + end diff --git a/lib/ace/snippets/luapage.js b/lib/ace/snippets/luapage.js new file mode 100644 index 00000000..86b22842 --- /dev/null +++ b/lib/ace/snippets/luapage.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./luapage.snippets"); +exports.scope = "luapage"; + +}); diff --git a/lib/ace/snippets/luapage.snippets b/lib/ace/snippets/luapage.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/lucene.js b/lib/ace/snippets/lucene.js new file mode 100644 index 00000000..01edb07d --- /dev/null +++ b/lib/ace/snippets/lucene.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./lucene.snippets"); +exports.scope = "lucene"; + +}); diff --git a/lib/ace/snippets/lucene.snippets b/lib/ace/snippets/lucene.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/makefile.js b/lib/ace/snippets/makefile.js new file mode 100644 index 00000000..0ec05ac0 --- /dev/null +++ b/lib/ace/snippets/makefile.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./makefile.snippets"); +exports.scope = "makefile"; + +}); diff --git a/lib/ace/snippets/makefile.snippets b/lib/ace/snippets/makefile.snippets new file mode 100644 index 00000000..43648136 --- /dev/null +++ b/lib/ace/snippets/makefile.snippets @@ -0,0 +1,4 @@ +snippet ifeq + ifeq (${1:cond0},${2:cond1}) + ${3:code} + endif diff --git a/lib/ace/snippets/mako.snippets b/lib/ace/snippets/mako.snippets new file mode 100644 index 00000000..2a0aef9c --- /dev/null +++ b/lib/ace/snippets/mako.snippets @@ -0,0 +1,54 @@ +snippet def + <%def name="${1:name}"> + ${2:} + +snippet call + <%call expr="${1:name}"> + ${2:} + +snippet doc + <%doc> + ${1:} + +snippet text + <%text> + ${1:} + +snippet for + % for ${1:i} in ${2:iter}: + ${3:} + % endfor +snippet if if + % if ${1:condition}: + ${2:} + % endif +snippet if if/else + % if ${1:condition}: + ${2:} + % else: + ${3:} + % endif +snippet try + % try: + ${1:} + % except${2:}: + ${3:pass} + % endtry +snippet wh + % while ${1:}: + ${2:} + % endwhile +snippet $ + ${ ${1:} } +snippet <% + <% ${1:} %> +snippet +snippet inherit + <%inherit file="${1:filename}" /> +snippet include + <%include file="${1:filename}" /> +snippet namespace + <%namespace file="${1:name}" /> +snippet page + <%page args="${1:}" /> diff --git a/lib/ace/snippets/markdown.js b/lib/ace/snippets/markdown.js new file mode 100644 index 00000000..3940bc90 --- /dev/null +++ b/lib/ace/snippets/markdown.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./markdown.snippets"); +exports.scope = "markdown"; + +}); diff --git a/lib/ace/snippets/markdown.snippets b/lib/ace/snippets/markdown.snippets new file mode 100644 index 00000000..a5110fc9 --- /dev/null +++ b/lib/ace/snippets/markdown.snippets @@ -0,0 +1,88 @@ +# Markdown + +# Includes octopress (http://octopress.org/) snippets + +snippet [ + [${1:text}](http://${2:address} "${3:title}") +snippet [* + [${1:link}](${2:`@*`} "${3:title}")${4} + +snippet [: + [${1:id}]: http://${2:url} "${3:title}" +snippet [:* + [${1:id}]: ${2:`@*`} "${3:title}" + +snippet ![ + ![${1:alttext}](${2:/images/image.jpg} "${3:title}") +snippet ![* + ![${1:alt}](${2:`@*`} "${3:title}")${4} + +snippet ![: + ![${1:id}]: ${2:url} "${3:title}" +snippet ![:* + ![${1:id}]: ${2:`@*`} "${3:title}" + +snippet === +regex /^/=+/=*// + ${PREV_LINE/./=/g} + + ${0} +snippet --- +regex /^/-+/-*// + ${PREV_LINE/./-/g} + + ${0} +snippet blockquote + {% blockquote %} + ${1:quote} + {% endblockquote %} + +snippet blockquote-author + {% blockquote ${1:author}, ${2:title} %} + ${3:quote} + {% endblockquote %} + +snippet blockquote-link + {% blockquote ${1:author} ${2:URL} ${3:link_text} %} + ${4:quote} + {% endblockquote %} + +snippet bt-codeblock-short + ``` + ${1:code_snippet} + ``` + +snippet bt-codeblock-full + ``` ${1:language} ${2:title} ${3:URL} ${4:link_text} + ${5:code_snippet} + ``` + +snippet codeblock-short + {% codeblock %} + ${1:code_snippet} + {% endcodeblock %} + +snippet codeblock-full + {% codeblock ${1:title} lang:${2:language} ${3:URL} ${4:link_text} %} + ${5:code_snippet} + {% endcodeblock %} + +snippet gist-full + {% gist ${1:gist_id} ${2:filename} %} + +snippet gist-short + {% gist ${1:gist_id} %} + +snippet img + {% img ${1:class} ${2:URL} ${3:width} ${4:height} ${5:title_text} ${6:alt_text} %} + +snippet youtube + {% youtube ${1:video_id} %} + +# The quote should appear only once in the text. It is inherently part of it. +# See http://octopress.org/docs/plugins/pullquote/ for more info. + +snippet pullquote + {% pullquote %} + ${1:text} {" ${2:quote} "} ${3:text} + {% endpullquote %} diff --git a/lib/ace/snippets/mask.js b/lib/ace/snippets/mask.js new file mode 100644 index 00000000..7fbca678 --- /dev/null +++ b/lib/ace/snippets/mask.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./mask.snippets"); +exports.scope = "mask"; + +}); diff --git a/lib/ace/snippets/mask.snippets b/lib/ace/snippets/mask.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/matlab.js b/lib/ace/snippets/matlab.js new file mode 100644 index 00000000..698366ba --- /dev/null +++ b/lib/ace/snippets/matlab.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./matlab.snippets"); +exports.scope = "matlab"; + +}); diff --git a/lib/ace/snippets/matlab.snippets b/lib/ace/snippets/matlab.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/mel.js b/lib/ace/snippets/mel.js new file mode 100644 index 00000000..090d79b3 --- /dev/null +++ b/lib/ace/snippets/mel.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./mel.snippets"); +exports.scope = "mel"; + +}); diff --git a/lib/ace/snippets/mel.snippets b/lib/ace/snippets/mel.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/mushcode.js b/lib/ace/snippets/mushcode.js new file mode 100644 index 00000000..8b0d2dcb --- /dev/null +++ b/lib/ace/snippets/mushcode.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./mushcode.snippets"); +exports.scope = "mushcode"; + +}); diff --git a/lib/ace/snippets/mushcode.snippets b/lib/ace/snippets/mushcode.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/mushcode_high_rules.js b/lib/ace/snippets/mushcode_high_rules.js new file mode 100644 index 00000000..25d42827 --- /dev/null +++ b/lib/ace/snippets/mushcode_high_rules.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./mushcode_high_rules.snippets"); +exports.scope = "mushcode_high_rules"; + +}); diff --git a/lib/ace/snippets/mushcode_high_rules.snippets b/lib/ace/snippets/mushcode_high_rules.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/mysql.js b/lib/ace/snippets/mysql.js new file mode 100644 index 00000000..e5462390 --- /dev/null +++ b/lib/ace/snippets/mysql.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./mysql.snippets"); +exports.scope = "mysql"; + +}); diff --git a/lib/ace/snippets/mysql.snippets b/lib/ace/snippets/mysql.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/nim.js b/lib/ace/snippets/nim.js new file mode 100644 index 00000000..6e6d02bb --- /dev/null +++ b/lib/ace/snippets/nim.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./nim.snippets"); +exports.scope = "nim"; + +}); diff --git a/lib/ace/snippets/nim.snippets b/lib/ace/snippets/nim.snippets new file mode 100644 index 00000000..a8a20a00 --- /dev/null +++ b/lib/ace/snippets/nim.snippets @@ -0,0 +1,130 @@ +snippet #! + #!/usr/bin/env nim +snippet imp + import ${1:module} +snippet from + from ${1:package} import ${2:module} +# Module Docstring +snippet docs + ## File: ${1:FILENAME:file_name} + ## Author: ${2:author} + ## Description: ${3} +snippet wh + while ${1:condition}: + ${2:# TODO: write code...} +# dowh - does the same as do...while in other languages +snippet dowh + while true: + ${1:# TODO: write code...} + if ${2:condition}: + break +snippet with + with ${1:expr} as ${2:var}: + ${3:# TODO: write code...} +# New Function +snippet proc + proc ${1:fname}(${2:`indent('.') ? 'self' : ''`}): ${3: return type} = + ##${4:docstring for $1} + ${5:# TODO: write code...} +snippet deff + def ${1:fname}(${2:`indent('.') ? 'self' : ''`}): + ${3:# TODO: write code...} +# New Method +snippet defs + def ${1:mname}(self, ${2:arg}): + ${3:# TODO: write code...} +# New Property +snippet property + def ${1:foo}(): + doc = "${2:The $1 property.}" + def fget(self): + ${3:return self._$1} + def fset(self, value): + ${4:self._$1 = value} +# Ifs +snippet if + if ${1:condition}: + ${2:# TODO: write code...} +snippet el + else: + ${1:# TODO: write code...} +snippet ei + elif ${1:condition}: + ${2:# TODO: write code...} +# For +snippet for + for ${1:item} in ${2:items}: + ${3:# TODO: write code...} +# Encodes +snippet cutf8 + # -*- coding: utf-8 -*- +snippet clatin1 + # -*- coding: latin-1 -*- +snippet cascii + # -*- coding: ascii -*- +# Lambda +snippet ld + ${1:var} = lambda ${2:vars} : ${3:action} +snippet . + self. +snippet try Try/Except + try: + ${1:# TODO: write code...} + except ${2:Exception}, ${3:e}: + ${4:raise $3} +snippet try Try/Except/Else + try: + ${1:# TODO: write code...} + except ${2:Exception}, ${3:e}: + ${4:raise $3} + else: + ${5:# TODO: write code...} +snippet try Try/Except/Finally + try: + ${1:# TODO: write code...} + except ${2:Exception}, ${3:e}: + ${4:raise $3} + finally: + ${5:# TODO: write code...} +snippet try Try/Except/Else/Finally + try: + ${1:# TODO: write code...} + except ${2:Exception}, ${3:e}: + ${4:raise $3} + else: + ${5:# TODO: write code...} + finally: + ${6:# TODO: write code...} +# if __name__ == '__main__': +snippet ifmain + if isMainModule: + ${1:main()} +snippet " + ## ${1:doc} +# test function/method +snippet test + def test_${1:description}(${2:self}): + ${3:# TODO: write code...} +# test case +snippet testcase + class ${1:ExampleCase}(unittest.TestCase): + + def test_${2:description}(self): + ${3:# TODO: write code...} +#getopt +snippet getopt + try: + # Short option syntax: "hv:" + # Long option syntax: "help" or "verbose=" + opts, args = getopt.getopt(sys.argv[1:], "${1:short_options}", [${2:long_options}]) + + except getopt.GetoptError, err: + # Print debug info + print str(err) + ${3:error_action} + + for option, argument in opts: + if option in ("-h", "--help"): + ${4} + elif option in ("-v", "--verbose"): + verbose = argument diff --git a/lib/ace/snippets/nix.js b/lib/ace/snippets/nix.js new file mode 100644 index 00000000..583abf85 --- /dev/null +++ b/lib/ace/snippets/nix.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./nix.snippets"); +exports.scope = "nix"; + +}); diff --git a/lib/ace/snippets/nix.snippets b/lib/ace/snippets/nix.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/objc.snippets b/lib/ace/snippets/objc.snippets new file mode 100644 index 00000000..5517b062 --- /dev/null +++ b/lib/ace/snippets/objc.snippets @@ -0,0 +1,247 @@ +# #import <...> +snippet Imp + #import <${1:Cocoa/Cocoa.h}>${2} +# #import "..." +snippet imp + #import "${1:`Filename()`.h}"${2} +# @selector(...) +snippet sel + @selector(${1:method}:)${3} +# @"..." string +snippet s + @"${1}"${2} +# Object +snippet o + ${1:NSObject} *${2:foo} = [${3:$1 alloc}]${4};${5} +# NSLog(...) +snippet log + NSLog(@"${1:%@}"${2});${3} +# Class +snippet objc + @interface ${1:`Filename('', 'someClass')`} : ${2:NSObject} + { + } + @end + + @implementation $1 + ${3} + @end +# Class Interface +snippet int + @interface ${1:`Filename('', 'someClass')`} : ${2:NSObject} + {${3} + } + ${4} + @end +snippet @interface + @interface ${1:`Filename('', 'someClass')`} : ${2:NSObject} + {${3} + } + ${4} + @end +# Class Implementation +snippet impl + @implementation ${1:`Filename('', 'someClass')`} + ${2} + @end +snippet @implementation + @implementation ${1:`Filename('', 'someClass')`} + ${2} + @end +# Protocol +snippet pro + @protocol ${1:`Filename('$1Delegate', 'MyProtocol')`} ${2:} + ${3} + @end +snippet @protocol + @protocol ${1:`Filename('$1Delegate', 'MyProtocol')`} ${2:} + ${3} + @end +# init Definition +snippet init + - (id)init + { + if (self = [super init]) { + ${1} + } + return self; + } +# dealloc Definition +snippet dealloc + - (void) dealloc + { + ${1:deallocations} + [super dealloc]; + } +snippet su + [super ${1:init}]${2} +snippet ibo + IBOutlet ${1:NSSomeClass} *${2:$1};${3} +# Category +snippet cat + @interface ${1:NSObject} (${2:MyCategory}) + @end + + @implementation $1 ($2) + ${3} + @end +# Category Interface +snippet cath + @interface ${1:`Filename('$1', 'NSObject')`} (${2:MyCategory}) + ${3} + @end +# Method +snippet m + - (${1:id})${2:method} + { + ${3} + } +# Method declaration +snippet md + - (${1:id})${2:method};${3} +# IBAction declaration +snippet ibad + - (IBAction)${1:method}:(${2:id})sender;${3} +# IBAction method +snippet iba + - (IBAction)${1:method}:(${2:id})sender + { + ${3} + } +# awakeFromNib method +snippet wake + - (void)awakeFromNib + { + ${1} + } +# Class Method +snippet M + + (${1:id})${2:method} + { + ${3:return nil;} + } +# Sub-method (Call super) +snippet sm + - (${1:id})${2:method} + { + [super $2];${3} + return self; + } +# Accessor Methods For: +# Object +snippet objacc + - (${1:id})${2:thing} + { + return $2; + } + + - (void)set$2:($1)${3:new$2} + { + [$3 retain]; + [$2 release]; + $2 = $3; + }${4} +# for (object in array) +snippet forin + for (${1:Class} *${2:some$1} in ${3:array}) { + ${4} + } +snippet fore + for (${1:object} in ${2:array}) { + ${3:statements} + } +snippet forarray + unsigned int ${1:object}Count = [${2:array} count]; + + for (unsigned int index = 0; index < $1Count; index++) { + ${3:id} $1 = [$2 $1AtIndex:index]; + ${4} + } +snippet fora + unsigned int ${1:object}Count = [${2:array} count]; + + for (unsigned int index = 0; index < $1Count; index++) { + ${3:id} $1 = [$2 $1AtIndex:index]; + ${4} + } +# Try / Catch Block +snippet @try + @try { + ${1:statements} + } + @catch (NSException * e) { + ${2:handler} + } + @finally { + ${3:statements} + } +snippet @catch + @catch (${1:exception}) { + ${2:handler} + } +snippet @finally + @finally { + ${1:statements} + } +# IBOutlet +# @property (Objective-C 2.0) +snippet prop + @property (${1:retain}) ${2:NSSomeClass} ${3:*$2};${4} +# @synthesize (Objective-C 2.0) +snippet syn + @synthesize ${1:property};${2} +# [[ alloc] init] +snippet alloc + [[${1:foo} alloc] init${2}];${3} +snippet a + [[${1:foo} alloc] init${2}];${3} +# retain +snippet ret + [${1:foo} retain];${2} +# release +snippet rel + [${1:foo} release]; +# autorelease +snippet arel + [${1:foo} autorelease]; +# autorelease pool +snippet pool + NSAutoreleasePool *${1:pool} = [[NSAutoreleasePool alloc] init]; + ${2:/* code */} + [$1 drain]; +# Throw an exception +snippet except + NSException *${1:badness}; + $1 = [NSException exceptionWithName:@"${2:$1Name}" + reason:@"${3}" + userInfo:nil]; + [$1 raise]; +snippet prag + #pragma mark ${1:-} +snippet cl + @class ${1:Foo};${2} +snippet color + [[NSColor ${1:blackColor}] set]; +# NSArray +snippet array + NSMutableArray *${1:array} = [NSMutable array];${2} +snippet nsa + NSArray ${1} +snippet nsma + NSMutableArray ${1} +snippet aa + NSArray * array;${1} +snippet ma + NSMutableArray * array;${1} +# NSDictionary +snippet dict + NSMutableDictionary *${1:dict} = [NSMutableDictionary dictionary];${2} +snippet nsd + NSDictionary ${1} +snippet nsmd + NSMutableDictionary ${1} +# NSString +snippet nss + NSString ${1} +snippet nsms + NSMutableString ${1} diff --git a/lib/ace/snippets/objectivec.js b/lib/ace/snippets/objectivec.js new file mode 100644 index 00000000..ed5d5fa8 --- /dev/null +++ b/lib/ace/snippets/objectivec.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./objectivec.snippets"); +exports.scope = "objectivec"; + +}); diff --git a/lib/ace/snippets/objectivec.snippets b/lib/ace/snippets/objectivec.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/ocaml.js b/lib/ace/snippets/ocaml.js new file mode 100644 index 00000000..a6e6842e --- /dev/null +++ b/lib/ace/snippets/ocaml.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./ocaml.snippets"); +exports.scope = "ocaml"; + +}); diff --git a/lib/ace/snippets/ocaml.snippets b/lib/ace/snippets/ocaml.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/pascal.js b/lib/ace/snippets/pascal.js new file mode 100644 index 00000000..cd8f19fe --- /dev/null +++ b/lib/ace/snippets/pascal.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./pascal.snippets"); +exports.scope = "pascal"; + +}); diff --git a/lib/ace/snippets/pascal.snippets b/lib/ace/snippets/pascal.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/perl.js b/lib/ace/snippets/perl.js new file mode 100644 index 00000000..9b1fbe8d --- /dev/null +++ b/lib/ace/snippets/perl.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./perl.snippets"); +exports.scope = "perl"; + +}); diff --git a/lib/ace/snippets/perl.snippets b/lib/ace/snippets/perl.snippets new file mode 100644 index 00000000..9cebedea --- /dev/null +++ b/lib/ace/snippets/perl.snippets @@ -0,0 +1,347 @@ +# #!/usr/bin/perl +snippet #! + #!/usr/bin/env perl + +# Hash Pointer +snippet . + => +# Function +snippet sub + sub ${1:function_name} { + ${2:#body ...} + } +# Conditional +snippet if + if (${1}) { + ${2:# body...} + } +# Conditional if..else +snippet ife + if (${1}) { + ${2:# body...} + } + else { + ${3:# else...} + } +# Conditional if..elsif..else +snippet ifee + if (${1}) { + ${2:# body...} + } + elsif (${3}) { + ${4:# elsif...} + } + else { + ${5:# else...} + } +# Conditional One-line +snippet xif + ${1:expression} if ${2:condition};${3} +# Unless conditional +snippet unless + unless (${1}) { + ${2:# body...} + } +# Unless conditional One-line +snippet xunless + ${1:expression} unless ${2:condition};${3} +# Try/Except +snippet eval + local $@; + eval { + ${1:# do something risky...} + }; + if (my $e = $@) { + ${2:# handle failure...} + } +# While Loop +snippet wh + while (${1}) { + ${2:# body...} + } +# While Loop One-line +snippet xwh + ${1:expression} while ${2:condition};${3} +# C-style For Loop +snippet cfor + for (my $${2:var} = 0; $$2 < ${1:count}; $$2${3:++}) { + ${4:# body...} + } +# For loop one-line +snippet xfor + ${1:expression} for @${2:array};${3} +# Foreach Loop +snippet for + foreach my $${1:x} (@${2:array}) { + ${3:# body...} + } +# Foreach Loop One-line +snippet fore + ${1:expression} foreach @${2:array};${3} +# Package +snippet package + package ${1:`substitute(Filename('', 'Page Title'), '^.', '\u&', '')`}; + + ${2} + + 1; + + __END__ +# Package syntax perl >= 5.14 +snippet packagev514 + package ${1:`substitute(Filename('', 'Page Title'), '^.', '\u&', '')`} ${2:0.99}; + + ${3} + + 1; + + __END__ +#moose +snippet moose + use Moose; + use namespace::autoclean; + ${1:#}BEGIN {extends '${2:ParentClass}'}; + + ${3} +# parent +snippet parent + use parent qw(${1:Parent Class}); +# Read File +snippet slurp + my $${1:var} = do { local $/; open my $file, '<', "${2:file}"; <$file> }; + ${3} +# strict warnings +snippet strwar + use strict; + use warnings; +# older versioning with perlcritic bypass +snippet vers + ## no critic + our $VERSION = '${1:version}'; + eval $VERSION; + ## use critic +# new 'switch' like feature +snippet switch + use feature 'switch'; + +# Anonymous subroutine +snippet asub + sub { + ${1:# body } + } + + + +# Begin block +snippet begin + BEGIN { + ${1:# begin body} + } + +# call package function with some parameter +snippet pkgmv + __PACKAGE__->${1:package_method}(${2:var}) + +# call package function without a parameter +snippet pkgm + __PACKAGE__->${1:package_method}() + +# call package "get_" function without a parameter +snippet pkget + __PACKAGE__->get_${1:package_method}() + +# call package function with a parameter +snippet pkgetv + __PACKAGE__->get_${1:package_method}(${2:var}) + +# complex regex +snippet qrx + qr/ + ${1:regex} + /xms + +#simpler regex +snippet qr/ + qr/${1:regex}/x + +#given +snippet given + given ($${1:var}) { + ${2:# cases} + ${3:# default} + } + +# switch-like case +snippet when + when (${1:case}) { + ${2:# body} + } + +# hash slice +snippet hslice + @{ ${1:hash} }{ ${2:array} } + + +# map +snippet map + map { ${2: body } } ${1: @array } ; + + + +# Pod stub +snippet ppod + =head1 NAME + + ${1:ClassName} - ${2:ShortDesc} + + =head1 SYNOPSIS + + use $1; + + ${3:# synopsis...} + + =head1 DESCRIPTION + + ${4:# longer description...} + + + =head1 INTERFACE + + + =head1 DEPENDENCIES + + + =head1 SEE ALSO + + +# Heading for a subroutine stub +snippet psub + =head2 ${1:MethodName} + + ${2:Summary....} + +# Heading for inline subroutine pod +snippet psubi + =head2 ${1:MethodName} + + ${2:Summary...} + + + =cut +# inline documented subroutine +snippet subpod + =head2 $1 + + Summary of $1 + + =cut + + sub ${1:subroutine_name} { + ${2:# body...} + } +# Subroutine signature +snippet parg + =over 2 + + =item + Arguments + + + =over 3 + + =item + C<${1:DataStructure}> + + ${2:Sample} + + + =back + + + =item + Return + + =over 3 + + + =item + C<${3:...return data}> + + + =back + + + =back + + + +# Moose has +snippet has + has ${1:attribute} => ( + is => '${2:ro|rw}', + isa => '${3:Str|Int|HashRef|ArrayRef|etc}', + default => sub { + ${4:defaultvalue} + }, + ${5:# other attributes} + ); + + +# override +snippet override + override ${1:attribute} => sub { + ${2:# my $self = shift;}; + ${3:# my ($self, $args) = @_;}; + }; + + +# use test classes +snippet tuse + use Test::More; + use Test::Deep; # (); # uncomment to stop prototype errors + use Test::Exception; + +# local test lib +snippet tlib + use lib qw{ ./t/lib }; + +#test methods +snippet tmeths + $ENV{TEST_METHOD} = '${1:regex}'; + +# runtestclass +snippet trunner + use ${1:test_class}; + $1->runtests(); + +# Test::Class-style test +snippet tsub + sub t${1:number}_${2:test_case} :Test(${3:num_of_tests}) { + my $self = shift; + ${4:# body} + + } + +# Test::Routine-style test +snippet trsub + test ${1:test_name} => { description => '${2:Description of test.}'} => sub { + my ($self) = @_; + ${3:# test code} + }; + +#prep test method +snippet tprep + sub prep${1:number}_${2:test_case} :Test(startup) { + my $self = shift; + ${4:# body} + } + +# cause failures to print stack trace +snippet debug_trace + use Carp; # 'verbose'; + # cloak "die" + # warn "warning" + $SIG{'__DIE__'} = sub { + require Carp; Carp::confess + }; + diff --git a/lib/ace/snippets/pgsql.js b/lib/ace/snippets/pgsql.js new file mode 100644 index 00000000..9bbd9012 --- /dev/null +++ b/lib/ace/snippets/pgsql.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./pgsql.snippets"); +exports.scope = "pgsql"; + +}); diff --git a/lib/ace/snippets/pgsql.snippets b/lib/ace/snippets/pgsql.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/php.js b/lib/ace/snippets/php.js new file mode 100644 index 00000000..b8f8ce0e --- /dev/null +++ b/lib/ace/snippets/php.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./php.snippets"); +exports.scope = "php"; + +}); diff --git a/lib/ace/snippets/php.snippets b/lib/ace/snippets/php.snippets new file mode 100644 index 00000000..8d11a281 --- /dev/null +++ b/lib/ace/snippets/php.snippets @@ -0,0 +1,377 @@ +snippet +# this one is for php5.4 +snippet +snippet ns + namespace ${1:Foo\Bar\Baz}; + ${2} +snippet use + use ${1:Foo\Bar\Baz}; + ${2} +snippet c + ${1:abstract }class ${2:$FILENAME} + { + ${3} + } +snippet i + interface ${1:$FILENAME} + { + ${2} + } +snippet t. + $this->${1} +snippet f + function ${1:foo}(${2:array }${3:$bar}) + { + ${4} + } +# method +snippet m + ${1:abstract }${2:protected}${3: static} function ${4:foo}(${5:array }${6:$bar}) + { + ${7} + } +# setter method +snippet sm + /** + * Sets the value of ${1:foo} + * + * @param ${2:$1} $$1 ${3:description} + * + * @return ${4:$FILENAME} + */ + ${5:public} function set${6:$2}(${7:$2 }$$1) + { + $this->${8:$1} = $$1; + return $this; + }${9} +# getter method +snippet gm + /** + * Gets the value of ${1:foo} + * + * @return ${2:$1} + */ + ${3:public} function get${4:$2}() + { + return $this->${5:$1}; + }${6} +#setter +snippet $s + ${1:$foo}->set${2:Bar}(${3}); +#getter +snippet $g + ${1:$foo}->get${2:Bar}(); + +# Tertiary conditional +snippet =?: + $${1:foo} = ${2:true} ? ${3:a} : ${4}; +snippet ?: + ${1:true} ? ${2:a} : ${3} + +snippet C + $_COOKIE['${1:variable}']${2} +snippet E + $_ENV['${1:variable}']${2} +snippet F + $_FILES['${1:variable}']${2} +snippet G + $_GET['${1:variable}']${2} +snippet P + $_POST['${1:variable}']${2} +snippet R + $_REQUEST['${1:variable}']${2} +snippet S + $_SERVER['${1:variable}']${2} +snippet SS + $_SESSION['${1:variable}']${2} + +# the following are old ones +snippet inc + include '${1:file}';${2} +snippet inc1 + include_once '${1:file}';${2} +snippet req + require '${1:file}';${2} +snippet req1 + require_once '${1:file}';${2} +# Start Docblock +snippet /* + /** + * ${1} + */ +# Class - post doc +snippet doc_cp + /** + * ${1:undocumented class} + * + * @package ${2:default} + * @subpackage ${3:default} + * @author ${4:`g:snips_author`} + */${5} +# Class Variable - post doc +snippet doc_vp + /** + * ${1:undocumented class variable} + * + * @var ${2:string} + */${3} +# Class Variable +snippet doc_v + /** + * ${3:undocumented class variable} + * + * @var ${4:string} + */ + ${1:var} $${2};${5} +# Class +snippet doc_c + /** + * ${3:undocumented class} + * + * @package ${4:default} + * @subpackage ${5:default} + * @author ${6:`g:snips_author`} + */ + ${1:}class ${2:} + { + ${7} + } // END $1class $2 +# Constant Definition - post doc +snippet doc_dp + /** + * ${1:undocumented constant} + */${2} +# Constant Definition +snippet doc_d + /** + * ${3:undocumented constant} + */ + define(${1}, ${2});${4} +# Function - post doc +snippet doc_fp + /** + * ${1:undocumented function} + * + * @return ${2:void} + * @author ${3:`g:snips_author`} + */${4} +# Function signature +snippet doc_s + /** + * ${4:undocumented function} + * + * @return ${5:void} + * @author ${6:`g:snips_author`} + */ + ${1}function ${2}(${3});${7} +# Function +snippet doc_f + /** + * ${4:undocumented function} + * + * @return ${5:void} + * @author ${6:`g:snips_author`} + */ + ${1}function ${2}(${3}) + {${7} + } +# Header +snippet doc_h + /** + * ${1} + * + * @author ${2:`g:snips_author`} + * @version ${3:$Id$} + * @copyright ${4:$2}, `strftime('%d %B, %Y')` + * @package ${5:default} + */ + +# Interface +snippet interface + /** + * ${2:undocumented class} + * + * @package ${3:default} + * @author ${4:`g:snips_author`} + */ + interface ${1:$FILENAME} + { + ${5} + } +# class ... +snippet class + /** + * ${1} + */ + class ${2:$FILENAME} + { + ${3} + /** + * ${4} + */ + ${5:public} function ${6:__construct}(${7:argument}) + { + ${8:// code...} + } + } +# define(...) +snippet def + define('${1}'${2});${3} +# defined(...) +snippet def? + ${1}defined('${2}')${3} +snippet wh + while (${1:/* condition */}) { + ${2:// code...} + } +# do ... while +snippet do + do { + ${2:// code... } + } while (${1:/* condition */}); +snippet if + if (${1:/* condition */}) { + ${2:// code...} + } +snippet ifil + + ${2:} + +snippet ife + if (${1:/* condition */}) { + ${2:// code...} + } else { + ${3:// code...} + } + ${4} +snippet ifeil + + ${2:} + + ${3:} + + ${4} +snippet else + else { + ${1:// code...} + } +snippet elseif + elseif (${1:/* condition */}) { + ${2:// code...} + } +snippet switch + switch ($${1:variable}) { + case '${2:value}': + ${3:// code...} + break; + ${5} + default: + ${4:// code...} + break; + } +snippet case + case '${1:value}': + ${2:// code...} + break;${3} +snippet for + for ($${2:i} = 0; $$2 < ${1:count}; $$2${3:++}) { + ${4: // code...} + } +snippet foreach + foreach ($${1:variable} as $${2:value}) { + ${3:// code...} + } +snippet foreachil + + ${3:} + +snippet foreachk + foreach ($${1:variable} as $${2:key} => $${3:value}) { + ${4:// code...} + } +snippet foreachkil + $${3:value}): ?> + ${4:} + +# $... = array (...) +snippet array + $${1:arrayName} = array('${2}' => ${3});${4} +snippet try + try { + ${2} + } catch (${1:Exception} $e) { + } +# lambda with closure +snippet lambda + ${1:static }function (${2:args}) use (${3:&$x, $y /*put vars in scope (closure) */}) { + ${4} + }; +# pre_dump(); +snippet pd + echo '
    '; var_dump(${1}); echo '
    '; +# pre_dump(); die(); +snippet pdd + echo '
    '; var_dump(${1}); echo '
    '; die(${2:}); +snippet vd + var_dump(${1}); +snippet vdd + var_dump(${1}); die(${2:}); +snippet http_redirect + header ("HTTP/1.1 301 Moved Permanently"); + header ("Location: ".URL); + exit(); +# Getters & Setters +snippet gs + /** + * Gets the value of ${1:foo} + * + * @return ${2:$1} + */ + public function get${3:$2}() + { + return $this->${4:$1}; + } + + /** + * Sets the value of $1 + * + * @param $2 $$1 ${5:description} + * + * @return ${6:$FILENAME} + */ + public function set$3(${7:$2 }$$1) + { + $this->$4 = $$1; + return $this; + }${8} +# anotation, get, and set, useful for doctrine +snippet ags + /** + * ${1:description} + * + * @${7} + */ + ${2:protected} $${3:foo}; + + public function get${4:$3}() + { + return $this->$3; + } + + public function set$4(${5:$4 }$${6:$3}) + { + $this->$3 = $$6; + return $this; + } +snippet rett + return true; +snippet retf + return false; diff --git a/lib/ace/snippets/plain_text.js b/lib/ace/snippets/plain_text.js new file mode 100644 index 00000000..4b4dad55 --- /dev/null +++ b/lib/ace/snippets/plain_text.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./plain_text.snippets"); +exports.scope = "plain_text"; + +}); diff --git a/lib/ace/snippets/plain_text.snippets b/lib/ace/snippets/plain_text.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/powershell.js b/lib/ace/snippets/powershell.js new file mode 100644 index 00000000..4639a304 --- /dev/null +++ b/lib/ace/snippets/powershell.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./powershell.snippets"); +exports.scope = "powershell"; + +}); diff --git a/lib/ace/snippets/powershell.snippets b/lib/ace/snippets/powershell.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/praat.js b/lib/ace/snippets/praat.js new file mode 100644 index 00000000..18afa87f --- /dev/null +++ b/lib/ace/snippets/praat.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./praat.snippets"); +exports.scope = "praat"; + +}); diff --git a/lib/ace/snippets/praat.snippets b/lib/ace/snippets/praat.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/prolog.js b/lib/ace/snippets/prolog.js new file mode 100644 index 00000000..7c9d0fbc --- /dev/null +++ b/lib/ace/snippets/prolog.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./prolog.snippets"); +exports.scope = "prolog"; + +}); diff --git a/lib/ace/snippets/prolog.snippets b/lib/ace/snippets/prolog.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/properties.js b/lib/ace/snippets/properties.js new file mode 100644 index 00000000..18bd3883 --- /dev/null +++ b/lib/ace/snippets/properties.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./properties.snippets"); +exports.scope = "properties"; + +}); diff --git a/lib/ace/snippets/properties.snippets b/lib/ace/snippets/properties.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/protobuf.js b/lib/ace/snippets/protobuf.js new file mode 100644 index 00000000..24855545 --- /dev/null +++ b/lib/ace/snippets/protobuf.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = ""; +exports.scope = "protobuf"; + +}); \ No newline at end of file diff --git a/lib/ace/snippets/protobuf.snippets b/lib/ace/snippets/protobuf.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/python.js b/lib/ace/snippets/python.js new file mode 100644 index 00000000..48ddba28 --- /dev/null +++ b/lib/ace/snippets/python.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./python.snippets"); +exports.scope = "python"; + +}); diff --git a/lib/ace/snippets/python.snippets b/lib/ace/snippets/python.snippets new file mode 100644 index 00000000..347bbdeb --- /dev/null +++ b/lib/ace/snippets/python.snippets @@ -0,0 +1,158 @@ +snippet #! + #!/usr/bin/env python +snippet imp + import ${1:module} +snippet from + from ${1:package} import ${2:module} +# Module Docstring +snippet docs + ''' + File: ${1:FILENAME:file_name} + Author: ${2:author} + Description: ${3} + ''' +snippet wh + while ${1:condition}: + ${2:# TODO: write code...} +# dowh - does the same as do...while in other languages +snippet dowh + while True: + ${1:# TODO: write code...} + if ${2:condition}: + break +snippet with + with ${1:expr} as ${2:var}: + ${3:# TODO: write code...} +# New Class +snippet cl + class ${1:ClassName}(${2:object}): + """${3:docstring for $1}""" + def __init__(self, ${4:arg}): + ${5:super($1, self).__init__()} + self.$4 = $4 + ${6} +# New Function +snippet def + def ${1:fname}(${2:`indent('.') ? 'self' : ''`}): + """${3:docstring for $1}""" + ${4:# TODO: write code...} +snippet deff + def ${1:fname}(${2:`indent('.') ? 'self' : ''`}): + ${3:# TODO: write code...} +# New Method +snippet defs + def ${1:mname}(self, ${2:arg}): + ${3:# TODO: write code...} +# New Property +snippet property + def ${1:foo}(): + doc = "${2:The $1 property.}" + def fget(self): + ${3:return self._$1} + def fset(self, value): + ${4:self._$1 = value} +# Ifs +snippet if + if ${1:condition}: + ${2:# TODO: write code...} +snippet el + else: + ${1:# TODO: write code...} +snippet ei + elif ${1:condition}: + ${2:# TODO: write code...} +# For +snippet for + for ${1:item} in ${2:items}: + ${3:# TODO: write code...} +# Encodes +snippet cutf8 + # -*- coding: utf-8 -*- +snippet clatin1 + # -*- coding: latin-1 -*- +snippet cascii + # -*- coding: ascii -*- +# Lambda +snippet ld + ${1:var} = lambda ${2:vars} : ${3:action} +snippet . + self. +snippet try Try/Except + try: + ${1:# TODO: write code...} + except ${2:Exception}, ${3:e}: + ${4:raise $3} +snippet try Try/Except/Else + try: + ${1:# TODO: write code...} + except ${2:Exception}, ${3:e}: + ${4:raise $3} + else: + ${5:# TODO: write code...} +snippet try Try/Except/Finally + try: + ${1:# TODO: write code...} + except ${2:Exception}, ${3:e}: + ${4:raise $3} + finally: + ${5:# TODO: write code...} +snippet try Try/Except/Else/Finally + try: + ${1:# TODO: write code...} + except ${2:Exception}, ${3:e}: + ${4:raise $3} + else: + ${5:# TODO: write code...} + finally: + ${6:# TODO: write code...} +# if __name__ == '__main__': +snippet ifmain + if __name__ == '__main__': + ${1:main()} +# __magic__ +snippet _ + __${1:init}__${2} +# python debugger (pdb) +snippet pdb + import pdb; pdb.set_trace() +# ipython debugger (ipdb) +snippet ipdb + import ipdb; ipdb.set_trace() +# ipython debugger (pdbbb) +snippet pdbbb + import pdbpp; pdbpp.set_trace() +snippet pprint + import pprint; pprint.pprint(${1})${2} +snippet " + """ + ${1:doc} + """ +# test function/method +snippet test + def test_${1:description}(${2:self}): + ${3:# TODO: write code...} +# test case +snippet testcase + class ${1:ExampleCase}(unittest.TestCase): + + def test_${2:description}(self): + ${3:# TODO: write code...} +snippet fut + from __future__ import ${1} +#getopt +snippet getopt + try: + # Short option syntax: "hv:" + # Long option syntax: "help" or "verbose=" + opts, args = getopt.getopt(sys.argv[1:], "${1:short_options}", [${2:long_options}]) + + except getopt.GetoptError, err: + # Print debug info + print str(err) + ${3:error_action} + + for option, argument in opts: + if option in ("-h", "--help"): + ${4} + elif option in ("-v", "--verbose"): + verbose = argument diff --git a/lib/ace/snippets/r.js b/lib/ace/snippets/r.js new file mode 100644 index 00000000..6b319194 --- /dev/null +++ b/lib/ace/snippets/r.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./r.snippets"); +exports.scope = "r"; + +}); diff --git a/lib/ace/snippets/r.snippets b/lib/ace/snippets/r.snippets new file mode 100644 index 00000000..948542f5 --- /dev/null +++ b/lib/ace/snippets/r.snippets @@ -0,0 +1,121 @@ +snippet #! + #!/usr/bin/env Rscript + +# includes +snippet lib + library(${1:package}) +snippet req + require(${1:package}) +snippet source + source('${1:file}') + +# conditionals +snippet if + if (${1:condition}) { + ${2:code} + } +snippet el + else { + ${1:code} + } +snippet ei + else if (${1:condition}) { + ${2:code} + } + +# functions +snippet fun + ${1:name} = function (${2:variables}) { + ${3:code} + } +snippet ret + return(${1:code}) + +# dataframes, lists, etc +snippet df + ${1:name}[${2:rows}, ${3:cols}] +snippet c + c(${1:items}) +snippet li + list(${1:items}) +snippet mat + matrix(${1:data}, nrow=${2:rows}, ncol=${3:cols}) + +# apply functions +snippet apply + apply(${1:array}, ${2:margin}, ${3:function}) +snippet lapply + lapply(${1:list}, ${2:function}) +snippet sapply + sapply(${1:list}, ${2:function}) +snippet vapply + vapply(${1:list}, ${2:function}, ${3:type}) +snippet mapply + mapply(${1:function}, ${2:...}) +snippet tapply + tapply(${1:vector}, ${2:index}, ${3:function}) +snippet rapply + rapply(${1:list}, ${2:function}) + +# plyr functions +snippet dd + ddply(${1:frame}, ${2:variables}, ${3:function}) +snippet dl + dlply(${1:frame}, ${2:variables}, ${3:function}) +snippet da + daply(${1:frame}, ${2:variables}, ${3:function}) +snippet d_ + d_ply(${1:frame}, ${2:variables}, ${3:function}) + +snippet ad + adply(${1:array}, ${2:margin}, ${3:function}) +snippet al + alply(${1:array}, ${2:margin}, ${3:function}) +snippet aa + aaply(${1:array}, ${2:margin}, ${3:function}) +snippet a_ + a_ply(${1:array}, ${2:margin}, ${3:function}) + +snippet ld + ldply(${1:list}, ${2:function}) +snippet ll + llply(${1:list}, ${2:function}) +snippet la + laply(${1:list}, ${2:function}) +snippet l_ + l_ply(${1:list}, ${2:function}) + +snippet md + mdply(${1:matrix}, ${2:function}) +snippet ml + mlply(${1:matrix}, ${2:function}) +snippet ma + maply(${1:matrix}, ${2:function}) +snippet m_ + m_ply(${1:matrix}, ${2:function}) + +# plot functions +snippet pl + plot(${1:x}, ${2:y}) +snippet ggp + ggplot(${1:data}, aes(${2:aesthetics})) +snippet img + ${1:(jpeg,bmp,png,tiff)}(filename="${2:filename}", width=${3}, height=${4}, unit="${5}") + ${6:plot} + dev.off() + +# statistical test functions +snippet fis + fisher.test(${1:x}, ${2:y}) +snippet chi + chisq.test(${1:x}, ${2:y}) +snippet tt + t.test(${1:x}, ${2:y}) +snippet wil + wilcox.test(${1:x}, ${2:y}) +snippet cor + cor.test(${1:x}, ${2:y}) +snippet fte + var.test(${1:x}, ${2:y}) +snippet kvt + kv.test(${1:x}, ${2:y}) diff --git a/lib/ace/snippets/rdoc.js b/lib/ace/snippets/rdoc.js new file mode 100644 index 00000000..0d9e6c95 --- /dev/null +++ b/lib/ace/snippets/rdoc.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./rdoc.snippets"); +exports.scope = "rdoc"; + +}); diff --git a/lib/ace/snippets/rdoc.snippets b/lib/ace/snippets/rdoc.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/rhtml.js b/lib/ace/snippets/rhtml.js new file mode 100644 index 00000000..96707f21 --- /dev/null +++ b/lib/ace/snippets/rhtml.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./rhtml.snippets"); +exports.scope = "rhtml"; + +}); diff --git a/lib/ace/snippets/rhtml.snippets b/lib/ace/snippets/rhtml.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/rst.snippets b/lib/ace/snippets/rst.snippets new file mode 100644 index 00000000..97845de3 --- /dev/null +++ b/lib/ace/snippets/rst.snippets @@ -0,0 +1,22 @@ +# rst + +snippet : + :${1:field name}: ${2:field body} +snippet * + *${1:Emphasis}* +snippet ** + **${1:Strong emphasis}** +snippet _ + \`${1:hyperlink-name}\`_ + .. _\`$1\`: ${2:link-block} +snippet = + ${1:Title} + =====${2:=} + ${3} +snippet - + ${1:Title} + -----${2:-} + ${3} +snippet cont: + .. contents:: + diff --git a/lib/ace/snippets/ruby.js b/lib/ace/snippets/ruby.js new file mode 100644 index 00000000..f7050449 --- /dev/null +++ b/lib/ace/snippets/ruby.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./ruby.snippets"); +exports.scope = "ruby"; + +}); diff --git a/lib/ace/snippets/ruby.snippets b/lib/ace/snippets/ruby.snippets new file mode 100644 index 00000000..0500aaa1 --- /dev/null +++ b/lib/ace/snippets/ruby.snippets @@ -0,0 +1,928 @@ +######################################## +# Ruby snippets - for Rails, see below # +######################################## + +# encoding for Ruby 1.9 +snippet enc + # encoding: utf-8 + +# #!/usr/bin/env ruby +snippet #! + #!/usr/bin/env ruby + # encoding: utf-8 + +# New Block +snippet =b + =begin rdoc + ${1} + =end +snippet y + :yields: ${1:arguments} +snippet rb + #!/usr/bin/env ruby -wKU +snippet beg + begin + ${3} + rescue ${1:Exception} => ${2:e} + end + +snippet req require + require "${1}"${2} +snippet # + # => +snippet end + __END__ +snippet case + case ${1:object} + when ${2:condition} + ${3} + end +snippet when + when ${1:condition} + ${2} +snippet def + def ${1:method_name} + ${2} + end +snippet deft + def test_${1:case_name} + ${2} + end +snippet if + if ${1:condition} + ${2} + end +snippet ife + if ${1:condition} + ${2} + else + ${3} + end +snippet elsif + elsif ${1:condition} + ${2} +snippet unless + unless ${1:condition} + ${2} + end +snippet while + while ${1:condition} + ${2} + end +snippet for + for ${1:e} in ${2:c} + ${3} + end +snippet until + until ${1:condition} + ${2} + end +snippet cla class .. end + class ${1:`substitute(Filename(), '\(_\|^\)\(.\)', '\u\2', 'g')`} + ${2} + end +snippet cla class .. initialize .. end + class ${1:`substitute(Filename(), '\(_\|^\)\(.\)', '\u\2', 'g')`} + def initialize(${2:args}) + ${3} + end + end +snippet cla class .. < ParentClass .. initialize .. end + class ${1:`substitute(Filename(), '\(_\|^\)\(.\)', '\u\2', 'g')`} < ${2:ParentClass} + def initialize(${3:args}) + ${4} + end + end +snippet cla ClassName = Struct .. do .. end + ${1:`substitute(Filename(), '\(_\|^\)\(.\)', '\u\2', 'g')`} = Struct.new(:${2:attr_names}) do + def ${3:method_name} + ${4} + end + end +snippet cla class BlankSlate .. initialize .. end + class ${1:BlankSlate} + instance_methods.each { |meth| undef_method(meth) unless meth =~ /\A__/ } + end +snippet cla class << self .. end + class << ${1:self} + ${2} + end +# class .. < DelegateClass .. initialize .. end +snippet cla- + class ${1:`substitute(Filename(), '\(_\|^\)\(.\)', '\u\2', 'g')`} < DelegateClass(${2:ParentClass}) + def initialize(${3:args}) + super(${4:del_obj}) + + ${5} + end + end +snippet mod module .. end + module ${1:`substitute(Filename(), '\(_\|^\)\(.\)', '\u\2', 'g')`} + ${2} + end +snippet mod module .. module_function .. end + module ${1:`substitute(Filename(), '\(_\|^\)\(.\)', '\u\2', 'g')`} + module_function + + ${2} + end +snippet mod module .. ClassMethods .. end + module ${1:`substitute(Filename(), '\(_\|^\)\(.\)', '\u\2', 'g')`} + module ClassMethods + ${2} + end + + module InstanceMethods + + end + + def self.included(receiver) + receiver.extend ClassMethods + receiver.send :include, InstanceMethods + end + end +# attr_reader +snippet r + attr_reader :${1:attr_names} +# attr_writer +snippet w + attr_writer :${1:attr_names} +# attr_accessor +snippet rw + attr_accessor :${1:attr_names} +snippet atp + attr_protected :${1:attr_names} +snippet ata + attr_accessible :${1:attr_names} +# include Enumerable +snippet Enum + include Enumerable + + def each(&block) + ${1} + end +# include Comparable +snippet Comp + include Comparable + + def <=>(other) + ${1} + end +# extend Forwardable +snippet Forw- + extend Forwardable +# def self +snippet defs + def self.${1:class_method_name} + ${2} + end +# def method_missing +snippet defmm + def method_missing(meth, *args, &blk) + ${1} + end +snippet defd + def_delegator :${1:@del_obj}, :${2:del_meth}, :${3:new_name} +snippet defds + def_delegators :${1:@del_obj}, :${2:del_methods} +snippet am + alias_method :${1:new_name}, :${2:old_name} +snippet app + if __FILE__ == $PROGRAM_NAME + ${1} + end +# usage_if() +snippet usai + if ARGV.${1} + abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3} + end +# usage_unless() +snippet usau + unless ARGV.${1} + abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3} + end +snippet array + Array.new(${1:10}) { |${2:i}| ${3} } +snippet hash + Hash.new { |${1:hash}, ${2:key}| $1[$2] = ${3} } +snippet file File.foreach() { |line| .. } + File.foreach(${1:"path/to/file"}) { |${2:line}| ${3} } +snippet file File.read() + File.read(${1:"path/to/file"})${2} +snippet Dir Dir.global() { |file| .. } + Dir.glob(${1:"dir/glob/*"}) { |${2:file}| ${3} } +snippet Dir Dir[".."] + Dir[${1:"glob/**/*.rb"}]${2} +snippet dir + Filename.dirname(__FILE__) +snippet deli + delete_if { |${1:e}| ${2} } +snippet fil + fill(${1:range}) { |${2:i}| ${3} } +# flatten_once() +snippet flao + inject(Array.new) { |${1:arr}, ${2:a}| $1.push(*$2)}${3} +snippet zip + zip(${1:enums}) { |${2:row}| ${3} } +# downto(0) { |n| .. } +snippet dow + downto(${1:0}) { |${2:n}| ${3} } +snippet ste + step(${1:2}) { |${2:n}| ${3} } +snippet tim + times { |${1:n}| ${2} } +snippet upt + upto(${1:1.0/0.0}) { |${2:n}| ${3} } +snippet loo + loop { ${1} } +snippet ea + each { |${1:e}| ${2} } +snippet ead + each do |${1:e}| + ${2} + end +snippet eab + each_byte { |${1:byte}| ${2} } +snippet eac- each_char { |chr| .. } + each_char { |${1:chr}| ${2} } +snippet eac- each_cons(..) { |group| .. } + each_cons(${1:2}) { |${2:group}| ${3} } +snippet eai + each_index { |${1:i}| ${2} } +snippet eaid + each_index do |${1:i}| + ${2} + end +snippet eak + each_key { |${1:key}| ${2} } +snippet eakd + each_key do |${1:key}| + ${2} + end +snippet eal + each_line { |${1:line}| ${2} } +snippet eald + each_line do |${1:line}| + ${2} + end +snippet eap + each_pair { |${1:name}, ${2:val}| ${3} } +snippet eapd + each_pair do |${1:name}, ${2:val}| + ${3} + end +snippet eas- + each_slice(${1:2}) { |${2:group}| ${3} } +snippet easd- + each_slice(${1:2}) do |${2:group}| + ${3} + end +snippet eav + each_value { |${1:val}| ${2} } +snippet eavd + each_value do |${1:val}| + ${2} + end +snippet eawi + each_with_index { |${1:e}, ${2:i}| ${3} } +snippet eawid + each_with_index do |${1:e},${2:i}| + ${3} + end +snippet reve + reverse_each { |${1:e}| ${2} } +snippet reved + reverse_each do |${1:e}| + ${2} + end +snippet inj + inject(${1:init}) { |${2:mem}, ${3:var}| ${4} } +snippet injd + inject(${1:init}) do |${2:mem}, ${3:var}| + ${4} + end +snippet map + map { |${1:e}| ${2} } +snippet mapd + map do |${1:e}| + ${2} + end +snippet mapwi- + enum_with_index.map { |${1:e}, ${2:i}| ${3} } +snippet sor + sort { |a, b| ${1} } +snippet sorb + sort_by { |${1:e}| ${2} } +snippet ran + sort_by { rand } +snippet all + all? { |${1:e}| ${2} } +snippet any + any? { |${1:e}| ${2} } +snippet cl + classify { |${1:e}| ${2} } +snippet col + collect { |${1:e}| ${2} } +snippet cold + collect do |${1:e}| + ${2} + end +snippet det + detect { |${1:e}| ${2} } +snippet detd + detect do |${1:e}| + ${2} + end +snippet fet + fetch(${1:name}) { |${2:key}| ${3} } +snippet fin + find { |${1:e}| ${2} } +snippet find + find do |${1:e}| + ${2} + end +snippet fina + find_all { |${1:e}| ${2} } +snippet finad + find_all do |${1:e}| + ${2} + end +snippet gre + grep(${1:/pattern/}) { |${2:match}| ${3} } +snippet sub + ${1:g}sub(${2:/pattern/}) { |${3:match}| ${4} } +snippet sca + scan(${1:/pattern/}) { |${2:match}| ${3} } +snippet scad + scan(${1:/pattern/}) do |${2:match}| + ${3} + end +snippet max + max { |a, b| ${1} } +snippet min + min { |a, b| ${1} } +snippet par + partition { |${1:e}| ${2} } +snippet pard + partition do |${1:e}| + ${2} + end +snippet rej + reject { |${1:e}| ${2} } +snippet rejd + reject do |${1:e}| + ${2} + end +snippet sel + select { |${1:e}| ${2} } +snippet seld + select do |${1:e}| + ${2} + end +snippet lam + lambda { |${1:args}| ${2} } +snippet doo + do + ${1} + end +snippet dov + do |${1:variable}| + ${2} + end +snippet : + :${1:key} => ${2:"value"}${3} +snippet ope + open(${1:"path/or/url/or/pipe"}, "${2:w}") { |${3:io}| ${4} } +# path_from_here() +snippet fpath + File.join(File.dirname(__FILE__), *%2[${1:rel path here}])${2} +# unix_filter {} +snippet unif + ARGF.each_line${1} do |${2:line}| + ${3} + end +# option_parse {} +snippet optp + require "optparse" + + options = {${1:default => "args"}} + + ARGV.options do |opts| + opts.banner = "Usage: #{File.basename($PROGRAM_NAME)} +snippet opt + opts.on( "-${1:o}", "--${2:long-option-name}", ${3:String}, + "${4:Option description.}") do |${5:opt}| + ${6} + end +snippet tc + require "test/unit" + + require "${1:library_file_name}" + + class Test${2:$1} < Test::Unit::TestCase + def test_${3:case_name} + ${4} + end + end +snippet ts + require "test/unit" + + require "tc_${1:test_case_file}" + require "tc_${2:test_case_file}"${3} +snippet as + assert ${1:test}, "${2:Failure message.}"${3} +snippet ase + assert_equal ${1:expected}, ${2:actual}${3} +snippet asne + assert_not_equal ${1:unexpected}, ${2:actual}${3} +snippet asid + assert_in_delta ${1:expected_float}, ${2:actual_float}, ${3:2 ** -20}${4} +snippet asio + assert_instance_of ${1:ExpectedClass}, ${2:actual_instance}${3} +snippet asko + assert_kind_of ${1:ExpectedKind}, ${2:actual_instance}${3} +snippet asn + assert_nil ${1:instance}${2} +snippet asnn + assert_not_nil ${1:instance}${2} +snippet asm + assert_match /${1:expected_pattern}/, ${2:actual_string}${3} +snippet asnm + assert_no_match /${1:unexpected_pattern}/, ${2:actual_string}${3} +snippet aso + assert_operator ${1:left}, :${2:operator}, ${3:right}${4} +snippet asr + assert_raise ${1:Exception} { ${2} } +snippet asrd + assert_raise ${1:Exception} do + ${2} + end +snippet asnr + assert_nothing_raised ${1:Exception} { ${2} } +snippet asnrd + assert_nothing_raised ${1:Exception} do + ${2} + end +snippet asrt + assert_respond_to ${1:object}, :${2:method}${3} +snippet ass assert_same(..) + assert_same ${1:expected}, ${2:actual}${3} +snippet ass assert_send(..) + assert_send [${1:object}, :${2:message}, ${3:args}]${4} +snippet asns + assert_not_same ${1:unexpected}, ${2:actual}${3} +snippet ast + assert_throws :${1:expected} { ${2} } +snippet astd + assert_throws :${1:expected} do + ${2} + end +snippet asnt + assert_nothing_thrown { ${1} } +snippet asntd + assert_nothing_thrown do + ${1} + end +snippet fl + flunk "${1:Failure message.}"${2} +# Benchmark.bmbm do .. end +snippet bm- + TESTS = ${1:10_000} + Benchmark.bmbm do |results| + ${2} + end +snippet rep + results.report("${1:name}:") { TESTS.times { ${2} }} +# Marshal.dump(.., file) +snippet Md + File.open(${1:"path/to/file.dump"}, "wb") { |${2:file}| Marshal.dump(${3:obj}, $2) }${4} +# Mashal.load(obj) +snippet Ml + File.open(${1:"path/to/file.dump"}, "rb") { |${2:file}| Marshal.load($2) }${3} +# deep_copy(..) +snippet deec + Marshal.load(Marshal.dump(${1:obj_to_copy}))${2} +snippet Pn- + PStore.new(${1:"file_name.pstore"})${2} +snippet tra + transaction(${1:true}) { ${2} } +# xmlread(..) +snippet xml- + REXML::Document.new(File.read(${1:"path/to/file"}))${2} +# xpath(..) { .. } +snippet xpa + elements.each(${1:"//Xpath"}) do |${2:node}| + ${3} + end +# class_from_name() +snippet clafn + split("::").inject(Object) { |par, const| par.const_get(const) } +# singleton_class() +snippet sinc + class << self; self end +snippet nam + namespace :${1:`Filename()`} do + ${2} + end +snippet tas + desc "${1:Task description}" + task :${2:task_name => [:dependent, :tasks]} do + ${3} + end +# block +snippet b + { |${1:var}| ${2} } +snippet begin + begin + raise 'A test exception.' + rescue Exception => e + puts e.message + puts e.backtrace.inspect + else + # other exception + ensure + # always executed + end + +#debugging +snippet debug + require 'ruby-debug'; debugger; true; +snippet pry + require 'pry'; binding.pry + +############################################# +# Rails snippets - for pure Ruby, see above # +############################################# +snippet art + assert_redirected_to ${1::action => "${2:index}"} +snippet artnp + assert_redirected_to ${1:parent}_${2:child}_path(${3:@$1}, ${4:@$2}) +snippet artnpp + assert_redirected_to ${1:parent}_${2:child}_path(${3:@$1}) +snippet artp + assert_redirected_to ${1:model}_path(${2:@$1}) +snippet artpp + assert_redirected_to ${1:model}s_path +snippet asd + assert_difference "${1:Model}.${2:count}", $1 do + ${3} + end +snippet asnd + assert_no_difference "${1:Model}.${2:count}" do + ${3} + end +snippet asre + assert_response :${1:success}, @response.body${2} +snippet asrj + assert_rjs :${1:replace}, "${2:dom id}" +snippet ass assert_select(..) + assert_select '${1:path}', :${2:text} => '${3:inner_html' ${4:do} +snippet bf + before_filter :${1:method} +snippet bt + belongs_to :${1:association} +snippet crw + cattr_accessor :${1:attr_names} +snippet defcreate + def create + @${1:model_class_name} = ${2:ModelClassName}.new(params[:$1]) + + respond_to do |wants| + if @$1.save + flash[:notice] = '$2 was successfully created.' + wants.html { redirect_to(@$1) } + wants.xml { render :xml => @$1, :status => :created, :location => @$1 } + else + wants.html { render :action => "new" } + wants.xml { render :xml => @$1.errors, :status => :unprocessable_entity } + end + end + end${3} +snippet defdestroy + def destroy + @${1:model_class_name} = ${2:ModelClassName}.find(params[:id]) + @$1.destroy + + respond_to do |wants| + wants.html { redirect_to($1s_url) } + wants.xml { head :ok } + end + end${3} +snippet defedit + def edit + @${1:model_class_name} = ${2:ModelClassName}.find(params[:id]) + end +snippet defindex + def index + @${1:model_class_name} = ${2:ModelClassName}.all + + respond_to do |wants| + wants.html # index.html.erb + wants.xml { render :xml => @$1s } + end + end${3} +snippet defnew + def new + @${1:model_class_name} = ${2:ModelClassName}.new + + respond_to do |wants| + wants.html # new.html.erb + wants.xml { render :xml => @$1 } + end + end${3} +snippet defshow + def show + @${1:model_class_name} = ${2:ModelClassName}.find(params[:id]) + + respond_to do |wants| + wants.html # show.html.erb + wants.xml { render :xml => @$1 } + end + end${3} +snippet defupdate + def update + @${1:model_class_name} = ${2:ModelClassName}.find(params[:id]) + + respond_to do |wants| + if @$1.update_attributes(params[:$1]) + flash[:notice] = '$2 was successfully updated.' + wants.html { redirect_to(@$1) } + wants.xml { head :ok } + else + wants.html { render :action => "edit" } + wants.xml { render :xml => @$1.errors, :status => :unprocessable_entity } + end + end + end${3} +snippet flash + flash[:${1:notice}] = "${2}" +snippet habtm + has_and_belongs_to_many :${1:object}, :join_table => "${2:table_name}", :foreign_key => "${3}_id"${4} +snippet hm + has_many :${1:object} +snippet hmd + has_many :${1:other}s, :class_name => "${2:$1}", :foreign_key => "${3:$1}_id", :dependent => :destroy${4} +snippet hmt + has_many :${1:object}, :through => :${2:object} +snippet ho + has_one :${1:object} +snippet i18 + I18n.t('${1:type.key}')${2} +snippet ist + <%= image_submit_tag("${1:agree.png}", :id => "${2:id}"${3} %> +snippet log + Rails.logger.${1:debug} ${2} +snippet log2 + RAILS_DEFAULT_LOGGER.${1:debug} ${2} +snippet logd + logger.debug { "${1:message}" }${2} +snippet loge + logger.error { "${1:message}" }${2} +snippet logf + logger.fatal { "${1:message}" }${2} +snippet logi + logger.info { "${1:message}" }${2} +snippet logw + logger.warn { "${1:message}" }${2} +snippet mapc + ${1:map}.${2:connect} '${3:controller/:action/:id}' +snippet mapca + ${1:map}.catch_all "*${2:anything}", :controller => "${3:default}", :action => "${4:error}"${5} +snippet mapr + ${1:map}.resource :${2:resource} +snippet maprs + ${1:map}.resources :${2:resource} +snippet mapwo + ${1:map}.with_options :${2:controller} => '${3:thing}' do |$3| + ${4} + end +snippet mbs + before_save :${1:method} +snippet mcht + change_table :${1:table_name} do |t| + ${2} + end +snippet mp + map(&:${1:id}) +snippet mrw + mattr_accessor :${1:attr_names} +snippet oa + order("${1:field}") +snippet od + order("${1:field} DESC") +snippet pa + params[:${1:id}]${2} +snippet ra + render :action => "${1:action}" +snippet ral + render :action => "${1:action}", :layout => "${2:layoutname}" +snippet rest + respond_to do |wants| + wants.${1:html} { ${2} } + end +snippet rf + render :file => "${1:filepath}" +snippet rfu + render :file => "${1:filepath}", :use_full_path => ${2:false} +snippet ri + render :inline => "${1:<%= 'hello' %>}" +snippet ril + render :inline => "${1:<%= 'hello' %>}", :locals => { ${2::name} => "${3:value}"${4} } +snippet rit + render :inline => "${1:<%= 'hello' %>}", :type => ${2::rxml} +snippet rjson + render :json => ${1:text to render} +snippet rl + render :layout => "${1:layoutname}" +snippet rn + render :nothing => ${1:true} +snippet rns + render :nothing => ${1:true}, :status => ${2:401} +snippet rp + render :partial => "${1:item}" +snippet rpc + render :partial => "${1:item}", :collection => ${2:@$1s} +snippet rpl + render :partial => "${1:item}", :locals => { :${2:$1} => ${3:@$1} +snippet rpo + render :partial => "${1:item}", :object => ${2:@$1} +snippet rps + render :partial => "${1:item}", :status => ${2:500} +snippet rt + render :text => "${1:text to render}" +snippet rtl + render :text => "${1:text to render}", :layout => "${2:layoutname}" +snippet rtlt + render :text => "${1:text to render}", :layout => ${2:true} +snippet rts + render :text => "${1:text to render}", :status => ${2:401} +snippet ru + render :update do |${1:page}| + $1.${2} + end +snippet rxml + render :xml => ${1:text to render} +snippet sc + scope :${1:name}, :where(:@${2:field} => ${3:value}) +snippet sl + scope :${1:name}, lambda do |${2:value}| + where("${3:field = ?}", ${4:bind var}) + end +snippet sha1 + Digest::SHA1.hexdigest(${1:string}) +snippet sweeper + class ${1:ModelClassName}Sweeper < ActionController::Caching::Sweeper + observe $1 + + def after_save(${2:model_class_name}) + expire_cache($2) + end + + def after_destroy($2) + expire_cache($2) + end + + def expire_cache($2) + expire_page + end + end +snippet tcb + t.boolean :${1:title} + ${2} +snippet tcbi + t.binary :${1:title}, :limit => ${2:2}.megabytes + ${3} +snippet tcd + t.decimal :${1:title}, :precision => ${2:10}, :scale => ${3:2} + ${4} +snippet tcda + t.date :${1:title} + ${2} +snippet tcdt + t.datetime :${1:title} + ${2} +snippet tcf + t.float :${1:title} + ${2} +snippet tch + t.change :${1:name}, :${2:string}, :${3:limit} => ${4:80} + ${5} +snippet tci + t.integer :${1:title} + ${2} +snippet tcl + t.integer :lock_version, :null => false, :default => 0 + ${1} +snippet tcr + t.references :${1:taggable}, :polymorphic => { :default => '${2:Photo}' } + ${3} +snippet tcs + t.string :${1:title} + ${2} +snippet tct + t.text :${1:title} + ${2} +snippet tcti + t.time :${1:title} + ${2} +snippet tcts + t.timestamp :${1:title} + ${2} +snippet tctss + t.timestamps + ${1} +snippet va + validates_associated :${1:attribute} +snippet vao + validates_acceptance_of :${1:terms} +snippet vc + validates_confirmation_of :${1:attribute} +snippet ve + validates_exclusion_of :${1:attribute}, :in => ${2:%w( mov avi )} +snippet vf + validates_format_of :${1:attribute}, :with => /${2:regex}/ +snippet vi + validates_inclusion_of :${1:attribute}, :in => %w(${2: mov avi }) +snippet vl + validates_length_of :${1:attribute}, :within => ${2:3}..${3:20} +snippet vn + validates_numericality_of :${1:attribute} +snippet vpo + validates_presence_of :${1:attribute} +snippet vu + validates_uniqueness_of :${1:attribute} +snippet wants + wants.${1:js|xml|html} { ${2} } +snippet wc + where(${1:"conditions"}${2:, bind_var}) +snippet wh + where(${1:field} => ${2:value}) +snippet xdelete + xhr :delete, :${1:destroy}, :id => ${2:1}${3} +snippet xget + xhr :get, :${1:show}, :id => ${2:1}${3} +snippet xpost + xhr :post, :${1:create}, :${2:object} => { ${3} } +snippet xput + xhr :put, :${1:update}, :id => ${2:1}, :${3:object} => { ${4} }${5} +snippet test + test "should ${1:do something}" do + ${2} + end +#migrations +snippet mac + add_column :${1:table_name}, :${2:column_name}, :${3:data_type} +snippet mrc + remove_column :${1:table_name}, :${2:column_name} +snippet mrnc + rename_column :${1:table_name}, :${2:old_column_name}, :${3:new_column_name} +snippet mcc + change_column :${1:table}, :${2:column}, :${3:type} +snippet mccc + t.column :${1:title}, :${2:string} +snippet mct + create_table :${1:table_name} do |t| + t.column :${2:name}, :${3:type} + end +snippet migration + class ${1:class_name} < ActiveRecord::Migration + def self.up + ${2} + end + + def self.down + end + end + +snippet trc + t.remove :${1:column} +snippet tre + t.rename :${1:old_column_name}, :${2:new_column_name} + ${3} +snippet tref + t.references :${1:model} + +#rspec +snippet it + it "${1:spec_name}" do + ${2} + end +snippet itp + it "${1:spec_name}" + ${2} +snippet desc + describe ${1:class_name} do + ${2} + end +snippet cont + context "${1:message}" do + ${2} + end +snippet bef + before :${1:each} do + ${2} + end +snippet aft + after :${1:each} do + ${2} + end diff --git a/lib/ace/snippets/rust.js b/lib/ace/snippets/rust.js new file mode 100644 index 00000000..556d9a6b --- /dev/null +++ b/lib/ace/snippets/rust.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./rust.snippets"); +exports.scope = "rust"; + +}); diff --git a/lib/ace/snippets/rust.snippets b/lib/ace/snippets/rust.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/sass.js b/lib/ace/snippets/sass.js new file mode 100644 index 00000000..ba728ac2 --- /dev/null +++ b/lib/ace/snippets/sass.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./sass.snippets"); +exports.scope = "sass"; + +}); diff --git a/lib/ace/snippets/sass.snippets b/lib/ace/snippets/sass.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/scad.js b/lib/ace/snippets/scad.js new file mode 100644 index 00000000..28db2155 --- /dev/null +++ b/lib/ace/snippets/scad.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./scad.snippets"); +exports.scope = "scad"; + +}); diff --git a/lib/ace/snippets/scad.snippets b/lib/ace/snippets/scad.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/scala.js b/lib/ace/snippets/scala.js new file mode 100644 index 00000000..2e5a8c57 --- /dev/null +++ b/lib/ace/snippets/scala.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./scala.snippets"); +exports.scope = "scala"; + +}); diff --git a/lib/ace/snippets/scala.snippets b/lib/ace/snippets/scala.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/scheme.js b/lib/ace/snippets/scheme.js new file mode 100644 index 00000000..7d3c6f65 --- /dev/null +++ b/lib/ace/snippets/scheme.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./scheme.snippets"); +exports.scope = "scheme"; + +}); diff --git a/lib/ace/snippets/scheme.snippets b/lib/ace/snippets/scheme.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/scss.js b/lib/ace/snippets/scss.js new file mode 100644 index 00000000..a940eabd --- /dev/null +++ b/lib/ace/snippets/scss.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./scss.snippets"); +exports.scope = "scss"; + +}); diff --git a/lib/ace/snippets/scss.snippets b/lib/ace/snippets/scss.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/sh.js b/lib/ace/snippets/sh.js new file mode 100644 index 00000000..c48dc17f --- /dev/null +++ b/lib/ace/snippets/sh.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./sh.snippets"); +exports.scope = "sh"; + +}); diff --git a/lib/ace/snippets/sh.snippets b/lib/ace/snippets/sh.snippets new file mode 100644 index 00000000..9a48eb51 --- /dev/null +++ b/lib/ace/snippets/sh.snippets @@ -0,0 +1,83 @@ +# Shebang. Executing bash via /usr/bin/env makes scripts more portable. +snippet #! + #!/usr/bin/env bash + +snippet if + if [[ ${1:condition} ]]; then + ${2:#statements} + fi +snippet elif + elif [[ ${1:condition} ]]; then + ${2:#statements} +snippet for + for (( ${2:i} = 0; $2 < ${1:count}; $2++ )); do + ${3:#statements} + done +snippet fori + for ${1:needle} in ${2:haystack} ; do + ${3:#statements} + done +snippet wh + while [[ ${1:condition} ]]; do + ${2:#statements} + done +snippet until + until [[ ${1:condition} ]]; do + ${2:#statements} + done +snippet case + case ${1:word} in + ${2:pattern}) + ${3};; + esac +snippet go + while getopts '${1:o}' ${2:opts} + do + case $$2 in + ${3:o0}) + ${4:#staments};; + esac + done +# Set SCRIPT_DIR variable to directory script is located. +snippet sdir + SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +# getopt +snippet getopt + __ScriptVersion="${1:version}" + + #=== FUNCTION ================================================================ + # NAME: usage + # DESCRIPTION: Display usage information. + #=============================================================================== + function usage () + { + cat <<- EOT + + Usage : $${0:0} [options] [--] + + Options: + -h|help Display this message + -v|version Display script version + + EOT + } # ---------- end of function usage ---------- + + #----------------------------------------------------------------------- + # Handle command line arguments + #----------------------------------------------------------------------- + + while getopts ":hv" opt + do + case $opt in + + h|help ) usage; exit 0 ;; + + v|version ) echo "$${0:0} -- Version $__ScriptVersion"; exit 0 ;; + + \? ) echo -e "\n Option does not exist : $OPTARG\n" + usage; exit 1 ;; + + esac # --- end of case --- + done + shift $(($OPTIND-1)) + diff --git a/lib/ace/snippets/sjs.js b/lib/ace/snippets/sjs.js new file mode 100644 index 00000000..a88cfc90 --- /dev/null +++ b/lib/ace/snippets/sjs.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./sjs.snippets"); +exports.scope = "sjs"; + +}); diff --git a/lib/ace/snippets/sjs.snippets b/lib/ace/snippets/sjs.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/smarty.js b/lib/ace/snippets/smarty.js new file mode 100644 index 00000000..121d0b7c --- /dev/null +++ b/lib/ace/snippets/smarty.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./smarty.snippets"); +exports.scope = "smarty"; + +}); diff --git a/lib/ace/snippets/smarty.snippets b/lib/ace/snippets/smarty.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/snippets.js b/lib/ace/snippets/snippets.js new file mode 100644 index 00000000..0927805b --- /dev/null +++ b/lib/ace/snippets/snippets.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./snippets.snippets"); +exports.scope = "snippets"; + +}); diff --git a/lib/ace/snippets/snippets.snippets b/lib/ace/snippets/snippets.snippets new file mode 100644 index 00000000..4223fa39 --- /dev/null +++ b/lib/ace/snippets/snippets.snippets @@ -0,0 +1,9 @@ +# snippets for making snippets :) +snippet snip + snippet ${1:trigger} + ${2} +snippet msnip + snippet ${1:trigger} ${2:description} + ${3} +snippet v + {VISUAL} diff --git a/lib/ace/snippets/soy_template.js b/lib/ace/snippets/soy_template.js new file mode 100644 index 00000000..194da757 --- /dev/null +++ b/lib/ace/snippets/soy_template.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./soy_template.snippets"); +exports.scope = "soy_template"; + +}); diff --git a/lib/ace/snippets/soy_template.snippets b/lib/ace/snippets/soy_template.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/space.js b/lib/ace/snippets/space.js new file mode 100644 index 00000000..766d493e --- /dev/null +++ b/lib/ace/snippets/space.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./space.snippets"); +exports.scope = "space"; + +}); diff --git a/lib/ace/snippets/space.snippets b/lib/ace/snippets/space.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/sql.js b/lib/ace/snippets/sql.js new file mode 100644 index 00000000..c96f6cb2 --- /dev/null +++ b/lib/ace/snippets/sql.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./sql.snippets"); +exports.scope = "sql"; + +}); diff --git a/lib/ace/snippets/sql.snippets b/lib/ace/snippets/sql.snippets new file mode 100644 index 00000000..eb4b37ca --- /dev/null +++ b/lib/ace/snippets/sql.snippets @@ -0,0 +1,26 @@ +snippet tbl + create table ${1:table} ( + ${2:columns} + ); +snippet col + ${1:name} ${2:type} ${3:default ''} ${4:not null} +snippet ccol + ${1:name} varchar2(${2:size}) ${3:default ''} ${4:not null} +snippet ncol + ${1:name} number ${3:default 0} ${4:not null} +snippet dcol + ${1:name} date ${3:default sysdate} ${4:not null} +snippet ind + create index ${3:$1_$2} on ${1:table}(${2:column}); +snippet uind + create unique index ${1:name} on ${2:table}(${3:column}); +snippet tblcom + comment on table ${1:table} is '${2:comment}'; +snippet colcom + comment on column ${1:table}.${2:column} is '${3:comment}'; +snippet addcol + alter table ${1:table} add (${2:column} ${3:type}); +snippet seq + create sequence ${1:name} start with ${2:1} increment by ${3:1} minvalue ${4:1}; +snippet s* + select * from ${1:table} diff --git a/lib/ace/snippets/sqlserver.js b/lib/ace/snippets/sqlserver.js new file mode 100644 index 00000000..f84694dc --- /dev/null +++ b/lib/ace/snippets/sqlserver.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./sqlserver.snippets"); +exports.scope = "sqlserver"; + +}); diff --git a/lib/ace/snippets/sqlserver.snippets b/lib/ace/snippets/sqlserver.snippets new file mode 100644 index 00000000..403bd6bc --- /dev/null +++ b/lib/ace/snippets/sqlserver.snippets @@ -0,0 +1,70 @@ +# ISNULL +snippet isnull + ISNULL(${1:check_expression}, ${2:replacement_value}) +# FORMAT +snippet format + FORMAT(${1:value}, ${2:format}) +# CAST +snippet cast + CAST(${1:expression} AS ${2:data_type}) +# CONVERT +snippet convert + CONVERT(${1:data_type}, ${2:expression}) +# DATEPART +snippet datepart + DATEPART(${1:datepart}, ${2:date}) +# DATEDIFF +snippet datediff + DATEDIFF(${1:datepart}, ${2:startdate}, ${3:enddate}) +# DATEADD +snippet dateadd + DATEADD(${1:datepart}, ${2:number}, ${3:date}) +# DATEFROMPARTS +snippet datefromparts + DATEFROMPARTS(${1:year}, ${2:month}, ${3:day}) +# OBJECT_DEFINITION +snippet objectdef + SELECT OBJECT_DEFINITION(OBJECT_ID('${1:sys.server_permissions /*object name*/}')) +# STUFF XML +snippet stuffxml + STUFF((SELECT ', ' + ${1:ColumnName} + FROM ${2:TableName} + WHERE ${3:WhereClause} + FOR XML PATH('')), 1, 1, '') AS ${4:Alias} + ${5:/*https://msdn.microsoft.com/en-us/library/ms188043.aspx*/} +# Create Procedure +snippet createproc + -- ============================================= + -- Author: ${1:Author} + -- Create date: ${2:Date} + -- Description: ${3:Description} + -- ============================================= + CREATE PROCEDURE ${4:Procedure_Name} + ${5:/*Add the parameters for the stored procedure here*/} + AS + BEGIN + -- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements. + SET NOCOUNT ON; + + ${6:/*Add the T-SQL statements to compute the return value here*/} + + END + GO +# Create Scalar Function +snippet createfn + -- ============================================= + -- Author: ${1:Author} + -- Create date: ${2:Date} + -- Description: ${3:Description} + -- ============================================= + CREATE FUNCTION ${4:Scalar_Function_Name} + -- Add the parameters for the function here + RETURNS ${5:Function_Data_Type} + AS + BEGIN + DECLARE @Result ${5:Function_Data_Type} + + ${6:/*Add the T-SQL statements to compute the return value here*/} + + END + GO \ No newline at end of file diff --git a/lib/ace/snippets/stylus.js b/lib/ace/snippets/stylus.js new file mode 100644 index 00000000..86a79f7a --- /dev/null +++ b/lib/ace/snippets/stylus.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./stylus.snippets"); +exports.scope = "stylus"; + +}); diff --git a/lib/ace/snippets/stylus.snippets b/lib/ace/snippets/stylus.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/svg.js b/lib/ace/snippets/svg.js new file mode 100644 index 00000000..aeb62456 --- /dev/null +++ b/lib/ace/snippets/svg.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./svg.snippets"); +exports.scope = "svg"; + +}); diff --git a/lib/ace/snippets/svg.snippets b/lib/ace/snippets/svg.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/tcl.js b/lib/ace/snippets/tcl.js new file mode 100644 index 00000000..53482fc7 --- /dev/null +++ b/lib/ace/snippets/tcl.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./tcl.snippets"); +exports.scope = "tcl"; + +}); diff --git a/lib/ace/snippets/tcl.snippets b/lib/ace/snippets/tcl.snippets new file mode 100644 index 00000000..1fe1cb96 --- /dev/null +++ b/lib/ace/snippets/tcl.snippets @@ -0,0 +1,92 @@ +# #!/usr/bin/env tclsh +snippet #! + #!/usr/bin/env tclsh + +# Process +snippet pro + proc ${1:function_name} {${2:args}} { + ${3:#body ...} + } +#xif +snippet xif + ${1:expr}? ${2:true} : ${3:false} +# Conditional +snippet if + if {${1}} { + ${2:# body...} + } +# Conditional if..else +snippet ife + if {${1}} { + ${2:# body...} + } else { + ${3:# else...} + } +# Conditional if..elsif..else +snippet ifee + if {${1}} { + ${2:# body...} + } elseif {${3}} { + ${4:# elsif...} + } else { + ${5:# else...} + } +# If catch then +snippet ifc + if { [catch {${1:#do something...}} ${2:err}] } { + ${3:# handle failure...} + } +# Catch +snippet catch + catch {${1}} ${2:err} ${3:options} +# While Loop +snippet wh + while {${1}} { + ${2:# body...} + } +# For Loop +snippet for + for {set ${2:var} 0} {$$2 < ${1:count}} {${3:incr} $2} { + ${4:# body...} + } +# Foreach Loop +snippet fore + foreach ${1:x} {${2:#list}} { + ${3:# body...} + } +# after ms script... +snippet af + after ${1:ms} ${2:#do something} +# after cancel id +snippet afc + after cancel ${1:id or script} +# after idle +snippet afi + after idle ${1:script} +# after info id +snippet afin + after info ${1:id} +# Expr +snippet exp + expr {${1:#expression here}} +# Switch +snippet sw + switch ${1:var} { + ${3:pattern 1} { + ${4:#do something} + } + default { + ${2:#do something} + } + } +# Case +snippet ca + ${1:pattern} { + ${2:#do something} + }${3} +# Namespace eval +snippet ns + namespace eval ${1:path} {${2:#script...}} +# Namespace current +snippet nsc + namespace current diff --git a/lib/ace/snippets/tex.js b/lib/ace/snippets/tex.js new file mode 100644 index 00000000..267b6b69 --- /dev/null +++ b/lib/ace/snippets/tex.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./tex.snippets"); +exports.scope = "tex"; + +}); diff --git a/lib/ace/snippets/tex.snippets b/lib/ace/snippets/tex.snippets new file mode 100644 index 00000000..10fa82ef --- /dev/null +++ b/lib/ace/snippets/tex.snippets @@ -0,0 +1,191 @@ +#PREAMBLE +#newcommand +snippet nc + \newcommand{\${1:cmd}}[${2:opt}]{${3:realcmd}}${4} +#usepackage +snippet up + \usepackage[${1:[options}]{${2:package}} +#newunicodechar +snippet nuc + \newunicodechar{${1}}{${2:\ensuremath}${3:tex-substitute}}} +#DeclareMathOperator +snippet dmo + \DeclareMathOperator{${1}}{${2}} + +#DOCUMENT +# \begin{}...\end{} +snippet begin + \begin{${1:env}} + ${2} + \end{$1} +# Tabular +snippet tab + \begin{${1:tabular}}{${2:c}} + ${3} + \end{$1} +snippet thm + \begin[${1:author}]{${2:thm}} + ${3} + \end{$1} +snippet center + \begin{center} + ${1} + \end{center} +# Align(ed) +snippet ali + \begin{align${1:ed}} + ${2} + \end{align$1} +# Gather(ed) +snippet gat + \begin{gather${1:ed}} + ${2} + \end{gather$1} +# Equation +snippet eq + \begin{equation} + ${1} + \end{equation} +# Equation +snippet eq* + \begin{equation*} + ${1} + \end{equation*} +# Unnumbered Equation +snippet \ + \[ + ${1} + \] +# Enumerate +snippet enum + \begin{enumerate} + \item ${1} + \end{enumerate} +# Itemize +snippet itemize + \begin{itemize} + \item ${1} + \end{itemize} +# Description +snippet desc + \begin{description} + \item[${1}] ${2} + \end{description} +# Matrix +snippet mat + \begin{${1:p/b/v/V/B/small}matrix} + ${2} + \end{$1matrix} +# Cases +snippet cas + \begin{cases} + ${1:equation}, &\text{ if }${2:case}\\ + ${3} + \end{cases} +# Split +snippet spl + \begin{split} + ${1} + \end{split} +# Part +snippet part + \part{${1:part name}} % (fold) + \label{prt:${2:$1}} + ${3} + % part $2 (end) +# Chapter +snippet cha + \chapter{${1:chapter name}} + \label{cha:${2:$1}} + ${3} +# Section +snippet sec + \section{${1:section name}} + \label{sec:${2:$1}} + ${3} +# Sub Section +snippet sub + \subsection{${1:subsection name}} + \label{sub:${2:$1}} + ${3} +# Sub Sub Section +snippet subs + \subsubsection{${1:subsubsection name}} + \label{ssub:${2:$1}} + ${3} +# Paragraph +snippet par + \paragraph{${1:paragraph name}} + \label{par:${2:$1}} + ${3} +# Sub Paragraph +snippet subp + \subparagraph{${1:subparagraph name}} + \label{subp:${2:$1}} + ${3} +#References +snippet itd + \item[${1:description}] ${2:item} +snippet figure + ${1:Figure}~\ref{${2:fig:}}${3} +snippet table + ${1:Table}~\ref{${2:tab:}}${3} +snippet listing + ${1:Listing}~\ref{${2:list}}${3} +snippet section + ${1:Section}~\ref{${2:sec:}}${3} +snippet page + ${1:page}~\pageref{${2}}${3} +snippet index + \index{${1:index}}${2} +#Citations +snippet cite + \cite[${1}]{${2}}${3} +snippet fcite + \footcite[${1}]{${2}}${3} +#Formating text: italic, bold, underline, small capital, emphase .. +snippet it + \textit{${1:text}} +snippet bf + \textbf{${1:text}} +snippet under + \underline{${1:text}} +snippet emp + \emph{${1:text}} +snippet sc + \textsc{${1:text}} +#Choosing font +snippet sf + \textsf{${1:text}} +snippet rm + \textrm{${1:text}} +snippet tt + \texttt{${1:text}} +#misc +snippet ft + \footnote{${1:text}} +snippet fig + \begin{figure} + \begin{center} + \includegraphics[scale=${1}]{Figures/${2}} + \end{center} + \caption{${3}} + \label{fig:${4}} + \end{figure} +snippet tikz + \begin{figure} + \begin{center} + \begin{tikzpicture}[scale=${1:1}] + ${2} + \end{tikzpicture} + \end{center} + \caption{${3}} + \label{fig:${4}} + \end{figure} +#math +snippet stackrel + \stackrel{${1:above}}{${2:below}} ${3} +snippet frac + \frac{${1:num}}{${2:denom}} +snippet sum + \sum^{${1:n}}_{${2:i=1}}{${3}} \ No newline at end of file diff --git a/lib/ace/snippets/text.js b/lib/ace/snippets/text.js new file mode 100644 index 00000000..434d75be --- /dev/null +++ b/lib/ace/snippets/text.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./text.snippets"); +exports.scope = "text"; + +}); diff --git a/lib/ace/snippets/text.snippets b/lib/ace/snippets/text.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/textile.js b/lib/ace/snippets/textile.js new file mode 100644 index 00000000..f2622e05 --- /dev/null +++ b/lib/ace/snippets/textile.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./textile.snippets"); +exports.scope = "textile"; + +}); diff --git a/lib/ace/snippets/textile.snippets b/lib/ace/snippets/textile.snippets new file mode 100644 index 00000000..c78d6ec8 --- /dev/null +++ b/lib/ace/snippets/textile.snippets @@ -0,0 +1,30 @@ +# Jekyll post header +snippet header + --- + title: ${1:title} + layout: post + date: ${2:date} ${3:hour:minute:second} -05:00 + --- + +# Image +snippet img + !${1:url}(${2:title}):${3:link}! + +# Table +snippet | + |${1}|${2} + +# Link +snippet link + "${1:link text}":${2:url} + +# Acronym +snippet ( + (${1:Expand acronym})${2} + +# Footnote +snippet fn + [${1:ref number}] ${3} + + fn$1. ${2:footnote} + diff --git a/lib/ace/snippets/tmsnippet.snippets b/lib/ace/snippets/tmsnippet.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/toml.js b/lib/ace/snippets/toml.js new file mode 100644 index 00000000..419b06d8 --- /dev/null +++ b/lib/ace/snippets/toml.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./toml.snippets"); +exports.scope = "toml"; + +}); diff --git a/lib/ace/snippets/toml.snippets b/lib/ace/snippets/toml.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/twig.js b/lib/ace/snippets/twig.js new file mode 100644 index 00000000..b08b884c --- /dev/null +++ b/lib/ace/snippets/twig.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./twig.snippets"); +exports.scope = "twig"; + +}); diff --git a/lib/ace/snippets/twig.snippets b/lib/ace/snippets/twig.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/typescript.js b/lib/ace/snippets/typescript.js new file mode 100644 index 00000000..495da3f3 --- /dev/null +++ b/lib/ace/snippets/typescript.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./typescript.snippets"); +exports.scope = "typescript"; + +}); diff --git a/lib/ace/snippets/typescript.snippets b/lib/ace/snippets/typescript.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/vala.js b/lib/ace/snippets/vala.js new file mode 100644 index 00000000..6092d3c1 --- /dev/null +++ b/lib/ace/snippets/vala.js @@ -0,0 +1,195 @@ +define(function(require, exports, module) { +"use strict"; + +// exports.snippetText = require("../requirejs/text!./.snippets"); +exports.snippets = [ + { + "content": "case ${1:condition}:\n\t$0\n\tbreak;\n", + "name": "case", + "scope": "vala", + "tabTrigger": "case" + }, + { + "content": "/**\n * ${6}\n */\n${1:public} class ${2:MethodName}${3: : GLib.Object} {\n\n\t/**\n\t * ${7}\n\t */\n\tpublic ${2}(${4}) {\n\t\t${5}\n\t}\n\n\t$0\n}", + "name": "class", + "scope": "vala", + "tabTrigger": "class" + }, + { + "content": "(${1}) => {\n\t${0}\n}\n", + "name": "closure", + "scope": "vala", + "tabTrigger": "=>" + }, + { + "content": "/*\n * $0\n */", + "name": "Comment (multiline)", + "scope": "vala", + "tabTrigger": "/*" + }, + { + "content": "Console.WriteLine($1);\n$0", + "name": "Console.WriteLine (writeline)", + "scope": "vala", + "tabTrigger": "writeline" + }, + { + "content": "[DBus(name = \"$0\")]", + "name": "DBus annotation", + "scope": "vala", + "tabTrigger": "[DBus" + }, + { + "content": "delegate ${1:void} ${2:DelegateName}($0);", + "name": "delegate", + "scope": "vala", + "tabTrigger": "delegate" + }, + { + "content": "do {\n\t$0\n} while ($1);\n", + "name": "do while", + "scope": "vala", + "tabTrigger": "dowhile" + }, + { + "content": "/**\n * $0\n */", + "name": "DocBlock", + "scope": "vala", + "tabTrigger": "/**" + }, + { + "content": "else if ($1) {\n\t$0\n}\n", + "name": "else if (elseif)", + "scope": "vala", + "tabTrigger": "elseif" + }, + { + "content": "else {\n\t$0\n}", + "name": "else", + "scope": "vala", + "tabTrigger": "else" + }, + { + "content": "enum {$1:EnumName} {\n\t$0\n}", + "name": "enum", + "scope": "vala", + "tabTrigger": "enum" + }, + { + "content": "public errordomain ${1:Error} {\n\t$0\n}", + "name": "error domain", + "scope": "vala", + "tabTrigger": "errordomain" + }, + { + "content": "for ($1;$2;$3) {\n\t$0\n}", + "name": "for", + "scope": "vala", + "tabTrigger": "for" + }, + { + "content": "foreach ($1 in $2) {\n\t$0\n}", + "name": "foreach", + "scope": "vala", + "tabTrigger": "foreach" + }, + { + "content": "Gee.ArrayList<${1:G}>($0);", + "name": "Gee.ArrayList", + "scope": "vala", + "tabTrigger": "ArrayList" + }, + { + "content": "Gee.HashMap<${1:K},${2:V}>($0);", + "name": "Gee.HashMap", + "scope": "vala", + "tabTrigger": "HashMap" + }, + { + "content": "Gee.HashSet<${1:G}>($0);", + "name": "Gee.HashSet", + "scope": "vala", + "tabTrigger": "HashSet" + }, + { + "content": "if ($1) {\n\t$0\n}", + "name": "if", + "scope": "vala", + "tabTrigger": "if" + }, + { + "content": "interface ${1:InterfaceName}{$2: : SuperInterface} {\n\t$0\n}", + "name": "interface", + "scope": "vala", + "tabTrigger": "interface" + }, + { + "content": "public static int main(string [] argv) {\n\t${0}\n\treturn 0;\n}", + "name": "Main function", + "scope": "vala", + "tabTrigger": "main" + }, + { + "content": "namespace $1 {\n\t$0\n}\n", + "name": "namespace (ns)", + "scope": "vala", + "tabTrigger": "ns" + }, + { + "content": "stdout.printf($0);", + "name": "printf", + "scope": "vala", + "tabTrigger": "printf" + }, + { + "content": "${1:public} ${2:Type} ${3:Name} {\n\tset {\n\t\t$0\n\t}\n\tget {\n\n\t}\n}", + "name": "property (prop)", + "scope": "vala", + "tabTrigger": "prop" + }, + { + "content": "${1:public} ${2:Type} ${3:Name} {\n\tget {\n\t\t$0\n\t}\n}", + "name": "read-only property (roprop)", + "scope": "vala", + "tabTrigger": "roprop" + }, + { + "content": "@\"${1:\\$var}\"", + "name": "String template (@)", + "scope": "vala", + "tabTrigger": "@" + }, + { + "content": "struct ${1:StructName} {\n\t$0\n}", + "name": "struct", + "scope": "vala", + "tabTrigger": "struct" + }, + { + "content": "switch ($1) {\n\t$0\n}", + "name": "switch", + "scope": "vala", + "tabTrigger": "switch" + }, + { + "content": "try {\n\t$2\n} catch (${1:Error} e) {\n\t$0\n}", + "name": "try/catch", + "scope": "vala", + "tabTrigger": "try" + }, + { + "content": "\"\"\"$0\"\"\";", + "name": "Verbatim string (\"\"\")", + "scope": "vala", + "tabTrigger": "verbatim" + }, + { + "content": "while ($1) {\n\t$0\n}", + "name": "while", + "scope": "vala", + "tabTrigger": "while" + } +]; +exports.scope = ""; + +}); diff --git a/lib/ace/snippets/vala.snippets b/lib/ace/snippets/vala.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/vbscript.js b/lib/ace/snippets/vbscript.js new file mode 100644 index 00000000..5ab8e650 --- /dev/null +++ b/lib/ace/snippets/vbscript.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./vbscript.snippets"); +exports.scope = "vbscript"; + +}); diff --git a/lib/ace/snippets/vbscript.snippets b/lib/ace/snippets/vbscript.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/velocity.js b/lib/ace/snippets/velocity.js new file mode 100644 index 00000000..ba522dd2 --- /dev/null +++ b/lib/ace/snippets/velocity.js @@ -0,0 +1,8 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./velocity.snippets"); +exports.scope = "velocity"; +exports.includeScopes = ["html", "javascript", "css"]; + +}); diff --git a/lib/ace/snippets/velocity.snippets b/lib/ace/snippets/velocity.snippets new file mode 100644 index 00000000..dedca589 --- /dev/null +++ b/lib/ace/snippets/velocity.snippets @@ -0,0 +1,28 @@ +# macro +snippet #macro + #macro ( ${1:macroName} ${2:\$var1, [\$var2, ...]} ) + ${3:## macro code} + #end +# foreach +snippet #foreach + #foreach ( ${1:\$item} in ${2:\$collection} ) + ${3:## foreach code} + #end +# if +snippet #if + #if ( ${1:true} ) + ${0} + #end +# if ... else +snippet #ife + #if ( ${1:true} ) + ${2} + #else + ${0} + #end +#import +snippet #import + #import ( "${1:path/to/velocity/format}" ) +# set +snippet #set + #set ( $${1:var} = ${0} ) diff --git a/lib/ace/snippets/verilog.js b/lib/ace/snippets/verilog.js new file mode 100644 index 00000000..7360341e --- /dev/null +++ b/lib/ace/snippets/verilog.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./verilog.snippets"); +exports.scope = "verilog"; + +}); diff --git a/lib/ace/snippets/verilog.snippets b/lib/ace/snippets/verilog.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/vhdl.js b/lib/ace/snippets/vhdl.js new file mode 100644 index 00000000..fe5e708f --- /dev/null +++ b/lib/ace/snippets/vhdl.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./vhdl.snippets"); +exports.scope = "vhdl"; + +}); \ No newline at end of file diff --git a/lib/ace/snippets/vhdl.snippets b/lib/ace/snippets/vhdl.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/xml.js b/lib/ace/snippets/xml.js new file mode 100644 index 00000000..83b1870c --- /dev/null +++ b/lib/ace/snippets/xml.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./xml.snippets"); +exports.scope = "xml"; + +}); diff --git a/lib/ace/snippets/xml.snippets b/lib/ace/snippets/xml.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/xquery.js b/lib/ace/snippets/xquery.js new file mode 100644 index 00000000..d96a0619 --- /dev/null +++ b/lib/ace/snippets/xquery.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./xquery.snippets"); +exports.scope = "xquery"; + +}); diff --git a/lib/ace/snippets/xquery.snippets b/lib/ace/snippets/xquery.snippets new file mode 100644 index 00000000..965034b7 --- /dev/null +++ b/lib/ace/snippets/xquery.snippets @@ -0,0 +1,61 @@ +snippet for + for $${1:item} in ${2:expr} +snippet return + return ${1:expr} +snippet import + import module namespace ${1:ns} = "${2:http://www.example.com/}"; +snippet some + some $${1:varname} in ${2:expr} satisfies ${3:expr} +snippet every + every $${1:varname} in ${2:expr} satisfies ${3:expr} +snippet if + if(${1:true}) then ${2:expr} else ${3:true} +snippet switch + switch(${1:"foo"}) + case ${2:"foo"} + return ${3:true} + default return ${4:false} +snippet try + try { ${1:expr} } catch ${2:*} { ${3:expr} } +snippet tumbling + for tumbling window $${1:varname} in ${2:expr} + start at $${3:start} when ${4:expr} + end at $${5:end} when ${6:expr} + return ${7:expr} +snippet sliding + for sliding window $${1:varname} in ${2:expr} + start at $${3:start} when ${4:expr} + end at $${5:end} when ${6:expr} + return ${7:expr} +snippet let + let $${1:varname} := ${2:expr} +snippet group + group by $${1:varname} := ${2:expr} +snippet order + order by ${1:expr} ${2:descending} +snippet stable + stable order by ${1:expr} +snippet count + count $${1:varname} +snippet ordered + ordered { ${1:expr} } +snippet unordered + unordered { ${1:expr} } +snippet treat + treat as ${1:expr} +snippet castable + castable as ${1:atomicType} +snippet cast + cast as ${1:atomicType} +snippet typeswitch + typeswitch(${1:expr}) + case ${2:type} return ${3:expr} + default return ${4:expr} +snippet var + declare variable $${1:varname} := ${2:expr}; +snippet fn + declare function ${1:ns}:${2:name}(){ + ${3:expr} + }; +snippet module + module namespace ${1:ns} = "${2:http://www.example.com}"; diff --git a/lib/ace/snippets/xslt.snippets b/lib/ace/snippets/xslt.snippets new file mode 100644 index 00000000..e7abdf3f --- /dev/null +++ b/lib/ace/snippets/xslt.snippets @@ -0,0 +1,97 @@ +snippet apply-templates with-param + + ${3}${4} + ${5} + +snippet apply-templates sort-by + + ${5} + ${6} + +snippet apply-templates plain + ${2} + +snippet attribute blank + ${2}${3} + +snippet attribute value-of + + + ${3} + +snippet call-template + + +snippet call-template with-param + + ${3}${4} + ${5} + +snippet choose + + + ${2} + ${3} + + +snippet copy-of + ${2} + +snippet for-each + ${2} + ${3} + +snippet if + ${2} + ${3} + +snippet import + ${2} + +snippet include + ${2} + +snippet otherwise + ${1} + + +snippet param + ${2} + ${3} + +snippet stylesheet + ${1} + + +snippet template + ${3} + + +snippet template named + ${2} + + +snippet text + ${1} + +snippet value-of + ${2} + +snippet variable blank + ${2} + + +snippet variable select + ${2} + +snippet when + ${2} + + +snippet with-param + ${2} + +snippet with-param select + + diff --git a/lib/ace/snippets/yaml.js b/lib/ace/snippets/yaml.js new file mode 100644 index 00000000..17e70a3c --- /dev/null +++ b/lib/ace/snippets/yaml.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./yaml.snippets"); +exports.scope = "yaml"; + +}); diff --git a/lib/ace/snippets/yaml.snippets b/lib/ace/snippets/yaml.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets_test.js b/lib/ace/snippets_test.js new file mode 100644 index 00000000..1870d950 --- /dev/null +++ b/lib/ace/snippets_test.js @@ -0,0 +1,131 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { +"use strict"; +var EditSession = require("./edit_session").EditSession; +var Editor = require("./editor").Editor; +var MockRenderer = require("./test/mockrenderer").MockRenderer; +var MultiSelect = require("./multi_select").MultiSelect; + +var snippetManager = require("./snippets").snippetManager; +var assert = require("./test/assertions"); + +module.exports = { + setUp : function(next) { + this.editor = new Editor(new MockRenderer()); + next(); + }, + + "test: textmate style format strings" : function() { + var fmt = snippetManager.tmStrFormat; + snippetManager.tmStrFormat("hello", { + guard: "(..)(.)(.)", + flag:"g", + fmt: "a\\UO\\l$1\\E$2" + }) == "aOHElo"; + }, + "test: parse snipmate file" : function() { + var expected = [{ + name: "a", + guard: "(?:(=)|(:))?s*)", + trigger: "\\(?f", + endTrigger: "\\)", + endGuard: "", + content: "{$0}\n" + }, { + tabTrigger: "f", + name: "f function", + content: "function" + }]; + + + + var parsed = snippetManager.parseSnippetFile( + "name a\nregex /(?:(=)|(:))?\s*)/\\(?f/\\)/\n\t{$0}" + + "\n\t\n\n#function\nsnippet f function\n\tfunction" + ); + + assert.equal(JSON.stringify(expected, null, 4), JSON.stringify(parsed, null, 4)) + }, + "test: parse snippet": function() { + var content = "-\\$$2a${1:x${$2:y$3\\}\\n\\}$TM_SELECTION}"; + var tokens = snippetManager.tokenizeTmSnippet(content); + assert.equal(tokens.length, 15); + assert.equal(tokens[4], tokens[14]); + assert.equal(tokens[2].tabstopId, 2); + + var content = "\\}${var/as\\/d/\\ul\\//g:s}" + var tokens = snippetManager.tokenizeTmSnippet(content); + assert.equal(tokens.length, 4); + assert.equal(tokens[1], tokens[3]); + assert.equal(tokens[2], "s"); + assert.equal(tokens[1].text, "var"); + assert.equal(tokens[1].fmt, "\\ul\\/"); + assert.equal(tokens[1].guard, "as\\/d"); + assert.equal(tokens[1].flag, "g"); + }, + "test: expand snippet with nested tabstops": function() { + var content = "-${1}-${1:1}--${2:2 ${3} 2}-${3:3 $1 3}-${4:4 $2 4}"; + this.editor.setValue(""); + snippetManager.insertSnippet(this.editor, content); + assert.equal(this.editor.getValue(), "-1-1--2 3 1 3 2-3 1 3-4 2 3 1 3 2 4"); + + assert.equal(this.editor.getSelectedText(), "1\n1\n1\n1\n1"); + this.editor.tabstopManager.tabNext(); + assert.equal(this.editor.getSelectedText(), "2 3 1 3 2\n2 3 1 3 2"); + this.editor.tabstopManager.tabNext(); + assert.equal(this.editor.getSelectedText(), "3 1 3\n3 1 3\n3 1 3"); + this.editor.tabstopManager.tabNext(); + assert.equal(this.editor.getSelectedText(), "4 2 3 1 3 2 4"); + this.editor.tabstopManager.tabNext(); + assert.equal(this.editor.getSelectedText(), ""); + + this.editor.setValue(""); + snippetManager.insertSnippet(this.editor, "-${1:a$2}-${2:b$1}"); + assert.equal(this.editor.getValue(), "-ab-ba"); + + assert.equal(this.editor.getSelectedText(), "ab\na"); + this.editor.tabstopManager.tabNext(); + assert.equal(this.editor.getSelectedText(), "b\nba"); + this.editor.tabstopManager.tabNext(); + assert.equal(this.editor.getSelectedText(), ""); + } +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} diff --git a/lib/ace/split.js b/lib/ace/split.js new file mode 100644 index 00000000..878b0dc3 --- /dev/null +++ b/lib/ace/split.js @@ -0,0 +1,373 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var lang = require("./lib/lang"); +var EventEmitter = require("./lib/event_emitter").EventEmitter; + +var Editor = require("./editor").Editor; +var Renderer = require("./virtual_renderer").VirtualRenderer; +var EditSession = require("./edit_session").EditSession; + +/** + * @class Split + * + * + * + **/ + + +var Split = function(container, theme, splits) { + this.BELOW = 1; + this.BESIDE = 0; + + this.$container = container; + this.$theme = theme; + this.$splits = 0; + this.$editorCSS = ""; + this.$editors = []; + this.$orientation = this.BESIDE; + + this.setSplits(splits || 1); + this.$cEditor = this.$editors[0]; + + + this.on("focus", function(editor) { + this.$cEditor = editor; + }.bind(this)); +}; + +(function(){ + + oop.implement(this, EventEmitter); + + this.$createEditor = function() { + var el = document.createElement("div"); + el.className = this.$editorCSS; + el.style.cssText = "position: absolute; top:0px; bottom:0px"; + this.$container.appendChild(el); + var editor = new Editor(new Renderer(el, this.$theme)); + + editor.on("focus", function() { + this._emit("focus", editor); + }.bind(this)); + + this.$editors.push(editor); + editor.setFontSize(this.$fontSize); + return editor; + }; + + this.setSplits = function(splits) { + var editor; + if (splits < 1) { + throw "The number of splits have to be > 0!"; + } + + if (splits == this.$splits) { + return; + } else if (splits > this.$splits) { + while (this.$splits < this.$editors.length && this.$splits < splits) { + editor = this.$editors[this.$splits]; + this.$container.appendChild(editor.container); + editor.setFontSize(this.$fontSize); + this.$splits ++; + } + while (this.$splits < splits) { + this.$createEditor(); + this.$splits ++; + } + } else { + while (this.$splits > splits) { + editor = this.$editors[this.$splits - 1]; + this.$container.removeChild(editor.container); + this.$splits --; + } + } + this.resize(); + }; + + /** + * + * Returns the number of splits. + * @returns {Number} + **/ + this.getSplits = function() { + return this.$splits; + }; + + /** + * @param {Number} idx The index of the editor you want + * + * Returns the editor identified by the index `idx`. + * + **/ + this.getEditor = function(idx) { + return this.$editors[idx]; + }; + + /** + * + * Returns the current editor. + * @returns {Editor} + **/ + this.getCurrentEditor = function() { + return this.$cEditor; + }; + + /** + * Focuses the current editor. + * @related Editor.focus + **/ + this.focus = function() { + this.$cEditor.focus(); + }; + + /** + * Blurs the current editor. + * @related Editor.blur + **/ + this.blur = function() { + this.$cEditor.blur(); + }; + + /** + * + * @param {String} theme The name of the theme to set + * + * Sets a theme for each of the available editors. + * @related Editor.setTheme + **/ + this.setTheme = function(theme) { + this.$editors.forEach(function(editor) { + editor.setTheme(theme); + }); + }; + + /** + * + * @param {String} keybinding + * + * Sets the keyboard handler for the editor. + * @related editor.setKeyboardHandler + **/ + this.setKeyboardHandler = function(keybinding) { + this.$editors.forEach(function(editor) { + editor.setKeyboardHandler(keybinding); + }); + }; + + /** + * + * @param {Function} callback A callback function to execute + * @param {String} scope The default scope for the callback + * + * Executes `callback` on all of the available editors. + * + **/ + this.forEach = function(callback, scope) { + this.$editors.forEach(callback, scope); + }; + + + this.$fontSize = ""; + /** + * @param {Number} size The new font size + * + * Sets the font size, in pixels, for all the available editors. + * + **/ + this.setFontSize = function(size) { + this.$fontSize = size; + this.forEach(function(editor) { + editor.setFontSize(size); + }); + }; + + this.$cloneSession = function(session) { + var s = new EditSession(session.getDocument(), session.getMode()); + + var undoManager = session.getUndoManager(); + if (undoManager) { + var undoManagerProxy = new UndoManagerProxy(undoManager, s); + s.setUndoManager(undoManagerProxy); + } + + // Overwrite the default $informUndoManager function such that new delas + // aren't added to the undo manager from the new and the old session. + s.$informUndoManager = lang.delayedCall(function() { s.$deltas = []; }); + + // Copy over 'settings' from the session. + s.setTabSize(session.getTabSize()); + s.setUseSoftTabs(session.getUseSoftTabs()); + s.setOverwrite(session.getOverwrite()); + s.setBreakpoints(session.getBreakpoints()); + s.setUseWrapMode(session.getUseWrapMode()); + s.setUseWorker(session.getUseWorker()); + s.setWrapLimitRange(session.$wrapLimitRange.min, + session.$wrapLimitRange.max); + s.$foldData = session.$cloneFoldData(); + + return s; + }; + + /** + * + * @param {EditSession} session The new edit session + * @param {Number} idx The editor's index you're interested in + * + * Sets a new [[EditSession `EditSession`]] for the indicated editor. + * @related Editor.setSession + **/ + this.setSession = function(session, idx) { + var editor; + if (idx == null) { + editor = this.$cEditor; + } else { + editor = this.$editors[idx]; + } + + // Check if the session is used already by any of the editors in the + // split. If it is, we have to clone the session as two editors using + // the same session can cause terrible side effects (e.g. UndoQueue goes + // wrong). This also gives the user of Split the possibility to treat + // each session on each split editor different. + var isUsed = this.$editors.some(function(editor) { + return editor.session === session; + }); + + if (isUsed) { + session = this.$cloneSession(session); + } + editor.setSession(session); + + // Return the session set on the editor. This might be a cloned one. + return session; + }; + + /** + * + * Returns the orientation. + * @returns {Number} + **/ + this.getOrientation = function() { + return this.$orientation; + }; + + /** + * + * Sets the orientation. + * @param {Number} orientation The new orientation value + * + * + **/ + this.setOrientation = function(orientation) { + if (this.$orientation == orientation) { + return; + } + this.$orientation = orientation; + this.resize(); + }; + + /** + * Resizes the editor. + **/ + this.resize = function() { + var width = this.$container.clientWidth; + var height = this.$container.clientHeight; + var editor; + + if (this.$orientation == this.BESIDE) { + var editorWidth = width / this.$splits; + for (var i = 0; i < this.$splits; i++) { + editor = this.$editors[i]; + editor.container.style.width = editorWidth + "px"; + editor.container.style.top = "0px"; + editor.container.style.left = i * editorWidth + "px"; + editor.container.style.height = height + "px"; + editor.resize(); + } + } else { + var editorHeight = height / this.$splits; + for (var i = 0; i < this.$splits; i++) { + editor = this.$editors[i]; + editor.container.style.width = width + "px"; + editor.container.style.top = i * editorHeight + "px"; + editor.container.style.left = "0px"; + editor.container.style.height = editorHeight + "px"; + editor.resize(); + } + } + }; + +}).call(Split.prototype); + + +function UndoManagerProxy(undoManager, session) { + this.$u = undoManager; + this.$doc = session; +} + +(function() { + this.execute = function(options) { + this.$u.execute(options); + }; + + this.undo = function() { + var selectionRange = this.$u.undo(true); + if (selectionRange) { + this.$doc.selection.setSelectionRange(selectionRange); + } + }; + + this.redo = function() { + var selectionRange = this.$u.redo(true); + if (selectionRange) { + this.$doc.selection.setSelectionRange(selectionRange); + } + }; + + this.reset = function() { + this.$u.reset(); + }; + + this.hasUndo = function() { + return this.$u.hasUndo(); + }; + + this.hasRedo = function() { + return this.$u.hasRedo(); + }; +}).call(UndoManagerProxy.prototype); + +exports.Split = Split; +}); diff --git a/lib/ace/test/all.js b/lib/ace/test/all.js index 19101373..e437d6f0 100644 --- a/lib/ace/test/all.js +++ b/lib/ace/test/all.js @@ -1,64 +1,35 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ -require("../../../support/paths"); +"use strict"; -require("./mockdom"); -var async = require("asyncjs"); - -async.concat( - require("./anchor_test"), - require("./change_document_test"), - require("./document_test"), - require("./edit_session_test"), - require("./event_emitter_test"), - require("./navigation_test"), - require("./range_test"), - require("./search_test"), - require("./selection_test"), - require("./text_edit_test"), - require("./highlight_selected_word_test"), - require("./mode/css_test"), - require("./mode/css_tokenizer_test"), - require("./mode/html_test"), - require("./mode/html_tokenizer_test"), - require("./mode/javascript_test"), - require("./mode/javascript_tokenizer_test"), - require("./mode/text_test"), - require("./mode/xml_test"), - require("./mode/xml_tokenizer_test") -).exec(); +require("amd-loader"); +var test = require("asyncjs").test; +test.walkTestCases(__dirname + "/..").exec(); diff --git a/lib/ace/test/all_browser.js b/lib/ace/test/all_browser.js index f3d5638e..7ac5092e 100644 --- a/lib/ace/test/all_browser.js +++ b/lib/ace/test/all_browser.js @@ -1,76 +1,150 @@ define(function(require, exports, module) { +"use strict"; -require("pilot/fixoldbrowsers"); +require("ace/lib/fixoldbrowsers"); +var AsyncTest = require("asyncjs").test; var async = require("asyncjs"); -var dom = require("pilot/dom"); var passed = 0 var failed = 0 var log = document.getElementById("log") -async.concat( - require("./anchor_test"), - require("./change_document_test"), - require("./document_test"), - require("./edit_session_test"), - require("./event_emitter_test"), - require("./navigation_test"), - require("./range_test"), - require("./search_test"), - require("./selection_test"), - require("./text_edit_test"), - require("./virtual_renderer_test"), - require("./highlight_selected_word_test"), - require("./mode/css_test"), - require("./mode/css_tokenizer_test"), - require("./mode/html_test"), - require("./mode/html_tokenizer_test"), - require("./mode/javascript_test"), - require("./mode/javascript_tokenizer_test"), - require("./mode/text_test"), - require("./mode/xml_test"), - require("./mode/xml_tokenizer_test") -) - .run() - .each(function(test, next) { - var node = document.createElement("div"); - node.className = test.passed ? "passed" : "failed"; - - var name = test.name - if (test.suiteName) - name = test.suiteName + ": " + test.name - - var msg = "[" + test.count + "/" + test.index + "] " + name + " " + (test.passed ? "OK" : "FAIL") - if (!test.passed) { - if (test.err.stack) - var err = test.err.stack - else - var err = test.err - - msg += "
    " + err + "
    "; - } - - node.innerHTML = msg; - log.appendChild(node); +var testNames = [ + "ace/anchor_test", + "ace/background_tokenizer_test", + "ace/commands/command_manager_test", + "ace/config_test", + "ace/document_test", + "ace/edit_session_test", + "ace/editor_change_document_test", + "ace/editor_highlight_selected_word_test", + "ace/editor_navigation_test", + "ace/editor_text_edit_test", + "ace/ext/static_highlight_test", + "ace/incremental_search_test", + "ace/keyboard/emacs_test", + "ace/keyboard/keybinding_test", + "ace/keyboard/vim_test", + "ace/layer/text_test", + "ace/lib/event_emitter_test", + "ace/mode/coffee/parser_test", + "ace/mode/coldfusion_test", + "ace/mode/css_test", + "ace/mode/css_worker", + "ace/mode/html_test", + "ace/mode/javascript_test", + "ace/mode/javascript_worker_test", + "ace/mode/logiql_test", + "ace/mode/python_test", + "ace/mode/text_test", + "ace/mode/xml_test", + "ace/mode/folding/cstyle_test", + "ace/mode/folding/html_test", + "ace/mode/folding/pythonic_test", + "ace/mode/folding/xml_test", + "ace/mode/folding/coffee_test", + "ace/mode/behaviour/behaviour_test", + "ace/multi_select_test", + "ace/mouse/mouse_handler_test", + "ace/occur_test", + "ace/placeholder_test", + "ace/range_test", + "ace/range_list_test", + "ace/search_test", + "ace/selection_test", + "ace/snippets_test", + "ace/token_iterator_test", + "ace/tokenizer_test", + "ace/virtual_renderer_test" +]; - next() - }) - .each(function(test) { - if (test.passed) - passed += 1 - else - failed += 1 - }) - .end(function() { - log.innerHTML += [ - "
    ", - "
    ", - "Summary:
    ", - "
    ", - "Total number of tests: " + (passed + failed) + "
    ", - (passed ? "Passed tests: " + passed + "
    " : ""), - (failed ? "Failed tests: " + failed + "
    " : "") - ].join("") - }) +var html = ["all tests
    "]; +for (var i in testNames) { + var href = testNames[i]; + html.push("", href.replace(/^ace\//, "") ,"
    "); +} + +var nav = document.createElement("div"); +nav.innerHTML = html.join(""); +nav.style.cssText = "position:absolute;right:0;top:0"; +document.body.appendChild(nav); + +if (location.search) + testNames = location.search.substr(1).split(",") + +var filter = location.hash.substr(1); + +require(testNames, function() { + var tests = testNames.map(function(x) { + var module = require(x); + module.href = x; + return module; + }); + + async.list(tests) + .expand(function(test) { + if (filter) { + Object.keys(test).forEach(function(method) { + if (method.match(/^>?test/) && !method.match(filter)) + test[method] = undefined; + }); + } + return AsyncTest.testcase(test) + }, AsyncTest.TestGenerator) + .run() + .each(function(test, next) { + if (test.index == 1 && test.context.href) { + var href = test.context.href; + var node = document.createElement("div"); + node.innerHTML = "" + href.replace(/^ace\//, "") + ""; + log.appendChild(node); + } + var node = document.createElement("div"); + node.className = test.passed ? "passed" : "failed"; + + var name = test.name + if (test.suiteName) + name = test.suiteName + ": " + test.name + + var msg = "[" + test.count + "/" + test.index + "] " + name + " " + (test.passed ? "OK" : "FAIL") + if (!test.passed) { + if (test.err.stack) + var err = test.err.stack + else + var err = test.err + + console.error(msg); + console.error(err); + msg += "
    " + err + "
    "; + } else { + console.log(msg); + } + + node.innerHTML = msg; + log.appendChild(node); + + next() + }) + .each(function(test) { + if (test.passed) + passed += 1 + else + failed += 1 + }) + .end(function() { + log.innerHTML += [ + "
    ", + "
    ", + "Summary:
    ", + "
    ", + "Total number of tests: " + (passed + failed) + "
    ", + (passed ? "Passed tests: " + passed + "
    " : ""), + (failed ? "Failed tests: " + failed + "
    " : "") + ].join("") + console.log("Total number of tests: " + (passed + failed)); + console.log("Passed tests: " + passed); + console.log("Failed tests: " + failed); + }) +}); }); diff --git a/lib/ace/test/assertions.js b/lib/ace/test/assertions.js index 9c7b16c7..3a521003 100644 --- a/lib/ace/test/assertions.js +++ b/lib/ace/test/assertions.js @@ -1,41 +1,35 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; var assert = require("assert"); @@ -51,7 +45,7 @@ assert.range = function(range, startRow, startColumn, endRow, endColumn) { assert.notOk = function(value) { assert.equal(value, false); -} +}; exports.jsonEquals = function(foundJson, expectedJson) { assert.equal(JSON.stringify(foundJson), JSON.stringify(expectedJson)); @@ -59,4 +53,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 0972a8d1..96e3f6e2 100644 --- a/lib/ace/test/asyncjs/assert.js +++ b/lib/ace/test/asyncjs/assert.js @@ -1,5 +1,5 @@ define(function(require, exports, module) { - + // http://wiki.commonjs.org/wiki/Unit_Testing/1.0 // // THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! @@ -25,7 +25,7 @@ define(function(require, exports, module) { // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // UTILITY -var oop = require('pilot/oop'); +var oop = require("ace/lib/oop"); var pSlice = Array.prototype.slice; // 1. The assert module provides functions that throw @@ -53,14 +53,21 @@ assert.AssertionError = function AssertionError(options) { }; oop.inherits(assert.AssertionError, Error); +toJSON = function(obj) { + if (typeof JSON !== "undefined") + return JSON.stringify(obj); + else + return obj.toString(); +} + assert.AssertionError.prototype.toString = function() { if (this.message) { return [this.name + ':', this.message].join(' '); } else { return [this.name + ':', - JSON.stringify(this.expected), + toJSON(this.expected), this.operator, - JSON.stringify(this.actual)].join(' '); + toJSON(this.actual)].join(' '); } }; @@ -134,7 +141,7 @@ function _deepEqual(actual, expected) { if (actual === expected) { return true; - } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { + } else if (typeof Buffer !== "undefined" && Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { if (actual.length != expected.length) return false; for (var i = 0; i < actual.length; i++) { @@ -303,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 89e49955..e8265119 100644 --- a/lib/ace/test/asyncjs/async.js +++ b/lib/ace/test/asyncjs/async.js @@ -270,6 +270,46 @@ exports.Generator = function(source) { }) } + this.expand = function(inserter, constructor) { + if (!inserter) + return this + + var inserter = makeAsync(1, inserter) + var constructor = constructor || this.constructor + var source = this.source; + var spliced = null; + + return new constructor(function next(callback) { + if (!spliced) { + source.next(function(err, value) { + if (err) + return callback(err) + + inserter(value, function(err, toInsert) { + if (err) + return callback(err) + + spliced = toInsert + next(callback) + }) + + }) + } + else { + spliced.next(function(err, value) { + if (err == STOP) { + spliced = null + return next(callback) + } + else if (err) + return callback(err) + + callback(err, value) + }) + } + }) + } + this.sort = function(compare) { var self = this var arrGen @@ -320,7 +360,7 @@ exports.Generator = function(source) { } this.end = function(breakOnError, callback) { - if (!callback) { + if (!callback) { callback = arguments[0] breakOnError = true } @@ -427,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. @@ -486,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 6903fff4..ed63914b 100644 --- a/lib/ace/test/asyncjs/index.js +++ b/lib/ace/test/asyncjs/index.js @@ -7,6 +7,7 @@ define(function(require, exports, module) { 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 d1f68b06..4374ef7c 100644 --- a/lib/ace/test/asyncjs/test.js +++ b/lib/ace/test/asyncjs/test.js @@ -6,7 +6,7 @@ define(function(require, exports, module) { -var oop = require("pilot/oop") +var oop = require("ace/lib/oop") var async = require("asyncjs/async") require("asyncjs/utils") @@ -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 604ef1d6..75fb3095 100644 --- a/lib/ace/test/asyncjs/utils.js +++ b/lib/ace/test/asyncjs/utils.js @@ -11,7 +11,9 @@ var async = require("asyncjs/async") async.plugin({ delay: function(delay) { return this.each(function(item, next) { - setTimeout(next, delay) + setTimeout(function() { + next(); + }, delay) }) }, @@ -60,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 new file mode 100644 index 00000000..cd3953c8 --- /dev/null +++ b/lib/ace/test/benchmark.js @@ -0,0 +1,78 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { +"use strict"; + +var EditSession = require("../edit_session").EditSession; + +module.exports = { + setUp : function() { + this.start = Date.now(); + }, + + tearDown : function() { + console.log("took: ", Date.now() - this.start + "ms"); + }, + + "test: document to screen position": function() { + var s = new EditSession(Array(6000).join('someText\n')); + + for (var i=0; i<6000; i++) + s.documentToScreenPosition(i, 0); + + for (var i=0; i<6000; i++) + s.documentToScreenPosition(i, 0); + + console.log(s.$rowCache.length); + }, + + "test: screen to document position": function() { + var s = new EditSession(Array(6000).join('someText\n')); + + for (var i=0; i<6000; i++) + s.screenToDocumentPosition(i, 0); + + for (var i=0; i<6000; i++) + s.documentToScreenPosition(i, 0); + + console.log(s.$rowCache.length); + } +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec(); +} diff --git a/lib/ace/test/edit_session_test.js b/lib/ace/test/edit_session_test.js deleted file mode 100644 index 3cb061bb..00000000 --- a/lib/ace/test/edit_session_test.js +++ /dev/null @@ -1,351 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var EditSession = require("ace/edit_session").EditSession, - Editor = require("../editor").Editor, - UndoManager = require("ace/undomanager").UndoManager, - MockRenderer = require("./mockrenderer"), - Range = require("ace/range").Range, - assert = require("./assertions"), - async = require("asyncjs"); - -var Test = { - - "test: find matching opening bracket" : function() { - var session = new EditSession(["(()(", "())))"]); - - assert.position(session.findMatchingBracket({row: 0, column: 3}), 0, 1); - assert.position(session.findMatchingBracket({row: 1, column: 2}), 1, 0); - assert.position(session.findMatchingBracket({row: 1, column: 3}), 0, 3); - assert.position(session.findMatchingBracket({row: 1, column: 4}), 0, 0); - assert.equal(session.findMatchingBracket({row: 1, column: 5}), null); - }, - - "test: find matching closing bracket" : function() { - var session = new EditSession(["(()(", "())))"]); - - assert.position(session.findMatchingBracket({row: 1, column: 1}), 1, 1); - assert.position(session.findMatchingBracket({row: 1, column: 1}), 1, 1); - assert.position(session.findMatchingBracket({row: 0, column: 4}), 1, 2); - assert.position(session.findMatchingBracket({row: 0, column: 2}), 0, 2); - assert.position(session.findMatchingBracket({row: 0, column: 1}), 1, 3); - assert.equal(session.findMatchingBracket({row: 0, column: 0}), null); - }, - - "test: match different bracket types" : function() { - var session = new EditSession(["({[", ")]}"]); - - assert.position(session.findMatchingBracket({row: 0, column: 1}), 1, 0); - assert.position(session.findMatchingBracket({row: 0, column: 2}), 1, 2); - assert.position(session.findMatchingBracket({row: 0, column: 3}), 1, 1); - - assert.position(session.findMatchingBracket({row: 1, column: 1}), 0, 0); - assert.position(session.findMatchingBracket({row: 1, column: 2}), 0, 2); - assert.position(session.findMatchingBracket({row: 1, column: 3}), 0, 1); - }, - - "test: move lines down" : function() { - var session = new EditSession(["a1", "a2", "a3", "a4"]); - - session.moveLinesDown(0, 1); - assert.equal(session.getValue(), ["a3", "a1", "a2", "a4"].join("\n")); - - session.moveLinesDown(1, 2); - assert.equal(session.getValue(), ["a3", "a4", "a1", "a2"].join("\n")); - - session.moveLinesDown(2, 3); - assert.equal(session.getValue(), ["a3", "a4", "a1", "a2"].join("\n")); - - session.moveLinesDown(2, 2); - assert.equal(session.getValue(), ["a3", "a4", "a2", "a1"].join("\n")); - }, - - "test: move lines up" : function() { - var session = new EditSession(["a1", "a2", "a3", "a4"]); - - session.moveLinesUp(2, 3); - assert.equal(session.getValue(), ["a1", "a3", "a4", "a2"].join("\n")); - - session.moveLinesUp(1, 2); - assert.equal(session.getValue(), ["a3", "a4", "a1", "a2"].join("\n")); - - session.moveLinesUp(0, 1); - assert.equal(session.getValue(), ["a3", "a4", "a1", "a2"].join("\n")); - - session.moveLinesUp(2, 2); - assert.equal(session.getValue(), ["a3", "a1", "a4", "a2"].join("\n")); - }, - - "test: duplicate lines" : function() { - var session = new EditSession(["1", "2", "3", "4"]); - - session.duplicateLines(1, 2); - assert.equal(session.getValue(), ["1", "2", "3", "2", "3", "4"].join("\n")); - }, - - "test: duplicate last line" : function() { - var session = new EditSession(["1", "2", "3"]); - - session.duplicateLines(2, 2); - assert.equal(session.getValue(), ["1", "2", "3", "3"].join("\n")); - }, - - "test: duplicate first line" : function() { - var session = new EditSession(["1", "2", "3"]); - - session.duplicateLines(0, 0); - assert.equal(session.getValue(), ["1", "1", "2", "3"].join("\n")); - }, - - "test: convert document to screen coordinates" : function() { - var session = new EditSession("01234\t567890\t1234"); - session.setTabSize(4); - - assert.equal(session.documentToScreenColumn(0, 0), 0); - assert.equal(session.documentToScreenColumn(0, 4), 4); - assert.equal(session.documentToScreenColumn(0, 5), 5); - assert.equal(session.documentToScreenColumn(0, 6), 9); - assert.equal(session.documentToScreenColumn(0, 12), 15); - assert.equal(session.documentToScreenColumn(0, 13), 19); - - session.setTabSize(2); - - assert.equal(session.documentToScreenColumn(0, 0), 0); - assert.equal(session.documentToScreenColumn(0, 4), 4); - assert.equal(session.documentToScreenColumn(0, 5), 5); - assert.equal(session.documentToScreenColumn(0, 6), 7); - assert.equal(session.documentToScreenColumn(0, 12), 13); - assert.equal(session.documentToScreenColumn(0, 13), 15); - }, - - "test: convert document to screen coordinates with leading tabs": function() { - var session = new EditSession("\t\t123"); - session.setTabSize(4); - - assert.equal(session.documentToScreenColumn(0, 0), 0); - assert.equal(session.documentToScreenColumn(0, 1), 4); - assert.equal(session.documentToScreenColumn(0, 2), 8); - assert.equal(session.documentToScreenColumn(0, 3), 9); - }, - - "test: documentToScreen with soft wrap and multibyte characters": function() { - var tabSize = 4; - var wrapLimit = 12; - var session = new EditSession(["foo bar foo bar"]); - session.setUseWrapMode(true); - session.setWrapLimitRange(12, 12); - session.adjustWrapLimit(80); - - assert.position(session.documentToScreenPosition(0, 11), 0, 11); - assert.position(session.documentToScreenPosition(0, 12), 1, 0); - - session = new EditSession(["ぁぁa"]); - session.setUseWrapMode(true); - session.setWrapLimitRange(2, 2); - session.adjustWrapLimit(80); - - assert.position(session.documentToScreenPosition(0, 1), 1, 0); - assert.position(session.documentToScreenPosition(0, 2), 2, 0); - assert.position(session.documentToScreenPosition(0, 4), 2, 1); - }, - - "test: convert screen to document coordinates" : function() { - var session = new EditSession("01234\t567890\t1234"); - session.setTabSize(4); - - assert.equal(session.screenToDocumentColumn(0, 0), 0); - assert.equal(session.screenToDocumentColumn(0, 4), 4); - assert.equal(session.screenToDocumentColumn(0, 5), 5); - assert.equal(session.screenToDocumentColumn(0, 6), 5); - assert.equal(session.screenToDocumentColumn(0, 7), 5); - assert.equal(session.screenToDocumentColumn(0, 8), 5); - assert.equal(session.screenToDocumentColumn(0, 9), 6); - assert.equal(session.screenToDocumentColumn(0, 15), 12); - assert.equal(session.screenToDocumentColumn(0, 19), 13); - }, - - "test: screenToDocument with soft wrap and multi byte characters": function() { - var tabSize = 4; - var wrapLimit = 12; - var session = new EditSession(["foo bar foo bar"]); - session.setUseWrapMode(true); - session.setWrapLimitRange(12, 12); - session.adjustWrapLimit(80); - - assert.position(session.screenToDocumentPosition(1, 0), 0, 12); - assert.position(session.screenToDocumentPosition(0, 11), 0, 11); - // Check if the position is clamped the right way. - assert.position(session.screenToDocumentPosition(0, 12), 0, 11); - assert.position(session.screenToDocumentPosition(0, 20), 0, 11); - - session = new EditSession(["ぁ a"]); - session.setUseWrapMode(true); - session.adjustWrapLimit(80); - - assert.position(session.screenToDocumentPosition(0, 1), 0, 0); - assert.position(session.screenToDocumentPosition(0, 2), 0, 1); - assert.position(session.screenToDocumentPosition(0, 3), 0, 2); - assert.position(session.screenToDocumentPosition(0, 4), 0, 3); - assert.position(session.screenToDocumentPosition(0, 5), 0, 3); - }, - - "test: wrapLine split function" : function() { - var splits; - var computeWrapSplits = EditSession.prototype.$computeWrapSplits; - var c = 0; - - function computeAndAssert(line, assertEqual, wrapLimit, tabSize) { - wrapLimit = wrapLimit || 12; - tabSize = tabSize || 4; - splits = computeWrapSplits.call(EditSession.prototype, line, wrapLimit, tabSize); - // console.log("String:", line, "Result:", splits, "Expected:", assertEqual); - assert.ok(splits.length == assertEqual.length); - for (var i = 0; i < splits.length; i++) { - assert.ok(splits[i] == assertEqual[i]); - } - } - - // Basic splitting. - computeAndAssert("foo bar foo bar", [ 12 ]); - computeAndAssert("foo bar f bar", [ 12 ]); - computeAndAssert("foo bar f r", [ 14 ]); - computeAndAssert("foo bar foo bar foo bara foo", [12, 25]); - - // Don't split if there is only whitespaces/tabs at the end of the line. - computeAndAssert("foo foo foo \t \t", [ ]); - - // If there is no space to split, force split. - computeAndAssert("foooooooooooooo", [ 12 ]); - computeAndAssert("fooooooooooooooooooooooooooo", [12, 24]); - computeAndAssert("foo bar fooooooooooobooooooo", [8, 20]); - - // Basic splitting + tabs. - computeAndAssert("foo \t\tbar", [ 6 ]); - computeAndAssert("foo \t \tbar", [ 7 ]); - - // Ignore spaces/tabs at beginning of split. - computeAndAssert("foo \t \t \t \t bar", [ 14 ]); - - // Test wrapping for asian characters. - computeAndAssert("ぁぁ", [1], 2); - computeAndAssert(" ぁぁ", [1, 2], 2); - computeAndAssert(" ぁ\tぁ", [1, 3], 2); - computeAndAssert(" ぁぁ\tぁ", [1, 4], 4); - }, - - "test get longest line" : function() { - var session = new EditSession(["12"]); - session.setTabSize(4); - assert.equal(session.getWidth(), 2); - assert.equal(session.getScreenWidth(), 2); - - session.doc.insertNewLine(0); - session.doc.insertLines(1, ["123"]); - assert.equal(session.getWidth(), 3); - assert.equal(session.getScreenWidth(), 3); - - session.doc.insertNewLine(0); - session.doc.insertLines(1, ["\t\t"]); - - assert.equal(session.getWidth(), 3); - assert.equal(session.getScreenWidth(), 8); - - session.setTabSize(2); - assert.equal(session.getWidth(), 3); - assert.equal(session.getScreenWidth(), 4); - }, - - "test getDisplayString": function() { - var session = new EditSession(["12"]); - session.setTabSize(4); - - assert.equal(session.$getDisplayTokens("\t").length, 4); - assert.equal(session.$getDisplayTokens("abc").length, 3); - assert.equal(session.$getDisplayTokens("abc\t").length, 7); - }, - - "test issue 83": function() { - var session = new EditSession(""); - var editor = new Editor(new MockRenderer(), session); - var document = session.getDocument(); - - session.setUseWrapMode(true); - - document.insertLines(0, ["a", "b"]); - document.insertLines(2, ["c", "d"]); - document.removeLines(1, 2); - }, - - "test wrapMode init has to create wrapData array": function() { - var session = new EditSession("foo bar\nfoo bar"); - var editor = new Editor(new MockRenderer(), session); - var document = session.getDocument(); - - session.setUseWrapMode(true); - session.setWrapLimitRange(3, 3); - session.adjustWrapLimit(80); - - // Test if wrapData is there and was computed. - assert.equal(session.$wrapData.length, 2); - assert.equal(session.$wrapData[0].length, 1); - assert.equal(session.$wrapData[1].length, 1); - }, - - "test first line blank with wrap": function() { - var session = new EditSession("\nfoo"); - session.setUseWrapMode(true); - assert.equal(session.doc.getValue(), ["", "foo"].join("\n")); - }, - - "test first line blank with wrap 2" : function() { - var session = new EditSession(""); - session.setUseWrapMode(true); - session.setValue("\nfoo"); - - assert.equal(session.doc.getValue(), ["", "foo"].join("\n")); - } -}; - -module.exports = require("asyncjs/test").testcase(Test); -}); - -if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec() -} \ No newline at end of file diff --git a/lib/ace/test/event_emitter_test.js b/lib/ace/test/event_emitter_test.js deleted file mode 100644 index 19e12596..00000000 --- a/lib/ace/test/event_emitter_test.js +++ /dev/null @@ -1,64 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var oop = require("pilot/oop"); - EventEmitter = require("pilot/event_emitter").EventEmitter, - assert = require("./assertions"); - -var Emitter = function() {}; - -oop.implement(Emitter.prototype, EventEmitter); - -var Test = { - "test: dispatch event with no data" : function() { - var emitter = new Emitter(); - - var called = false; - emitter.addEventListener("juhu", function(e) { - called = true; - assert.equal(e.type, "juhu"); - }); - - emitter._dispatchEvent("juhu"); - assert.ok(called); - } -}; - -module.exports = require("asyncjs/test").testcase(Test) -}); \ No newline at end of file diff --git a/lib/ace/test/mockdom.js b/lib/ace/test/mockdom.js index 1c9b8476..54991fc5 100644 --- a/lib/ace/test/mockdom.js +++ b/lib/ace/test/mockdom.js @@ -1,8 +1,10 @@ -var dom = require('jsdom/level2/html').dom.level2.html; -var browser = require('jsdom/browser/index').windowAugmentation(dom); +"use strict"; + +var dom = require('jsdom/lib/jsdom/level2/html').dom.level2.html; +var browser = require('jsdom/lib/jsdom/browser/index').windowAugmentation(dom); 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 7a9cc378..ba4c9563 100644 --- a/lib/ace/test/mockrenderer.js +++ b/lib/ace/test/mockrenderer.js @@ -1,44 +1,39 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -MockRenderer = function(visibleRowCount) { +var MockRenderer = exports.MockRenderer = function(visibleRowCount) { this.container = document.createElement("div"); + this.scroller = document.createElement("div"); this.visibleRowCount = visibleRowCount || 20; this.layerConfig = { @@ -47,6 +42,8 @@ MockRenderer = function(visibleRowCount) { }; this.isMockRenderer = true; + + this.$gutter = {}; }; @@ -58,6 +55,14 @@ MockRenderer.prototype.getLastVisibleRow = function() { return this.layerConfig.lastVisibleRow; }; +MockRenderer.prototype.getFirstFullyVisibleRow = function() { + return this.layerConfig.firstVisibleRow; +}; + +MockRenderer.prototype.getLastFullyVisibleRow = function() { + return this.layerConfig.lastVisibleRow; +}; + MockRenderer.prototype.getContainerElement = function() { return this.container; }; @@ -70,6 +75,12 @@ MockRenderer.prototype.getTextAreaContainer = function() { return this.container; }; +MockRenderer.prototype.addGutterDecoration = function() { +}; + +MockRenderer.prototype.removeGutterDecoration = function() { +}; + MockRenderer.prototype.moveTextAreaToCursor = function() { }; @@ -84,14 +95,24 @@ MockRenderer.prototype.getSession = function(session) { MockRenderer.prototype.setTokenizer = function() { }; +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) {}; + MockRenderer.prototype.scrollToLine = function(line, center) { - var lineHeight = { lineHeight: 16 }; + var lineHeight = 16; var row = 0; for (var l = 1; l < line; l++) { - row += this.session.getRowHeight(lineHeight, l-1) / lineHeight.lineHeight; + row += this.session.getRowLength(l-1); } if (center) { @@ -100,6 +121,9 @@ MockRenderer.prototype.scrollToLine = function(line, center) { this.scrollToRow(row); }; +MockRenderer.prototype.scrollSelectionIntoView = function() { +}; + MockRenderer.prototype.scrollCursorIntoView = function() { var cursor = this.session.getSelection().getCursor(); if (cursor.row < this.layerConfig.firstVisibleRow) { @@ -124,6 +148,9 @@ MockRenderer.prototype.getScrollTopRow = function() { MockRenderer.prototype.draw = function() { }; +MockRenderer.prototype.onChangeTabSize = function(startRow, endRow) { +}; + MockRenderer.prototype.updateLines = function(startRow, endRow) { }; @@ -133,7 +160,7 @@ MockRenderer.prototype.updateBackMarkers = function() { MockRenderer.prototype.updateFrontMarkers = function() { }; -MockRenderer.prototype.setBreakpoints = function() { +MockRenderer.prototype.updateBreakpoints = function() { }; MockRenderer.prototype.onResize = function() { @@ -154,6 +181,12 @@ MockRenderer.prototype.visualizeFocus = function() { MockRenderer.prototype.setAnnotations = function() { }; +MockRenderer.prototype.setStyle = function() { +}; + +MockRenderer.prototype.unsetStyle = function() { +}; + MockRenderer.prototype.textToScreenCoordinates = function() { return { pageX: 0, @@ -161,5 +194,15 @@ MockRenderer.prototype.textToScreenCoordinates = function() { } }; -return MockRenderer; +MockRenderer.prototype.screenToTextCoordinates = function() { + return { + row: 0, + column: 0 + } +}; + +MockRenderer.prototype.adjustWrapLimit = function () { + +}; + }); diff --git a/lib/ace/test/mode/css_test.js b/lib/ace/test/mode/css_test.js deleted file mode 100644 index e5aa099e..00000000 --- a/lib/ace/test/mode/css_test.js +++ /dev/null @@ -1,79 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var EditSession = require("ace/edit_session").EditSession; -var CssMode = require("ace/mode/css").Mode; -var assert = require("../assertions"); - -var Test = { - setUp : function() { - this.mode = new CssMode(); - }, - - "test: toggle comment lines should not do anything" : function() { - var session = new EditSession([" abc", "cde", "fg"].join("\n")); - - var comment = this.mode.toggleCommentLines("start", session, 0, 1); - assert.equal([" abc", "cde", "fg"].join("\n"), session.toString()); - }, - - - "test: lines should keep indentation" : function() { - assert.equal(" ", this.mode.getNextLineIndent("start", " abc", " ")); - assert.equal("\t", this.mode.getNextLineIndent("start", "\tabc", " ")); - }, - - "test: new line after { should increase indent" : function() { - assert.equal(" ", this.mode.getNextLineIndent("start", " abc{", " ")); - assert.equal("\t ", this.mode.getNextLineIndent("start", "\tabc { ", " ")); - }, - - "test: no indent increase after { in a comment" : function() { - assert.equal(" ", this.mode.getNextLineIndent("start", " /*{", " ")); - assert.equal(" ", this.mode.getNextLineIndent("start", " /*{ ", " ")); - } -}; - -module.exports = require("asyncjs/test").testcase(Test); -}); - -if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec() -} \ No newline at end of file diff --git a/lib/ace/test/mode/css_tokenizer_test.js b/lib/ace/test/mode/css_tokenizer_test.js deleted file mode 100644 index dbad83c8..00000000 --- a/lib/ace/test/mode/css_tokenizer_test.js +++ /dev/null @@ -1,94 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var CssMode = require("ace/mode/css").Mode; -var assert = require("../assertions"); - -var Test = { - setUp : function() { - this.tokenizer = new CssMode().getTokenizer(); - }, - - "test: tokenize pixel number" : function() { - var line = "-12px"; - var tokens = this.tokenizer.getLineTokens(line, "start").tokens; - - assert.equal(1, tokens.length); - assert.equal("constant.numeric", tokens[0].type); - }, - - "test: tokenize hex3 color" : function() { - var tokens = this.tokenizer.getLineTokens("#abc", "start").tokens; - - assert.equal(1, tokens.length); - assert.equal("constant.numeric", tokens[0].type); - }, - - "test: tokenize hex6 color" : function() { - var tokens = this.tokenizer.getLineTokens("#abc012", "start").tokens; - - assert.equal(1, tokens.length); - assert.equal("constant.numeric", tokens[0].type); - }, - - "test: tokenize parens" : function() { - var tokens = this.tokenizer.getLineTokens("{()}", "start").tokens; - - assert.equal(3, tokens.length); - assert.equal("lparen", tokens[0].type); - assert.equal("text", tokens[1].type); - assert.equal("rparen", tokens[2].type); - }, - - "test for last rule in ruleset to catch capturing group bugs" : function() { - var tokens = this.tokenizer.getLineTokens("top", "start").tokens; - - assert.equal(1, tokens.length); - assert.equal("support.type", tokens[0].type); - } -}; - -module.exports = require("asyncjs/test").testcase(Test, "css tokenizer"); - -}); - -if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec() -} \ No newline at end of file diff --git a/lib/ace/test/mode/html_test.js b/lib/ace/test/mode/html_test.js deleted file mode 100644 index c614b6b8..00000000 --- a/lib/ace/test/mode/html_test.js +++ /dev/null @@ -1,71 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var EditSession = require("ace/edit_session").EditSession; -var Range = require("ace/range").Range; -var HtmlMode = require("ace/mode/html").Mode; -var assert = require("../assertions"); - -var Test = { - setUp : function() { - this.mode = new HtmlMode(); - }, - - "test: toggle comment lines should not do anything" : function() { - var session = new EditSession([" abc", "cde", "fg"]); - - var range = new Range(0, 3, 1, 1); - var comment = this.mode.toggleCommentLines("start", session, 0, 1); - assert.equal([" abc", "cde", "fg"].join("\n"), session.toString()); - }, - - "test: next line indent should be the same as the current line indent" : function() { - assert.equal(" ", this.mode.getNextLineIndent("start", " abc")); - assert.equal("", this.mode.getNextLineIndent("start", "abc")); - assert.equal("\t", this.mode.getNextLineIndent("start", "\tabc")); - } -}; - -module.exports = require("asyncjs/test").testcase(Test); -}); - -if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec(); -} \ No newline at end of file diff --git a/lib/ace/test/mode/html_tokenizer_test.js b/lib/ace/test/mode/html_tokenizer_test.js deleted file mode 100644 index 14e697ba..00000000 --- a/lib/ace/test/mode/html_tokenizer_test.js +++ /dev/null @@ -1,74 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var HtmlMode = require("ace/mode/html").Mode; -var assert = require("../assertions"); - -var Test = { - setUp : function() { - this.tokenizer = new HtmlMode().getTokenizer(); - }, - - "test: tokenize embedded script" : function() { - - var line = "'123'"; - var tokens = this.tokenizer.getLineTokens(line, "start").tokens; - - //assert.equal(10, tokens.length); - assert.equal("text", tokens[0].type); - assert.equal("keyword", tokens[1].type); - assert.equal("text", tokens[2].type); - assert.equal("keyword", tokens[3].type); - assert.equal("text", tokens[4].type); - assert.equal("string", tokens[5].type); - assert.equal("text", tokens[6].type); - assert.equal("keyword", tokens[7].type); - assert.equal("text", tokens[8].type); - assert.equal("keyword", tokens[9].type); - assert.equal("text", tokens[10].type); - } -}; - -module.exports = require("asyncjs/test").testcase(Test); -}); - -if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec(); -} \ No newline at end of file diff --git a/lib/ace/test/mode/javascript_test.js b/lib/ace/test/mode/javascript_test.js deleted file mode 100644 index 316ea910..00000000 --- a/lib/ace/test/mode/javascript_test.js +++ /dev/null @@ -1,153 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var EditSession = require("ace/edit_session").EditSession; -var Tokenizer = require("ace/tokenizer").Tokenizer; -var JavaScriptMode = require("ace/mode/javascript").Mode; -var assert = require("../assertions"); - -var Test = { - setUp : function() { - this.mode = new JavaScriptMode(); - }, - - "test: getTokenizer() (smoke test)" : function() { - var tokenizer = this.mode.getTokenizer(); - - assert.ok(tokenizer instanceof Tokenizer); - - var tokens = tokenizer.getLineTokens("'juhu'", "start").tokens; - assert.equal("string", tokens[0].type); - }, - - "test: toggle comment lines should prepend '//' to each line" : function() { - var session = new EditSession([" abc", "cde", "fg"]); - - var comment = this.mode.toggleCommentLines("start", session, 0, 1); - assert.equal(["// abc", "//cde", "fg"].join("\n"), session.toString()); - }, - - "test: toggle comment on commented lines should remove leading '//' chars" : function() { - var session = new EditSession(["// abc", "//cde", "fg"]); - - var comment = this.mode.toggleCommentLines("start", session, 0, 1); - assert.equal([" abc", "cde", "fg"].join("\n"), session.toString()); - }, - - "test: toggle comment lines twice should return the original text" : function() { - var session = new EditSession([" abc", "cde", "fg"]); - - this.mode.toggleCommentLines("start", session, 0, 2); - this.mode.toggleCommentLines("start", session, 0, 2); - assert.equal([" abc", "cde", "fg"].join("\n"), session.toString()); - }, - - "test: toggle comment on multiple lines with one commented line prepend '//' to each line" : function() { - var session = new EditSession(["// abc", "//cde", "fg"]); - - var comment = this.mode.toggleCommentLines("start", session, 0, 2); - assert.equal(["//// abc", "////cde", "//fg"].join("\n"), session.toString()); - }, - - "test: toggle comment on a comment line with leading white space": function() { - var session = new EditSession(["//cde", " //fg"]); - - var comment = this.mode.toggleCommentLines("start", session, 0, 1); - assert.equal(["cde", " fg"].join("\n"), session.toString()); - }, - - "test: auto indent after opening brace" : function() { - assert.equal(" ", this.mode.getNextLineIndent("start", "if () {", " ")); - }, - - "test: no auto indent after opening brace in multi line comment" : function() { - assert.equal("", this.mode.getNextLineIndent("start", "/*if () {", " ")); - assert.equal(" ", this.mode.getNextLineIndent("comment", " abcd", " ")); - }, - - "test: no auto indent after opening brace in single line comment" : function() { - assert.equal("", this.mode.getNextLineIndent("start", "//if () {", " ")); - assert.equal(" ", this.mode.getNextLineIndent("start", " //if () {", " ")); - }, - - "test: no auto indent should add to existing indent" : function() { - assert.equal(" ", this.mode.getNextLineIndent("start", " if () {", " ")); - assert.equal(" ", this.mode.getNextLineIndent("start", " cde", " ")); - }, - - "test: special indent in doc comments" : function() { - assert.equal(" * ", this.mode.getNextLineIndent("doc-start", "/**", " ")); - assert.equal(" * ", this.mode.getNextLineIndent("doc-start", " /**", " ")); - assert.equal(" * ", this.mode.getNextLineIndent("doc-start", " *", " ")); - assert.equal(" * ", this.mode.getNextLineIndent("doc-start", " *", " ")); - assert.equal(" ", this.mode.getNextLineIndent("doc-start", " abc", " ")); - }, - - "test: no indent after doc comments" : function() { - assert.equal("", this.mode.getNextLineIndent("doc-start", " */", " ")); - }, - - "test: trigger outdent if line is space and new text starts with closing brace" : function() { - assert.ok(this.mode.checkOutdent("start", " ", " }")); - assert.ok(!this.mode.checkOutdent("start", " a ", " }")); - assert.ok(!this.mode.checkOutdent("start", "", "}")); - assert.ok(!this.mode.checkOutdent("start", " ", "a }")); - assert.ok(!this.mode.checkOutdent("start", " }", "}")); - }, - - "test: auto outdent should indent the line with the same indent as the line with the matching opening brace" : function() { - var session = new EditSession([" function foo() {", " bla", " }"]); - this.mode.autoOutdent("start", session, 2); - assert.equal(" }", session.getLine(2)); - }, - - "test: no auto outdent if no matching brace is found" : function() { - var session = new EditSession([" function foo()", " bla", " }"]); - this.mode.autoOutdent("start", session, 2); - assert.equal(" }", session.getLine(2)); - } -}; - -module.exports = require("asyncjs/test").testcase(Test); -}); - -if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec(); -} \ No newline at end of file diff --git a/lib/ace/test/mode/javascript_tokenizer_test.js b/lib/ace/test/mode/javascript_tokenizer_test.js deleted file mode 100644 index c4aa922a..00000000 --- a/lib/ace/test/mode/javascript_tokenizer_test.js +++ /dev/null @@ -1,115 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var JavaScriptMode = require("ace/mode/javascript").Mode; -var assert = require("../assertions"); - -var Test = { - setUp : function() { - this.tokenizer = new JavaScriptMode().getTokenizer(); - }, - - "test: tokenize1" : function() { - var line = "foo = function"; - - var tokens = this.tokenizer.getLineTokens(line, "start").tokens; - - assert.equal(5, tokens.length); - assert.equal("identifier", tokens[0].type); - assert.equal("text", tokens[1].type); - assert.equal("keyword.operator", tokens[2].type); - assert.equal("text", tokens[3].type); - assert.equal("keyword", tokens[4].type); - }, - - "test: tokenize doc comment" : function() { - var line = "abc /** de */ fg"; - - var tokens = this.tokenizer.getLineTokens(line, "start").tokens; - - assert.equal(5, tokens.length); - assert.equal("identifier", tokens[0].type); - assert.equal("text", tokens[1].type); - assert.equal("comment.doc", tokens[2].type); - assert.equal("text", tokens[3].type); - assert.equal("identifier", tokens[4].type); - }, - - "test: tokenize doc comment with tag" : function() { - var line = "/** @param {} */"; - - var tokens = this.tokenizer.getLineTokens(line, "start").tokens; - - assert.equal(3, tokens.length); - assert.equal("comment.doc", tokens[0].type); - assert.equal("comment.doc.tag", tokens[1].type); - assert.equal("comment.doc", tokens[2].type); - }, - - "test: tokenize parens" : function() { - var line = "[{( )}]"; - - var tokens = this.tokenizer.getLineTokens(line, "start").tokens; - - assert.equal(3, tokens.length); - assert.equal("lparen", tokens[0].type); - assert.equal("text", tokens[1].type); - assert.equal("rparen", tokens[2].type); - }, - - "test for last rule in ruleset to catch capturing group bugs" : function() { - var tokens = this.tokenizer.getLineTokens("}", "start").tokens; - - assert.equal(1, tokens.length); - assert.equal("rparen", tokens[0].type); - }, - - "test tokenize regular expressions": function() { - var tokens = this.tokenizer.getLineTokens("a/b/c", "start").tokens; - assert.equal(5, tokens.length); - } -}; - -module.exports = require("asyncjs/test").testcase(Test); -}); - -if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec(); -} \ No newline at end of file diff --git a/lib/ace/test/mode/text_test.js b/lib/ace/test/mode/text_test.js deleted file mode 100644 index 1284d97d..00000000 --- a/lib/ace/test/mode/text_test.js +++ /dev/null @@ -1,68 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var EditSession = require("ace/edit_session").EditSession; -var TextMode = require("ace/mode/text").Mode; -var assert = require("../assertions"); - -var Test = { - setUp : function() { - this.mode = new TextMode(); - }, - - "test: toggle comment lines should not do anything" : function() { - var session = new EditSession([" abc", "cde", "fg"]); - - var comment = this.mode.toggleCommentLines("start", session, 0, 1); - assert.equal([" abc", "cde", "fg"].join("\n"), session.toString()); - }, - - - "text: lines should not be indented" : function() { - assert.equal("", this.mode.getNextLineIndent("start", " abc", " ")); - } -}; - -module.exports = require("asyncjs/test").testcase(Test); -}); - -if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec(); -} \ No newline at end of file diff --git a/lib/ace/test/mode/xml_test.js b/lib/ace/test/mode/xml_test.js deleted file mode 100644 index c5e7810a..00000000 --- a/lib/ace/test/mode/xml_test.js +++ /dev/null @@ -1,79 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var EditSession = require("ace/edit_session").EditSession; -var Tokenizer = require("ace/tokenizer").Tokenizer; -var XmlMode = require("ace/mode/xml").Mode; -var assert = require("../assertions"); - -var Test = { - setUp : function() { - this.mode = new XmlMode(); - }, - - "test: getTokenizer() (smoke test)" : function() { - var tokenizer = this.mode.getTokenizer(); - - assert.ok(tokenizer instanceof Tokenizer); - - var tokens = tokenizer.getLineTokens("", "start").tokens; - assert.equal("keyword", tokens[1].type); - }, - - "test: toggle comment lines should not do anything" : function() { - var session = new EditSession([" abc", "cde", "fg"]); - - var comment = this.mode.toggleCommentLines("start", session, 0, 1); - assert.equal([" abc", "cde", "fg"].join("\n"), session.toString()); - }, - - "test: next line indent should be the same as the current line indent" : function() { - assert.equal(" ", this.mode.getNextLineIndent("start", " abc")); - assert.equal("", this.mode.getNextLineIndent("start", "abc")); - assert.equal("\t", this.mode.getNextLineIndent("start", "\tabc")); - } -}; - -module.exports = require("asyncjs/test").testcase(Test); -}); - -if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec(); -} \ No newline at end of file diff --git a/lib/ace/test/mode/xml_tokenizer_test.js b/lib/ace/test/mode/xml_tokenizer_test.js deleted file mode 100644 index dcf22b33..00000000 --- a/lib/ace/test/mode/xml_tokenizer_test.js +++ /dev/null @@ -1,69 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - - -define(function(require, exports, module) { - -var XmlMode = require("ace/mode/xml").Mode; -var assert = require("../assertions"); - -var Test = { - setUp : function() { - this.tokenizer = new XmlMode().getTokenizer(); - }, - - "test: tokenize1" : function() { - - var line = "//Juhu Kinners"; - var tokens = this.tokenizer.getLineTokens(line, "start").tokens; - - assert.equal(5, tokens.length); - assert.equal("text", tokens[0].type); - assert.equal("keyword", tokens[1].type); - assert.equal("text", tokens[2].type); - assert.equal("keyword", tokens[3].type); - assert.equal("text", tokens[4].type); - } -}; - -module.exports = require("asyncjs/test").testcase(Test); -}); - -if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec(); -} \ No newline at end of file diff --git a/lib/ace/test/selection_test.js b/lib/ace/test/selection_test.js deleted file mode 100644 index b94a17db..00000000 --- a/lib/ace/test/selection_test.js +++ /dev/null @@ -1,335 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var EditSession = require("ace/edit_session").EditSession, - assert = require("./assertions"); - -var Test = { - createSession : function(rows, cols) { - var line = new Array(cols + 1).join("a"); - var text = new Array(rows).join(line + "\n") + line; - return new EditSession(text); - }, - - "test: move cursor to end of file should place the cursor on last row and column" : function() { - var session = this.createSession(200, 10); - var selection = session.getSelection(); - - selection.moveCursorFileEnd(); - assert.position(selection.getCursor(), 199, 10); - }, - - "test: moveCursor to start of file should place the cursor on the first row and column" : function() { - var session = this.createSession(200, 10); - var selection = session.getSelection(); - - selection.moveCursorFileStart(); - assert.position(selection.getCursor(), 0, 0); - }, - - "test: move selection lead to end of file" : function() { - var session = this.createSession(200, 10); - var selection = session.getSelection(); - - selection.moveCursorTo(100, 5); - selection.selectFileEnd(); - - var range = selection.getRange(); - - assert.position(range.start, 100, 5); - assert.position(range.end, 199, 10); - }, - - "test: move selection lead to start of file" : function() { - var session = this.createSession(200, 10); - var selection = session.getSelection(); - - selection.moveCursorTo(100, 5); - selection.selectFileStart(); - - var range = selection.getRange(); - - assert.position(range.start, 0, 0); - assert.position(range.end, 100, 5); - }, - - "test: move cursor word right" : function() { - var session = new EditSession( ["ab", - " Juhu Kinners (abc, 12)", " cde"].join("\n")); - var selection = session.getSelection(); - - selection.moveCursorDown(); - assert.position(selection.getCursor(), 1, 0); - - selection.moveCursorWordRight(); - assert.position(selection.getCursor(), 1, 1); - - selection.moveCursorWordRight(); - assert.position(selection.getCursor(), 1, 5); - - selection.moveCursorWordRight(); - assert.position(selection.getCursor(), 1, 6); - - selection.moveCursorWordRight(); - assert.position(selection.getCursor(), 1, 13); - - selection.moveCursorWordRight(); - assert.position(selection.getCursor(), 1, 15); - - selection.moveCursorWordRight(); - assert.position(selection.getCursor(), 1, 18); - - selection.moveCursorWordRight(); - assert.position(selection.getCursor(), 1, 20); - - selection.moveCursorWordRight(); - assert.position(selection.getCursor(), 1, 22); - - selection.moveCursorWordRight(); - assert.position(selection.getCursor(), 1, 23); - - // wrap line - selection.moveCursorWordRight(); - assert.position(selection.getCursor(), 2, 0); - }, - - "test: select word right if cursor in word" : function() { - var session = new EditSession("Juhu Kinners"); - var selection = session.getSelection(); - - selection.moveCursorTo(0, 2); - selection.moveCursorWordRight(); - - assert.position(selection.getCursor(), 0, 4); - }, - - "test: moveCursor word left" : function() { - var session = new EditSession( ["ab", - " Juhu Kinners (abc, 12)", " cde"].join("\n")); - var selection = session.getSelection(); - - selection.moveCursorDown(); - selection.moveCursorLineEnd(); - assert.position(selection.getCursor(), 1, 23); - - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 1, 22); - - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 1, 20); - - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 1, 18); - - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 1, 15); - - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 1, 13); - - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 1, 6); - - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 1, 5); - - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 1, 1); - - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 1, 0); - - // wrap line - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 0, 2); - }, - - "test: select word left if cursor in word" : function() { - var session = new EditSession("Juhu Kinners"); - var selection = session.getSelection(); - - selection.moveCursorTo(0, 8); - - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 0, 5); - }, - - "test: select word right and select" : function() { - var session = new EditSession("Juhu Kinners"); - var selection = session.getSelection(); - - selection.moveCursorTo(0, 0); - selection.selectWordRight(); - - var range = selection.getRange(); - - assert.position(range.start, 0, 0); - assert.position(range.end, 0, 4); - }, - - "test: select word left and select" : function() { - var session = new EditSession("Juhu Kinners"); - var selection = session.getSelection(); - - selection.moveCursorTo(0, 3); - selection.selectWordLeft(); - - var range = selection.getRange(); - - assert.position(range.start, 0, 0); - assert.position(range.end, 0, 3); - }, - - "test: select word with cursor in word should select the word" : function() { - var session = new EditSession("Juhu Kinners 123"); - var selection = session.getSelection(); - - selection.moveCursorTo(0, 8); - selection.selectWord(); - - var range = selection.getRange(); - assert.position(range.start, 0, 5); - assert.position(range.end, 0, 12); - }, - - "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(); - - selection.moveCursorTo(0, 4); - selection.selectWord(); - - var range = selection.getRange(); - assert.position(range.start, 0, 0); - assert.position(range.end, 0, 4); - - selection.moveCursorTo(0, 5); - selection.selectWord(); - - var range = selection.getRange(); - assert.position(range.start, 0, 5); - assert.position(range.end, 0, 12); - }, - - "test: select word with cursor in white space should select white space" : function() { - var session = new EditSession("Juhu Kinners"); - var selection = session.getSelection(); - - selection.moveCursorTo(0, 5); - selection.selectWord(); - - var range = selection.getRange(); - assert.position(range.start, 0, 4); - assert.position(range.end, 0, 6); - }, - - "test: moving cursor should fire a 'changeCursor' event" : function() { - var session = new EditSession("Juhu Kinners"); - var selection = session.getSelection(); - - selection.moveCursorTo(0, 5); - - var called = false; - selection.addEventListener("changeCursor", function() { - called = true; - }); - - selection.moveCursorTo(0, 6); - assert.ok(called); - }, - - "test: calling setCursor with the same position should not fire an event": function() { - var session = new EditSession("Juhu Kinners"); - var selection = session.getSelection(); - - selection.moveCursorTo(0, 5); - - var called = false; - selection.addEventListener("changeCursor", function() { - called = true; - }); - - selection.moveCursorTo(0, 5); - assert.notOk(called); - }, - - "test: moveWordLeft should move past || and [": function() { - var session = new EditSession("||foo["); - var selection = session.getSelection(); - - // Move behind || - selection.moveCursorWordRight(); - assert.position(selection.getCursor(), 0, 2); - - // Move beind foo - selection.moveCursorWordRight(); - assert.position(selection.getCursor(), 0, 5); - - // Move behind [ - selection.moveCursorWordRight(); - assert.position(selection.getCursor(), 0, 6); - }, - - "test: moveWordRight should move past || and [": function() { - var session = new EditSession("||foo["); - var selection = session.getSelection(); - - selection.moveCursorTo(0, 6); - - // Move behind [ - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 0, 5); - - // Move beind foo - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 0, 2); - - // Move behind || - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 0, 0); - } -}; - -module.exports = require("asyncjs/test").testcase(Test); -}); - -if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec() -} diff --git a/lib/ace/test/tests.html b/lib/ace/test/tests.html index 2af7ea55..113ecc03 100644 --- a/lib/ace/test/tests.html +++ b/lib/ace/test/tests.html @@ -23,32 +23,24 @@
    - - + + diff --git a/lib/ace/test/virtual_renderer_test.js b/lib/ace/test/virtual_renderer_test.js deleted file mode 100644 index 0d2304d3..00000000 --- a/lib/ace/test/virtual_renderer_test.js +++ /dev/null @@ -1,81 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - -var EditSession = require("ace/edit_session").EditSession, - VirtualRenderer = require("../virtual_renderer").VirtualRenderer, - assert = require("./assertions"); - -var Test = { - "test: screen2text the column should be rounded to the next character edge" : function() { - var el = document.createElement("div"); - el.style.left = "0px"; - el.style.top = "0px"; - el.style.width = "100px"; - el.style.height = "100px"; - document.body.style.margin = "0px"; - document.body.style.padding = "0px"; - document.body.appendChild(el); - - var renderer = new VirtualRenderer(el); - renderer.setPadding(0); - renderer.setSession(new EditSession("1234")); - - renderer.characterWidth = 10; - renderer.lineHeight = 15; - - assert.position(renderer.screenToTextCoordinates(0, 0), 0, 0); - assert.position(renderer.screenToTextCoordinates(4, 0), 0, 0); - assert.position(renderer.screenToTextCoordinates(5, 0), 0, 1); - assert.position(renderer.screenToTextCoordinates(9, 0), 0, 1); - assert.position(renderer.screenToTextCoordinates(10, 0), 0, 1); - assert.position(renderer.screenToTextCoordinates(14, 0), 0, 1); - assert.position(renderer.screenToTextCoordinates(15, 0), 0, 2); - document.body.removeChild(el); - } - - // change tab size after setDocument (for text layer) -}; - -module.exports = require("asyncjs/test").testcase(Test); -}); - -if (typeof module !== "undefined" && module === require.main) { - require("../../../support/paths"); - exports.exec(); -} diff --git a/lib/ace/theme/ambiance.css b/lib/ace/theme/ambiance.css new file mode 100644 index 00000000..9f9f7afa --- /dev/null +++ b/lib/ace/theme/ambiance.css @@ -0,0 +1,221 @@ +.ace-ambiance .ace_gutter { + background-color: #3d3d3d; + background-image: -moz-linear-gradient(left, #3D3D3D, #333); + background-image: -ms-linear-gradient(left, #3D3D3D, #333); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#3D3D3D), to(#333)); + background-image: -webkit-linear-gradient(left, #3D3D3D, #333); + background-image: -o-linear-gradient(left, #3D3D3D, #333); + background-image: linear-gradient(left, #3D3D3D, #333); + background-repeat: repeat-x; + border-right: 1px solid #4d4d4d; + text-shadow: 0px 1px 1px #4d4d4d; + color: #222; +} + +.ace-ambiance .ace_gutter-layer { + background: repeat left top; +} + +.ace-ambiance .ace_gutter-active-line { + background-color: #3F3F3F; +} + +.ace-ambiance .ace_fold-widget { + text-align: center; +} + +.ace-ambiance .ace_fold-widget:hover { + color: #777; +} + +.ace-ambiance .ace_fold-widget.ace_start, +.ace-ambiance .ace_fold-widget.ace_end, +.ace-ambiance .ace_fold-widget.ace_closed{ + background: none; + border: none; + box-shadow: none; +} + +.ace-ambiance .ace_fold-widget.ace_start:after { + content: '▾' +} + +.ace-ambiance .ace_fold-widget.ace_end:after { + content: '▴' +} + +.ace-ambiance .ace_fold-widget.ace_closed:after { + content: '‣' +} + +.ace-ambiance .ace_print-margin { + border-left: 1px dotted #2D2D2D; + right: 0; + background: #262626; +} + +.ace-ambiance .ace_scroller { + -webkit-box-shadow: inset 0 0 10px black; + -moz-box-shadow: inset 0 0 10px black; + -o-box-shadow: inset 0 0 10px black; + box-shadow: inset 0 0 10px black; +} + +.ace-ambiance { + color: #E6E1DC; + background-color: #202020; +} + +.ace-ambiance .ace_cursor { + border-left: 1px solid #7991E8; +} + +.ace-ambiance .ace_overwrite-cursors .ace_cursor { + border: 1px solid #FFE300; + background: #766B13; +} + +.ace-ambiance.normal-mode .ace_cursor-layer { + z-index: 0; +} + +.ace-ambiance .ace_marker-layer .ace_selection { + background: rgba(221, 240, 255, 0.20); +} + +.ace-ambiance .ace_marker-layer .ace_selected-word { + border-radius: 4px; + border: 8px solid #3f475d; + box-shadow: 0 0 4px black; +} + +.ace-ambiance .ace_marker-layer .ace_step { + background: rgb(198, 219, 174); +} + +.ace-ambiance .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgba(255, 255, 255, 0.25); +} + +.ace-ambiance .ace_marker-layer .ace_active-line { + background: rgba(255, 255, 255, 0.031); +} + +.ace-ambiance .ace_invisible { + color: #333; +} + +.ace-ambiance .ace_paren { + color: #24C2C7; +} + +.ace-ambiance .ace_keyword { + color: #cda869; +} + +.ace-ambiance .ace_keyword.ace_operator { + color: #fa8d6a; +} + +.ace-ambiance .ace_punctuation.ace_operator { + color: #fa8d6a; +} + +.ace-ambiance .ace_identifier { +} + +.ace-ambiance .ace-statement { + color: #cda869; +} + +.ace-ambiance .ace_constant { + color: #CF7EA9; +} + +.ace-ambiance .ace_constant.ace_language { + color: #CF7EA9; +} + +.ace-ambiance .ace_constant.ace_library { + +} + +.ace-ambiance .ace_constant.ace_numeric { + color: #78CF8A; +} + +.ace-ambiance .ace_invalid { + text-decoration: underline; +} + +.ace-ambiance .ace_invalid.ace_illegal { + color:#F8F8F8; + background-color: rgba(86, 45, 86, 0.75); +} + +.ace-ambiance .ace_invalid, +.ace-ambiance .ace_deprecated { + text-decoration: underline; + font-style: italic; + color: #D2A8A1; +} + +.ace-ambiance .ace_support { + color: #9B859D; +} + +.ace-ambiance .ace_support.ace_function { + color: #DAD085; +} + +.ace-ambiance .ace_function.ace_buildin { + color: #9b859d; +} + +.ace-ambiance .ace_string { + color: #8f9d6a; +} + +.ace-ambiance .ace_string.ace_regexp { + color: #DAD085; +} + +.ace-ambiance .ace_comment { + font-style: italic; + color: #555; +} + +.ace-ambiance .ace_comment.ace_doc { +} + +.ace-ambiance .ace_comment.ace_doc.ace_tag { + color: #666; + font-style: normal; +} + +.ace-ambiance .ace_definition, +.ace-ambiance .ace_type { + color: #aac6e3; +} + +.ace-ambiance .ace_variable { + color: #9999cc; +} + +.ace-ambiance .ace_variable.ace_language { + color: #9b859d; +} + +.ace-ambiance .ace_xml-pe { + color: #494949; +} + +.ace-ambiance .ace_gutter-layer, +.ace-ambiance .ace_text-layer { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAQAAAAHUWYVAABFFUlEQVQYGbzBCeDVU/74/6fj9HIcx/FRHx9JCFmzMyGRURhLZIkUsoeRfUjS2FNDtr6WkMhO9sm+S8maJfu+Jcsg+/o/c+Z4z/t97/vezy3z+z8ekGlnYICG/o7gdk+wmSHZ1z4pJItqapjoKXWahm8NmV6eOTbWUOp6/6a/XIg6GQqmenJ2lDHyvCFZ2cBDbmtHA043VFhHwXxClWmeYAdLhV00Bd85go8VmaFCkbVkzlQENzfBDZ5gtN7HwF0KDrTwJ0dypSOzpaKCMwQHKTIreYIxlmhXTzTWkVm+LTynZhiSBT3RZQ7aGfjGEd3qyXQ1FDymqbKxpspERQN2MiRjNZlFFQXfCNFm9nM1zpAsoYjmtRTc5ajwuaXc5xrWskT97RaKzAGe5ARHhVUsDbjKklziiX5WROcJwSNCNI+9w1Jwv4Zb2r7lCMZ4oq5C0EdTx+2GzNuKpJ+iFf38JEWkHJn9DNF7mmBDITrWEg0VWL3pHU20tSZnuqWu+R3BtYa8XxV1HO7GyD32UkOpL/yDloINFTmvtId+nmAjxRw40VMwVKiwrKLE4bK5UOVntYwhOcSSXKrJHKPJedocpGjVz/ZMIbnYUPB10/eKCrs5apqpgVmWzBYWpmtKHecJPjaUuEgRDDaU0oZghCJ6zNMQ5ZhDYx05r5v2muQdM0EILtXUsaKiQX9WMEUotagQzFbUNN6NUPC2nm5pxEWGCjMc3GdJHjSU2kORLK/JGSrkfGEIjncU/CYUnOipoYemwj8tST9NsJmB7TUVXtbUtXATJVZXBMvYeTXJfobgJUPmGMP/yFaWonaa6BcFO3nqcIqCozSZoZoSr1g4zJOzuyGnxTEX3lUEJ7WcZgme8ddaWvWJo2AJR9DZU3CUIbhCSG6ybSwN6qtJVnCU2svDTP2ZInOw2cBTrqtQahtNZn9NcJ4l2NaSmSkkP1noZWnVwkLmdUPOwLZEwy2Z3S3R+4rIG9hcbpPXHFVWcQdZkn2FOta3cKWQnNRC5g1LsJah4GCzSVsKnCOY5OAFRTBekyyryeyilhFKva75r4Mc0aWanGEaThcy31s439KKxTzJYY5WTHPU1FtIHjQU3Oip4xlNzj/lBw23dYZVliQa7WAXf4shetcQfatI+jWRDBPmyNeW6A1P5kdDgyYJlba0BIM8BZu1JfrFwItyjcAMR3K0BWOIrtMEXyhyrlVEx3ui5dUBjmB/Q3CXW85R4mBD0s7B+4q5tKUjOlb9qqmhi5AZ6GFIC5HXtOobdYGlVdMVbNJ8toNTFcHxnoL+muBagcctjWnbNMuR00uI7nQESwg5q2qqrKWIfrNUmeQocY6HuyxJV02wj36w00yhpmUFenv4p6fUkZYqLyuinx2RGOjhCXYyJF84oiU00YMOOhhquNdfbOB7gU88pY4xJO8LVdp6/q2voeB4R04vIdhSE40xZObx1HGGJ/ja0LBthFInKaLPPFzuCaYaoj8JjPME8yoyxo6zlBqkiUZYgq00OYMswbWO5NGmq+xhipxHLRW29ARjNKXO0wRnear8XSg4XFPLKEPUS1GqvyLwiuBUoa7zpZ0l5xxFwWmWZC1H5h5FwU8eQ7K+g8UcVY6TMQreVQT/8uQ8Z+ALIXnSEa2pYZQneE9RZbSBNYXfWYJzW/h/4j4Dp1tYVcFIC5019Vyi4ThPqSFCzjGWaHQTBU8q6vrVwgxP9Lkm840imWKpcLCjYTtrKuwvsKSnrvHCXGkSMk9p6lhckfRpIeis+N2PiszT+mFLspyGleUhDwcLrZqmyeylxwjBcKHEapqkmyangyLZRVOijwOtCY5SsG5zL0OwlCJ4y5KznF3EUNDDrinwiyLZRzOXtlBbK5ITHFGLp8Q0R6ab6mS7enI2cFrxOyHvOCFaT1HThS1krjCwqWeurCkk+willhCC+RSZnRXBiZaC5RXRIZYKp2lyfrHwiKPKR0JDzrdU2EFgpidawlFDR6FgXUMNa+g1FY3bUQh2cLCwosRdnuQTS/S+JVrGLeWIvtQUvONJxlqSQYYKpwoN2kaocLjdVsis4Mk80ESF2YpSkzwldjHkjFCUutI/r+EHDU8oCs6yzL3PhWiEooZdFMkymlas4AcI3KmoMMNSQ3tHzjGWCrcJJdYyZC7QFGwjRL9p+MrRkAGWzIaWCn9W0F3TsK01c2ZvQw0byvxuQU0r1lM0qJO7wW0kRIMdDTtXEdzi4VIh+EoIHm0mWtAtpCixlabgn83fKTI7anJe9ST7WIK1DMGpQmYeA58ImV6ezOGOzK2Kgq01pd60cKWiUi9Lievb/0vIDPHQ05Kzt4ddPckQBQtoaurjyHnek/nKzpQLrVgKPjIkh2v4uyezpv+Xoo7fPFXaGFp1vaLKxQ4uUpQQS5VuQs7BCq4xRJv7fwpVvvFEB3j+620haOuocqMhWd6TTPAEx+mdFNGHdranFe95WrWmIvlY4F1Dle2ECgc6cto7SryuqGGGha0tFQ5V53migUKmg6XKAo4qS3mik+0OZpAhOLeZKicacgaYcyx5hypYQE02ZA4xi/pNhOQxR4klNKyqacj+mpxnLTnnGSo85++3ZCZq6lrZkXlGEX3o+C9FieccJbZWVFjC0Yo1FZnJhoYMFoI1hEZ9r6hwg75HwzBNhbZCdJEfJwTPGzJvaKImw1yYX1HDAmpXR+ZJQ/SmgqMNVQb5vgamGwLtt7VwvP7Qk1xpiM5x5Cyv93E06MZmgs0Nya2azIKOYKCGBQQW97RmhKNKF02JZqHEJ4o58qp7X5EcZmc56trXEqzjCBZ1MFGR87Ql2tSTs6CGxS05PTzRQorkbw7aKoKXFDXsYW42VJih/q+FP2BdTzDTwVqOYB13liM50vG7wy28qagyuIXMeQI/Oqq8bcn5wJI50xH00CRntyfpL1T4hydYpoXgNiFzoIUTDZnLNRzh4TBHwbYGDvZkxmlyJloyr6tRihpeUG94GnKtIznREF0tzJG/OOr73JBcrSh1k6WuTprgLU+mnSGnv6Zge0NNz+kTDdH8nuAuTdJDCNb21LCiIuqlYbqGzT3RAoZofQfjFazkqeNWdYaGvYTM001EW2oKPvVk1ldUGSgUtHFwjKM1h9jnFcmy5lChoLNaQMGGDsYbKixlaMBmmsx1QjCfflwTfO/gckW0ruZ3jugKR3R5W9hGUWqCgxuFgsuaCHorotGKzGaeZB9DMsaTnKCpMtwTvOzhYk0rdrArKCqcaWmVk1+F372ur1YkKxgatI8Qfe1gIX9wE9FgS8ESmuABIXnRUbCapcKe+nO7slClSZFzpV/LkLncEb1qiO42fS3R855Su2mCLh62t1SYZZYVmKwIHjREF2uihTzB20JOkz7dkxzYQnK0UOU494wh+VWRc6Un2kpTaVgLDFEkJ/uhzRcI0YKGgpGWOlocBU/a4fKoJ/pEaNV6jip3+Es9VXY078rGnmAdf7t9ylPXS34RBSuYPs1UecZTU78WanhBCHpZ5sAoTz0LGZKjPf9TRypqWEiTvOFglL1fCEY3wY/++rbk7C8bWebA6p6om6PgOL2kp44TFJlVNBXae2rqqdZztOJpT87GQsE9jqCPIe9VReZuQ/CIgacsyZdCpIScSYqcZk8r+nsyCzhyfhOqHGOIvrLknC8wTpFcaYiGC/RU1NRbUeUpocQOnkRpGOrIOcNRx+1uA0UrzhSSt+VyS3SJpnFWkzNDqOFGIWcfR86DnmARTQ1HKIL33ExPiemeOhYSSjzlSUZZuE4TveoJLnBUOFof6KiysCbnAEcZgcUNTDOwkqWu3RWtmGpZwlHhJENdZ3miGz0lJlsKnjbwqSHQjpxnFDlTLLwqJPMZMjd7KrzkSG7VsxXBZE+F8YZkb01Oe00yyRK9psh5SYh29ySPKBo2ylNht7ZkZnsKenjKNJu9PNEyZpaCHv4Kt6RQsLvAVp7M9kIimmCUwGeWqLMmGuIotYMmWNpSahkhZw9FqZsVnKJhsjAHvtHMsTM9fCI06Dx/u3vfUXCqfsKRc4oFY2jMsoo/7DJDwZ1CsIKnJu+J9ldkpmiCxQx1rWjI+T9FwcWWzOuaYH0Hj7klNRVWEQpmaqosakiGNTFHdjS/qnUdmf0NJW5xsL0HhimCCZZSRzmSPTXJQ4aaztAwtZnoabebJ+htCaZ7Cm535ByoqXKbX1WRc4Eh2MkRXWzImVc96Cj4VdOKVxR84VdQsIUM8Psoou2byVHyZFuq7O8otbSQ2UAoeEWTudATLGSpZzVLlXVkPU2Jc+27lsw2jmg5T5VhbeE3BT083K9WsTTkFU/Osi0rC5lRlpwRHUiesNS0sOvmqGML1aRbPAxTJD9ZKtxuob+hhl8cwYGWpJ8nub7t5p6coYbMovZ1BTdaKn1jYD6h4GFDNFyT/Kqe1XCXphXHOKLZmuRSRdBPEfVUXQzJm5YGPGGJdvAEr7hHNdGZnuBvrpciGmopOLf5N0uVMy0FfYToJk90uUCbJupaVpO53UJXR2bVpoU00V2KOo4zMFrBd0Jtz2pa0clT5Q5L8IpQ177mWQejPMEJhuQjS10ref6HHjdEhy1P1EYR7GtO0uSsKJQYLiTnG1rVScj5lyazpqWGl5uBbRWl7m6ixGOOnEsMJR7z8J0n6KMnCdxhiNYQCoZ6CmYLnO8omC3MkW3bktlPmEt/VQQHejL3+dOE5FlPdK/Mq8hZxxJtLyRrepLThYKbLZxkSb5W52vYxNOaOxUF0yxMUPwBTYqCzy01XayYK0sJyWBLqX0MwU5CzoymRzV0EjjeUeLgDpTo6ij42ZAzvD01dHUUTPLU96MdLbBME8nFBn7zJCMtJcZokn8YoqU0FS5WFKyniHobguMcmW8N0XkWZjkyN3hqOMtS08r+/xTBwpZSZ3qiVRX8SzMHHjfUNFjgHEPmY9PL3ykEzxkSre/1ZD6z/NuznuB0RcE1TWTm9zRgfUWVJiG6yrzgmWPXC8EAR4Wxhlad0ZbgQyEz3pG5RVEwwDJH2mgKpjcTiCOzn1lfUWANFbZ2BA8balnEweJC9J0iuaeZoI+ippFCztEKVvckR2iice1JvhVytrQwUAZpgsubCPaU7xUe9vWnaOpaSBEspalykhC9bUlOMpT42ZHca6hyrqKmw/wMR8H5ZmdFoBVJb03O4UL0tSNnvIeRmkrLWqrs78gcrEn2tpcboh0UPOW3UUR9PMk4T4nnNKWmCjlrefhCwxRNztfmIQVdDElvS4m1/WuOujoZCs5XVOjtKPGokJzsYCtFYoWonSPT21DheU/wWhM19FcElwqNGOsp9Q8N/cwXaiND1MmeL1Q5XROtYYgGeFq1aTMsoMmcrKjQrOFQTQ1fmBYhmW6o8Jkjc7iDJRTBIo5kgJD5yMEYA3srCg7VFKwiVJkmRCc5ohGOKhsYMn/XBLdo5taZjlb9YAlGWRimqbCsoY7HFAXLa5I1HPRxMMsQDHFkWtRNniqT9UEeNjcE7RUlrCJ4R2CSJuqlKHWvJXjAUNcITYkenuBRB84TbeepcqTj3zZyFJzgYQdHnqfgI0ddUwS6GqWpsKWhjq9cV0vBAEMN2znq+EBfIWT+pClYw5xsTlJU6GeIBsjGmmANTzJZiIYpgrM0Oa8ZMjd7NP87jxhqGOhJlnQtjuQpB+8aEE00wZFznSJPyHxgH3HkPOsJFvYk8zqCHzTs1BYOa4J3PFU+UVRZxlHDM4YavlNUuMoRveiZA2d7grMNc2g+RbSCEKzmgYsUmWmazFJyoiOZ4KnyhKOGRzWJa0+moyV4TVHDzn51Awtqaphfk/lRQ08FX1iiqxTB/kLwd0VynKfEvI6cd4XMV5bMhZ7gZUWVzYQ6Nm2BYzxJbw3bGthEUUMfgbGeorae6DxHtJoZ6alhZ0+ytiVoK1R4z5PTrOECT/SugseEOlb1MMNR4VRNcJy+V1Hg9ONClSZFZjdHlc6W6FBLdJja2MC5hhpu0DBYEY1TFGwiFAxRRCsYkiM9JRb0JNMVkW6CZYT/2EiTGWmo8k+h4FhDNE7BvppoTSFnmCV5xZKzvcCdDo7VVPnIU+I+Rc68juApC90MwcFCsJ5hDqxgScYKreruyQwTqrzoqDCmhWi4IbhB0Yrt3RGa6GfDv52rKXWhh28dyZaWUvcZeMTBaZoSGyiCtRU5J8iviioHaErs7Jkj61syVzTTgOcUOQ8buFBTYWdL5g3T4qlpe0+wvD63heAXRfCCIed9RbCsp2CiI7raUOYOTU13N8PNHvpaGvayo4a3LLT1lDrVEPT2zLUlheB1R+ZTRfKWJ+dcocLJfi11vyJ51lLqJ0WD7tRwryezjiV5W28uJO9qykzX8JDe2lHl/9oyBwa2UMfOngpXCixvKdXTk3wrsKmiVYdZIqsoWEERjbcUNDuiaQomGoIbFdEHmsyWnuR+IeriKDVLnlawlyNHKwKlSU631PKep8J4Q+ayjkSLKYLhalNHlYvttb6fHm0p6OApsZ4l2VfdqZkjuysy6ysKLlckf1KUutCTs39bmCgEyyoasIWlVaMF7mgmWtBT8Kol5xpH9IGllo8cJdopcvZ2sImlDmMIbtDk3KIpeNiS08lQw11NFPTwVFlPP6pJ2gvRfI7gQUfmNAtf6Gs0wQxDsKGlVBdF8rCa3jzdwMaGHOsItrZk7hAyOzpK9VS06j5F49b0VNGOOfKs3lDToMsMBe9ZWtHFEgxTJLs7qrygKZjUnmCYoeAqeU6jqWuLJup4WghOdvCYJnrSkSzoyRkm5M2StQwVltPkfCAk58tET/CSg+8MUecmotMEnhBKfWBIZsg2ihruMJQaoIm+tkTLKEqspMh00w95gvFCQRtDwTT1gVDDSEVdlwqZfxoQRbK0g+tbiBZxzKlpnpypejdDwTaeOvorMk/IJE10h9CqRe28hhLbe0pMsdSwv4ZbhKivo2BjDWfL8UKJgeavwlwb5KlwhyE4u4XkGE2ytZCznKLCDZZq42VzT8HLCrpruFbIfOIINmh/qCdZ1ZBc65kLHR1Bkyf5zn6pN3SvGKIlFNGplhrO9QSXanLOMQTLCa0YJCRrCZm/CZmrLTm7WzCK4GJDiWUdFeYx1LCFg3NMd0XmCuF3Y5rITLDUsYS9zoHVzwnJoYpSTQoObyEzr4cFBNqYTopoaU/wkyLZ2lPhX/5Y95ulxGTV7KjhWrOZgl8MyUUafjYraNjNU1N3IWcjT5WzWqjwtoarHSUObGYO3GCJZpsBlnJGPd6ZYLyl1GdCA2625IwwJDP8GUKymbzuyPlZlvTUsaUh5zFDhRWFzPKKZLAlWdcQbObgF9tOqOsmB1dqcqYJmWstFbZRRI9poolmqiLnU0POvxScpah2iSL5UJNzgScY5+AuIbpO0YD3NCW+dLMszFSdFCWGqG6eVq2uYVNDdICGD6W7EPRWZEY5gpsE9rUkS3mijzzJnm6UpUFXG1hCUeVoS5WfNcFpblELL2qqrCvMvRfd45oalvKU2tiQ6ePJOVMRXase9iTtLJztPxJKLWpo2CRDcJwn2sWSLKIO1WQWNTCvpVUvOZhgSC40JD0dOctaSqzkCRbXsKlb11Oip6PCJ0IwSJM31j3akRxlP7Rwn6aGaUL0qiLnJkvB3xWZ2+Q1TfCwpQH3G0o92UzmX4o/oJNQMMSQc547wVHhdk+VCw01DFYEnTxzZKAm74QmeNNR1w6WzEhNK15VJzuCdxQ53dRUDws5KvwgBMOEgpcVNe0hZI6RXT1Jd0cyj5nsaEAHgVmGaJIlWdsc5Ui2ElrRR6jrRAttNMEAIWrTDFubkZaok7/AkzfIwfuWVq0jHzuCK4QabtLUMVPB3kJ0oyHTSVFlqMALilJf2Rf8k5aaHtMfayocLBS8L89oKoxpJvnAkDPa0qp5DAUTHKWmCcnthlou8iCKaFFLHWcINd1nyIwXqrSxMNmSs6KmoL2QrKuWtlQ5V0120xQ5vRyZS1rgFkWwhiOwiuQbR0OOVhQM9iS3tiXp4RawRPMp5tDletOOBL95MpM01dZTBM9pkn5qF010rIeHFcFZhmSGpYpTsI6nwhqe5C9ynhlpp5ophuRb6WcJFldkVnVEwwxVfrVkvnWUuNLCg5bgboFHPDlDPDmnK7hUrWiIbjadDclujlZcaokOFup4Ri1kacV6jmrrK1hN9bGwpKEBQ4Q6DvIUXOmo6U5LqQM6EPyiKNjVkPnJkDPNEaxhiFay5ExW1NXVUGqcpYYdPcGiCq7z/TSlbhL4pplWXKd7NZO5QQFrefhRQW/NHOsqcIglc4UhWklR8K0QzbAw08CBDnpbgqXdeD/QUsM4RZXDFBW6WJKe/mFPdH0LtBgiq57wFLzlyQzz82qYx5D5WJP5yVJDW01BfyHnS6HKO/reZqId1WGa4Hkh2kWodJ8i6KoIPlAj2hPt76CzXsVR6koPRzWTfKqIentatYpQw2me4AA3y1Kind3SwoOKZDcFXTwl9tWU6mfgRk9d71sKtlNwrjnYw5tC5n5LdKiGry3JKNlHEd3oaMCFHrazBPMp/uNJ+V7IudcSbeOIdjUEdwl0VHCOZo5t6YluEuaC9mQeMgSfOyKnYGFHcIeQ84yQWbuJYJpZw5CzglDH7gKnWqqM9ZTaXcN0TeYhR84eQtJT76JJ1lREe7WnnvsMmRc9FQ7SBBM9mV3lCUdmHk/S2RAMt0QjFNFqQpWjDPQ01DXWUdDBkXziKPjGEP3VP+zIWU2t7im41FOloyWzn/L6dkUy3VLDaZ6appgDLHPjJEsyvJngWEPUyVBiAaHCTEXwrLvSEbV1e1gKJniicWorC1MUrVjB3uDhJE/wgSOzk1DXpk0k73qCM8xw2UvD5kJmDUfOomqMpWCkJRlvKXGmoeBm18USjVIk04SClxTB6YrgLAPLWYK9HLUt5cmc0vYES8GnTeRc6skZbQkWdxRsIcyBRzx1DbTk9FbU0caTPOgJHhJKnOGIVhQqvKmo0llRw9sabrZkDtdg3PqaKi9oatjY8B+G371paMg6+mZFNNtQ04mWBq3rYLOmtWWQp8KJnpy9DdFensyjdqZ+yY40VJlH8wcdLzC8PZnvHMFUTZUrDTkLyQaGus5X5LzpYAf3i+e/ZlhqGqWhh6Ou6xTR9Z6oi5AZZtp7Mj2EEm8oSpxiYZCHU/1fbGdNNNRRoZMhmilEb2gqHOEJDtXkHK/JnG6IrvbPCwV3NhONVdS1thBMs1T4QOBcTWa2IzhMk2nW5Kyn9tXUtpv9RsG2msxk+ZsQzRQacJncpgke0+T8y5Fzj8BiGo7XlJjaTIlpQs7KFjpqGnKuoyEPeIKnFMkZHvopgh81ySxNFWvJWcKRs70j2FOT012IllEEO1n4pD1513Yg2ssQPOThOkvyrqHUdEXOSEsihmBbTbKX1kLBPWqWkLOqJbjB3GBIZmoa8qWl4CG/iZ7oiA72ZL7TJNeZUY7kFQftDcHHluBzRbCegzMtrRjVQpX2lgoPKKLJAkcbMl01XK2p7yhL8pCBbQ3BN2avJgKvttcrWDK3CiUOVxQ8ZP+pqXKyIxnmBymCg5vJjNfkPK4+c8cIfK8ocVt7kmfd/I5SR1hKvCzUtb+lhgc00ZaO6CyhIQP1Uv4yIZjload72PXX0OIJvnFU+0Zf6MhsJwTfW0r0UwQfW4LNLZl5HK261JCZ4qnBaAreVAS3WrjV0LBnNDUNNDToCEeFfwgcb4gOEqLRhirWkexrCEYKVV711DLYEE1XBEsp5tpTGjorkomKYF9FDXv7fR3BGwbettSxnyL53MBPjsxDZjMh+VUW9NRxq1DhVk+FSxQcaGjV9Pawv6eGByw5qzoy7xk4RsOShqjJwWKe/1pEEfzkobeD/dQJmpqedcyBTy2sr4nGNRH0c0SPWTLrqAc0OQcb/gemKgqucQT7ySWKCn2EUotoCvpZct7RO2sy/QW0IWcXd7pQRQyZVwT2USRO87uhjioTLKV2brpMUcMQRbKH/N2T+UlTpaMls6cmc6CCNy3JdYYSUzzJQ4oSD3oKLncULOiJvjBEC2oqnCJkJluCYy2ZQ5so9YYlZ1VLlQU1mXEW1jZERwj/MUSRc24TdexlqLKfQBtDTScJUV8FszXBEY5ktpD5Ur9hYB4Nb1iikw3JoYpkKX+RodRKFt53MMuRnKSpY31PwYaGaILh3wxJGz9TkTPEETxoCWZrgvOlmyMzxFEwVJE5xZKzvyJ4WxEc16Gd4Xe3Weq4XH2jKRikqOkGQ87hQnC7wBmGYLAnesX3M+S87eFATauuN+Qcrh7xIxXJbUIdMw3JGE3ylCWzrieaqCn4zhGM19TQ3z1oH1AX+pWEqIc7wNGAkULBo/ZxRaV9NNyh4Br3rCHZzbzmSfawBL0dNRwpW1kK9mxPXR9povcdrGSZK9c2k0xwFGzjuniCtRSZCZ6ccZ7gaktmgAOtKbG/JnOkJrjcQTdFMsxRQ2cLY3WTIrlCw1eWKn8R6pvt4GFDso3QoL4a3nLk3G6JrtME3dSenpx7PNFTmga0EaJTLQ061sEeQoWXhSo9LTXsaSjoJQRXeZLtDclbCrYzfzHHeaKjHCVOUkQHO3JeEepr56mhiyaYYKjjNU+Fed1wS5VlhWSqI/hYUdDOkaxiKehoyOnrCV5yBHtbWFqTHCCwtpDcYolesVR5yUzTZBb3RNMd0d6WP+SvhuBmRcGxnuQzT95IC285cr41cLGQ6aJJhmi4TMGempxeimBRQw1tFKV+8jd6KuzoSTqqDxzRtpZkurvKEHxlqXKRIjjfUNNXQsNOsRScoWFLT+YeRZVD3GRN0MdQcKqQjHDMrdGGVu3iYJpQx3WGUvfbmxwFfR20WBq0oYY7LMFhhgYtr8jpaEnaOzjawWWaTP8mMr0t/EPDPoqcnxTBI5o58L7uoWnMrpoqPwgVrlAUWE+V+TQl9rawoyP6QGAlQw2TPRX+YSkxyBC8Z6jhHkXBgQL7WII3DVFnRfCrBfxewv9D6xsyjys4VkhWb9pUU627JllV0YDNHMku/ldNMMXDEo4aFnAkk4U6frNEU4XgZUPmEKHUl44KrzmYamjAbh0JFvGnaTLPu1s9jPCwjFpYiN7z1DTOk/nc07CfDFzmCf7i+bfNHXhDtLeBXzTBT5rkMvWOIxpl4EMh2LGJBu2syDnAEx2naEhHDWMMzPZEhygyS1mS5RTJr5ZkoKbEUoYqr2kqdDUE8ztK7OaIntJkFrIECwv8LJTaVx5XJE86go8dFeZ3FN3rjabCAYpoYEeC9zzJVULBbmZhDyd7ko09ydpNZ3nm2Kee4FPPXHnYEF1nqOFEC08LUVcDvYXkJHW8gTaKCk9YGOeIJhqiE4ToPEepdp7IWFjdwnWaufGMwJJCMtUTTBBK9BGCOy2tGGrJTHIwyEOzp6aPzNMOtlZkDvcEWpP5SVNhfkvDxhmSazTJXYrM9U1E0xwFVwqZQwzJxw6+kGGGUj2FglGGmnb1/G51udRSMNlTw6GGnCcUwVcOpmsqTHa06o72sw1RL02p9z0VbnMLOaIX3QKaYKSCFQzBKEUNHTSc48k53RH9wxGMtpQa5KjjW0W0n6XCCCG4yxNNdhQ4R4l1Ff+2sSd6UFHiIEOyqqFgT01mEUMD+joy75jPhOA+oVVLm309FR4yVOlp4RhLiScNmSmaYF5Pw0STrOIoWMSR2UkRXOMp+M4SHW8o8Zoi6OZgjKOaFar8zZDzkWzvKOjkKBjmCXby8JahhjXULY4KlzgKLvAwxVGhvyd4zxB1d9T0piazmKLCVZY5sKiD0y2ZSYrkUEPUbIk+dlQ4SJHTR50k1DPaUWIdTZW9NJwnJMOECgd7ou/MnppMJ02O1VT4Wsh85MnZzcFTngpXGKo84qmwgKbCL/orR/SzJ2crA+t6Mp94KvxJUeIbT3CQu1uIdlQEOzlKfS3UMcrTiFmOuroocrZrT2AcmamOKg8YomeEKm/rlT2sociMaybaUlFhuqHCM2qIJ+rg4EcDFymiDSxzaHdPcpE62pD5kyM5SBMoA1PaUtfIthS85ig1VPiPPYXgYEMNk4Qq7TXBgo7oT57gPUdwgCHzhIVFPFU6OYJzHAX9m5oNrVjeE61miDrqQ4VSa1oiURTsKHC0IfjNwU2WzK6eqK8jWln4g15TVBnqmDteCJ501PGAocJhhqjZdtBEB6lnhLreFJKxmlKbeGrqLiSThVIbCdGzloasa6lpMQXHCME2boLpJgT7yWaemu6wBONbqGNVRS0PKIL7LckbjmQtR7K8I5qtqel+T/ChJTNIKLjdUMNIRyvOEko9YYl2cwQveBikCNawJKcLBbc7+JM92mysNvd/Fqp8a0k6CNEe7cnZrxlW0wQXaXjaktnRwNOGZKYiONwS7a1JVheq3WgJHlQUGKHKmp4KAxXR/ULURcNgoa4zhKSLpZR3kxRRb0NmD0OFn+UCS7CzI1nbP6+o4x47QZE5xRCt3ZagnYcvmpYQktXdk5YKXTzBC57kKEe0VVuiSYqapssMS3C9p2CKkHOg8B8Pa8p5atrIw3qezIWanMGa5HRDNF6RM9wcacl0N+Q8Z8hsIkSnaIIdHRUOEebAPy1zbCkhM062FCJtif7PU+UtoVXzWKqM1PxXO8cfdruhFQ/a6x3JKYagvVDhQEtNiyiiSQ7OsuRsZUku0CRNDs4Sog6KKjsZgk2bYJqijgsEenoKeniinRXBn/U3lgpPdyDZynQx8IiioMnCep5Ky8mjGs6Wty0l1hUQTcNWswS3WRp2kCNZwJG8omG8JphPUaFbC8lEfabwP7VtM9yoaNCAjpR41VNhrD9LkbN722v0CoZMByFzhaW+MyzRYEWFDQwN2M4/JiT76PuljT3VU/A36eaIThb+R9oZGOAJ9tewkgGvqOMNRWYjT/Cwu99Q8LqDE4TgbLWxJ1jaDDAERsFOFrobgjUsBScaguXU8kKm2RL19tRypSHnHNlHiIZqgufs4opgQdVdwxBNNFBR6kVFqb8ogimOzB6a6HTzrlDHEpYaxjiiA4TMQobkDg2vejjfwJGWmnbVFAw3H3hq2NyQfG7hz4aC+w3BbwbesG0swYayvpAs6++Ri1Vfzx93mFChvyN5xVHTS+0p9aqCAxyZ6ZacZyw5+7uuQkFPR9DDk9NOiE7X1PCYJVjVUqq7JlrHwWALF5nfHNGjApdpqgzx5OwilDhCiDYTgnc9waGW4BdLNNUQvOtpzDOWHDH8D7TR/A/85KljEQu3NREc4Pl/6B1Hhc8Umb5CsKMmGC9EPcxoT2amwHNCmeOEnOPbklnMkbOgIvO5UMOpQrS9UGVdt6iH/fURjhI/WOpaW9OKLYRod6HCUEdOX000wpDZQ6hwg6LgZfOqo1RfT/CrJzjekXOGhpc1VW71ZLbXyyp+93ILbC1kPtIEYx0FIx1VDrLoVzXRKRYWk809yYlC9ImcrinxtabKnzRJk3lAU1OLEN1j2zrYzr2myHRXJFf4h4QKT1qSTzTB5+ZNTzTRkAxX8FcLV2uS8eoQQ2aAkFzvCM72sJIcJET3WPjRk5wi32uSS9rfZajpWEvj9hW42F4o5NytSXYy8IKHay10VYdrcl4SkqscrXpMwyGOgtkajheSxdQqmpxP1L3t4R5PqasFnrQEjytq6qgp9Y09Qx9o4S1FzhUCn1kyHSzBWLemoSGvOqLNhZyBjmCaAUYpMgt4Ck7wBBMMwWKWgjsUwTaGVsxWC1mYoKiyqqeGKYqonSIRQ3KIkHO0pmAxTdBHkbOvfllfr+AA+7gnc50huVKYK393FOyg7rbPO/izI7hE4CnHHHnJ0ogNPRUGeUpsrZZTBJcrovUcJe51BPsr6GkJdhCCsZ6aTtMEb2pqWkqeVtDXE/QVggsU/Nl86d9RMF3DxvZTA58agu810RWawCiSzzXBeU3MMW9oyJUedvNEvQyNu1f10BSMddR1vaLCYpYa/mGocLSiYDcLbQz8aMn5iyF4xBNMs1P0QEOV7o5gaWGuzSeLue4tt3ro7y4Tgm4G/mopdZgl6q0o6KzJWE3mMksNr3r+a6CbT8g5wZNzT9O7fi/zpaOmnz3BRoqos+tv9zMbdpxsqDBOEewtJLt7cg5wtKKbvldpSzRRCD43VFheCI7yZLppggMVBS/KMAdHODJvOwq2NQSbKKKPLdFWQs7Fqo+mpl01JXYRgq8dnGLhTiFzqmWsUMdpllZdbKlyvSdYxhI9YghOtxR8LgSLWHK62mGGVoxzBE8LNWzqH9CUesQzFy5RQzTc56mhi6fgXEWwpKfE5Z7M05ZgZUPmo6auiv8YKzDYwWBLMErIbKHJvOwIrvEdhOBcQ9JdU1NHQ7CXn2XIDFBKU2WAgcX9UAUzDXWd5alwuyJ41Z9rjKLCL4aCp4WarhPm2rH+SaHUYE001JDZ2ZAzXPjdMpZWvC9wmqIB2lLhQ01D5jO06hghWMndbM7yRJMsoCj1vYbnFQVrW9jak3OlEJ3s/96+p33dEPRV5GxiqaGjIthUU6FFEZyqCa5qJrpBdzSw95IUnOPIrCUUjRZQFrbw5PR0R1qiYx3cb6nrWUMrBmmiBQxVHtTew5ICP/ip6g4hed/Akob/32wvBHsIOX83cI8hGeNeNPCIkPmXe8fPKx84OMSRM1MTdXSwjCZ4S30jVGhvqTRak/OVhgGazHuOCud5onEO1lJr6ecVyaOK6H7zqlBlIaHE0oroCgfvGJIdPcmfLNGLjpz7hZwZQpUbFME0A1cIJa7VNORkgfsMBatbKgwwJM9bSvQXeNOvbIjelg6WWvo5kvbKaJJNHexkKNHL9xRyFlH8Ti2riB5wVPhUk7nGkJnoCe428LR/wRGdYIlmWebCyxou1rCk4g/ShugBDX0V0ZQWkh0dOVsagkM0yV6OoLd5ye+pRlsCr0n+KiQrGuq5yJDzrTAXHtLUMduTDBVKrSm3eHL+6ijxhFDX9Z5gVU/wliHYTMiMFpKLNMEywu80wd3meoFmt6VbRMPenhrOc6DVe4pgXU8DnnHakLOIIrlF4FZPIw6R+zxBP0dyq6OOZ4Q5sLKCcz084ok+VsMMyQhNZmmBgX5xIXOEJTmi7VsGTvMTNdHHhpzdbE8Du2oKxgvBqQKdDDnTFOylCFaxR1syz2iqrOI/FEpNc3C6f11/7+ASS6l2inq2ciTrCCzgyemrCL5SVPjQkdPZUmGy2c9Sw9FtR1sS30RmsKPCS4rkIC/2U0MduwucYolGaPjKEyhzmiPYXagyWbYz8LWBDdzRimAXzxx4z8K9hpzlhLq+NiQ97HuKorMUfK/OVvC2JfiHUPCQI/q7J2gjK+tTDNxkCc4TMssqCs4TGtLVwQihyoAWgj9bosU80XGW6Ac9TJGziaUh5+hnFcHOnlaM1iRn29NaqGENTTTSUHCH2tWTeV0osUhH6psuVLjRUmGWhm6OZEshGeNowABHcJ2Bpy2ZszRcKkRXd2QuKVEeXnbfaEq825FguqfgfE2whlChSRMdron+LATTPQ2Z369t4B9C5gs/ylzv+CMmepIDPclFQl13W0rspPd1JOcbghGOEutqCv5qacURQl3dDKyvyJlqKXGPgcM9FfawJAMVmdcspcYKOZc4GjDYkFlK05olNMHyHn4zFNykyOxt99RkHlfwmiHo60l2EKI+mhreEKp080Tbug08BVPcgoqC5zWt+NLDTZ7oNSF51N1qie7Va3uCCwyZbkINf/NED6jzOsBdZjFN8oqG3wxVunqCSYYKf3EdhJyf9YWGf7tRU2oH3VHgPr1fe5J9hOgHd7xQ0y7qBwXr23aGErP0cm64JVjZwsOGqL+mhNgZmhJLW2oY4UhedsyBgzrCKrq7BmcpNVhR6jBPq64Vgi+kn6XE68pp8J5/+0wRHGOpsKenQn9DZntPzjRLZpDAdD2fnSgkG9tmIXnUwQ6WVighs7Yi2MxQ0N3CqYaCXkJ0oyOztMDJjmSSpcpvlrk0RMMOjmArQ04PRV1DO1FwhCVaUVPpKUM03JK5SxPsIWRu8/CGHi8UHChiqGFDTbSRJWeYUDDcH6vJWUxR4k1FXbMUwV6e4AJFXS8oMqsZKqzvYQ9DDQdZckY4aGsIhtlubbd2r3j4QBMoTamdPZk7O/Bf62lacZwneNjQoGcdVU7zJOd7ghsUHOkosagic6cnWc8+4gg285R6zZP5s1/LUbCKIznTwK36PkdwlOrl4U1LwfdCCa+IrvFkmgw1PCAUXKWo0sURXWcI2muKJlgyFzhynCY4RBOsqCjoI1R5zREco0n2Vt09BQtYSizgKNHfUmUrQ5UOCh51BFcLmY7umhYqXKQomOop8bUnWNNQcIiBcYaC6xzMNOS8JQQfeqKBmmglB+97ok/lfk3ygaHSyZaCRTzRxQo6GzLfa2jWBPepw+UmT7SQEJyiyRkhBLMVOfcoMjcK0eZChfUNzFAUzCsEN5vP/X1uP/n/aoMX+K+nw/Hjr/9xOo7j7Pju61tLcgvJpTWXNbfN5jLpi6VfCOviTktKlFusQixdEKWmEBUKNaIpjZRSSOXSgzaaKLdabrm1/9nZ+/f+vd/vz/v9+Xy+zZ7PRorYoZqyLrCwQdEAixxVOEXNNnjX2nUSRlkqGmWowk8lxR50JPy9Bo6qJXaXwNvREBvnThPEPrewryLhcAnj5WE15Fqi8W7R1sAuEu86S4ENikItFN4xkv9Af4nXSnUVcLiA9xzesFpivRRVeFKtsMRaKBhuSbjOELnAUtlSQUpXgdfB4Z1oSbnFEetbQ0IrAe+Y+pqnDcEJFj6S8LDZzZHwY4e3XONNlARraomNEt2bkvGsosA3ioyHm+6jCMbI59wqt4eeara28IzEmyPgoRaUOEDhTVdEJhmCoTWfC0p8aNkCp0oYqih2iqGi4yXeMkOsn4LdLLnmKfh/YogjNsPebeFGR4m9BJHLzB61XQ3BtpISfS2FugsK9FAtLWX1dCRcrCnUp44CNzuCowUZmxSRgYaE6Za0W2u/E7CVXCiI/UOR8aAm1+OSyE3mOUcwyc1zBBeoX1kiKy0Zfxck1Gsyulti11i83QTBF5Kg3pDQThFMVHiPSlK+0cSedng/VaS8bOZbtsBcTcZAR8JP5KeqQ1OYKAi20njdNNRpgnsU//K+JnaXJaGTomr7aYIphoRn9aeShJWKEq9LcozSF7QleEfDI5LYm5bgVkFkRwVDBCVu0DDIkGupo8TZBq+/pMQURYErJQmPKGKjNDkWOLx7Jd5QizdUweIaKrlP7SwJDhZvONjLkOsBBX9UpGxnydhXkfBLQ8IxgojQbLFnJf81JytSljclYYyEFyx0kVBvKWOFJmONpshGAcsduQY5giVNCV51eOdJYo/pLhbvM0uDHSevNKRcrKZIqnCtJeEsO95RoqcgGK4ocZcho1tTYtcZvH41pNQ7vA0WrhIfOSraIIntIAi+NXWCErdbkvrWwjRLrt0NKUdL6KSOscTOdMSOUtBHwL6OLA0vNSdynaWQEnCpIvKaIrJJEbvHkmuNhn6OjM8VkSGSqn1uYJCGHnq9I3aLhNME3t6GjIkO7xrNFumpyTNX/NrwX7CrIRiqqWijI9JO4d1iieykyfiposQIQ8YjjsjlBh6oHWbwRjgYJQn2NgSnNycmJAk3NiXhx44Sxykihxm8ybUwT1OVKySc7vi3OXVkdBJ4AyXBeksDXG0IhgtYY0lY5ahCD0ehborIk5aUWRJviMA7Xt5kyRjonrXENkm8yYqgs8VzgrJmClK20uMM3jRJ0FiQICQF9hdETlLQWRIb5ki6WDfWRPobvO6a4GP5mcOrNzDFELtTkONLh9dXE8xypEg7z8A9jkhrQ6Fhjlg/QVktJXxt4WXzT/03Q8IaQWSqIuEvloQ2mqC9Jfi7wRul4RX3pSPlzpoVlmCtI2jvKHCFhjcM3sN6lqF6HxnKelLjXWbwrpR4xzuCrTUZx2qq9oAh8p6ixCUGr78g8oyjRAtB5CZFwi80VerVpI0h+IeBxa6Zg6kWvpDHaioYYuEsRbDC3eOmC2JvGYLeioxGknL2UATNJN6hmtj1DlpLvDVmocYbrGCVJKOrg4X6DgddLA203BKMFngdJJFtFd7vJLm6KEpc5yjQrkk7M80SGe34X24nSex1Ra5Omgb71JKyg8SrU3i/kARKwWpH0kOGhKkObyfd0ZGjvyXlAkVZ4xRbYJ2irFMkFY1SwyWxr2oo4zlNiV+7zmaweFpT4kR3kaDAFW6xpSqzJay05FtYR4HmZhc9UxKbbfF2V8RG1MBmSaE+kmC6JnaRXK9gsiXhJHl/U0qM0WTcbyhwkYIvFGwjSbjfwhiJt8ZSQU+Bd5+marPMOkVkD0muxYLIfEuhh60x/J92itguihJSEMySVPQnTewnEm+620rTQEMsOfo4/kP/0ARvWjitlpSX7GxBgcMEsd3EEeYWvdytd+Saawi6aCIj1CkGb6Aj9rwhx16Cf3vAwFy5pyLhVonXzy51FDpdEblbkdJbUcEPDEFzQ8qNmhzzLTmmKWKbFCXeEuRabp6rxbvAtLF442QjQ+wEA9eL1xSR7Q0JXzlSHjJ4exq89yR0laScJ/FW6z4a73pFMEfDiRZvuvijIt86RaSFOl01riV2mD1UEvxGk/Geg5aWwGki1zgKPG9J2U8PEg8qYvMsZeytiTRXBMslCU8JSlxi8EabjwUldlDNLfzTUmCgxWsjqWCOHavYAqsknKFIO0yQ61VL5AVFxk6WhEaCAkdJgt9aSkzXlKNX2jEa79waYuc7gq0N3GDJGCBhoiTXUEPsdknCUE1CK0fwsiaylSF2uiDyO4XX3pFhNd7R4itFGc0k/ElBZwWvq+GC6szVeEoS/MZ+qylwpKNKv9Z469UOjqCjwlusicyTxG6VpNxcQ8IncoR4RhLbR+NdpGGmJWOcIzJGUuKPGpQg8rrG21dOMqQssJQ4RxH5jaUqnZuQ0F4Q+cjxLwPtpZbIAk3QTJHQWBE5S1BokoVtDd6lhqr9UpHSUxMcIYl9pojsb8h4SBOsMQcqvOWC2E8EVehqiJ1hrrAEbQxeK0NGZ0Gkq+guSRgniM23bIHVkqwx4hiHd7smaOyglyIyQuM978j4VS08J/A2G1KeMBRo4fBaSNhKUEZfQewVQ/C1I+MgfbEleEzCUw7mKXI0M3hd1EESVji8x5uQ41nxs1q4RMJCCXs7Iq9acpxn22oSDnQ/sJTxsCbHIYZiLyhY05TY0ZLIOQrGaSJDDN4t8pVaIrsqqFdEegtizc1iTew5Q4ayBDMUsQMkXocaYkc0hZua412siZ1rSXlR460zRJ5SlHGe5j801RLMlJTxtaOM3Q1pvxJ45zUlWFD7rsAbpfEm1JHxG0eh8w2R7QQVzBUw28FhFp5QZzq8t2rx2joqulYTWSuJdTYfWwqMFMcovFmSyJPNyLhE4E10pHzYjOC3huArRa571ZsGajQpQx38SBP5pyZB6lMU3khDnp0MBV51BE9o2E+TY5Ml2E8S7C0o6w1xvCZjf0HkVEHCzFoyNmqC+9wdcqN+Tp7jSDheE9ws8Y5V0NJCn2bk2tqSY4okdrEhx1iDN8cSudwepWmAGXKcJXK65H9to8jYQRH7SBF01ESUJdd0TayVInaWhLkOjlXE5irKGOnI6GSWGCJa482zBI9rCr0jyTVcEuzriC1vcr6mwFGSiqy5zMwxBH/TJHwjSPhL8+01kaaSUuMFKTcLEvaUePcrSmwn8DZrgikWb7CGPxkSjhQwrRk57tctmxLsb9sZvL9LSlyuSLlWkqOjwduo8b6Uv1DkmudIeFF2dHCgxVtk8dpIvHpBxhEOdhKk7OLIUSdJ+cSRY57B+0DgGUUlNfpthTfGkauzxrvTsUUaCVhlKeteTXCoJDCa2NOKhOmC4G1H8JBd4OBZReSRGkqcb/CO1PyLJTLB4j1q8JYaIutEjSLX8YKM+a6phdMsdLFUoV5RTm9JSkuDN8WcIon0NZMNZWh1q8C7SJEwV5HxrmnnTrf3KoJBlmCYI2ilSLlfEvlE4011NNgjgthzEua0oKK7JLE7HZHlEl60BLMVFewg4EWNt0ThrVNEVkkiTwpKXSWJzdRENgvKGq4IhjsiezgSFtsfCUq8qki5S1LRQeYQQ4nemmCkImWMw3tFUoUBZk4NOeZYEp4XRKTGa6wJjrWNHBVJR4m3FCnbuD6aak2WsMTh3SZImGCIPKNgsDpVwnsa70K31lCFJZYcwwSMFcQulGTsZuEaSdBXkPGZhu0FsdUO73RHjq8MPGGIfaGIbVTk6iuI3GFgucHrIQkmWSJdBd7BBu+uOryWAhY7+Lki9rK5wtEQzWwvtbqGhIMFwWRJsElsY4m9IIg9L6lCX0VklaPAYkfkZEGDnOWowlBJjtMUkcGK4Lg6EtoZInMUBVYLgn0UsdmCyCz7gIGHFfk+k1QwTh5We7A9x+IdJ6CvIkEagms0hR50eH9UnTQJ+2oiKyVlLFUE+8gBGu8MQ3CppUHesnjTHN4QB/UGPhCTHLFPHMFrCqa73gqObUJGa03wgbhHkrCfpEpzNLE7JDS25FMKhlhKKWKfCgqstLCPu1zBXy0J2ztwjtixBu8UTRn9LVtkmCN2iyFhtME70JHRQ1KVZXqKI/KNIKYMCYs1GUMEKbM1bKOI9LDXC7zbHS+bt+1MTWS9odA9DtrYtpbImQJ2VHh/lisEwaHqUk1kjKTAKknkBEXkbkdMGwq0dnhzLJF3NJH3JVwrqOB4Sca2hti75nmJN0WzxS6UxDYoEpxpa4htVlRjkYE7DZGzJVU72uC9IyhQL4i8YfGWSYLLNcHXloyz7QhNifmKSE9JgfGmuyLhc403Xm9vqcp6gXe3xuuv8F6VJNxkyTHEkHG2g0aKXL0MsXc1bGfgas2//dCONXiNLCX+5mB7eZIl1kHh7ajwpikyzlUUWOVOsjSQlsS+M0R+pPje/dzBXRZGO0rMtgQrLLG9VSu9n6CMXS3BhwYmSoIBhsjNBmZbgusE9BCPCP5triU4VhNbJfE+swSP27aayE8tuTpYYjtrYjMVGZdp2NpS1s6aBnKSHDsbKuplKbHM4a0wMFd/5/DmGyKrJSUaW4IBrqUhx0vyfzTBBLPIUcnZdrAkNsKR0sWRspumSns6Ch0v/qqIbBYUWKvPU/CFoyrDJGwSNFhbA/MlzKqjrO80hRbpKx0Jewsi/STftwGSlKc1JZyAzx05dhLEdnfQvhZOqiHWWEAHC7+30FuRcZUgaO5gpaIK+xsiHRUsqaPElTV40xQZQ107Q9BZE1nryDVGU9ZSQ47bmhBpLcYpUt7S+xuK/FiT8qKjwXYw5ypS2iuCv7q1gtgjhuBuB8LCFY5cUuCNtsQOFcT+4Ih9JX+k8Ea6v0iCIRZOtCT0Et00JW5UeC85Cg0ScK0k411HcG1zKtre3SeITBRk7WfwDhEvaYLTHP9le0m8By0JDwn4TlLW/aJOvGHxdjYUes+ScZigCkYQdNdEOhkiezgShqkx8ueKjI8lDfK2oNiOFvrZH1hS+tk7NV7nOmLHicGWEgubkXKdwdtZknCLJXaCpkrjZBtLZFsDP9CdxWsSr05Sxl6CMmoFbCOgryX40uDtamB7SVmXW4Ihlgpmq+00tBKUUa83WbjLUNkzDmY7cow1JDygyPGlhgGKYKz4vcV7QBNbJIgM11TUqZaMdwTeSguH6rOaw1JRKzaaGyxVm2EJ/uCIrVWUcZUkcp2grMsEjK+DMwS59jQk3Kd6SEq1d0S6uVmO4Bc1lDXTUcHjluCXEq+1OlBDj1pi9zgiXxnKuE0SqTXwhqbETW6RggMEnGl/q49UT2iCzgJvRwVXS2K/d6+ZkyUl7jawSVLit46EwxVljDZwoSQ20sDBihztHfk2yA8NVZghiXwrYHQdfKAOtzsayjhY9bY0yE2CWEeJ9xfzO423xhL5syS2TFJofO2pboHob0nY4GiAgRrvGQEDa/FWSsoaaYl0syRsEt3kWoH3B01shCXhTUWe9w3Bt44SC9QCh3eShQctwbaK2ApLroGCMlZrYqvlY3qYhM0aXpFkPOuoqJ3Dm6fxXrGwVF9gCWZagjPqznfkuMKQ8DPTQRO8ZqG1hPGKEm9IgpGW4DZDgTNriTxvFiq+Lz+0cKfp4wj6OCK9JSnzNSn9LFU7UhKZZMnYwcJ8s8yRsECScK4j5UOB95HFO0CzhY4xJxuCix0lDlEUeMdS6EZBkTsUkZ4K74dugyTXS7aNgL8aqjDfkCE0ZbwkCXpaWCKhl8P7VD5jxykivSyxyZrYERbe168LYu9ZYh86IkscgVLE7tWPKmJv11CgoyJltMEbrohtVAQfO4ImltiHEroYEs7RxAarVpY8AwXMcMReFOTYWe5iiLRQxJ5Q8DtJ8LQhWOhIeFESPGsILhbNDRljNbHzNRlTFbk2S3L0NOS6V1KFJYKUbSTcIIhM0wQ/s2TM0SRMNcQmSap3jCH4yhJZKSkwyRHpYYgsFeQ4U7xoCB7VVOExhXepo9ABBsYbvGWKXPME3lyH95YioZ0gssQRWWbI+FaSMkXijZXwgiTlYdPdkNLaETxlyDVIwqeaEus0aTcYcg0RVOkpR3CSJqIddK+90JCxzsDVloyrFd5ZAr4TBKfaWa6boEA7C7s6EpYaeFPjveooY72mjIccLHJ9HUwVlDhKkmutJDJBwnp1rvulJZggKDRfbXAkvC/4l3ozQOG9a8lxjx0i7nV4jSXc7vhe3OwIxjgSHjdEhhsif9YkPGlus3iLFDnWOFhtCZbJg0UbQcIaR67JjthoCyMEZRwhiXWyxO5QxI6w5NhT4U1WsJvDO60J34fW9hwzwlKij6ZAW9ne4L0s8C6XeBMEkd/LQy1VucBRot6QMlbivaBhoBgjqGiCJNhsqVp/S2SsG6DIONCR0dXhvWbJ+MRRZJkkuEjgDXJjFQW6SSL7GXK8Z2CZg7cVsbWGoKmEpzQ5elpiy8Ryg7dMkLLUEauzeO86CuwlSOlgYLojZWeJ9xM3S1PWfEfKl5ISLQ0MEKR8YOB2QfCxJBjrKPCN4f9MkaSsqoVXJBmP7EpFZ9UQfOoOFwSzBN4MQ8LsGrymlipcJQhmy0GaQjPqCHaXRwuCZwRbqK2Fg9wlClZqYicrIgMdZfxTQ0c7TBIbrChxmuzoKG8XRaSrIhhiyNFJkrC7oIAWMEOQa5aBekPCRknCo4IKPrYkvCDI8aYmY7WFtprgekcJZ3oLIqssCSMtFbQTJKwXYy3BY5oCh2iKPCpJOE+zRdpYgi6O2KmOAgvVCYaU4ySRek1sgyFhJ403QFHiVEmJHwtybO1gs8Hr5+BETQX3War0qZngYGgtVZtoqd6vFSk/UwdZElYqyjrF4HXUeFspIi9IGKf4j92pKGAdCYMVsbcV3kRF0N+R8LUd5PCsIGWoxDtBkCI0nKofdJQxT+LtZflvuc8Q3CjwWkq8KwUpHzkK/NmSsclCL0nseQdj5FRH5CNHSgtLiW80Of5HU9Hhlsga9bnBq3fEVltKfO5IaSTmGjjc4J0otcP7QsJUSQM8pEj5/wCuUuC2DWz8AAAAAElFTkSuQmCC"); +} + +.ace-ambiance .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQUFD4z6Crq/sfAAuYAuYl+7lfAAAAAElFTkSuQmCC") right repeat-y; +} \ No newline at end of file diff --git a/lib/ace/theme/ambiance.js b/lib/ace/theme/ambiance.js new file mode 100644 index 00000000..475c2e87 --- /dev/null +++ b/lib/ace/theme/ambiance.js @@ -0,0 +1,33 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright 2011 Irakli Gozalishvili. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = true; +exports.cssClass = "ace-ambiance"; +exports.cssText = require("../requirejs/text!./ambiance.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); + +}); diff --git a/lib/ace/theme/chaos.css b/lib/ace/theme/chaos.css new file mode 100644 index 00000000..f57e59b3 --- /dev/null +++ b/lib/ace/theme/chaos.css @@ -0,0 +1,154 @@ +.ace-chaos .ace_gutter { + background: #141414; + color: #595959; + border-right: 1px solid #282828; +} +.ace-chaos .ace_gutter-cell.ace_warning { + background-image: none; + background: #FC0; + border-left: none; + padding-left: 0; + color: #000; +} +.ace-chaos .ace_gutter-cell.ace_error { + background-position: -6px center; + background-image: none; + background: #F10; + border-left: none; + padding-left: 0; + color: #000; +} +.ace-chaos .ace_print-margin { + border-left: 1px solid #555; + right: 0; + background: #1D1D1D; +} +.ace-chaos { + background-color: #161616; + color: #E6E1DC; +} + +.ace-chaos .ace_cursor { + border-left: 2px solid #FFFFFF; +} +.ace-chaos .ace_cursor.ace_overwrite { + border-left: 0px; + border-bottom: 1px solid #FFFFFF; +} +.ace-chaos .ace_marker-layer .ace_selection { + background: #494836; +} +.ace-chaos .ace_marker-layer .ace_step { + background: rgb(198, 219, 174); +} +.ace-chaos .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #FCE94F; +} +.ace-chaos .ace_marker-layer .ace_active-line { + background: #333; +} +.ace-chaos .ace_gutter-active-line { + background-color: #222; +} +.ace-chaos .ace_invisible { + color: #404040; +} +.ace-chaos .ace_keyword { + color:#00698F; +} +.ace-chaos .ace_keyword.ace_operator { + color:#FF308F; +} +.ace-chaos .ace_constant { + color:#1EDAFB; +} +.ace-chaos .ace_constant.ace_language { + color:#FDC251; +} +.ace-chaos .ace_constant.ace_library { + color:#8DFF0A; +} +.ace-chaos .ace_constant.ace_numeric { + color:#58C554; +} +.ace-chaos .ace_invalid { + color:#FFFFFF; + background-color:#990000; +} +.ace-chaos .ace_invalid.ace_deprecated { + color:#FFFFFF; + background-color:#990000; +} +.ace-chaos .ace_support { + color: #999; +} +.ace-chaos .ace_support.ace_function { + color:#00AEEF; +} +.ace-chaos .ace_function { + color:#00AEEF; +} +.ace-chaos .ace_string { + color:#58C554; +} +.ace-chaos .ace_comment { + color:#555; + font-style:italic; + padding-bottom: 0px; +} +.ace-chaos .ace_variable { + color:#997744; +} +.ace-chaos .ace_meta.ace_tag { + color:#BE53E6; +} +.ace-chaos .ace_entity.ace_other.ace_attribute-name { + color:#FFFF89; +} +.ace-chaos .ace_markup.ace_underline { + text-decoration: underline; +} +.ace-chaos .ace_fold-widget { + text-align: center; +} + +.ace-chaos .ace_fold-widget:hover { + color: #777; +} + +.ace-chaos .ace_fold-widget.ace_start, +.ace-chaos .ace_fold-widget.ace_end, +.ace-chaos .ace_fold-widget.ace_closed{ + background: none; + border: none; + box-shadow: none; +} + +.ace-chaos .ace_fold-widget.ace_start:after { + content: '▾' +} + +.ace-chaos .ace_fold-widget.ace_end:after { + content: '▴' +} + +.ace-chaos .ace_fold-widget.ace_closed:after { + content: '‣' +} + +.ace-chaos .ace_indent-guide { + border-right:1px dotted #333; + margin-right:-1px; +} + +.ace-chaos .ace_fold { + background: #222; + border-radius: 3px; + color: #7AF; + border: none; +} +.ace-chaos .ace_fold:hover { + background: #CCC; + color: #000; +} diff --git a/lib/ace/theme/chaos.js b/lib/ace/theme/chaos.js new file mode 100644 index 00000000..9ee83720 --- /dev/null +++ b/lib/ace/theme/chaos.js @@ -0,0 +1,33 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright 2011 Irakli Gozalishvili. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = true; +exports.cssClass = "ace-chaos"; +exports.cssText = require("../requirejs/text!./chaos.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); + +}); \ No newline at end of file diff --git a/lib/ace/theme/chrome.css b/lib/ace/theme/chrome.css new file mode 100644 index 00000000..c91e802a --- /dev/null +++ b/lib/ace/theme/chrome.css @@ -0,0 +1,154 @@ +.ace-chrome .ace_gutter { + background: #ebebeb; + color: #333; + overflow : hidden; +} + +.ace-chrome .ace_print-margin { + width: 1px; + background: #e8e8e8; +} + +.ace-chrome { + background-color: #FFFFFF; + color: black; +} + +.ace-chrome .ace_cursor { + color: black; +} + +.ace-chrome .ace_invisible { + color: rgb(191, 191, 191); +} + +.ace-chrome .ace_constant.ace_buildin { + color: rgb(88, 72, 246); +} + +.ace-chrome .ace_constant.ace_language { + color: rgb(88, 92, 246); +} + +.ace-chrome .ace_constant.ace_library { + color: rgb(6, 150, 14); +} + +.ace-chrome .ace_invalid { + background-color: rgb(153, 0, 0); + color: white; +} + +.ace-chrome .ace_fold { +} + +.ace-chrome .ace_support.ace_function { + color: rgb(60, 76, 114); +} + +.ace-chrome .ace_support.ace_constant { + color: rgb(6, 150, 14); +} + +.ace-chrome .ace_support.ace_type, +.ace-chrome .ace_support.ace_class +.ace-chrome .ace_support.ace_other { + color: rgb(109, 121, 222); +} + +.ace-chrome .ace_variable.ace_parameter { + font-style:italic; + color:#FD971F; +} +.ace-chrome .ace_keyword.ace_operator { + color: rgb(104, 118, 135); +} + +.ace-chrome .ace_comment { + color: #236e24; +} + +.ace-chrome .ace_comment.ace_doc { + color: #236e24; +} + +.ace-chrome .ace_comment.ace_doc.ace_tag { + color: #236e24; +} + +.ace-chrome .ace_constant.ace_numeric { + color: rgb(0, 0, 205); +} + +.ace-chrome .ace_variable { + color: rgb(49, 132, 149); +} + +.ace-chrome .ace_xml-pe { + color: rgb(104, 104, 91); +} + +.ace-chrome .ace_entity.ace_name.ace_function { + color: #0000A2; +} + + +.ace-chrome .ace_heading { + color: rgb(12, 7, 255); +} + +.ace-chrome .ace_list { + color:rgb(185, 6, 144); +} + +.ace-chrome .ace_marker-layer .ace_selection { + background: rgb(181, 213, 255); +} + +.ace-chrome .ace_marker-layer .ace_step { + background: rgb(252, 255, 0); +} + +.ace-chrome .ace_marker-layer .ace_stack { + background: rgb(164, 229, 101); +} + +.ace-chrome .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgb(192, 192, 192); +} + +.ace-chrome .ace_marker-layer .ace_active-line { + background: rgba(0, 0, 0, 0.07); +} + +.ace-chrome .ace_gutter-active-line { + background-color : #dcdcdc; +} + +.ace-chrome .ace_marker-layer .ace_selected-word { + background: rgb(250, 250, 255); + border: 1px solid rgb(200, 200, 250); +} + +.ace-chrome .ace_storage, +.ace-chrome .ace_keyword, +.ace-chrome .ace_meta.ace_tag { + color: rgb(147, 15, 128); +} + +.ace-chrome .ace_string.ace_regex { + color: rgb(255, 0, 0) +} + +.ace-chrome .ace_string { + color: #1A1AA6; +} + +.ace-chrome .ace_entity.ace_other.ace_attribute-name { + color: #994409; +} + +.ace-chrome .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; +} diff --git a/lib/ace/theme/chrome.js b/lib/ace/theme/chrome.js new file mode 100644 index 00000000..dafa99c2 --- /dev/null +++ b/lib/ace/theme/chrome.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = false; +exports.cssClass = "ace-chrome"; +exports.cssText = require("../requirejs/text!./chrome.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/clouds.css b/lib/ace/theme/clouds.css new file mode 100644 index 00000000..c11308d4 --- /dev/null +++ b/lib/ace/theme/clouds.css @@ -0,0 +1,111 @@ +.ace-clouds .ace_gutter { + background: #ebebeb; + color: #333 +} + +.ace-clouds .ace_print-margin { + width: 1px; + background: #e8e8e8 +} + +.ace-clouds { + background-color: #FFFFFF; + color: #000000 +} + +.ace-clouds .ace_cursor { + color: #000000 +} + +.ace-clouds .ace_marker-layer .ace_selection { + background: #BDD5FC +} + +.ace-clouds.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #FFFFFF; +} + +.ace-clouds .ace_marker-layer .ace_step { + background: rgb(255, 255, 0) +} + +.ace-clouds .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #BFBFBF +} + +.ace-clouds .ace_marker-layer .ace_active-line { + background: #FFFBD1 +} + +.ace-clouds .ace_gutter-active-line { + background-color : #dcdcdc +} + +.ace-clouds .ace_marker-layer .ace_selected-word { + border: 1px solid #BDD5FC +} + +.ace-clouds .ace_invisible { + color: #BFBFBF +} + +.ace-clouds .ace_keyword, +.ace-clouds .ace_meta, +.ace-clouds .ace_support.ace_constant.ace_property-value { + color: #AF956F +} + +.ace-clouds .ace_keyword.ace_operator { + color: #484848 +} + +.ace-clouds .ace_keyword.ace_other.ace_unit { + color: #96DC5F +} + +.ace-clouds .ace_constant.ace_language { + color: #39946A +} + +.ace-clouds .ace_constant.ace_numeric { + color: #46A609 +} + +.ace-clouds .ace_constant.ace_character.ace_entity { + color: #BF78CC +} + +.ace-clouds .ace_invalid { + background-color: #FF002A +} + +.ace-clouds .ace_fold { + background-color: #AF956F; + border-color: #000000 +} + +.ace-clouds .ace_storage, +.ace-clouds .ace_support.ace_class, +.ace-clouds .ace_support.ace_function, +.ace-clouds .ace_support.ace_other, +.ace-clouds .ace_support.ace_type { + color: #C52727 +} + +.ace-clouds .ace_string { + color: #5D90CD +} + +.ace-clouds .ace_comment { + color: #BCC8BA +} + +.ace-clouds .ace_entity.ace_name.ace_tag, +.ace-clouds .ace_entity.ace_other.ace_attribute-name { + color: #606060 +} + +.ace-clouds .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/clouds.js b/lib/ace/theme/clouds.js index 6046ebd4..aa36edcf 100644 --- a/lib/ace/theme/clouds.js +++ b/lib/ace/theme/clouds.js @@ -1,195 +1,39 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { - var dom = require("pilot/dom"); +exports.isDark = false; +exports.cssClass = "ace-clouds"; +exports.cssText = require("../requirejs/text!./clouds.css"); - var cssText = ".ace-clouds .ace_editor {\ - border: 2px solid rgb(159, 159, 159);\ -}\ -\ -.ace-clouds .ace_editor.ace_focus {\ - border: 2px solid #327fbd;\ -}\ -\ -.ace-clouds .ace_gutter {\ - width: 50px;\ - background: #e8e8e8;\ - color: #333;\ - overflow : hidden;\ -}\ -\ -.ace-clouds .ace_gutter-layer {\ - width: 100%;\ - text-align: right;\ -}\ -\ -.ace-clouds .ace_gutter-layer .ace_gutter-cell {\ - padding-right: 6px;\ -}\ -\ -.ace-clouds .ace_print_margin {\ - width: 1px;\ - background: #e8e8e8;\ -}\ -\ -.ace-clouds .ace_scroller {\ - background-color: #FFFFFF;\ -}\ -\ -.ace-clouds .ace_text-layer {\ - cursor: text;\ - color: #000000;\ -}\ -\ -.ace-clouds .ace_cursor {\ - border-left: 2px solid #000000;\ -}\ -\ -.ace-clouds .ace_cursor.ace_overwrite {\ - border-left: 0px;\ - border-bottom: 1px solid #000000;\ -}\ - \ -.ace-clouds .ace_marker-layer .ace_selection {\ - background: #BDD5FC;\ -}\ -\ -.ace-clouds .ace_marker-layer .ace_step {\ - background: rgb(198, 219, 174);\ -}\ -\ -.ace-clouds .ace_marker-layer .ace_bracket {\ - margin: -1px 0 0 -1px;\ - border: 1px solid #BFBFBF;\ -}\ -\ -.ace-clouds .ace_marker-layer .ace_active_line {\ - background: #FFFBD1;\ -}\ -\ - \ -.ace-clouds .ace_invisible {\ - color: #BFBFBF;\ -}\ -\ -.ace-clouds .ace_keyword {\ - color:#AF956F;\ -}\ -\ -.ace-clouds .ace_keyword.ace_operator {\ - color:#484848;\ -}\ -\ -.ace-clouds .ace_constant {\ - \ -}\ -\ -.ace-clouds .ace_constant.ace_language {\ - color:#39946A;\ -}\ -\ -.ace-clouds .ace_constant.ace_library {\ - \ -}\ -\ -.ace-clouds .ace_constant.ace_numeric {\ - color:#46A609;\ -}\ -\ -.ace-clouds .ace_invalid {\ - background-color:#FF002A;\ -}\ -\ -.ace-clouds .ace_invalid.ace_illegal {\ - \ -}\ -\ -.ace-clouds .ace_invalid.ace_deprecated {\ - \ -}\ -\ -.ace-clouds .ace_support {\ - \ -}\ -\ -.ace-clouds .ace_support.ace_function {\ - color:#C52727;\ -}\ -\ -.ace-clouds .ace_function.ace_buildin {\ - \ -}\ -\ -.ace-clouds .ace_string {\ - color:#5D90CD;\ -}\ -\ -.ace-clouds .ace_string.ace_regexp {\ - \ -}\ -\ -.ace-clouds .ace_comment {\ - color:#BCC8BA;\ -}\ -\ -.ace-clouds .ace_comment.ace_doc {\ - \ -}\ -\ -.ace-clouds .ace_comment.ace_doc.ace_tag {\ - \ -}\ -\ -.ace-clouds .ace_variable {\ - \ -}\ -\ -.ace-clouds .ace_variable.ace_language {\ - \ -}\ -\ -.ace-clouds .ace_xml_pe {\ - \ -}"; - - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "ace-clouds"; -}); \ No newline at end of file +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/clouds_midnight.css b/lib/ace/theme/clouds_midnight.css new file mode 100644 index 00000000..08ee089d --- /dev/null +++ b/lib/ace/theme/clouds_midnight.css @@ -0,0 +1,112 @@ +.ace-clouds-midnight .ace_gutter { + background: #232323; + color: #929292 +} + +.ace-clouds-midnight .ace_print-margin { + width: 1px; + background: #232323 +} + +.ace-clouds-midnight { + background-color: #191919; + color: #929292 +} + +.ace-clouds-midnight .ace_cursor { + color: #7DA5DC +} + +.ace-clouds-midnight .ace_marker-layer .ace_selection { + background: #000000 +} + +.ace-clouds-midnight.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #191919; +} + +.ace-clouds-midnight .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.ace-clouds-midnight .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #BFBFBF +} + +.ace-clouds-midnight .ace_marker-layer .ace_active-line { + background: rgba(215, 215, 215, 0.031) +} + +.ace-clouds-midnight .ace_gutter-active-line { + background-color: rgba(215, 215, 215, 0.031) +} + +.ace-clouds-midnight .ace_marker-layer .ace_selected-word { + border: 1px solid #000000 +} + +.ace-clouds-midnight .ace_invisible { + color: #666 +} + +.ace-clouds-midnight .ace_keyword, +.ace-clouds-midnight .ace_meta, +.ace-clouds-midnight .ace_support.ace_constant.ace_property-value { + color: #927C5D +} + +.ace-clouds-midnight .ace_keyword.ace_operator { + color: #4B4B4B +} + +.ace-clouds-midnight .ace_keyword.ace_other.ace_unit { + color: #366F1A +} + +.ace-clouds-midnight .ace_constant.ace_language { + color: #39946A +} + +.ace-clouds-midnight .ace_constant.ace_numeric { + color: #46A609 +} + +.ace-clouds-midnight .ace_constant.ace_character.ace_entity { + color: #A165AC +} + +.ace-clouds-midnight .ace_invalid { + color: #FFFFFF; + background-color: #E92E2E +} + +.ace-clouds-midnight .ace_fold { + background-color: #927C5D; + border-color: #929292 +} + +.ace-clouds-midnight .ace_storage, +.ace-clouds-midnight .ace_support.ace_class, +.ace-clouds-midnight .ace_support.ace_function, +.ace-clouds-midnight .ace_support.ace_other, +.ace-clouds-midnight .ace_support.ace_type { + color: #E92E2E +} + +.ace-clouds-midnight .ace_string { + color: #5D90CD +} + +.ace-clouds-midnight .ace_comment { + color: #3C403B +} + +.ace-clouds-midnight .ace_entity.ace_name.ace_tag, +.ace-clouds-midnight .ace_entity.ace_other.ace_attribute-name { + color: #606060 +} + +.ace-clouds-midnight .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/clouds_midnight.js b/lib/ace/theme/clouds_midnight.js index 51fbbe41..e704d57c 100644 --- a/lib/ace/theme/clouds_midnight.js +++ b/lib/ace/theme/clouds_midnight.js @@ -1,196 +1,39 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { - var dom = require("pilot/dom"); +exports.isDark = true; +exports.cssClass = "ace-clouds-midnight"; +exports.cssText = require("../requirejs/text!./clouds_midnight.css"); - var cssText = ".ace-clouds-midnight .ace_editor {\ - border: 2px solid rgb(159, 159, 159);\ -}\ -\ -.ace-clouds-midnight .ace_editor.ace_focus {\ - border: 2px solid #327fbd;\ -}\ -\ -.ace-clouds-midnight .ace_gutter {\ - width: 50px;\ - background: #e8e8e8;\ - color: #333;\ - overflow : hidden;\ -}\ -\ -.ace-clouds-midnight .ace_gutter-layer {\ - width: 100%;\ - text-align: right;\ -}\ -\ -.ace-clouds-midnight .ace_gutter-layer .ace_gutter-cell {\ - padding-right: 6px;\ -}\ -\ -.ace-clouds-midnight .ace_print_margin {\ - width: 1px;\ - background: #e8e8e8;\ -}\ -\ -.ace-clouds-midnight .ace_scroller {\ - background-color: #191919;\ -}\ -\ -.ace-clouds-midnight .ace_text-layer {\ - cursor: text;\ - color: #929292;\ -}\ -\ -.ace-clouds-midnight .ace_cursor {\ - border-left: 2px solid #7DA5DC;\ -}\ -\ -.ace-clouds-midnight .ace_cursor.ace_overwrite {\ - border-left: 0px;\ - border-bottom: 1px solid #7DA5DC;\ -}\ - \ -.ace-clouds-midnight .ace_marker-layer .ace_selection {\ - background: #000000;\ -}\ -\ -.ace-clouds-midnight .ace_marker-layer .ace_step {\ - background: rgb(198, 219, 174);\ -}\ -\ -.ace-clouds-midnight .ace_marker-layer .ace_bracket {\ - margin: -1px 0 0 -1px;\ - border: 1px solid #BFBFBF;\ -}\ -\ -.ace-clouds-midnight .ace_marker-layer .ace_active_line {\ - background: rgba(215, 215, 215, 0.031);\ -}\ -\ - \ -.ace-clouds-midnight .ace_invisible {\ - color: #BFBFBF;\ -}\ -\ -.ace-clouds-midnight .ace_keyword {\ - color:#927C5D;\ -}\ -\ -.ace-clouds-midnight .ace_keyword.ace_operator {\ - color:#4B4B4B;\ -}\ -\ -.ace-clouds-midnight .ace_constant {\ - \ -}\ -\ -.ace-clouds-midnight .ace_constant.ace_language {\ - color:#39946A;\ -}\ -\ -.ace-clouds-midnight .ace_constant.ace_library {\ - \ -}\ -\ -.ace-clouds-midnight .ace_constant.ace_numeric {\ - color:#46A609;\ -}\ -\ -.ace-clouds-midnight .ace_invalid {\ - color:#FFFFFF;\ -background-color:#E92E2E;\ -}\ -\ -.ace-clouds-midnight .ace_invalid.ace_illegal {\ - \ -}\ -\ -.ace-clouds-midnight .ace_invalid.ace_deprecated {\ - \ -}\ -\ -.ace-clouds-midnight .ace_support {\ - \ -}\ -\ -.ace-clouds-midnight .ace_support.ace_function {\ - color:#E92E2E;\ -}\ -\ -.ace-clouds-midnight .ace_function.ace_buildin {\ - \ -}\ -\ -.ace-clouds-midnight .ace_string {\ - color:#5D90CD;\ -}\ -\ -.ace-clouds-midnight .ace_string.ace_regexp {\ - \ -}\ -\ -.ace-clouds-midnight .ace_comment {\ - color:#3C403B;\ -}\ -\ -.ace-clouds-midnight .ace_comment.ace_doc {\ - \ -}\ -\ -.ace-clouds-midnight .ace_comment.ace_doc.ace_tag {\ - \ -}\ -\ -.ace-clouds-midnight .ace_variable {\ - \ -}\ -\ -.ace-clouds-midnight .ace_variable.ace_language {\ - \ -}\ -\ -.ace-clouds-midnight .ace_xml_pe {\ - \ -}"; - - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "ace-clouds-midnight"; -}); \ No newline at end of file +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/cobalt.css b/lib/ace/theme/cobalt.css new file mode 100644 index 00000000..b883ba97 --- /dev/null +++ b/lib/ace/theme/cobalt.css @@ -0,0 +1,133 @@ +.ace-cobalt .ace_gutter { + background: #011e3a; + color: rgb(128,145,160) +} + +.ace-cobalt .ace_print-margin { + width: 1px; + background: #555555 +} + +.ace-cobalt { + background-color: #002240; + color: #FFFFFF +} + +.ace-cobalt .ace_cursor { + color: #FFFFFF +} + +.ace-cobalt .ace_marker-layer .ace_selection { + background: rgba(179, 101, 57, 0.75) +} + +.ace-cobalt.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #002240; +} + +.ace-cobalt .ace_marker-layer .ace_step { + background: rgb(127, 111, 19) +} + +.ace-cobalt .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgba(255, 255, 255, 0.15) +} + +.ace-cobalt .ace_marker-layer .ace_active-line { + background: rgba(0, 0, 0, 0.35) +} + +.ace-cobalt .ace_gutter-active-line { + background-color: rgba(0, 0, 0, 0.35) +} + +.ace-cobalt .ace_marker-layer .ace_selected-word { + border: 1px solid rgba(179, 101, 57, 0.75) +} + +.ace-cobalt .ace_invisible { + color: rgba(255, 255, 255, 0.15) +} + +.ace-cobalt .ace_keyword, +.ace-cobalt .ace_meta { + color: #FF9D00 +} + +.ace-cobalt .ace_constant, +.ace-cobalt .ace_constant.ace_character, +.ace-cobalt .ace_constant.ace_character.ace_escape, +.ace-cobalt .ace_constant.ace_other { + color: #FF628C +} + +.ace-cobalt .ace_invalid { + color: #F8F8F8; + background-color: #800F00 +} + +.ace-cobalt .ace_support { + color: #80FFBB +} + +.ace-cobalt .ace_support.ace_constant { + color: #EB939A +} + +.ace-cobalt .ace_fold { + background-color: #FF9D00; + border-color: #FFFFFF +} + +.ace-cobalt .ace_support.ace_function { + color: #FFB054 +} + +.ace-cobalt .ace_storage { + color: #FFEE80 +} + +.ace-cobalt .ace_entity { + color: #FFDD00 +} + +.ace-cobalt .ace_string { + color: #3AD900 +} + +.ace-cobalt .ace_string.ace_regexp { + color: #80FFC2 +} + +.ace-cobalt .ace_comment { + font-style: italic; + color: #0088FF +} + +.ace-cobalt .ace_heading, +.ace-cobalt .ace_markup.ace_heading { + color: #C8E4FD; + background-color: #001221 +} + +.ace-cobalt .ace_list, +.ace-cobalt .ace_markup.ace_list { + background-color: #130D26 +} + +.ace-cobalt .ace_variable { + color: #CCCCCC +} + +.ace-cobalt .ace_variable.ace_language { + color: #FF80E1 +} + +.ace-cobalt .ace_meta.ace_tag { + color: #9EFFFF +} + +.ace-cobalt .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHCLSvkPAAP3AgSDTRd4AAAAAElFTkSuQmCC) right repeat-y +} diff --git a/lib/ace/theme/cobalt.js b/lib/ace/theme/cobalt.js index e2762c2e..a466dd6c 100644 --- a/lib/ace/theme/cobalt.js +++ b/lib/ace/theme/cobalt.js @@ -1,197 +1,39 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { - var dom = require("pilot/dom"); +exports.isDark = true; +exports.cssClass = "ace-cobalt"; +exports.cssText = require("../requirejs/text!./cobalt.css"); - var cssText = ".ace-cobalt .ace_editor {\ - border: 2px solid rgb(159, 159, 159);\ -}\ -\ -.ace-cobalt .ace_editor.ace_focus {\ - border: 2px solid #327fbd;\ -}\ -\ -.ace-cobalt .ace_gutter {\ - width: 50px;\ - background: #e8e8e8;\ - color: #333;\ - overflow : hidden;\ -}\ -\ -.ace-cobalt .ace_gutter-layer {\ - width: 100%;\ - text-align: right;\ -}\ -\ -.ace-cobalt .ace_gutter-layer .ace_gutter-cell {\ - padding-right: 6px;\ -}\ -\ -.ace-cobalt .ace_print_margin {\ - width: 1px;\ - background: #e8e8e8;\ -}\ -\ -.ace-cobalt .ace_scroller {\ - background-color: #002240;\ -}\ -\ -.ace-cobalt .ace_text-layer {\ - cursor: text;\ - color: #FFFFFF;\ -}\ -\ -.ace-cobalt .ace_cursor {\ - border-left: 2px solid #FFFFFF;\ -}\ -\ -.ace-cobalt .ace_cursor.ace_overwrite {\ - border-left: 0px;\ - border-bottom: 1px solid #FFFFFF;\ -}\ - \ -.ace-cobalt .ace_marker-layer .ace_selection {\ - background: rgba(179, 101, 57, 0.75);\ -}\ -\ -.ace-cobalt .ace_marker-layer .ace_step {\ - background: rgb(198, 219, 174);\ -}\ -\ -.ace-cobalt .ace_marker-layer .ace_bracket {\ - margin: -1px 0 0 -1px;\ - border: 1px solid rgba(255, 255, 255, 0.15);\ -}\ -\ -.ace-cobalt .ace_marker-layer .ace_active_line {\ - background: rgba(0, 0, 0, 0.35);\ -}\ -\ - \ -.ace-cobalt .ace_invisible {\ - color: rgba(255, 255, 255, 0.15);\ -}\ -\ -.ace-cobalt .ace_keyword {\ - color:#FF9D00;\ -}\ -\ -.ace-cobalt .ace_keyword.ace_operator {\ - \ -}\ -\ -.ace-cobalt .ace_constant {\ - color:#FF628C;\ -}\ -\ -.ace-cobalt .ace_constant.ace_language {\ - \ -}\ -\ -.ace-cobalt .ace_constant.ace_library {\ - \ -}\ -\ -.ace-cobalt .ace_constant.ace_numeric {\ - \ -}\ -\ -.ace-cobalt .ace_invalid {\ - color:#F8F8F8;\ -background-color:#800F00;\ -}\ -\ -.ace-cobalt .ace_invalid.ace_illegal {\ - \ -}\ -\ -.ace-cobalt .ace_invalid.ace_deprecated {\ - \ -}\ -\ -.ace-cobalt .ace_support {\ - color:#80FFBB;\ -}\ -\ -.ace-cobalt .ace_support.ace_function {\ - color:#FFB054;\ -}\ -\ -.ace-cobalt .ace_function.ace_buildin {\ - \ -}\ -\ -.ace-cobalt .ace_string {\ - \ -}\ -\ -.ace-cobalt .ace_string.ace_regexp {\ - color:#80FFC2;\ -}\ -\ -.ace-cobalt .ace_comment {\ - font-style:italic;\ -color:#0088FF;\ -}\ -\ -.ace-cobalt .ace_comment.ace_doc {\ - \ -}\ -\ -.ace-cobalt .ace_comment.ace_doc.ace_tag {\ - \ -}\ -\ -.ace-cobalt .ace_variable {\ - color:#CCCCCC;\ -}\ -\ -.ace-cobalt .ace_variable.ace_language {\ - color:#FF80E1;\ -}\ -\ -.ace-cobalt .ace_xml_pe {\ - \ -}"; - - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "ace-cobalt"; -}); \ No newline at end of file +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/crimson_editor.css b/lib/ace/theme/crimson_editor.css new file mode 100644 index 00000000..e84292b4 --- /dev/null +++ b/lib/ace/theme/crimson_editor.css @@ -0,0 +1,143 @@ +.ace-crimson-editor .ace_gutter { + background: #ebebeb; + color: #333; + overflow : hidden; +} + +.ace-crimson-editor .ace_gutter-layer { + width: 100%; + text-align: right; +} + +.ace-crimson-editor .ace_print-margin { + width: 1px; + background: #e8e8e8; +} + +.ace-crimson-editor { + background-color: #FFFFFF; + color: rgb(64, 64, 64); +} + +.ace-crimson-editor .ace_cursor { + color: black; +} + +.ace-crimson-editor .ace_invisible { + color: rgb(191, 191, 191); +} + +.ace-crimson-editor .ace_identifier { + color: black; +} + +.ace-crimson-editor .ace_keyword { + color: blue; +} + +.ace-crimson-editor .ace_constant.ace_buildin { + color: rgb(88, 72, 246); +} + +.ace-crimson-editor .ace_constant.ace_language { + color: rgb(255, 156, 0); +} + +.ace-crimson-editor .ace_constant.ace_library { + color: rgb(6, 150, 14); +} + +.ace-crimson-editor .ace_invalid { + text-decoration: line-through; + color: rgb(224, 0, 0); +} + +.ace-crimson-editor .ace_fold { +} + +.ace-crimson-editor .ace_support.ace_function { + color: rgb(192, 0, 0); +} + +.ace-crimson-editor .ace_support.ace_constant { + color: rgb(6, 150, 14); +} + +.ace-crimson-editor .ace_support.ace_type, +.ace-crimson-editor .ace_support.ace_class { + color: rgb(109, 121, 222); +} + +.ace-crimson-editor .ace_keyword.ace_operator { + color: rgb(49, 132, 149); +} + +.ace-crimson-editor .ace_string { + color: rgb(128, 0, 128); +} + +.ace-crimson-editor .ace_comment { + color: rgb(76, 136, 107); +} + +.ace-crimson-editor .ace_comment.ace_doc { + color: rgb(0, 102, 255); +} + +.ace-crimson-editor .ace_comment.ace_doc.ace_tag { + color: rgb(128, 159, 191); +} + +.ace-crimson-editor .ace_constant.ace_numeric { + color: rgb(0, 0, 64); +} + +.ace-crimson-editor .ace_variable { + color: rgb(0, 64, 128); +} + +.ace-crimson-editor .ace_xml-pe { + color: rgb(104, 104, 91); +} + +.ace-crimson-editor .ace_marker-layer .ace_selection { + background: rgb(181, 213, 255); +} + +.ace-crimson-editor .ace_marker-layer .ace_step { + background: rgb(252, 255, 0); +} + +.ace-crimson-editor .ace_marker-layer .ace_stack { + background: rgb(164, 229, 101); +} + +.ace-crimson-editor .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgb(192, 192, 192); +} + +.ace-crimson-editor .ace_marker-layer .ace_active-line { + background: rgb(232, 242, 254); +} + +.ace-crimson-editor .ace_gutter-active-line { + background-color : #dcdcdc; +} + +.ace-crimson-editor .ace_meta.ace_tag { + color:rgb(28, 2, 255); +} + +.ace-crimson-editor .ace_marker-layer .ace_selected-word { + background: rgb(250, 250, 255); + border: 1px solid rgb(200, 200, 250); +} + +.ace-crimson-editor .ace_string.ace_regex { + color: rgb(192, 0, 192); +} + +.ace-crimson-editor .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; +} \ No newline at end of file diff --git a/lib/ace/theme/crimson_editor.js b/lib/ace/theme/crimson_editor.js new file mode 100644 index 00000000..a5971075 --- /dev/null +++ b/lib/ace/theme/crimson_editor.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +exports.isDark = false; +exports.cssText = require("../requirejs/text!./crimson_editor.css"); + +exports.cssClass = "ace-crimson-editor"; + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/dawn.css b/lib/ace/theme/dawn.css new file mode 100644 index 00000000..3c2884e1 --- /dev/null +++ b/lib/ace/theme/dawn.css @@ -0,0 +1,126 @@ +.ace-dawn .ace_gutter { + background: #ebebeb; + color: #333 +} + +.ace-dawn .ace_print-margin { + width: 1px; + background: #e8e8e8 +} + +.ace-dawn { + background-color: #F9F9F9; + color: #080808 +} + +.ace-dawn .ace_cursor { + color: #000000 +} + +.ace-dawn .ace_marker-layer .ace_selection { + background: rgba(39, 95, 255, 0.30) +} + +.ace-dawn.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #F9F9F9; +} + +.ace-dawn .ace_marker-layer .ace_step { + background: rgb(255, 255, 0) +} + +.ace-dawn .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgba(75, 75, 126, 0.50) +} + +.ace-dawn .ace_marker-layer .ace_active-line { + background: rgba(36, 99, 180, 0.12) +} + +.ace-dawn .ace_gutter-active-line { + background-color : #dcdcdc +} + +.ace-dawn .ace_marker-layer .ace_selected-word { + border: 1px solid rgba(39, 95, 255, 0.30) +} + +.ace-dawn .ace_invisible { + color: rgba(75, 75, 126, 0.50) +} + +.ace-dawn .ace_keyword, +.ace-dawn .ace_meta { + color: #794938 +} + +.ace-dawn .ace_constant, +.ace-dawn .ace_constant.ace_character, +.ace-dawn .ace_constant.ace_character.ace_escape, +.ace-dawn .ace_constant.ace_other { + color: #811F24 +} + +.ace-dawn .ace_invalid.ace_illegal { + text-decoration: underline; + font-style: italic; + color: #F8F8F8; + background-color: #B52A1D +} + +.ace-dawn .ace_invalid.ace_deprecated { + text-decoration: underline; + font-style: italic; + color: #B52A1D +} + +.ace-dawn .ace_support { + color: #691C97 +} + +.ace-dawn .ace_support.ace_constant { + color: #B4371F +} + +.ace-dawn .ace_fold { + background-color: #794938; + border-color: #080808 +} + +.ace-dawn .ace_list, +.ace-dawn .ace_markup.ace_list, +.ace-dawn .ace_support.ace_function { + color: #693A17 +} + +.ace-dawn .ace_storage { + font-style: italic; + color: #A71D5D +} + +.ace-dawn .ace_string { + color: #0B6125 +} + +.ace-dawn .ace_string.ace_regexp { + color: #CF5628 +} + +.ace-dawn .ace_comment { + font-style: italic; + color: #5A525F +} + +.ace-dawn .ace_heading, +.ace-dawn .ace_markup.ace_heading { + color: #19356D +} + +.ace-dawn .ace_variable { + color: #234A97 +} + +.ace-dawn .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYLh/5+x/AAizA4hxNNsZAAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/dawn.js b/lib/ace/theme/dawn.js index afab897a..2498aa3b 100644 --- a/lib/ace/theme/dawn.js +++ b/lib/ace/theme/dawn.js @@ -1,201 +1,39 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { - var dom = require("pilot/dom"); +exports.isDark = false; +exports.cssClass = "ace-dawn"; +exports.cssText = require("../requirejs/text!./dawn.css"); - var cssText = ".ace-dawn .ace_editor {\ - border: 2px solid rgb(159, 159, 159);\ -}\ -\ -.ace-dawn .ace_editor.ace_focus {\ - border: 2px solid #327fbd;\ -}\ -\ -.ace-dawn .ace_gutter {\ - width: 50px;\ - background: #e8e8e8;\ - color: #333;\ - overflow : hidden;\ -}\ -\ -.ace-dawn .ace_gutter-layer {\ - width: 100%;\ - text-align: right;\ -}\ -\ -.ace-dawn .ace_gutter-layer .ace_gutter-cell {\ - padding-right: 6px;\ -}\ -\ -.ace-dawn .ace_print_margin {\ - width: 1px;\ - background: #e8e8e8;\ -}\ -\ -.ace-dawn .ace_scroller {\ - background-color: #F9F9F9;\ -}\ -\ -.ace-dawn .ace_text-layer {\ - cursor: text;\ - color: #080808;\ -}\ -\ -.ace-dawn .ace_cursor {\ - border-left: 2px solid #000000;\ -}\ -\ -.ace-dawn .ace_cursor.ace_overwrite {\ - border-left: 0px;\ - border-bottom: 1px solid #000000;\ -}\ - \ -.ace-dawn .ace_marker-layer .ace_selection {\ - background: rgba(39, 95, 255, 0.30);\ -}\ -\ -.ace-dawn .ace_marker-layer .ace_step {\ - background: rgb(198, 219, 174);\ -}\ -\ -.ace-dawn .ace_marker-layer .ace_bracket {\ - margin: -1px 0 0 -1px;\ - border: 1px solid rgba(75, 75, 126, 0.50);\ -}\ -\ -.ace-dawn .ace_marker-layer .ace_active_line {\ - background: rgba(36, 99, 180, 0.12);\ -}\ -\ - \ -.ace-dawn .ace_invisible {\ - color: rgba(75, 75, 126, 0.50);\ -}\ -\ -.ace-dawn .ace_keyword {\ - color:#794938;\ -}\ -\ -.ace-dawn .ace_keyword.ace_operator {\ - \ -}\ -\ -.ace-dawn .ace_constant {\ - color:#811F24;\ -}\ -\ -.ace-dawn .ace_constant.ace_language {\ - \ -}\ -\ -.ace-dawn .ace_constant.ace_library {\ - \ -}\ -\ -.ace-dawn .ace_constant.ace_numeric {\ - \ -}\ -\ -.ace-dawn .ace_invalid {\ - \ -}\ -\ -.ace-dawn .ace_invalid.ace_illegal {\ - text-decoration:underline;\ -font-style:italic;\ -color:#F8F8F8;\ -background-color:#B52A1D;\ -}\ -\ -.ace-dawn .ace_invalid.ace_deprecated {\ - text-decoration:underline;\ -font-style:italic;\ -color:#B52A1D;\ -}\ -\ -.ace-dawn .ace_support {\ - color:#691C97;\ -}\ -\ -.ace-dawn .ace_support.ace_function {\ - color:#693A17;\ -}\ -\ -.ace-dawn .ace_function.ace_buildin {\ - \ -}\ -\ -.ace-dawn .ace_string {\ - color:#0B6125;\ -}\ -\ -.ace-dawn .ace_string.ace_regexp {\ - color:#CF5628;\ -}\ -\ -.ace-dawn .ace_comment {\ - font-style:italic;\ -color:#5A525F;\ -}\ -\ -.ace-dawn .ace_comment.ace_doc {\ - \ -}\ -\ -.ace-dawn .ace_comment.ace_doc.ace_tag {\ - \ -}\ -\ -.ace-dawn .ace_variable {\ - color:#234A97;\ -}\ -\ -.ace-dawn .ace_variable.ace_language {\ - \ -}\ -\ -.ace-dawn .ace_xml_pe {\ - \ -}"; - - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "ace-dawn"; -}); \ No newline at end of file +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/dreamweaver.css b/lib/ace/theme/dreamweaver.css new file mode 100644 index 00000000..84865a1c --- /dev/null +++ b/lib/ace/theme/dreamweaver.css @@ -0,0 +1,176 @@ +.ace-dreamweaver .ace_gutter { + background: #e8e8e8; + color: #333; +} + +.ace-dreamweaver .ace_print-margin { + width: 1px; + background: #e8e8e8; +} + +.ace-dreamweaver { + background-color: #FFFFFF; + color: black; +} + +.ace-dreamweaver .ace_fold { + background-color: #757AD8; +} + +.ace-dreamweaver .ace_cursor { + color: black; +} + +.ace-dreamweaver .ace_invisible { + color: rgb(191, 191, 191); +} + +.ace-dreamweaver .ace_storage, +.ace-dreamweaver .ace_keyword { + color: blue; +} + +.ace-dreamweaver .ace_constant.ace_buildin { + color: rgb(88, 72, 246); +} + +.ace-dreamweaver .ace_constant.ace_language { + color: rgb(88, 92, 246); +} + +.ace-dreamweaver .ace_constant.ace_library { + color: rgb(6, 150, 14); +} + +.ace-dreamweaver .ace_invalid { + background-color: rgb(153, 0, 0); + color: white; +} + +.ace-dreamweaver .ace_support.ace_function { + color: rgb(60, 76, 114); +} + +.ace-dreamweaver .ace_support.ace_constant { + color: rgb(6, 150, 14); +} + +.ace-dreamweaver .ace_support.ace_type, +.ace-dreamweaver .ace_support.ace_class { + color: #009; +} + +.ace-dreamweaver .ace_support.ace_php_tag { + color: #f00; +} + +.ace-dreamweaver .ace_keyword.ace_operator { + color: rgb(104, 118, 135); +} + +.ace-dreamweaver .ace_string { + color: #00F; +} + +.ace-dreamweaver .ace_comment { + color: rgb(76, 136, 107); +} + +.ace-dreamweaver .ace_comment.ace_doc { + color: rgb(0, 102, 255); +} + +.ace-dreamweaver .ace_comment.ace_doc.ace_tag { + color: rgb(128, 159, 191); +} + +.ace-dreamweaver .ace_constant.ace_numeric { + color: rgb(0, 0, 205); +} + +.ace-dreamweaver .ace_variable { + color: #06F +} + +.ace-dreamweaver .ace_xml-pe { + color: rgb(104, 104, 91); +} + +.ace-dreamweaver .ace_entity.ace_name.ace_function { + color: #00F; +} + + +.ace-dreamweaver .ace_heading { + color: rgb(12, 7, 255); +} + +.ace-dreamweaver .ace_list { + color:rgb(185, 6, 144); +} + +.ace-dreamweaver .ace_marker-layer .ace_selection { + background: rgb(181, 213, 255); +} + +.ace-dreamweaver .ace_marker-layer .ace_step { + background: rgb(252, 255, 0); +} + +.ace-dreamweaver .ace_marker-layer .ace_stack { + background: rgb(164, 229, 101); +} + +.ace-dreamweaver .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgb(192, 192, 192); +} + +.ace-dreamweaver .ace_marker-layer .ace_active-line { + background: rgba(0, 0, 0, 0.07); +} + +.ace-dreamweaver .ace_gutter-active-line { + background-color : #DCDCDC; +} + +.ace-dreamweaver .ace_marker-layer .ace_selected-word { + background: rgb(250, 250, 255); + border: 1px solid rgb(200, 200, 250); +} + +.ace-dreamweaver .ace_meta.ace_tag { + color:#009; +} + +.ace-dreamweaver .ace_meta.ace_tag.ace_anchor { + color:#060; +} + +.ace-dreamweaver .ace_meta.ace_tag.ace_form { + color:#F90; +} + +.ace-dreamweaver .ace_meta.ace_tag.ace_image { + color:#909; +} + +.ace-dreamweaver .ace_meta.ace_tag.ace_script { + color:#900; +} + +.ace-dreamweaver .ace_meta.ace_tag.ace_style { + color:#909; +} + +.ace-dreamweaver .ace_meta.ace_tag.ace_table { + color:#099; +} + +.ace-dreamweaver .ace_string.ace_regex { + color: rgb(255, 0, 0) +} + +.ace-dreamweaver .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; +} \ No newline at end of file diff --git a/lib/ace/theme/dreamweaver.js b/lib/ace/theme/dreamweaver.js new file mode 100644 index 00000000..943dc692 --- /dev/null +++ b/lib/ace/theme/dreamweaver.js @@ -0,0 +1,38 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +exports.isDark = false; +exports.cssClass = "ace-dreamweaver"; +exports.cssText = require("../requirejs/text!./dreamweaver.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/eclipse.css b/lib/ace/theme/eclipse.css new file mode 100644 index 00000000..c83d07a3 --- /dev/null +++ b/lib/ace/theme/eclipse.css @@ -0,0 +1,113 @@ +.ace-eclipse .ace_gutter { + background: #ebebeb; + border-right: 1px solid rgb(159, 159, 159); + color: rgb(136, 136, 136); +} + +.ace-eclipse .ace_print-margin { + width: 1px; + background: #ebebeb; +} + +.ace-eclipse { + background-color: #FFFFFF; + color: black; +} + +.ace-eclipse .ace_fold { + background-color: rgb(60, 76, 114); +} + +.ace-eclipse .ace_cursor { + color: black; +} + +.ace-eclipse .ace_storage, +.ace-eclipse .ace_keyword, +.ace-eclipse .ace_variable { + color: rgb(127, 0, 85); +} + +.ace-eclipse .ace_constant.ace_buildin { + color: rgb(88, 72, 246); +} + +.ace-eclipse .ace_constant.ace_library { + color: rgb(6, 150, 14); +} + +.ace-eclipse .ace_function { + color: rgb(60, 76, 114); +} + +.ace-eclipse .ace_string { + color: rgb(42, 0, 255); +} + +.ace-eclipse .ace_comment { + color: rgb(113, 150, 130); +} + +.ace-eclipse .ace_comment.ace_doc { + color: rgb(63, 95, 191); +} + +.ace-eclipse .ace_comment.ace_doc.ace_tag { + color: rgb(127, 159, 191); +} + +.ace-eclipse .ace_constant.ace_numeric { + color: darkblue; +} + +.ace-eclipse .ace_tag { + color: rgb(25, 118, 116); +} + +.ace-eclipse .ace_type { + color: rgb(127, 0, 127); +} + +.ace-eclipse .ace_xml-pe { + color: rgb(104, 104, 91); +} + +.ace-eclipse .ace_marker-layer .ace_selection { + background: rgb(181, 213, 255); +} + +.ace-eclipse .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgb(192, 192, 192); +} + +.ace-eclipse .ace_meta.ace_tag { + color:rgb(25, 118, 116); +} + +.ace-eclipse .ace_invisible { + color: #ddd; +} + +.ace-eclipse .ace_entity.ace_other.ace_attribute-name { + color:rgb(127, 0, 127); +} +.ace-eclipse .ace_marker-layer .ace_step { + background: rgb(255, 255, 0); +} + +.ace-eclipse .ace_active-line { + background: rgb(232, 242, 254); +} + +.ace-eclipse .ace_gutter-active-line { + background-color : #DADADA; +} + +.ace-eclipse .ace_marker-layer .ace_selected-word { + border: 1px solid rgb(181, 213, 255); +} + +.ace-eclipse .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; +} \ No newline at end of file diff --git a/lib/ace/theme/eclipse.js b/lib/ace/theme/eclipse.js index c97ae0d0..329b8b79 100644 --- a/lib/ace/theme/eclipse.js +++ b/lib/ace/theme/eclipse.js @@ -1,134 +1,41 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; - var dom = require("pilot/dom"); +exports.isDark = false; +exports.cssText = require("../requirejs/text!./eclipse.css"); - var cssText = ".ace-eclipse .ace_editor {\ - border: 2px solid rgb(159, 159, 159);\ -}\ -\ -.ace-eclipse .ace_editor.ace_focus {\ - border: 2px solid #327fbd;\ -}\ -\ -.ace-eclipse .ace_gutter {\ - width: 50px;\ - background: rgb(227, 227, 227);\ - border-right: 1px solid rgb(159, 159, 159); \ - color: rgb(136, 136, 136);\ -}\ -\ -.ace-eclipse .ace_gutter-layer {\ - width: 100%;\ - text-align: right;\ -}\ -\ -.ace-eclipse .ace_gutter-layer .ace_gutter-cell {\ - padding-right: 6px;\ -}\ -\ -.ace-eclipse .ace_text-layer {\ - cursor: text;\ -}\ -\ -.ace-eclipse .ace_cursor {\ - border-left: 1px solid black;\ -}\ -\ -.ace-eclipse .ace_line .ace_keyword, .ace-eclipse .ace_line .ace_variable {\ - color: rgb(127, 0, 85);\ -}\ -\ -.ace-eclipse .ace_line .ace_constant.ace_buildin {\ - color: rgb(88, 72, 246);\ -}\ -\ -.ace-eclipse .ace_line .ace_constant.ace_library {\ - color: rgb(6, 150, 14);\ -}\ -\ -.ace-eclipse .ace_line .ace_function {\ - color: rgb(60, 76, 114);\ -}\ -\ -.ace-eclipse .ace_line .ace_string {\ - color: rgb(42, 0, 255);\ -}\ -\ -.ace-eclipse .ace_line .ace_comment {\ - color: rgb(63, 127, 95);\ -}\ -\ -.ace-eclipse .ace_line .ace_comment.ace_doc {\ - color: rgb(63, 95, 191);\ -}\ -\ -.ace-eclipse .ace_line .ace_comment.ace_doc.ace_tag {\ - color: rgb(127, 159, 191);\ -}\ -\ -.ace-eclipse .ace_line .ace_constant.ace_numeric {\ -}\ -\ -.ace-eclipse .ace_line .ace_tag {\ - color: rgb(63, 127, 127);\ -}\ -\ -.ace-eclipse .ace_line .ace_xml_pe {\ - color: rgb(104, 104, 91);\ -}\ -\ -.ace-eclipse .ace_marker-layer .ace_selection {\ - background: rgb(181, 213, 255);\ -}\ -\ -.ace-eclipse .ace_marker-layer .ace_bracket {\ - margin: -1px 0 0 -1px;\ - border: 1px solid rgb(192, 192, 192);\ -}\ -\ -.ace-eclipse .ace_marker-layer .ace_active_line {\ - background: rgb(232, 242, 254);\ -}"; +exports.cssClass = "ace-eclipse"; - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "ace-eclipse"; +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); }); diff --git a/lib/ace/theme/github.css b/lib/ace/theme/github.css new file mode 100644 index 00000000..213d3fd3 --- /dev/null +++ b/lib/ace/theme/github.css @@ -0,0 +1,125 @@ +/* CSS style content from github's default pygments highlighter template. + Cursor and selection styles from textmate.css. */ +.ace-github .ace_gutter { + background: #e8e8e8; + color: #AAA; +} + +.ace-github { + background: #fff; + color: #000; +} + +.ace-github .ace_keyword { + font-weight: bold; +} + +.ace-github .ace_string { + color: #D14; +} + +.ace-github .ace_variable.ace_class { + color: teal; +} + +.ace-github .ace_constant.ace_numeric { + color: #099; +} + +.ace-github .ace_constant.ace_buildin { + color: #0086B3; +} + +.ace-github .ace_support.ace_function { + color: #0086B3; +} + +.ace-github .ace_comment { + color: #998; + font-style: italic; +} + +.ace-github .ace_variable.ace_language { + color: #0086B3; +} + +.ace-github .ace_paren { + font-weight: bold; +} + +.ace-github .ace_boolean { + font-weight: bold; +} + +.ace-github .ace_string.ace_regexp { + color: #009926; + font-weight: normal; +} + +.ace-github .ace_variable.ace_instance { + color: teal; +} + +.ace-github .ace_constant.ace_language { + font-weight: bold; +} + +.ace-github .ace_cursor { + color: black; +} + +.ace-github.ace_focus .ace_marker-layer .ace_active-line { + background: rgb(255, 255, 204); +} +.ace-github .ace_marker-layer .ace_active-line { + background: rgb(245, 245, 245); +} + +.ace-github .ace_marker-layer .ace_selection { + background: rgb(181, 213, 255); +} + +.ace-github.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px white; + border-radius: 2px; +} +/* bold keywords cause cursor issues for some fonts */ +/* this disables bold style for editor and keeps for static highlighter */ +.ace-github.ace_nobold .ace_line > span { + font-weight: normal !important; +} + +.ace-github .ace_marker-layer .ace_step { + background: rgb(252, 255, 0); +} + +.ace-github .ace_marker-layer .ace_stack { + background: rgb(164, 229, 101); +} + +.ace-github .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgb(192, 192, 192); +} + +.ace-github .ace_gutter-active-line { + background-color : rgba(0, 0, 0, 0.07); +} + +.ace-github .ace_marker-layer .ace_selected-word { + background: rgb(250, 250, 255); + border: 1px solid rgb(200, 200, 250); +} + +.ace-github .ace_invisible { + color: #BFBFBF +} + +.ace-github .ace_print-margin { + width: 1px; + background: #e8e8e8; +} + +.ace-github .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; +} \ No newline at end of file diff --git a/lib/ace/theme/github.js b/lib/ace/theme/github.js new file mode 100644 index 00000000..de013c8c --- /dev/null +++ b/lib/ace/theme/github.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = false; +exports.cssClass = "ace-github"; +exports.cssText = require("../requirejs/text!./github.css"); + + var dom = require("../lib/dom"); + dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/idle_fingers.css b/lib/ace/theme/idle_fingers.css new file mode 100644 index 00000000..b5e1bff2 --- /dev/null +++ b/lib/ace/theme/idle_fingers.css @@ -0,0 +1,112 @@ +.ace-idle-fingers .ace_gutter { + background: #3b3b3b; + color: rgb(153,153,153) +} + +.ace-idle-fingers .ace_print-margin { + width: 1px; + background: #3b3b3b +} + +.ace-idle-fingers { + background-color: #323232; + color: #FFFFFF +} + +.ace-idle-fingers .ace_cursor { + color: #91FF00 +} + +.ace-idle-fingers .ace_marker-layer .ace_selection { + background: rgba(90, 100, 126, 0.88) +} + +.ace-idle-fingers.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #323232; +} + +.ace-idle-fingers .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.ace-idle-fingers .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #404040 +} + +.ace-idle-fingers .ace_marker-layer .ace_active-line { + background: #353637 +} + +.ace-idle-fingers .ace_gutter-active-line { + background-color: #353637 +} + +.ace-idle-fingers .ace_marker-layer .ace_selected-word { + border: 1px solid rgba(90, 100, 126, 0.88) +} + +.ace-idle-fingers .ace_invisible { + color: #404040 +} + +.ace-idle-fingers .ace_keyword, +.ace-idle-fingers .ace_meta { + color: #CC7833 +} + +.ace-idle-fingers .ace_constant, +.ace-idle-fingers .ace_constant.ace_character, +.ace-idle-fingers .ace_constant.ace_character.ace_escape, +.ace-idle-fingers .ace_constant.ace_other, +.ace-idle-fingers .ace_support.ace_constant { + color: #6C99BB +} + +.ace-idle-fingers .ace_invalid { + color: #FFFFFF; + background-color: #FF0000 +} + +.ace-idle-fingers .ace_fold { + background-color: #CC7833; + border-color: #FFFFFF +} + +.ace-idle-fingers .ace_support.ace_function { + color: #B83426 +} + +.ace-idle-fingers .ace_variable.ace_parameter { + font-style: italic +} + +.ace-idle-fingers .ace_string { + color: #A5C261 +} + +.ace-idle-fingers .ace_string.ace_regexp { + color: #CCCC33 +} + +.ace-idle-fingers .ace_comment { + font-style: italic; + color: #BC9458 +} + +.ace-idle-fingers .ace_meta.ace_tag { + color: #FFE5BB +} + +.ace-idle-fingers .ace_entity.ace_name { + color: #FFC66D +} + +.ace-idle-fingers .ace_collab.ace_user1 { + color: #323232; + background-color: #FFF980 +} + +.ace-idle-fingers .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMwMjLyZYiPj/8PAAreAwAI1+g0AAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/idle_fingers.js b/lib/ace/theme/idle_fingers.js index 6273139e..096a2314 100644 --- a/lib/ace/theme/idle_fingers.js +++ b/lib/ace/theme/idle_fingers.js @@ -1,202 +1,39 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { - var dom = require("pilot/dom"); +exports.isDark = true; +exports.cssClass = "ace-idle-fingers"; +exports.cssText = require("../requirejs/text!./idle_fingers.css"); - var cssText = ".ace-idle-fingers .ace_editor {\ - border: 2px solid rgb(159, 159, 159);\ -}\ -\ -.ace-idle-fingers .ace_editor.ace_focus {\ - border: 2px solid #327fbd;\ -}\ -\ -.ace-idle-fingers .ace_gutter {\ - width: 50px;\ - background: #e8e8e8;\ - color: #333;\ - overflow : hidden;\ -}\ -\ -.ace-idle-fingers .ace_gutter-layer {\ - width: 100%;\ - text-align: right;\ -}\ -\ -.ace-idle-fingers .ace_gutter-layer .ace_gutter-cell {\ - padding-right: 6px;\ -}\ -\ -.ace-idle-fingers .ace_print_margin {\ - width: 1px;\ - background: #e8e8e8;\ -}\ -\ -.ace-idle-fingers .ace_scroller {\ - background-color: #323232;\ -}\ -\ -.ace-idle-fingers .ace_text-layer {\ - cursor: text;\ - color: #FFFFFF;\ -}\ -\ -.ace-idle-fingers .ace_cursor {\ - border-left: 2px solid #91FF00;\ -}\ -\ -.ace-idle-fingers .ace_cursor.ace_overwrite {\ - border-left: 0px;\ - border-bottom: 1px solid #91FF00;\ -}\ - \ -.ace-idle-fingers .ace_marker-layer .ace_selection {\ - background: rgba(90, 100, 126, 0.88);\ -}\ -\ -.ace-idle-fingers .ace_marker-layer .ace_step {\ - background: rgb(198, 219, 174);\ -}\ -\ -.ace-idle-fingers .ace_marker-layer .ace_bracket {\ - margin: -1px 0 0 -1px;\ - border: 1px solid #404040;\ -}\ -\ -.ace-idle-fingers .ace_marker-layer .ace_active_line {\ - background: #353637;\ -}\ -\ - \ -.ace-idle-fingers .ace_invisible {\ - color: #404040;\ -}\ -\ -.ace-idle-fingers .ace_keyword {\ - color:#CC7833;\ -}\ -\ -.ace-idle-fingers .ace_keyword.ace_operator {\ - \ -}\ -\ -.ace-idle-fingers .ace_constant {\ - color:#6C99BB;\ -}\ -\ -.ace-idle-fingers .ace_constant.ace_language {\ - \ -}\ -\ -.ace-idle-fingers .ace_constant.ace_library {\ - \ -}\ -\ -.ace-idle-fingers .ace_constant.ace_numeric {\ - \ -}\ -\ -.ace-idle-fingers .ace_invalid {\ - color:#FFFFFF;\ -background-color:#FF0000;\ -}\ -\ -.ace-idle-fingers .ace_invalid.ace_illegal {\ - \ -}\ -\ -.ace-idle-fingers .ace_invalid.ace_deprecated {\ - \ -}\ -\ -.ace-idle-fingers .ace_support {\ - \ -}\ -\ -.ace-idle-fingers .ace_support.ace_function {\ - color:#B83426;\ -}\ -\ -.ace-idle-fingers .ace_function.ace_buildin {\ - \ -}\ -\ -.ace-idle-fingers .ace_string {\ - color:#A5C261;\ -}\ -\ -.ace-idle-fingers .ace_string.ace_regexp {\ - color:#CCCC33;\ -}\ -\ -.ace-idle-fingers .ace_comment {\ - font-style:italic;\ -color:#BC9458;\ -}\ -\ -.ace-idle-fingers .ace_comment.ace_doc {\ - \ -}\ -\ -.ace-idle-fingers .ace_comment.ace_doc.ace_tag {\ - \ -}\ -\ -.ace-idle-fingers .ace_variable {\ - \ -}\ -\ -.ace-idle-fingers .ace_variable.ace_language {\ - \ -}\ -\ -.ace-idle-fingers .ace_xml_pe {\ - \ -}\ -\ -.ace-idle-fingers .ace_collab.ace_user1 {\ - color:#323232;\ -background-color:#FFF980; \ -}"; - - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "ace-idle-fingers"; -}); \ No newline at end of file +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/iplastic.css b/lib/ace/theme/iplastic.css new file mode 100644 index 00000000..b07dc8f9 --- /dev/null +++ b/lib/ace/theme/iplastic.css @@ -0,0 +1,140 @@ +.ace-iplastic .ace_gutter { + background: #dddddd; + color: #666666 +} + +.ace-iplastic .ace_print-margin { + width: 1px; + background: #bbbbbb +} + +.ace-iplastic { + background-color: #eeeeee; + color: #333333 +} + +.ace-iplastic .ace_cursor { + color: #333 +} + +.ace-iplastic .ace_marker-layer .ace_selection { + background: #BAD6FD; +} + +.ace-iplastic.ace_multiselect .ace_selection.ace_start { + border-radius: 4px +} + +.ace-iplastic .ace_marker-layer .ace_step { + background: #444444 +} + +.ace-iplastic .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #49483E; + background: #FFF799 +} + +.ace-iplastic .ace_marker-layer .ace_active-line { + background: #e5e5e5 +} + +.ace-iplastic .ace_gutter-active-line { + background-color: #eeeeee +} + +.ace-iplastic .ace_marker-layer .ace_selected-word { + border: 1px solid #555555; + border-radius:4px +} + +.ace-iplastic .ace_invisible { + color: #999999 +} + +.ace-iplastic .ace_entity.ace_name.ace_tag, +.ace-iplastic .ace_keyword, +.ace-iplastic .ace_meta.ace_tag, +.ace-iplastic .ace_storage { + color: #0000FF +} + +.ace-iplastic .ace_punctuation, +.ace-iplastic .ace_punctuation.ace_tag { + color: #000 +} + +.ace-iplastic .ace_constant { + color: #333333; + font-weight: 700 +} + +.ace-iplastic .ace_constant.ace_character, +.ace-iplastic .ace_constant.ace_language, +.ace-iplastic .ace_constant.ace_numeric, +.ace-iplastic .ace_constant.ace_other { + color: #0066FF; + font-weight: 700 +} + +.ace-iplastic .ace_constant.ace_numeric{ + font-weight: 100 +} + +.ace-iplastic .ace_invalid { + color: #F8F8F0; + background-color: #F92672 +} + +.ace-iplastic .ace_invalid.ace_deprecated { + color: #F8F8F0; + background-color: #AE81FF +} + +.ace-iplastic .ace_support.ace_constant, +.ace-iplastic .ace_support.ace_function { + color: #333333; + font-weight: 700 +} + +.ace-iplastic .ace_fold { + background-color: #464646; + border-color: #F8F8F2 +} + +.ace-iplastic .ace_storage.ace_type, +.ace-iplastic .ace_support.ace_class, +.ace-iplastic .ace_support.ace_type { + color: #3333fc; + font-weight: 700 +} + +.ace-iplastic .ace_entity.ace_name.ace_function, +.ace-iplastic .ace_entity.ace_other, +.ace-iplastic .ace_entity.ace_other.ace_attribute-name, +.ace-iplastic .ace_variable { + color: #3366cc; + font-style: italic +} + +.ace-iplastic .ace_variable.ace_parameter { + font-style: italic; + color: #2469E0 +} + +.ace-iplastic .ace_string { + color: #a55f03 +} + +.ace-iplastic .ace_comment { + color: #777777; + font-style: italic +} + +.ace-iplastic .ace_fold-widget { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==); +} + +.ace-iplastic .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAABlJREFUeNpi+P//PwMzMzPzfwAAAAD//wMAGRsECSML/RIAAAAASUVORK5CYII=) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/iplastic.js b/lib/ace/theme/iplastic.js new file mode 100644 index 00000000..ff784196 --- /dev/null +++ b/lib/ace/theme/iplastic.js @@ -0,0 +1,40 @@ + +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = false; +exports.cssClass = "ace-iplastic"; +exports.cssText = require("../requirejs/text!./iplastic.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/katzenmilch.css b/lib/ace/theme/katzenmilch.css new file mode 100644 index 00000000..bf1569fb --- /dev/null +++ b/lib/ace/theme/katzenmilch.css @@ -0,0 +1,143 @@ +.ace-katzenmilch .ace_gutter, +/* THIS THEME WAS AUTOGENERATED BY Theme.tmpl.css (UUID: ) */ + +.ace-katzenmilch .ace_gutter { + background: #e8e8e8; + color: #333 +} + +.ace-katzenmilch .ace_print-margin { + width: 1px; + background: #e8e8e8 +} + +.ace-katzenmilch { + background-color: #f3f2f3; + color: rgba(15, 0, 9, 1.0) +} + +.ace-katzenmilch .ace_cursor { + border-left: 2px solid #100011 +} + +.ace-katzenmilch .ace_overwrite-cursors .ace_cursor { + border-left: 0px; + border-bottom: 1px solid #100011 +} + +.ace-katzenmilch .ace_marker-layer .ace_selection { + background: rgba(100, 5, 208, 0.27) +} + +.ace-katzenmilch.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #f3f2f3; +} + +.ace-katzenmilch .ace_marker-layer .ace_step { + background: rgb(198, 219, 174) +} + +.ace-katzenmilch .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #000000 +} + +.ace-katzenmilch .ace_marker-layer .ace_active-line { + background: rgb(232, 242, 254) +} + +.ace-katzenmilch .ace_gutter-active-line { + background-color: rgb(232, 242, 254) +} + +.ace-katzenmilch .ace_marker-layer .ace_selected-word { + border: 1px solid rgba(100, 5, 208, 0.27) +} + +.ace-katzenmilch .ace_invisible { + color: #BFBFBF +} + +.ace-katzenmilch .ace_fold { + background-color: rgba(2, 95, 73, 0.97); + border-color: rgba(15, 0, 9, 1.0) +} + +.ace-katzenmilch .ace_keyword { + color: #674Aa8; + rbackground-color: rgba(163, 170, 216, 0.055) +} + +.ace-katzenmilch .ace_constant.ace_language { + color: #7D7e52; + rbackground-color: rgba(189, 190, 130, 0.059) +} + +.ace-katzenmilch .ace_constant.ace_numeric { + color: rgba(79, 130, 123, 0.93); + rbackground-color: rgba(119, 194, 187, 0.059) +} + +.ace-katzenmilch .ace_constant.ace_character, +.ace-katzenmilch .ace_constant.ace_other { + color: rgba(2, 95, 105, 1.0); + rbackground-color: rgba(127, 34, 153, 0.063) +} + +.ace-katzenmilch .ace_support.ace_function { + color: #9D7e62; + rbackground-color: rgba(189, 190, 130, 0.039) +} + +.ace-katzenmilch .ace_support.ace_class { + color: rgba(239, 106, 167, 1.0); + rbackground-color: rgba(239, 106, 167, 0.063) +} + +.ace-katzenmilch .ace_storage { + color: rgba(123, 92, 191, 1.0); + rbackground-color: rgba(139, 93, 223, 0.051) +} + +.ace-katzenmilch .ace_invalid { + color: #DFDFD5; + rbackground-color: #CC1B27 +} + +.ace-katzenmilch .ace_string { + color: #5a5f9b; + rbackground-color: rgba(170, 175, 219, 0.035) +} + +.ace-katzenmilch .ace_comment { + font-style: italic; + color: rgba(64, 79, 80, 0.67); + rbackground-color: rgba(95, 15, 255, 0.0078) +} + +.ace-katzenmilch .ace_entity.ace_name.ace_function, +.ace-katzenmilch .ace_variable { + color: rgba(2, 95, 73, 0.97); + rbackground-color: rgba(34, 255, 73, 0.12) +} + +.ace-katzenmilch .ace_variable.ace_language { + color: #316fcf; + rbackground-color: rgba(58, 175, 255, 0.039) +} + +.ace-katzenmilch .ace_variable.ace_parameter { + font-style: italic; + color: rgba(51, 150, 159, 0.87); + rbackground-color: rgba(5, 214, 249, 0.043) +} + +.ace-katzenmilch .ace_entity.ace_other.ace_attribute-name { + color: rgba(73, 70, 194, 0.93); + rbackground-color: rgba(73, 134, 194, 0.035) +} + +.ace-katzenmilch .ace_entity.ace_name.ace_tag { + color: #3976a2; + rbackground-color: rgba(73, 166, 210, 0.039) +} \ No newline at end of file diff --git a/lib/ace/theme/katzenmilch.js b/lib/ace/theme/katzenmilch.js new file mode 100644 index 00000000..4787483d --- /dev/null +++ b/lib/ace/theme/katzenmilch.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = false; +exports.cssClass = "ace-katzenmilch"; +exports.cssText = require("../requirejs/text!./katzenmilch.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/kr_theme.css b/lib/ace/theme/kr_theme.css new file mode 100644 index 00000000..e232de47 --- /dev/null +++ b/lib/ace/theme/kr_theme.css @@ -0,0 +1,123 @@ +.ace-kr-theme .ace_gutter { + background: #1c1917; + color: #FCFFE0 +} + +.ace-kr-theme .ace_print-margin { + width: 1px; + background: #1c1917 +} + +.ace-kr-theme { + background-color: #0B0A09; + color: #FCFFE0 +} + +.ace-kr-theme .ace_cursor { + color: #FF9900 +} + +.ace-kr-theme .ace_marker-layer .ace_selection { + background: rgba(170, 0, 255, 0.45) +} + +.ace-kr-theme.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #0B0A09; +} + +.ace-kr-theme .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.ace-kr-theme .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgba(255, 177, 111, 0.32) +} + +.ace-kr-theme .ace_marker-layer .ace_active-line { + background: #38403D +} + +.ace-kr-theme .ace_gutter-active-line { + background-color : #38403D +} + +.ace-kr-theme .ace_marker-layer .ace_selected-word { + border: 1px solid rgba(170, 0, 255, 0.45) +} + +.ace-kr-theme .ace_invisible { + color: rgba(255, 177, 111, 0.32) +} + +.ace-kr-theme .ace_keyword, +.ace-kr-theme .ace_meta { + color: #949C8B +} + +.ace-kr-theme .ace_constant, +.ace-kr-theme .ace_constant.ace_character, +.ace-kr-theme .ace_constant.ace_character.ace_escape, +.ace-kr-theme .ace_constant.ace_other { + color: rgba(210, 117, 24, 0.76) +} + +.ace-kr-theme .ace_invalid { + color: #F8F8F8; + background-color: #A41300 +} + +.ace-kr-theme .ace_support { + color: #9FC28A +} + +.ace-kr-theme .ace_support.ace_constant { + color: #C27E66 +} + +.ace-kr-theme .ace_fold { + background-color: #949C8B; + border-color: #FCFFE0 +} + +.ace-kr-theme .ace_support.ace_function { + color: #85873A +} + +.ace-kr-theme .ace_storage { + color: #FFEE80 +} + +.ace-kr-theme .ace_string { + color: rgba(164, 161, 181, 0.8) +} + +.ace-kr-theme .ace_string.ace_regexp { + color: rgba(125, 255, 192, 0.65) +} + +.ace-kr-theme .ace_comment { + font-style: italic; + color: #706D5B +} + +.ace-kr-theme .ace_variable { + color: #D1A796 +} + +.ace-kr-theme .ace_list, +.ace-kr-theme .ace_markup.ace_list { + background-color: #0F0040 +} + +.ace-kr-theme .ace_variable.ace_language { + color: #FF80E1 +} + +.ace-kr-theme .ace_meta.ace_tag { + color: #BABD9C +} + +.ace-kr-theme .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYFBXV/8PAAJoAXX4kT2EAAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/kr_theme.js b/lib/ace/theme/kr_theme.js index 28a48f62..fb6a5abe 100644 --- a/lib/ace/theme/kr_theme.js +++ b/lib/ace/theme/kr_theme.js @@ -1,197 +1,39 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { - var dom = require("pilot/dom"); +exports.isDark = true; +exports.cssClass = "ace-kr-theme"; +exports.cssText = require("../requirejs/text!./kr_theme.css"); - var cssText = ".ace-kr-theme .ace_editor {\ - border: 2px solid rgb(159, 159, 159);\ -}\ -\ -.ace-kr-theme .ace_editor.ace_focus {\ - border: 2px solid #327fbd;\ -}\ -\ -.ace-kr-theme .ace_gutter {\ - width: 50px;\ - background: #e8e8e8;\ - color: #333;\ - overflow : hidden;\ -}\ -\ -.ace-kr-theme .ace_gutter-layer {\ - width: 100%;\ - text-align: right;\ -}\ -\ -.ace-kr-theme .ace_gutter-layer .ace_gutter-cell {\ - padding-right: 6px;\ -}\ -\ -.ace-kr-theme .ace_print_margin {\ - width: 1px;\ - background: #e8e8e8;\ -}\ -\ -.ace-kr-theme .ace_scroller {\ - background-color: #0B0A09;\ -}\ -\ -.ace-kr-theme .ace_text-layer {\ - cursor: text;\ - color: #FCFFE0;\ -}\ -\ -.ace-kr-theme .ace_cursor {\ - border-left: 2px solid #FF9900;\ -}\ -\ -.ace-kr-theme .ace_cursor.ace_overwrite {\ - border-left: 0px;\ - border-bottom: 1px solid #FF9900;\ -}\ - \ -.ace-kr-theme .ace_marker-layer .ace_selection {\ - background: rgba(170, 0, 255, 0.45);\ -}\ -\ -.ace-kr-theme .ace_marker-layer .ace_step {\ - background: rgb(198, 219, 174);\ -}\ -\ -.ace-kr-theme .ace_marker-layer .ace_bracket {\ - margin: -1px 0 0 -1px;\ - border: 1px solid rgba(255, 177, 111, 0.32);\ -}\ -\ -.ace-kr-theme .ace_marker-layer .ace_active_line {\ - background: #38403D;\ -}\ -\ - \ -.ace-kr-theme .ace_invisible {\ - color: rgba(255, 177, 111, 0.32);\ -}\ -\ -.ace-kr-theme .ace_keyword {\ - color:#949C8B;\ -}\ -\ -.ace-kr-theme .ace_keyword.ace_operator {\ - \ -}\ -\ -.ace-kr-theme .ace_constant {\ - color:rgba(210, 117, 24, 0.76);\ -}\ -\ -.ace-kr-theme .ace_constant.ace_language {\ - \ -}\ -\ -.ace-kr-theme .ace_constant.ace_library {\ - \ -}\ -\ -.ace-kr-theme .ace_constant.ace_numeric {\ - \ -}\ -\ -.ace-kr-theme .ace_invalid {\ - color:#F8F8F8;\ -background-color:#A41300;\ -}\ -\ -.ace-kr-theme .ace_invalid.ace_illegal {\ - \ -}\ -\ -.ace-kr-theme .ace_invalid.ace_deprecated {\ - \ -}\ -\ -.ace-kr-theme .ace_support {\ - color:#9FC28A;\ -}\ -\ -.ace-kr-theme .ace_support.ace_function {\ - color:#85873A;\ -}\ -\ -.ace-kr-theme .ace_function.ace_buildin {\ - \ -}\ -\ -.ace-kr-theme .ace_string {\ - \ -}\ -\ -.ace-kr-theme .ace_string.ace_regexp {\ - color:rgba(125, 255, 192, 0.65);\ -}\ -\ -.ace-kr-theme .ace_comment {\ - font-style:italic;\ -color:#706D5B;\ -}\ -\ -.ace-kr-theme .ace_comment.ace_doc {\ - \ -}\ -\ -.ace-kr-theme .ace_comment.ace_doc.ace_tag {\ - \ -}\ -\ -.ace-kr-theme .ace_variable {\ - color:#D1A796;\ -}\ -\ -.ace-kr-theme .ace_variable.ace_language {\ - color:#FF80E1;\ -}\ -\ -.ace-kr-theme .ace_xml_pe {\ - \ -}"; - - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "ace-kr-theme"; -}); \ No newline at end of file +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/kuroir.css b/lib/ace/theme/kuroir.css new file mode 100644 index 00000000..5e987abc --- /dev/null +++ b/lib/ace/theme/kuroir.css @@ -0,0 +1,71 @@ +/* THIS THEME WAS AUTOGENERATED BY Theme.tmpl.css (UUID: 467560D0-6ACE-4409-82FD-4791420837AC) */ + +.ace-kuroir .ace_gutter { + background: #e8e8e8; + color: #333; +} + +.ace-kuroir .ace_print-margin { + width: 1px; + background: #e8e8e8; +} + +.ace-kuroir { + background-color: #E8E9E8; + color: #363636; +} + +.ace-kuroir .ace_cursor { + color: #202020; +} + +.ace-kuroir .ace_marker-layer .ace_selection { + background: rgba(245, 170, 0, 0.57); +} + +.ace-kuroir.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #E8E9E8; + border-radius: 2px; +} + +.ace-kuroir .ace_marker-layer .ace_step { + background: rgb(198, 219, 174); +} + +.ace-kuroir .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgba(0, 0, 0, 0.29); +} + +.ace-kuroir .ace_marker-layer .ace_active-line { + background: rgba(203, 220, 47, 0.22); +} + +.ace-kuroir .ace_gutter-active-line { + background-color: rgba(203, 220, 47, 0.22); +} + +.ace-kuroir .ace_marker-layer .ace_selected-word { + border: 1px solid rgba(245, 170, 0, 0.57); +} + +.ace-kuroir .ace_invisible { + color: #BFBFBF +} + +.ace-kuroir .ace_fold { + border-color: #363636; +} + + + + + +.ace-kuroir .ace_constant{color:#CD6839;}.ace-kuroir .ace_constant.ace_numeric{color:#9A5925;}.ace-kuroir .ace_support{color:#104E8B;}.ace-kuroir .ace_support.ace_function{color:#005273;}.ace-kuroir .ace_support.ace_constant{color:#CF6A4C;}.ace-kuroir .ace_storage{color:#A52A2A;}.ace-kuroir .ace_invalid.ace_illegal{color:#FD1224; +background-color:rgba(255, 6, 0, 0.15);}.ace-kuroir .ace_invalid.ace_deprecated{text-decoration:underline; +font-style:italic; +color:#FD1732; +background-color:#E8E9E8;}.ace-kuroir .ace_string{color:#639300;}.ace-kuroir .ace_string.ace_regexp{color:#417E00; +background-color:#C9D4BE;}.ace-kuroir .ace_comment{color:rgba(148, 148, 148, 0.91); +background-color:rgba(220, 220, 220, 0.56);}.ace-kuroir .ace_variable{color:#009ACD;}.ace-kuroir .ace_meta.ace_tag{color:#005273;}.ace-kuroir .ace_markup.ace_heading{color:#B8012D; +background-color:rgba(191, 97, 51, 0.051);}.ace-kuroir .ace_markup.ace_list{color:#8F5B26;} diff --git a/lib/ace/theme/kuroir.js b/lib/ace/theme/kuroir.js new file mode 100644 index 00000000..cef6a50b --- /dev/null +++ b/lib/ace/theme/kuroir.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = false; +exports.cssClass = "ace-kuroir"; +exports.cssText = require("../requirejs/text!./kuroir.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/merbivore.css b/lib/ace/theme/merbivore.css new file mode 100644 index 00000000..9be25c66 --- /dev/null +++ b/lib/ace/theme/merbivore.css @@ -0,0 +1,109 @@ +.ace-merbivore .ace_gutter { + background: #202020; + color: #E6E1DC +} + +.ace-merbivore .ace_print-margin { + width: 1px; + background: #555651 +} + +.ace-merbivore { + background-color: #161616; + color: #E6E1DC +} + +.ace-merbivore .ace_cursor { + color: #FFFFFF +} + +.ace-merbivore .ace_marker-layer .ace_selection { + background: #454545 +} + +.ace-merbivore.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #161616; +} + +.ace-merbivore .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.ace-merbivore .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #404040 +} + +.ace-merbivore .ace_marker-layer .ace_active-line { + background: #333435 +} + +.ace-merbivore .ace_gutter-active-line { + background-color: #333435 +} + +.ace-merbivore .ace_marker-layer .ace_selected-word { + border: 1px solid #454545 +} + +.ace-merbivore .ace_invisible { + color: #404040 +} + +.ace-merbivore .ace_entity.ace_name.ace_tag, +.ace-merbivore .ace_keyword, +.ace-merbivore .ace_meta, +.ace-merbivore .ace_meta.ace_tag, +.ace-merbivore .ace_storage, +.ace-merbivore .ace_support.ace_function { + color: #FC6F09 +} + +.ace-merbivore .ace_constant, +.ace-merbivore .ace_constant.ace_character, +.ace-merbivore .ace_constant.ace_character.ace_escape, +.ace-merbivore .ace_constant.ace_other, +.ace-merbivore .ace_support.ace_type { + color: #1EDAFB +} + +.ace-merbivore .ace_constant.ace_character.ace_escape { + color: #519F50 +} + +.ace-merbivore .ace_constant.ace_language { + color: #FDC251 +} + +.ace-merbivore .ace_constant.ace_library, +.ace-merbivore .ace_string, +.ace-merbivore .ace_support.ace_constant { + color: #8DFF0A +} + +.ace-merbivore .ace_constant.ace_numeric { + color: #58C554 +} + +.ace-merbivore .ace_invalid { + color: #FFFFFF; + background-color: #990000 +} + +.ace-merbivore .ace_fold { + background-color: #FC6F09; + border-color: #E6E1DC +} + +.ace-merbivore .ace_comment { + font-style: italic; + color: #AD2EA4 +} + +.ace-merbivore .ace_entity.ace_other.ace_attribute-name { + color: #FFFF89 +} + +.ace-merbivore .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQFxf3ZXB1df0PAAdsAmERTkEHAAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/merbivore.js b/lib/ace/theme/merbivore.js new file mode 100644 index 00000000..9b29db1c --- /dev/null +++ b/lib/ace/theme/merbivore.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = true; +exports.cssClass = "ace-merbivore"; +exports.cssText = require("../requirejs/text!./merbivore.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/merbivore_soft.css b/lib/ace/theme/merbivore_soft.css new file mode 100644 index 00000000..0d615376 --- /dev/null +++ b/lib/ace/theme/merbivore_soft.css @@ -0,0 +1,110 @@ +.ace-merbivore-soft .ace_gutter { + background: #262424; + color: #E6E1DC +} + +.ace-merbivore-soft .ace_print-margin { + width: 1px; + background: #262424 +} + +.ace-merbivore-soft { + background-color: #1C1C1C; + color: #E6E1DC +} + +.ace-merbivore-soft .ace_cursor { + color: #FFFFFF +} + +.ace-merbivore-soft .ace_marker-layer .ace_selection { + background: #494949 +} + +.ace-merbivore-soft.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #1C1C1C; +} + +.ace-merbivore-soft .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.ace-merbivore-soft .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #404040 +} + +.ace-merbivore-soft .ace_marker-layer .ace_active-line { + background: #333435 +} + +.ace-merbivore-soft .ace_gutter-active-line { + background-color: #333435 +} + +.ace-merbivore-soft .ace_marker-layer .ace_selected-word { + border: 1px solid #494949 +} + +.ace-merbivore-soft .ace_invisible { + color: #404040 +} + +.ace-merbivore-soft .ace_entity.ace_name.ace_tag, +.ace-merbivore-soft .ace_keyword, +.ace-merbivore-soft .ace_meta, +.ace-merbivore-soft .ace_meta.ace_tag, +.ace-merbivore-soft .ace_storage { + color: #FC803A +} + +.ace-merbivore-soft .ace_constant, +.ace-merbivore-soft .ace_constant.ace_character, +.ace-merbivore-soft .ace_constant.ace_character.ace_escape, +.ace-merbivore-soft .ace_constant.ace_other, +.ace-merbivore-soft .ace_support.ace_type { + color: #68C1D8 +} + +.ace-merbivore-soft .ace_constant.ace_character.ace_escape { + color: #B3E5B4 +} + +.ace-merbivore-soft .ace_constant.ace_language { + color: #E1C582 +} + +.ace-merbivore-soft .ace_constant.ace_library, +.ace-merbivore-soft .ace_string, +.ace-merbivore-soft .ace_support.ace_constant { + color: #8EC65F +} + +.ace-merbivore-soft .ace_constant.ace_numeric { + color: #7FC578 +} + +.ace-merbivore-soft .ace_invalid, +.ace-merbivore-soft .ace_invalid.ace_deprecated { + color: #FFFFFF; + background-color: #FE3838 +} + +.ace-merbivore-soft .ace_fold { + background-color: #FC803A; + border-color: #E6E1DC +} + +.ace-merbivore-soft .ace_comment, +.ace-merbivore-soft .ace_meta { + font-style: italic; + color: #AC4BB8 +} + +.ace-merbivore-soft .ace_entity.ace_other.ace_attribute-name { + color: #EAF1A3 +} + +.ace-merbivore-soft .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWOQkpLyZfD09PwPAAfYAnaStpHRAAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/merbivore_soft.js b/lib/ace/theme/merbivore_soft.js new file mode 100644 index 00000000..c0ffd910 --- /dev/null +++ b/lib/ace/theme/merbivore_soft.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = true; +exports.cssClass = "ace-merbivore-soft"; +exports.cssText = require("../requirejs/text!./merbivore_soft.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/mono_industrial.css b/lib/ace/theme/mono_industrial.css new file mode 100644 index 00000000..6630e4a2 --- /dev/null +++ b/lib/ace/theme/mono_industrial.css @@ -0,0 +1,125 @@ +.ace-mono-industrial .ace_gutter { + background: #1d2521; + color: #C5C9C9 +} + +.ace-mono-industrial .ace_print-margin { + width: 1px; + background: #555651 +} + +.ace-mono-industrial { + background-color: #222C28; + color: #FFFFFF +} + +.ace-mono-industrial .ace_cursor { + color: #FFFFFF +} + +.ace-mono-industrial .ace_marker-layer .ace_selection { + background: rgba(145, 153, 148, 0.40) +} + +.ace-mono-industrial.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #222C28; +} + +.ace-mono-industrial .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.ace-mono-industrial .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgba(102, 108, 104, 0.50) +} + +.ace-mono-industrial .ace_marker-layer .ace_active-line { + background: rgba(12, 13, 12, 0.25) +} + +.ace-mono-industrial .ace_gutter-active-line { + background-color: rgba(12, 13, 12, 0.25) +} + +.ace-mono-industrial .ace_marker-layer .ace_selected-word { + border: 1px solid rgba(145, 153, 148, 0.40) +} + +.ace-mono-industrial .ace_invisible { + color: rgba(102, 108, 104, 0.50) +} + +.ace-mono-industrial .ace_string { + background-color: #151C19; + color: #FFFFFF +} + +.ace-mono-industrial .ace_keyword, +.ace-mono-industrial .ace_meta { + color: #A39E64 +} + +.ace-mono-industrial .ace_constant, +.ace-mono-industrial .ace_constant.ace_character, +.ace-mono-industrial .ace_constant.ace_character.ace_escape, +.ace-mono-industrial .ace_constant.ace_numeric, +.ace-mono-industrial .ace_constant.ace_other { + color: #E98800 +} + +.ace-mono-industrial .ace_entity.ace_name.ace_function, +.ace-mono-industrial .ace_keyword.ace_operator, +.ace-mono-industrial .ace_variable { + color: #A8B3AB +} + +.ace-mono-industrial .ace_invalid { + color: #FFFFFF; + background-color: rgba(153, 0, 0, 0.68) +} + +.ace-mono-industrial .ace_support.ace_constant { + color: #C87500 +} + +.ace-mono-industrial .ace_fold { + background-color: #A8B3AB; + border-color: #FFFFFF +} + +.ace-mono-industrial .ace_support.ace_function { + color: #588E60 +} + +.ace-mono-industrial .ace_entity.ace_name, +.ace-mono-industrial .ace_support.ace_class, +.ace-mono-industrial .ace_support.ace_type { + color: #5778B6 +} + +.ace-mono-industrial .ace_storage { + color: #C23B00 +} + +.ace-mono-industrial .ace_variable.ace_language, +.ace-mono-industrial .ace_variable.ace_parameter { + color: #648BD2 +} + +.ace-mono-industrial .ace_comment { + color: #666C68; + background-color: #151C19 +} + +.ace-mono-industrial .ace_entity.ace_other.ace_attribute-name { + color: #909993 +} + +.ace-mono-industrial .ace_entity.ace_name.ace_tag { + color: #A65EFF +} + +.ace-mono-industrial .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQ1NbwZfALD/4PAAlTArlEC4r/AAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/mono_industrial.js b/lib/ace/theme/mono_industrial.js index 04e1843d..cf0d0e48 100644 --- a/lib/ace/theme/mono_industrial.js +++ b/lib/ace/theme/mono_industrial.js @@ -1,197 +1,39 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { - var dom = require("pilot/dom"); +exports.isDark = true; +exports.cssClass = "ace-mono-industrial"; +exports.cssText = require("../requirejs/text!./mono_industrial.css"); - var cssText = ".ace-mono-industrial .ace_editor {\ - border: 2px solid rgb(159, 159, 159);\ -}\ -\ -.ace-mono-industrial .ace_editor.ace_focus {\ - border: 2px solid #327fbd;\ -}\ -\ -.ace-mono-industrial .ace_gutter {\ - width: 50px;\ - background: #e8e8e8;\ - color: #333;\ - overflow : hidden;\ -}\ -\ -.ace-mono-industrial .ace_gutter-layer {\ - width: 100%;\ - text-align: right;\ -}\ -\ -.ace-mono-industrial .ace_gutter-layer .ace_gutter-cell {\ - padding-right: 6px;\ -}\ -\ -.ace-mono-industrial .ace_print_margin {\ - width: 1px;\ - background: #e8e8e8;\ -}\ -\ -.ace-mono-industrial .ace_scroller {\ - background-color: #222C28;\ -}\ -\ -.ace-mono-industrial .ace_text-layer {\ - cursor: text;\ - color: #FFFFFF;\ -}\ -\ -.ace-mono-industrial .ace_cursor {\ - border-left: 2px solid #FFFFFF;\ -}\ -\ -.ace-mono-industrial .ace_cursor.ace_overwrite {\ - border-left: 0px;\ - border-bottom: 1px solid #FFFFFF;\ -}\ - \ -.ace-mono-industrial .ace_marker-layer .ace_selection {\ - background: rgba(145, 153, 148, 0.40);\ -}\ -\ -.ace-mono-industrial .ace_marker-layer .ace_step {\ - background: rgb(198, 219, 174);\ -}\ -\ -.ace-mono-industrial .ace_marker-layer .ace_bracket {\ - margin: -1px 0 0 -1px;\ - border: 1px solid rgba(102, 108, 104, 0.50);\ -}\ -\ -.ace-mono-industrial .ace_marker-layer .ace_active_line {\ - background: rgba(12, 13, 12, 0.25);\ -}\ -\ - \ -.ace-mono-industrial .ace_invisible {\ - color: rgba(102, 108, 104, 0.50);\ -}\ -\ -.ace-mono-industrial .ace_keyword {\ - color:#A39E64;\ -}\ -\ -.ace-mono-industrial .ace_keyword.ace_operator {\ - color:#A8B3AB;\ -}\ -\ -.ace-mono-industrial .ace_constant {\ - color:#E98800;\ -}\ -\ -.ace-mono-industrial .ace_constant.ace_language {\ - \ -}\ -\ -.ace-mono-industrial .ace_constant.ace_library {\ - \ -}\ -\ -.ace-mono-industrial .ace_constant.ace_numeric {\ - color:#E98800;\ -}\ -\ -.ace-mono-industrial .ace_invalid {\ - color:#FFFFFF;\ -background-color:rgba(153, 0, 0, 0.68);\ -}\ -\ -.ace-mono-industrial .ace_invalid.ace_illegal {\ - \ -}\ -\ -.ace-mono-industrial .ace_invalid.ace_deprecated {\ - \ -}\ -\ -.ace-mono-industrial .ace_support {\ - \ -}\ -\ -.ace-mono-industrial .ace_support.ace_function {\ - color:#588E60;\ -}\ -\ -.ace-mono-industrial .ace_function.ace_buildin {\ - \ -}\ -\ -.ace-mono-industrial .ace_string {\ - \ -}\ -\ -.ace-mono-industrial .ace_string.ace_regexp {\ - \ -}\ -\ -.ace-mono-industrial .ace_comment {\ - color:#666C68;\ -background-color:#151C19;\ -}\ -\ -.ace-mono-industrial .ace_comment.ace_doc {\ - \ -}\ -\ -.ace-mono-industrial .ace_comment.ace_doc.ace_tag {\ - \ -}\ -\ -.ace-mono-industrial .ace_variable {\ - \ -}\ -\ -.ace-mono-industrial .ace_variable.ace_language {\ - color:#648BD2;\ -}\ -\ -.ace-mono-industrial .ace_xml_pe {\ - \ -}"; - - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "ace-mono-industrial"; -}); \ No newline at end of file +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/monokai.css b/lib/ace/theme/monokai.css new file mode 100644 index 00000000..bcc26ef4 --- /dev/null +++ b/lib/ace/theme/monokai.css @@ -0,0 +1,121 @@ +.ace-monokai .ace_gutter { + background: #2F3129; + color: #8F908A +} + +.ace-monokai .ace_print-margin { + width: 1px; + background: #555651 +} + +.ace-monokai { + background-color: #272822; + color: #F8F8F2 +} + +.ace-monokai .ace_cursor { + color: #F8F8F0 +} + +.ace-monokai .ace_marker-layer .ace_selection { + background: #49483E +} + +.ace-monokai.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #272822; +} + +.ace-monokai .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.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: #202020 +} + +.ace-monokai .ace_gutter-active-line { + background-color: #272727 +} + +.ace-monokai .ace_marker-layer .ace_selected-word { + border: 1px solid #49483E +} + +.ace-monokai .ace_invisible { + color: #52524d +} + +.ace-monokai .ace_entity.ace_name.ace_tag, +.ace-monokai .ace_keyword, +.ace-monokai .ace_meta.ace_tag, +.ace-monokai .ace_storage { + color: #F92672 +} + +.ace-monokai .ace_punctuation, +.ace-monokai .ace_punctuation.ace_tag { + color: #fff +} + +.ace-monokai .ace_constant.ace_character, +.ace-monokai .ace_constant.ace_language, +.ace-monokai .ace_constant.ace_numeric, +.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, +.ace-monokai .ace_support.ace_function { + color: #66D9EF +} + +.ace-monokai .ace_fold { + background-color: #A6E22E; + border-color: #F8F8F2 +} + +.ace-monokai .ace_storage.ace_type, +.ace-monokai .ace_support.ace_class, +.ace-monokai .ace_support.ace_type { + font-style: italic; + color: #66D9EF +} + +.ace-monokai .ace_entity.ace_name.ace_function, +.ace-monokai .ace_entity.ace_other, +.ace-monokai .ace_entity.ace_other.ace_attribute-name, +.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_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ0FD0ZXBzd/wPAAjVAoxeSgNeAAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/monokai.js b/lib/ace/theme/monokai.js index 17d1d395..87d07786 100644 --- a/lib/ace/theme/monokai.js +++ b/lib/ace/theme/monokai.js @@ -1,197 +1,39 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { - var dom = require("pilot/dom"); +exports.isDark = true; +exports.cssClass = "ace-monokai"; +exports.cssText = require("../requirejs/text!./monokai.css"); - var 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 {\ - width: 50px;\ - background: #e8e8e8;\ - color: #333;\ - overflow : hidden;\ -}\ -\ -.ace-monokai .ace_gutter-layer {\ - width: 100%;\ - text-align: right;\ -}\ -\ -.ace-monokai .ace_gutter-layer .ace_gutter-cell {\ - padding-right: 6px;\ -}\ -\ -.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 .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_invisible {\ - color: #49483E;\ -}\ -\ -.ace-monokai .ace_keyword {\ - color:#F92672;\ -}\ -\ -.ace-monokai .ace_keyword.ace_operator {\ - \ -}\ -\ -.ace-monokai .ace_constant {\ - \ -}\ -\ -.ace-monokai .ace_constant.ace_language {\ - color:#AE81FF;\ -}\ -\ -.ace-monokai .ace_constant.ace_library {\ - \ -}\ -\ -.ace-monokai .ace_constant.ace_numeric {\ - color:#AE81FF;\ -}\ -\ -.ace-monokai .ace_invalid {\ - color:#F8F8F0;\ -background-color:#F92672;\ -}\ -\ -.ace-monokai .ace_invalid.ace_illegal {\ - \ -}\ -\ -.ace-monokai .ace_invalid.ace_deprecated {\ - color:#F8F8F0;\ -background-color:#AE81FF;\ -}\ -\ -.ace-monokai .ace_support {\ - \ -}\ -\ -.ace-monokai .ace_support.ace_function {\ - color:#66D9EF;\ -}\ -\ -.ace-monokai .ace_function.ace_buildin {\ - \ -}\ -\ -.ace-monokai .ace_string {\ - color:#E6DB74;\ -}\ -\ -.ace-monokai .ace_string.ace_regexp {\ - \ -}\ -\ -.ace-monokai .ace_comment {\ - color:#75715E;\ -}\ -\ -.ace-monokai .ace_comment.ace_doc {\ - \ -}\ -\ -.ace-monokai .ace_comment.ace_doc.ace_tag {\ - \ -}\ -\ -.ace-monokai .ace_variable {\ - \ -}\ -\ -.ace-monokai .ace_variable.ace_language {\ - \ -}\ -\ -.ace-monokai .ace_xml_pe {\ - \ -}"; - - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "ace-monokai"; -}); \ No newline at end of file +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/pastel_on_dark.css b/lib/ace/theme/pastel_on_dark.css new file mode 100644 index 00000000..0b637174 --- /dev/null +++ b/lib/ace/theme/pastel_on_dark.css @@ -0,0 +1,128 @@ +.ace-pastel-on-dark .ace_gutter { + background: #353030; + color: #8F938F +} + +.ace-pastel-on-dark .ace_print-margin { + width: 1px; + background: #353030 +} + +.ace-pastel-on-dark { + background-color: #2C2828; + color: #8F938F +} + +.ace-pastel-on-dark .ace_cursor { + color: #A7A7A7 +} + +.ace-pastel-on-dark .ace_marker-layer .ace_selection { + background: rgba(221, 240, 255, 0.20) +} + +.ace-pastel-on-dark.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #2C2828; +} + +.ace-pastel-on-dark .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.ace-pastel-on-dark .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgba(255, 255, 255, 0.25) +} + +.ace-pastel-on-dark .ace_marker-layer .ace_active-line { + background: rgba(255, 255, 255, 0.031) +} + +.ace-pastel-on-dark .ace_gutter-active-line { + background-color: rgba(255, 255, 255, 0.031) +} + +.ace-pastel-on-dark .ace_marker-layer .ace_selected-word { + border: 1px solid rgba(221, 240, 255, 0.20) +} + +.ace-pastel-on-dark .ace_invisible { + color: rgba(255, 255, 255, 0.25) +} + +.ace-pastel-on-dark .ace_keyword, +.ace-pastel-on-dark .ace_meta { + color: #757aD8 +} + +.ace-pastel-on-dark .ace_constant, +.ace-pastel-on-dark .ace_constant.ace_character, +.ace-pastel-on-dark .ace_constant.ace_character.ace_escape, +.ace-pastel-on-dark .ace_constant.ace_other { + color: #4FB7C5 +} + +.ace-pastel-on-dark .ace_keyword.ace_operator { + color: #797878 +} + +.ace-pastel-on-dark .ace_constant.ace_character { + color: #AFA472 +} + +.ace-pastel-on-dark .ace_constant.ace_language { + color: #DE8E30 +} + +.ace-pastel-on-dark .ace_constant.ace_numeric { + color: #CCCCCC +} + +.ace-pastel-on-dark .ace_invalid, +.ace-pastel-on-dark .ace_invalid.ace_illegal { + color: #F8F8F8; + background-color: rgba(86, 45, 86, 0.75) +} + +.ace-pastel-on-dark .ace_invalid.ace_deprecated { + text-decoration: underline; + font-style: italic; + color: #D2A8A1 +} + +.ace-pastel-on-dark .ace_fold { + background-color: #757aD8; + border-color: #8F938F +} + +.ace-pastel-on-dark .ace_support.ace_function { + color: #AEB2F8 +} + +.ace-pastel-on-dark .ace_string { + color: #66A968 +} + +.ace-pastel-on-dark .ace_string.ace_regexp { + color: #E9C062 +} + +.ace-pastel-on-dark .ace_comment { + color: #A6C6FF +} + +.ace-pastel-on-dark .ace_variable { + color: #BEBF55 +} + +.ace-pastel-on-dark .ace_variable.ace_language { + color: #C1C144 +} + +.ace-pastel-on-dark .ace_xml-pe { + color: #494949 +} + +.ace-pastel-on-dark .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYIiPj/8PAARgAh2NTMh8AAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/pastel_on_dark.js b/lib/ace/theme/pastel_on_dark.js index 2c5b49a2..6eea03a4 100644 --- a/lib/ace/theme/pastel_on_dark.js +++ b/lib/ace/theme/pastel_on_dark.js @@ -1,198 +1,39 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * André Fiedler - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { - var dom = require("pilot/dom"); +exports.isDark = true; +exports.cssClass = "ace-pastel-on-dark"; +exports.cssText = require("../requirejs/text!./pastel_on_dark.css"); - var cssText = ".ace-pastel-on-dark .ace_editor {\ - border: 2px solid rgb(159, 159, 159);\ -}\ -\ -.ace-pastel-on-dark .ace_editor.ace_focus {\ - border: 2px solid #327fbd;\ -}\ -\ -.ace-pastel-on-dark .ace_gutter {\ - width: 50px;\ - background: #e8e8e8;\ - color: #333;\ - overflow : hidden;\ -}\ -\ -.ace-pastel-on-dark .ace_gutter-layer {\ - width: 100%;\ - text-align: right;\ -}\ -\ -.ace-pastel-on-dark .ace_gutter-layer .ace_gutter-cell {\ - padding-right: 6px;\ -}\ -\ -.ace-pastel-on-dark .ace_print_margin {\ - width: 1px;\ - background: #e8e8e8;\ -}\ -\ -.ace-pastel-on-dark .ace_scroller {\ - background-color: #2c2828;\ -}\ -\ -.ace-pastel-on-dark .ace_text-layer {\ - cursor: text;\ - color: #8f938f;\ -}\ -\ -.ace-pastel-on-dark .ace_cursor {\ - border-left: 2px solid #A7A7A7;\ -}\ -\ -.ace-pastel-on-dark .ace_cursor.ace_overwrite {\ - border-left: 0px;\ - border-bottom: 1px solid #A7A7A7;\ -}\ - \ -.ace-pastel-on-dark .ace_marker-layer .ace_selection {\ - background: rgba(221, 240, 255, 0.20);\ -}\ -\ -.ace-pastel-on-dark .ace_marker-layer .ace_step {\ - background: rgb(198, 219, 174);\ -}\ -\ -.ace-pastel-on-dark .ace_marker-layer .ace_bracket {\ - margin: -1px 0 0 -1px;\ - border: 1px solid rgba(255, 255, 255, 0.25);\ -}\ -\ -.ace-pastel-on-dark .ace_marker-layer .ace_active_line {\ - background: rgba(255, 255, 255, 0.031);\ -}\ -\ - \ -.ace-pastel-on-dark .ace_invisible {\ - color: rgba(255, 255, 255, 0.25);\ -}\ -\ -.ace-pastel-on-dark .ace_keyword {\ - color:#757ad8;\ -}\ -\ -.ace-pastel-on-dark .ace_keyword.ace_operator {\ - color:#797878;\ -}\ -\ -.ace-pastel-on-dark .ace_constant {\ - color:#4fb7c5;\ -}\ -\ -.ace-pastel-on-dark .ace_constant.ace_language {\ - \ -}\ -\ -.ace-pastel-on-dark .ace_constant.ace_library {\ - \ -}\ -\ -.ace-pastel-on-dark .ace_constant.ace_numeric {\ - \ -}\ -\ -.ace-pastel-on-dark .ace_invalid {\ - \ -}\ -\ -.ace-pastel-on-dark .ace_invalid.ace_illegal {\ - color:#F8F8F8;\ -background-color:rgba(86, 45, 86, 0.75);\ -}\ -\ -.ace-pastel-on-dark .ace_invalid.ace_deprecated {\ - text-decoration:underline;\ -font-style:italic;\ -color:#D2A8A1;\ -}\ -\ -.ace-pastel-on-dark .ace_support {\ - color:#9a9a9a;\ -}\ -\ -.ace-pastel-on-dark .ace_support.ace_function {\ - color:#aeb2f8;\ -}\ -\ -.ace-pastel-on-dark .ace_function.ace_buildin {\ - \ -}\ -\ -.ace-pastel-on-dark .ace_string {\ - color:#66a968;\ -}\ -\ -.ace-pastel-on-dark .ace_string.ace_regexp {\ - color:#E9C062;\ -}\ -\ -.ace-pastel-on-dark .ace_comment {\ - color:#656865;\ -}\ -\ -.ace-pastel-on-dark .ace_comment.ace_doc {\ - color:A6C6FF;\ -}\ -\ -.ace-pastel-on-dark .ace_comment.ace_doc.ace_tag {\ - color:A6C6FF;\ -}\ -\ -.ace-pastel-on-dark .ace_variable {\ - color:#bebf55;\ -}\ -\ -.ace-pastel-on-dark .ace_variable.ace_language {\ - color:#bebf55;\ -}\ -\ -.ace-pastel-on-dark .ace_xml_pe {\ - color:#494949;\ -}"; - - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "ace-pastel-on-dark"; +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); }); diff --git a/lib/ace/theme/solarized_dark.css b/lib/ace/theme/solarized_dark.css new file mode 100644 index 00000000..09740e69 --- /dev/null +++ b/lib/ace/theme/solarized_dark.css @@ -0,0 +1,100 @@ +.ace-solarized-dark .ace_gutter { + background: #01313f; + color: #d0edf7 +} + +.ace-solarized-dark .ace_print-margin { + width: 1px; + background: #33555E +} + +.ace-solarized-dark { + background-color: #002B36; + color: #93A1A1 +} + +.ace-solarized-dark .ace_entity.ace_other.ace_attribute-name, +.ace-solarized-dark .ace_storage { + color: #93A1A1 +} + +.ace-solarized-dark .ace_cursor, +.ace-solarized-dark .ace_string.ace_regexp { + color: #D30102 +} + +.ace-solarized-dark .ace_marker-layer .ace_active-line, +.ace-solarized-dark .ace_marker-layer .ace_selection { + background: rgba(255, 255, 255, 0.1) +} + +.ace-solarized-dark.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #002B36; +} + +.ace-solarized-dark .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.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_gutter-active-line { + background-color: #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, +.ace-solarized-dark .ace_support.ace_class, +.ace-solarized-dark .ace_support.ace_type { + color: #859900 +} + +.ace-solarized-dark .ace_constant.ace_character, +.ace-solarized-dark .ace_constant.ace_other { + color: #CB4B16 +} + +.ace-solarized-dark .ace_constant.ace_language { + color: #B58900 +} + +.ace-solarized-dark .ace_constant.ace_numeric { + color: #D33682 +} + +.ace-solarized-dark .ace_fold { + background-color: #268BD2; + border-color: #93A1A1 +} + +.ace-solarized-dark .ace_entity.ace_name.ace_function, +.ace-solarized-dark .ace_entity.ace_name.ace_tag, +.ace-solarized-dark .ace_support.ace_function, +.ace-solarized-dark .ace_variable, +.ace-solarized-dark .ace_variable.ace_language { + color: #268BD2 +} + +.ace-solarized-dark .ace_string { + color: #2AA198 +} + +.ace-solarized-dark .ace_comment { + font-style: italic; + color: #657B83 +} + +.ace-solarized-dark .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNg0Db1ZVCxc/sPAAd4AlUHlLenAAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/solarized_dark.js b/lib/ace/theme/solarized_dark.js new file mode 100644 index 00000000..71812c28 --- /dev/null +++ b/lib/ace/theme/solarized_dark.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = true; +exports.cssClass = "ace-solarized-dark"; +exports.cssText = require("../requirejs/text!./solarized_dark.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/solarized_light.css b/lib/ace/theme/solarized_light.css new file mode 100644 index 00000000..65399fda --- /dev/null +++ b/lib/ace/theme/solarized_light.css @@ -0,0 +1,105 @@ +.ace-solarized-light .ace_gutter { + background: #fbf1d3; + color: #333 +} + +.ace-solarized-light .ace_print-margin { + width: 1px; + background: #e8e8e8 +} + +.ace-solarized-light { + background-color: #FDF6E3; + color: #586E75 +} + +.ace-solarized-light .ace_cursor { + color: #000000 +} + +.ace-solarized-light .ace_marker-layer .ace_selection { + background: rgba(7, 54, 67, 0.09) +} + +.ace-solarized-light.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #FDF6E3; +} + +.ace-solarized-light .ace_marker-layer .ace_step { + background: rgb(255, 255, 0) +} + +.ace-solarized-light .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgba(147, 161, 161, 0.50) +} + +.ace-solarized-light .ace_marker-layer .ace_active-line { + background: #EEE8D5 +} + +.ace-solarized-light .ace_gutter-active-line { + background-color : #EDE5C1 +} + +.ace-solarized-light .ace_marker-layer .ace_selected-word { + border: 1px solid #073642 +} + +.ace-solarized-light .ace_invisible { + color: rgba(147, 161, 161, 0.50) +} + +.ace-solarized-light .ace_keyword, +.ace-solarized-light .ace_meta, +.ace-solarized-light .ace_support.ace_class, +.ace-solarized-light .ace_support.ace_type { + color: #859900 +} + +.ace-solarized-light .ace_constant.ace_character, +.ace-solarized-light .ace_constant.ace_other { + color: #CB4B16 +} + +.ace-solarized-light .ace_constant.ace_language { + color: #B58900 +} + +.ace-solarized-light .ace_constant.ace_numeric { + color: #D33682 +} + +.ace-solarized-light .ace_fold { + background-color: #268BD2; + border-color: #586E75 +} + +.ace-solarized-light .ace_entity.ace_name.ace_function, +.ace-solarized-light .ace_entity.ace_name.ace_tag, +.ace-solarized-light .ace_support.ace_function, +.ace-solarized-light .ace_variable, +.ace-solarized-light .ace_variable.ace_language { + color: #268BD2 +} + +.ace-solarized-light .ace_storage { + color: #073642 +} + +.ace-solarized-light .ace_string { + color: #2AA198 +} + +.ace-solarized-light .ace_string.ace_regexp { + color: #D30102 +} + +.ace-solarized-light .ace_comment, +.ace-solarized-light .ace_entity.ace_other.ace_attribute-name { + color: #93A1A1 +} + +.ace-solarized-light .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHjy8NJ/AAjgA5fzQUmBAAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/solarized_light.js b/lib/ace/theme/solarized_light.js new file mode 100644 index 00000000..35ec219e --- /dev/null +++ b/lib/ace/theme/solarized_light.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = false; +exports.cssClass = "ace-solarized-light"; +exports.cssText = require("../requirejs/text!./solarized_light.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/sqlserver.css b/lib/ace/theme/sqlserver.css new file mode 100644 index 00000000..ff6d1e1c --- /dev/null +++ b/lib/ace/theme/sqlserver.css @@ -0,0 +1,171 @@ +.ace_line { + font-family: Consolas; +} + +.ace-sqlserver .ace_gutter { + background: #ebebeb; + color: #333; + overflow: hidden; +} + +.ace-sqlserver .ace_print-margin { + width: 1px; + background: #e8e8e8; +} + +.ace-sqlserver { + background-color: #FFFFFF; + color: black; +} + +.ace-sqlserver .ace_identifier { + color: black; +} + +.ace-sqlserver .ace_keyword { + color: #0000FF; +} + +.ace-sqlserver .ace_numeric { + color: black; +} + +.ace-sqlserver .ace_storage { + color: #11B7BE; +} + +.ace-sqlserver .ace_keyword.ace_operator, +.ace-sqlserver .ace_lparen, +.ace-sqlserver .ace_rparen, +.ace-sqlserver .ace_punctuation { + color: #808080; +} + +.ace-sqlserver .ace_set.ace_statement { + color: #0000FF; + text-decoration: underline; +} + +.ace-sqlserver .ace_cursor { + color: black; +} + +.ace-sqlserver .ace_invisible { + color: rgb(191, 191, 191); +} + +.ace-sqlserver .ace_constant.ace_buildin { + color: rgb(88, 72, 246); +} + +.ace-sqlserver .ace_constant.ace_language { + color: #979797; +} + +.ace-sqlserver .ace_constant.ace_library { + color: rgb(6, 150, 14); +} + +.ace-sqlserver .ace_invalid { + background-color: rgb(153, 0, 0); + color: white; +} + +.ace-sqlserver .ace_support.ace_function { + color: #FF00FF; +} + +.ace-sqlserver .ace_support.ace_constant { + color: rgb(6, 150, 14); +} + +.ace-sqlserver .ace_class { + color: #008080; +} + +.ace-sqlserver .ace_support.ace_other { + color: #6D79DE; +} + +.ace-sqlserver .ace_variable.ace_parameter { + font-style: italic; + color: #FD971F; +} + +.ace-sqlserver .ace_comment { + color: #008000; +} + +.ace-sqlserver .ace_constant.ace_numeric { + color: black; +} + +.ace-sqlserver .ace_variable { + color: rgb(49, 132, 149); +} + +.ace-sqlserver .ace_xml-pe { + color: rgb(104, 104, 91); +} + +.ace-sqlserver .ace_support.ace_storedprocedure { + color: #800000; +} + +.ace-sqlserver .ace_heading { + color: rgb(12, 7, 255); +} + +.ace-sqlserver .ace_list { + color: rgb(185, 6, 144); +} + +.ace-sqlserver .ace_marker-layer .ace_selection { + background: rgb(181, 213, 255); +} + +.ace-sqlserver .ace_marker-layer .ace_step { + background: rgb(252, 255, 0); +} + +.ace-sqlserver .ace_marker-layer .ace_stack { + background: rgb(164, 229, 101); +} + +.ace-sqlserver .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgb(192, 192, 192); +} + +.ace-sqlserver .ace_marker-layer .ace_active-line { + background: rgba(0, 0, 0, 0.07); +} + +.ace-sqlserver .ace_gutter-active-line { + background-color: #dcdcdc; +} + +.ace-sqlserver .ace_marker-layer .ace_selected-word { + background: rgb(250, 250, 255); + border: 1px solid rgb(200, 200, 250); +} + +.ace-sqlserver .ace_meta.ace_tag { + color: #0000FF; +} + +.ace-sqlserver .ace_string.ace_regex { + color: #FF0000; +} + +.ace-sqlserver .ace_string { + color: #FF0000; +} + +.ace-sqlserver .ace_entity.ace_other.ace_attribute-name { + color: #994409; +} + +.ace-sqlserver .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; +} diff --git a/lib/ace/theme/sqlserver.js b/lib/ace/theme/sqlserver.js new file mode 100644 index 00000000..ab657483 --- /dev/null +++ b/lib/ace/theme/sqlserver.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = false; +exports.cssClass = "ace-sqlserver"; +exports.cssText = require("../requirejs/text!./sqlserver.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/terminal.css b/lib/ace/theme/terminal.css new file mode 100644 index 00000000..f23a9ad6 --- /dev/null +++ b/lib/ace/theme/terminal.css @@ -0,0 +1,131 @@ +.ace-terminal-theme .ace_gutter { + background: #1a0005; + color: steelblue +} + +.ace-terminal-theme .ace_print-margin { + width: 1px; + background: #1a1a1a +} + +.ace-terminal-theme { + background-color: black; + color: #DEDEDE +} + +.ace-terminal-theme .ace_cursor { + color: #9F9F9F +} + +.ace-terminal-theme .ace_marker-layer .ace_selection { + background: #424242 +} + +.ace-terminal-theme.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px black; +} + +.ace-terminal-theme .ace_marker-layer .ace_step { + background: rgb(0, 0, 0) +} + +.ace-terminal-theme .ace_marker-layer .ace_bracket { + background: #090; +} + +.ace-terminal-theme .ace_marker-layer .ace_bracket-start { + background: #090; +} + +.ace-terminal-theme .ace_marker-layer .ace_bracket-unmatched { + margin: -1px 0 0 -1px; + border: 1px solid #900 +} + +.ace-terminal-theme .ace_marker-layer .ace_active-line { + background: #2A2A2A +} + +.ace-terminal-theme .ace_gutter-active-line { + background-color: #2A112A +} + +.ace-terminal-theme .ace_marker-layer .ace_selected-word { + border: 1px solid #424242 +} + +.ace-terminal-theme .ace_invisible { + color: #343434 +} + +.ace-terminal-theme .ace_keyword, +.ace-terminal-theme .ace_meta, +.ace-terminal-theme .ace_storage, +.ace-terminal-theme .ace_storage.ace_type, +.ace-terminal-theme .ace_support.ace_type { + color: tomato +} + +.ace-terminal-theme .ace_keyword.ace_operator { + color: deeppink +} + +.ace-terminal-theme .ace_constant.ace_character, +.ace-terminal-theme .ace_constant.ace_language, +.ace-terminal-theme .ace_constant.ace_numeric, +.ace-terminal-theme .ace_keyword.ace_other.ace_unit, +.ace-terminal-theme .ace_support.ace_constant, +.ace-terminal-theme .ace_variable.ace_parameter { + color: #E78C45 +} + +.ace-terminal-theme .ace_constant.ace_other { + color: gold +} + +.ace-terminal-theme .ace_invalid { + color: yellow; + background-color: red +} + +.ace-terminal-theme .ace_invalid.ace_deprecated { + color: #CED2CF; + background-color: #B798BF +} + +.ace-terminal-theme .ace_fold { + background-color: #7AA6DA; + border-color: #DEDEDE +} + +.ace-terminal-theme .ace_entity.ace_name.ace_function, +.ace-terminal-theme .ace_support.ace_function, +.ace-terminal-theme .ace_variable { + color: #7AA6DA +} + +.ace-terminal-theme .ace_support.ace_class, +.ace-terminal-theme .ace_support.ace_type { + color: #E7C547 +} + +.ace-terminal-theme .ace_heading, +.ace-terminal-theme .ace_string { + color: #B9CA4A +} + +.ace-terminal-theme .ace_entity.ace_name.ace_tag, +.ace-terminal-theme .ace_entity.ace_other.ace_attribute-name, +.ace-terminal-theme .ace_meta.ace_tag, +.ace-terminal-theme .ace_string.ace_regexp, +.ace-terminal-theme .ace_variable { + color: #D54E53 +} + +.ace-terminal-theme .ace_comment { + color: orangered +} + +.ace-terminal-theme .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYLBWV/8PAAK4AYnhiq+xAAAAAElFTkSuQmCC) right repeat-y; +} diff --git a/lib/ace/theme/terminal.js b/lib/ace/theme/terminal.js new file mode 100644 index 00000000..d7ff36ae --- /dev/null +++ b/lib/ace/theme/terminal.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = true; +exports.cssClass = "ace-terminal-theme"; +exports.cssText = require("../requirejs/text!./terminal.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/textmate.css b/lib/ace/theme/textmate.css new file mode 100644 index 00000000..18e2b4ee --- /dev/null +++ b/lib/ace/theme/textmate.css @@ -0,0 +1,154 @@ +.ace-tm .ace_gutter { + background: #f0f0f0; + color: #333; +} + +.ace-tm .ace_print-margin { + width: 1px; + background: #e8e8e8; +} + +.ace-tm .ace_fold { + background-color: #6B72E6; +} + +.ace-tm { + background-color: #FFFFFF; + color: black; +} + +.ace-tm .ace_cursor { + color: black; +} + +.ace-tm .ace_invisible { + color: rgb(191, 191, 191); +} + +.ace-tm .ace_storage, +.ace-tm .ace_keyword { + color: blue; +} + +.ace-tm .ace_constant { + color: rgb(197, 6, 11); +} + +.ace-tm .ace_constant.ace_buildin { + color: rgb(88, 72, 246); +} + +.ace-tm .ace_constant.ace_language { + color: rgb(88, 92, 246); +} + +.ace-tm .ace_constant.ace_library { + color: rgb(6, 150, 14); +} + +.ace-tm .ace_invalid { + background-color: rgba(255, 0, 0, 0.1); + color: red; +} + +.ace-tm .ace_support.ace_function { + color: rgb(60, 76, 114); +} + +.ace-tm .ace_support.ace_constant { + color: rgb(6, 150, 14); +} + +.ace-tm .ace_support.ace_type, +.ace-tm .ace_support.ace_class { + color: rgb(109, 121, 222); +} + +.ace-tm .ace_keyword.ace_operator { + color: rgb(104, 118, 135); +} + +.ace-tm .ace_string { + color: rgb(3, 106, 7); +} + +.ace-tm .ace_comment { + color: rgb(76, 136, 107); +} + +.ace-tm .ace_comment.ace_doc { + color: rgb(0, 102, 255); +} + +.ace-tm .ace_comment.ace_doc.ace_tag { + color: rgb(128, 159, 191); +} + +.ace-tm .ace_constant.ace_numeric { + color: rgb(0, 0, 205); +} + +.ace-tm .ace_variable { + color: rgb(49, 132, 149); +} + +.ace-tm .ace_xml-pe { + color: rgb(104, 104, 91); +} + +.ace-tm .ace_entity.ace_name.ace_function { + color: #0000A2; +} + + +.ace-tm .ace_heading { + color: rgb(12, 7, 255); +} + +.ace-tm .ace_list { + color:rgb(185, 6, 144); +} + +.ace-tm .ace_meta.ace_tag { + color:rgb(0, 22, 142); +} + +.ace-tm .ace_string.ace_regex { + color: rgb(255, 0, 0) +} + +.ace-tm .ace_marker-layer .ace_selection { + background: rgb(181, 213, 255); +} +.ace-tm.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px white; +} +.ace-tm .ace_marker-layer .ace_step { + background: rgb(252, 255, 0); +} + +.ace-tm .ace_marker-layer .ace_stack { + background: rgb(164, 229, 101); +} + +.ace-tm .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgb(192, 192, 192); +} + +.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); + border: 1px solid rgb(200, 200, 250); +} + +.ace-tm .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; +} diff --git a/lib/ace/theme/textmate.js b/lib/ace/theme/textmate.js index 337a8c57..75e19745 100644 --- a/lib/ace/theme/textmate.js +++ b/lib/ace/theme/textmate.js @@ -1,188 +1,40 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; - var dom = require("pilot/dom"); +exports.isDark = false; +exports.cssClass = "ace-tm"; +exports.cssText = require("../requirejs/text!./textmate.css"); - var cssText = ".ace-tm .ace_editor {\ - border: 2px solid rgb(159, 159, 159);\ -}\ -\ -.ace-tm .ace_editor.ace_focus {\ - border: 2px solid #327fbd;\ -}\ -\ -.ace-tm .ace_gutter {\ - width: 50px;\ - background: #e8e8e8;\ - color: #333;\ - overflow : hidden;\ -}\ -\ -.ace-tm .ace_gutter-layer {\ - width: 100%;\ - text-align: right;\ -}\ -\ -.ace-tm .ace_gutter-layer .ace_gutter-cell {\ - padding-right: 6px;\ -}\ -\ -.ace-tm .ace_print_margin {\ - width: 1px;\ - background: #e8e8e8;\ -}\ -\ -.ace-tm .ace_text-layer {\ - cursor: text;\ -}\ -\ -.ace-tm .ace_cursor {\ - border-left: 2px solid black;\ -}\ -\ -.ace-tm .ace_cursor.ace_overwrite {\ - border-left: 0px;\ - border-bottom: 1px solid black;\ -}\ - \ -.ace-tm .ace_line .ace_invisible {\ - color: rgb(191, 191, 191);\ -}\ -\ -.ace-tm .ace_line .ace_keyword {\ - color: blue;\ -}\ -\ -.ace-tm .ace_line .ace_constant.ace_buildin {\ - color: rgb(88, 72, 246);\ -}\ -\ -.ace-tm .ace_line .ace_constant.ace_language {\ - color: rgb(88, 92, 246);\ -}\ -\ -.ace-tm .ace_line .ace_constant.ace_library {\ - color: rgb(6, 150, 14);\ -}\ -\ -.ace-tm .ace_line .ace_invalid {\ - background-color: rgb(153, 0, 0);\ - color: white;\ -}\ -\ -.ace-tm .ace_line .ace_support.ace_function {\ - color: rgb(60, 76, 114);\ -}\ -\ -.ace-tm .ace_line .ace_support.ace_constant {\ - color: rgb(6, 150, 14);\ -}\ -\ -.ace-tm .ace_line .ace_support.ace_type,\ -.ace-tm .ace_line .ace_support.ace_class {\ - color: rgb(109, 121, 222);\ -}\ -\ -.ace-tm .ace_line .ace_keyword.ace_operator {\ - color: rgb(104, 118, 135);\ -}\ -\ -.ace-tm .ace_line .ace_string {\ - color: rgb(3, 106, 7);\ -}\ -\ -.ace-tm .ace_line .ace_comment {\ - color: rgb(76, 136, 107);\ -}\ -\ -.ace-tm .ace_line .ace_comment.ace_doc {\ - color: rgb(0, 102, 255);\ -}\ -\ -.ace-tm .ace_line .ace_comment.ace_doc.ace_tag {\ - color: rgb(128, 159, 191);\ -}\ -\ -.ace-tm .ace_line .ace_constant.ace_numeric {\ - color: rgb(0, 0, 205);\ -}\ -\ -.ace-tm .ace_line .ace_variable {\ - color: rgb(49, 132, 149);\ -}\ -\ -.ace-tm .ace_line .ace_xml_pe {\ - color: rgb(104, 104, 91);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_selection {\ - background: rgb(181, 213, 255);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_step {\ - background: rgb(252, 255, 0);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_stack {\ - background: rgb(164, 229, 101);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_bracket {\ - margin: -1px 0 0 -1px;\ - border: 1px solid rgb(192, 192, 192);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_active_line {\ - background: rgb(232, 242, 254);\ -}\ -\ -.ace-tm .ace_marker-layer .ace_selected_word {\ - background: rgb(250, 250, 255);\ - border: 1px solid rgb(200, 200, 250);\ -}\ -\ -.ace-tm .ace_string.ace_regex {\ - color: rgb(255, 0, 0)\ -}"; - - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "ace-tm"; +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); }); diff --git a/lib/ace/theme/the_night_after_tomorrow.css b/lib/ace/theme/the_night_after_tomorrow.css new file mode 100644 index 00000000..48d2602c --- /dev/null +++ b/lib/ace/theme/the_night_after_tomorrow.css @@ -0,0 +1,139 @@ +.ace-tomorrow-night .ace_gutter { + background: #25282c; + color: #C5C8C6 +} + +.ace-tomorrow-night .ace_print-margin { + width: 1px; + background: #25282c +} + +.ace-tomorrow-night { + background-color: #1D1F21; + color: #C5C8C6 +} + +.ace-tomorrow-night .ace_cursor { + color: #FFFFFF +} + +.ace-tomorrow-night .ace_marker-layer .ace_selection { + background: #373B41 +} + +.ace-tomorrow-night.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #1D1F21; + border-radius: 2px +} + +.ace-tomorrow-night .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.ace-tomorrow-night .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #4B4E55 +} + +.ace-tomorrow-night .ace_marker-layer .ace_active-line { + background: #282A2E +} + +.ace-tomorrow-night .ace_gutter-active-line { + background-color: #282A2E +} + +.ace-tomorrow-night .ace_marker-layer .ace_selected-word { + border: 1px solid #373B41 +} + +.ace-tomorrow-night .ace_invisible { + color: #4B4E55 +} + +.ace-tomorrow-night .ace_keyword, +.ace-tomorrow-night .ace_meta, +.ace-tomorrow-night .ace_support.ace_type { + color: #C4A400 +} + +.ace-tomorrow-night .ace_storage, +.ace-tomorrow-night .ace_storage.ace_type { + color: #327FD7 +} + +.ace-tomorrow-night .ace_keyword.ace_operator { + color: #8ABEB7 +} + +.ace-tomorrow-night .ace_constant.ace_language{ + color: #934B9F +} + +.ace-tomorrow-night .ace_constant.ace_character, +.ace-tomorrow-night .ace_constant.ace_numeric, +.ace-tomorrow-night .ace_keyword.ace_other.ace_unit, +.ace-tomorrow-night .ace_support.ace_constant, +.ace-tomorrow-night .ace_variable.ace_parameter { + color: #37BC9B +} + +.ace-tomorrow-night .ace_constant.ace_other { + color: #CED1CF +} + +.ace-tomorrow-night .ace_invalid { + color: #CED2CF; + background-color: #DF5F5F +} + +.ace-tomorrow-night .ace_invalid.ace_deprecated { + color: #CED2CF; + background-color: #B798BF +} + +.ace-tomorrow-night .ace_fold { + background-color: #62A5D6; + border-color: #C5C8C6 +} + +.ace-tomorrow-night .ace_entity.ace_name.ace_function, +.ace-tomorrow-night .ace_support.ace_function, +.ace-tomorrow-night .ace_variable { + color: #62A5D6 +} + +.ace-tomorrow-night .ace_support.ace_class, +.ace-tomorrow-night .ace_support.ace_type { + color: #F0C674 +} + +.ace-tomorrow-night .ace_heading, +.ace-tomorrow-night .ace_markup.ace_heading, +.ace-tomorrow-night .ace_string { + color: #CD0000 +} + +.ace-tomorrow-night .ace_proc_name { + color: #04939A +} + +.ace-tomorrow-night .ace_backtick { + color: #1DAA49 +} + +.ace-tomorrow-night .ace_entity.ace_name.ace_tag, +.ace-tomorrow-night .ace_entity.ace_other.ace_attribute-name, +.ace-tomorrow-night .ace_meta.ace_tag, +.ace-tomorrow-night .ace_string.ace_regexp, +.ace-tomorrow-night .ace_variable { + color: #FFFFFF +} + +.ace-tomorrow-night .ace_comment { + color: #3465A4 +} + +.ace-tomorrow-night .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y +} diff --git a/lib/ace/theme/the_night_after_tomorrow.js b/lib/ace/theme/the_night_after_tomorrow.js new file mode 100644 index 00000000..3108e2a9 --- /dev/null +++ b/lib/ace/theme/the_night_after_tomorrow.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = true; +exports.cssClass = "ace-tomorrow-night"; +exports.cssText = require("../requirejs/text!./the_night_after_tomorrow.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/tomorrow.css b/lib/ace/theme/tomorrow.css new file mode 100644 index 00000000..77407e66 --- /dev/null +++ b/lib/ace/theme/tomorrow.css @@ -0,0 +1,124 @@ +.ace-tomorrow .ace_gutter { + background: #f6f6f6; + color: #4D4D4C +} + +.ace-tomorrow .ace_print-margin { + width: 1px; + background: #f6f6f6 +} + +.ace-tomorrow { + background-color: #FFFFFF; + color: #4D4D4C +} + +.ace-tomorrow .ace_cursor { + color: #AEAFAD +} + +.ace-tomorrow .ace_marker-layer .ace_selection { + background: #D6D6D6 +} + +.ace-tomorrow.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #FFFFFF; +} + +.ace-tomorrow .ace_marker-layer .ace_step { + background: rgb(255, 255, 0) +} + +.ace-tomorrow .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #D1D1D1 +} + +.ace-tomorrow .ace_marker-layer .ace_active-line { + background: #EFEFEF +} + +.ace-tomorrow .ace_gutter-active-line { + background-color : #dcdcdc +} + +.ace-tomorrow .ace_marker-layer .ace_selected-word { + border: 1px solid #D6D6D6 +} + +.ace-tomorrow .ace_invisible { + color: #D1D1D1 +} + +.ace-tomorrow .ace_keyword, +.ace-tomorrow .ace_meta, +.ace-tomorrow .ace_storage, +.ace-tomorrow .ace_storage.ace_type, +.ace-tomorrow .ace_support.ace_type { + color: #8959A8 +} + +.ace-tomorrow .ace_keyword.ace_operator { + color: #3E999F +} + +.ace-tomorrow .ace_constant.ace_character, +.ace-tomorrow .ace_constant.ace_language, +.ace-tomorrow .ace_constant.ace_numeric, +.ace-tomorrow .ace_keyword.ace_other.ace_unit, +.ace-tomorrow .ace_support.ace_constant, +.ace-tomorrow .ace_variable.ace_parameter { + color: #F5871F +} + +.ace-tomorrow .ace_constant.ace_other { + color: #666969 +} + +.ace-tomorrow .ace_invalid { + color: #FFFFFF; + background-color: #C82829 +} + +.ace-tomorrow .ace_invalid.ace_deprecated { + color: #FFFFFF; + background-color: #8959A8 +} + +.ace-tomorrow .ace_fold { + background-color: #4271AE; + border-color: #4D4D4C +} + +.ace-tomorrow .ace_entity.ace_name.ace_function, +.ace-tomorrow .ace_support.ace_function, +.ace-tomorrow .ace_variable { + color: #4271AE +} + +.ace-tomorrow .ace_support.ace_class, +.ace-tomorrow .ace_support.ace_type { + color: #C99E00 +} + +.ace-tomorrow .ace_heading, +.ace-tomorrow .ace_markup.ace_heading, +.ace-tomorrow .ace_string { + color: #718C00 +} + +.ace-tomorrow .ace_entity.ace_name.ace_tag, +.ace-tomorrow .ace_entity.ace_other.ace_attribute-name, +.ace-tomorrow .ace_meta.ace_tag, +.ace-tomorrow .ace_string.ace_regexp, +.ace-tomorrow .ace_variable { + color: #C82829 +} + +.ace-tomorrow .ace_comment { + color: #8E908C +} + +.ace-tomorrow .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bdu3f/BwAlfgctduB85QAAAABJRU5ErkJggg==) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/tomorrow.js b/lib/ace/theme/tomorrow.js new file mode 100644 index 00000000..1f02d7d9 --- /dev/null +++ b/lib/ace/theme/tomorrow.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = false; +exports.cssClass = "ace-tomorrow"; +exports.cssText = require("../requirejs/text!./tomorrow.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/tomorrow_night.css b/lib/ace/theme/tomorrow_night.css new file mode 100644 index 00000000..e98a6580 --- /dev/null +++ b/lib/ace/theme/tomorrow_night.css @@ -0,0 +1,124 @@ +.ace-tomorrow-night .ace_gutter { + background: #25282c; + color: #C5C8C6 +} + +.ace-tomorrow-night .ace_print-margin { + width: 1px; + background: #25282c +} + +.ace-tomorrow-night { + background-color: #1D1F21; + color: #C5C8C6 +} + +.ace-tomorrow-night .ace_cursor { + color: #AEAFAD +} + +.ace-tomorrow-night .ace_marker-layer .ace_selection { + background: #373B41 +} + +.ace-tomorrow-night.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #1D1F21; +} + +.ace-tomorrow-night .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.ace-tomorrow-night .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #4B4E55 +} + +.ace-tomorrow-night .ace_marker-layer .ace_active-line { + background: #282A2E +} + +.ace-tomorrow-night .ace_gutter-active-line { + background-color: #282A2E +} + +.ace-tomorrow-night .ace_marker-layer .ace_selected-word { + border: 1px solid #373B41 +} + +.ace-tomorrow-night .ace_invisible { + color: #4B4E55 +} + +.ace-tomorrow-night .ace_keyword, +.ace-tomorrow-night .ace_meta, +.ace-tomorrow-night .ace_storage, +.ace-tomorrow-night .ace_storage.ace_type, +.ace-tomorrow-night .ace_support.ace_type { + color: #B294BB +} + +.ace-tomorrow-night .ace_keyword.ace_operator { + color: #8ABEB7 +} + +.ace-tomorrow-night .ace_constant.ace_character, +.ace-tomorrow-night .ace_constant.ace_language, +.ace-tomorrow-night .ace_constant.ace_numeric, +.ace-tomorrow-night .ace_keyword.ace_other.ace_unit, +.ace-tomorrow-night .ace_support.ace_constant, +.ace-tomorrow-night .ace_variable.ace_parameter { + color: #DE935F +} + +.ace-tomorrow-night .ace_constant.ace_other { + color: #CED1CF +} + +.ace-tomorrow-night .ace_invalid { + color: #CED2CF; + background-color: #DF5F5F +} + +.ace-tomorrow-night .ace_invalid.ace_deprecated { + color: #CED2CF; + background-color: #B798BF +} + +.ace-tomorrow-night .ace_fold { + background-color: #81A2BE; + border-color: #C5C8C6 +} + +.ace-tomorrow-night .ace_entity.ace_name.ace_function, +.ace-tomorrow-night .ace_support.ace_function, +.ace-tomorrow-night .ace_variable { + color: #81A2BE +} + +.ace-tomorrow-night .ace_support.ace_class, +.ace-tomorrow-night .ace_support.ace_type { + color: #F0C674 +} + +.ace-tomorrow-night .ace_heading, +.ace-tomorrow-night .ace_markup.ace_heading, +.ace-tomorrow-night .ace_string { + color: #B5BD68 +} + +.ace-tomorrow-night .ace_entity.ace_name.ace_tag, +.ace-tomorrow-night .ace_entity.ace_other.ace_attribute-name, +.ace-tomorrow-night .ace_meta.ace_tag, +.ace-tomorrow-night .ace_string.ace_regexp, +.ace-tomorrow-night .ace_variable { + color: #CC6666 +} + +.ace-tomorrow-night .ace_comment { + color: #969896 +} + +.ace-tomorrow-night .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/tomorrow_night.js b/lib/ace/theme/tomorrow_night.js new file mode 100644 index 00000000..e7137ffc --- /dev/null +++ b/lib/ace/theme/tomorrow_night.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = true; +exports.cssClass = "ace-tomorrow-night"; +exports.cssText = require("../requirejs/text!./tomorrow_night.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/tomorrow_night_blue.css b/lib/ace/theme/tomorrow_night_blue.css new file mode 100644 index 00000000..907eef35 --- /dev/null +++ b/lib/ace/theme/tomorrow_night_blue.css @@ -0,0 +1,121 @@ +.ace-tomorrow-night-blue .ace_gutter { + background: #00204b; + color: #7388b5 +} + +.ace-tomorrow-night-blue .ace_print-margin { + width: 1px; + background: #00204b +} + +.ace-tomorrow-night-blue { + background-color: #002451; + color: #FFFFFF +} + +.ace-tomorrow-night-blue .ace_constant.ace_other, +.ace-tomorrow-night-blue .ace_cursor { + color: #FFFFFF +} + +.ace-tomorrow-night-blue .ace_marker-layer .ace_selection { + background: #003F8E +} + +.ace-tomorrow-night-blue.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #002451; +} + +.ace-tomorrow-night-blue .ace_marker-layer .ace_step { + background: rgb(127, 111, 19) +} + +.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-color: #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, +.ace-tomorrow-night-blue .ace_storage, +.ace-tomorrow-night-blue .ace_storage.ace_type, +.ace-tomorrow-night-blue .ace_support.ace_type { + color: #EBBBFF +} + +.ace-tomorrow-night-blue .ace_keyword.ace_operator { + color: #99FFFF +} + +.ace-tomorrow-night-blue .ace_constant.ace_character, +.ace-tomorrow-night-blue .ace_constant.ace_language, +.ace-tomorrow-night-blue .ace_constant.ace_numeric, +.ace-tomorrow-night-blue .ace_keyword.ace_other.ace_unit, +.ace-tomorrow-night-blue .ace_support.ace_constant, +.ace-tomorrow-night-blue .ace_variable.ace_parameter { + color: #FFC58F +} + +.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_fold { + background-color: #BBDAFF; + border-color: #FFFFFF +} + +.ace-tomorrow-night-blue .ace_entity.ace_name.ace_function, +.ace-tomorrow-night-blue .ace_support.ace_function, +.ace-tomorrow-night-blue .ace_variable { + color: #BBDAFF +} + +.ace-tomorrow-night-blue .ace_support.ace_class, +.ace-tomorrow-night-blue .ace_support.ace_type { + color: #FFEEAD +} + +.ace-tomorrow-night-blue .ace_heading, +.ace-tomorrow-night-blue .ace_markup.ace_heading, +.ace-tomorrow-night-blue .ace_string { + color: #D1F1A9 +} + +.ace-tomorrow-night-blue .ace_entity.ace_name.ace_tag, +.ace-tomorrow-night-blue .ace_entity.ace_other.ace_attribute-name, +.ace-tomorrow-night-blue .ace_meta.ace_tag, +.ace-tomorrow-night-blue .ace_string.ace_regexp, +.ace-tomorrow-night-blue .ace_variable { + color: #FF9DA4 +} + +.ace-tomorrow-night-blue .ace_comment { + color: #7285B7 +} + +.ace-tomorrow-night-blue .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYJDzqfwPAANXAeNsiA+ZAAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/tomorrow_night_blue.js b/lib/ace/theme/tomorrow_night_blue.js new file mode 100644 index 00000000..dcdf4adc --- /dev/null +++ b/lib/ace/theme/tomorrow_night_blue.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = true; +exports.cssClass = "ace-tomorrow-night-blue"; +exports.cssText = require("../requirejs/text!./tomorrow_night_blue.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/tomorrow_night_bright.css b/lib/ace/theme/tomorrow_night_bright.css new file mode 100644 index 00000000..c0c33739 --- /dev/null +++ b/lib/ace/theme/tomorrow_night_bright.css @@ -0,0 +1,140 @@ +.ace-tomorrow-night-bright .ace_gutter { + background: #1a1a1a; + color: #DEDEDE +} + +.ace-tomorrow-night-bright .ace_print-margin { + width: 1px; + background: #1a1a1a +} + +.ace-tomorrow-night-bright { + background-color: #000000; + color: #DEDEDE +} + +.ace-tomorrow-night-bright .ace_cursor { + color: #9F9F9F +} + +.ace-tomorrow-night-bright .ace_marker-layer .ace_selection { + background: #424242 +} + +.ace-tomorrow-night-bright.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #000000; +} + +.ace-tomorrow-night-bright .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.ace-tomorrow-night-bright .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #888888 +} + +.ace-tomorrow-night-bright .ace_marker-layer .ace_highlight { + border: 1px solid rgb(110, 119, 0); + border-bottom: 0; + box-shadow: inset 0 -1px rgb(110, 119, 0); + margin: -1px 0 0 -1px; + background: rgba(255, 235, 0, 0.1) +} + +.ace-tomorrow-night-bright .ace_marker-layer .ace_active-line { + background: #2A2A2A +} + +.ace-tomorrow-night-bright .ace_gutter-active-line { + background-color: #2A2A2A +} + +.ace-tomorrow-night-bright .ace_stack { + background-color: rgb(66, 90, 44) +} + +.ace-tomorrow-night-bright .ace_marker-layer .ace_selected-word { + border: 1px solid #888888 +} + +.ace-tomorrow-night-bright .ace_invisible { + color: #343434 +} + +.ace-tomorrow-night-bright .ace_keyword, +.ace-tomorrow-night-bright .ace_meta, +.ace-tomorrow-night-bright .ace_storage, +.ace-tomorrow-night-bright .ace_storage.ace_type, +.ace-tomorrow-night-bright .ace_support.ace_type { + color: #C397D8 +} + +.ace-tomorrow-night-bright .ace_keyword.ace_operator { + color: #70C0B1 +} + +.ace-tomorrow-night-bright .ace_constant.ace_character, +.ace-tomorrow-night-bright .ace_constant.ace_language, +.ace-tomorrow-night-bright .ace_constant.ace_numeric, +.ace-tomorrow-night-bright .ace_keyword.ace_other.ace_unit, +.ace-tomorrow-night-bright .ace_support.ace_constant, +.ace-tomorrow-night-bright .ace_variable.ace_parameter { + color: #E78C45 +} + +.ace-tomorrow-night-bright .ace_constant.ace_other { + color: #EEEEEE +} + +.ace-tomorrow-night-bright .ace_invalid { + color: #CED2CF; + background-color: #DF5F5F +} + +.ace-tomorrow-night-bright .ace_invalid.ace_deprecated { + color: #CED2CF; + background-color: #B798BF +} + +.ace-tomorrow-night-bright .ace_fold { + background-color: #7AA6DA; + border-color: #DEDEDE +} + +.ace-tomorrow-night-bright .ace_entity.ace_name.ace_function, +.ace-tomorrow-night-bright .ace_support.ace_function, +.ace-tomorrow-night-bright .ace_variable { + color: #7AA6DA +} + +.ace-tomorrow-night-bright .ace_support.ace_class, +.ace-tomorrow-night-bright .ace_support.ace_type { + color: #E7C547 +} + +.ace-tomorrow-night-bright .ace_heading, +.ace-tomorrow-night-bright .ace_markup.ace_heading, +.ace-tomorrow-night-bright .ace_string { + color: #B9CA4A +} + +.ace-tomorrow-night-bright .ace_entity.ace_name.ace_tag, +.ace-tomorrow-night-bright .ace_entity.ace_other.ace_attribute-name, +.ace-tomorrow-night-bright .ace_meta.ace_tag, +.ace-tomorrow-night-bright .ace_string.ace_regexp, +.ace-tomorrow-night-bright .ace_variable { + color: #D54E53 +} + +.ace-tomorrow-night-bright .ace_comment { + color: #969896 +} + +.ace-tomorrow-night-bright .ace_c9searchresults.ace_keyword { + color: #C2C280 +} + +.ace-tomorrow-night-bright .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYFBXV/8PAAJoAXX4kT2EAAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/tomorrow_night_bright.js b/lib/ace/theme/tomorrow_night_bright.js new file mode 100644 index 00000000..4b285668 --- /dev/null +++ b/lib/ace/theme/tomorrow_night_bright.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = true; +exports.cssClass = "ace-tomorrow-night-bright"; +exports.cssText = require("../requirejs/text!./tomorrow_night_bright.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/tomorrow_night_eighties.css b/lib/ace/theme/tomorrow_night_eighties.css new file mode 100644 index 00000000..69277fb1 --- /dev/null +++ b/lib/ace/theme/tomorrow_night_eighties.css @@ -0,0 +1,124 @@ +.ace-tomorrow-night-eighties .ace_gutter { + background: #272727; + color: #CCC +} + +.ace-tomorrow-night-eighties .ace_print-margin { + width: 1px; + background: #272727 +} + +.ace-tomorrow-night-eighties { + background-color: #2D2D2D; + color: #CCCCCC +} + +.ace-tomorrow-night-eighties .ace_constant.ace_other, +.ace-tomorrow-night-eighties .ace_cursor { + color: #CCCCCC +} + +.ace-tomorrow-night-eighties .ace_marker-layer .ace_selection { + background: #515151 +} + +.ace-tomorrow-night-eighties.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #2D2D2D; +} + +.ace-tomorrow-night-eighties .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.ace-tomorrow-night-eighties .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #6A6A6A +} + +.ace-tomorrow-night-bright .ace_stack { + background: rgb(66, 90, 44) +} + +.ace-tomorrow-night-eighties .ace_marker-layer .ace_active-line { + background: #393939 +} + +.ace-tomorrow-night-eighties .ace_gutter-active-line { + background-color: #393939 +} + +.ace-tomorrow-night-eighties .ace_marker-layer .ace_selected-word { + border: 1px solid #515151 +} + +.ace-tomorrow-night-eighties .ace_invisible { + color: #6A6A6A +} + +.ace-tomorrow-night-eighties .ace_keyword, +.ace-tomorrow-night-eighties .ace_meta, +.ace-tomorrow-night-eighties .ace_storage, +.ace-tomorrow-night-eighties .ace_storage.ace_type, +.ace-tomorrow-night-eighties .ace_support.ace_type { + color: #CC99CC +} + +.ace-tomorrow-night-eighties .ace_keyword.ace_operator { + color: #66CCCC +} + +.ace-tomorrow-night-eighties .ace_constant.ace_character, +.ace-tomorrow-night-eighties .ace_constant.ace_language, +.ace-tomorrow-night-eighties .ace_constant.ace_numeric, +.ace-tomorrow-night-eighties .ace_keyword.ace_other.ace_unit, +.ace-tomorrow-night-eighties .ace_support.ace_constant, +.ace-tomorrow-night-eighties .ace_variable.ace_parameter { + color: #F99157 +} + +.ace-tomorrow-night-eighties .ace_invalid { + color: #CDCDCD; + background-color: #F2777A +} + +.ace-tomorrow-night-eighties .ace_invalid.ace_deprecated { + color: #CDCDCD; + background-color: #CC99CC +} + +.ace-tomorrow-night-eighties .ace_fold { + background-color: #6699CC; + border-color: #CCCCCC +} + +.ace-tomorrow-night-eighties .ace_entity.ace_name.ace_function, +.ace-tomorrow-night-eighties .ace_support.ace_function, +.ace-tomorrow-night-eighties .ace_variable { + color: #6699CC +} + +.ace-tomorrow-night-eighties .ace_support.ace_class, +.ace-tomorrow-night-eighties .ace_support.ace_type { + color: #FFCC66 +} + +.ace-tomorrow-night-eighties .ace_heading, +.ace-tomorrow-night-eighties .ace_markup.ace_heading, +.ace-tomorrow-night-eighties .ace_string { + color: #99CC99 +} + +.ace-tomorrow-night-eighties .ace_comment { + color: #999999 +} + +.ace-tomorrow-night-eighties .ace_entity.ace_name.ace_tag, +.ace-tomorrow-night-eighties .ace_entity.ace_other.ace_attribute-name, +.ace-tomorrow-night-eighties .ace_meta.ace_tag, +.ace-tomorrow-night-eighties .ace_variable { + color: #F2777A +} + +.ace-tomorrow-night-eighties .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ09NrYAgMjP4PAAtGAwchHMyAAAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/tomorrow_night_eighties.js b/lib/ace/theme/tomorrow_night_eighties.js new file mode 100644 index 00000000..9ac7be67 --- /dev/null +++ b/lib/ace/theme/tomorrow_night_eighties.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = true; +exports.cssClass = "ace-tomorrow-night-eighties"; +exports.cssText = require("../requirejs/text!./tomorrow_night_eighties.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/twilight.css b/lib/ace/theme/twilight.css new file mode 100644 index 00000000..ae353dae --- /dev/null +++ b/lib/ace/theme/twilight.css @@ -0,0 +1,127 @@ +.ace-twilight .ace_gutter { + background: #232323; + color: #E2E2E2 +} + +.ace-twilight .ace_print-margin { + width: 1px; + background: #232323 +} + +.ace-twilight { + background-color: #141414; + color: #F8F8F8 +} + +.ace-twilight .ace_cursor { + color: #A7A7A7 +} + +.ace-twilight .ace_marker-layer .ace_selection { + background: rgba(221, 240, 255, 0.20) +} + +.ace-twilight.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #141414; +} + +.ace-twilight .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.ace-twilight .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid rgba(255, 255, 255, 0.25) +} + +.ace-twilight .ace_marker-layer .ace_active-line { + background: rgba(255, 255, 255, 0.031) +} + +.ace-twilight .ace_gutter-active-line { + background-color: rgba(255, 255, 255, 0.031) +} + +.ace-twilight .ace_marker-layer .ace_selected-word { + border: 1px solid rgba(221, 240, 255, 0.20) +} + +.ace-twilight .ace_invisible { + color: rgba(255, 255, 255, 0.25) +} + +.ace-twilight .ace_keyword, +.ace-twilight .ace_meta { + color: #CDA869 +} + +.ace-twilight .ace_constant, +.ace-twilight .ace_constant.ace_character, +.ace-twilight .ace_constant.ace_character.ace_escape, +.ace-twilight .ace_constant.ace_other, +.ace-twilight .ace_heading, +.ace-twilight .ace_markup.ace_heading, +.ace-twilight .ace_support.ace_constant { + color: #CF6A4C +} + +.ace-twilight .ace_invalid.ace_illegal { + color: #F8F8F8; + background-color: rgba(86, 45, 86, 0.75) +} + +.ace-twilight .ace_invalid.ace_deprecated { + text-decoration: underline; + font-style: italic; + color: #D2A8A1 +} + +.ace-twilight .ace_support { + color: #9B859D +} + +.ace-twilight .ace_fold { + background-color: #AC885B; + border-color: #F8F8F8 +} + +.ace-twilight .ace_support.ace_function { + color: #DAD085 +} + +.ace-twilight .ace_list, +.ace-twilight .ace_markup.ace_list, +.ace-twilight .ace_storage { + color: #F9EE98 +} + +.ace-twilight .ace_entity.ace_name.ace_function, +.ace-twilight .ace_meta.ace_tag, +.ace-twilight .ace_variable { + color: #AC885B +} + +.ace-twilight .ace_string { + color: #8F9D6A +} + +.ace-twilight .ace_string.ace_regexp { + color: #E9C062 +} + +.ace-twilight .ace_comment { + font-style: italic; + color: #5F5A60 +} + +.ace-twilight .ace_variable { + color: #7587A6 +} + +.ace-twilight .ace_xml-pe { + color: #494949 +} + +.ace-twilight .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQERFpYLC1tf0PAAgOAnPnhxyiAAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/twilight.js b/lib/ace/theme/twilight.js index 7c5b5629..904f7ef6 100644 --- a/lib/ace/theme/twilight.js +++ b/lib/ace/theme/twilight.js @@ -1,199 +1,39 @@ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { - var dom = require("pilot/dom"); +exports.isDark = true; +exports.cssClass = "ace-twilight"; +exports.cssText = require("../requirejs/text!./twilight.css"); - var cssText = ".ace-twilight .ace_editor {\ - border: 2px solid rgb(159, 159, 159);\ -}\ -\ -.ace-twilight .ace_editor.ace_focus {\ - border: 2px solid #327fbd;\ -}\ -\ -.ace-twilight .ace_gutter {\ - width: 50px;\ - background: #e8e8e8;\ - color: #333;\ - overflow : hidden;\ -}\ -\ -.ace-twilight .ace_gutter-layer {\ - width: 100%;\ - text-align: right;\ -}\ -\ -.ace-twilight .ace_gutter-layer .ace_gutter-cell {\ - padding-right: 6px;\ -}\ -\ -.ace-twilight .ace_print_margin {\ - width: 1px;\ - background: #e8e8e8;\ -}\ -\ -.ace-twilight .ace_scroller {\ - background-color: #141414;\ -}\ -\ -.ace-twilight .ace_text-layer {\ - cursor: text;\ - color: #F8F8F8;\ -}\ -\ -.ace-twilight .ace_cursor {\ - border-left: 2px solid #A7A7A7;\ -}\ -\ -.ace-twilight .ace_cursor.ace_overwrite {\ - border-left: 0px;\ - border-bottom: 1px solid #A7A7A7;\ -}\ - \ -.ace-twilight .ace_marker-layer .ace_selection {\ - background: rgba(221, 240, 255, 0.20);\ -}\ -\ -.ace-twilight .ace_marker-layer .ace_step {\ - background: rgb(198, 219, 174);\ -}\ -\ -.ace-twilight .ace_marker-layer .ace_bracket {\ - margin: -1px 0 0 -1px;\ - border: 1px solid rgba(255, 255, 255, 0.25);\ -}\ -\ -.ace-twilight .ace_marker-layer .ace_active_line {\ - background: rgba(255, 255, 255, 0.031);\ -}\ -\ - \ -.ace-twilight .ace_invisible {\ - color: rgba(255, 255, 255, 0.25);\ -}\ -\ -.ace-twilight .ace_keyword {\ - color:#CDA869;\ -}\ -\ -.ace-twilight .ace_keyword.ace_operator {\ - \ -}\ -\ -.ace-twilight .ace_constant {\ - color:#CF6A4C;\ -}\ -\ -.ace-twilight .ace_constant.ace_language {\ - \ -}\ -\ -.ace-twilight .ace_constant.ace_library {\ - \ -}\ -\ -.ace-twilight .ace_constant.ace_numeric {\ - \ -}\ -\ -.ace-twilight .ace_invalid {\ - \ -}\ -\ -.ace-twilight .ace_invalid.ace_illegal {\ - color:#F8F8F8;\ -background-color:rgba(86, 45, 86, 0.75);\ -}\ -\ -.ace-twilight .ace_invalid.ace_deprecated {\ - text-decoration:underline;\ -font-style:italic;\ -color:#D2A8A1;\ -}\ -\ -.ace-twilight .ace_support {\ - color:#9B859D;\ -}\ -\ -.ace-twilight .ace_support.ace_function {\ - color:#DAD085;\ -}\ -\ -.ace-twilight .ace_function.ace_buildin {\ - \ -}\ -\ -.ace-twilight .ace_string {\ - color:#8F9D6A;\ -}\ -\ -.ace-twilight .ace_string.ace_regexp {\ - color:#E9C062;\ -}\ -\ -.ace-twilight .ace_comment {\ - font-style:italic;\ -color:#5F5A60;\ -}\ -\ -.ace-twilight .ace_comment.ace_doc {\ - \ -}\ -\ -.ace-twilight .ace_comment.ace_doc.ace_tag {\ - \ -}\ -\ -.ace-twilight .ace_variable {\ - color:#7587A6;\ -}\ -\ -.ace-twilight .ace_variable.ace_language {\ - \ -}\ -\ -.ace-twilight .ace_xml_pe {\ - color:#494949;\ -}"; - - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "ace-twilight"; -}); \ No newline at end of file +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/vibrant_ink.css b/lib/ace/theme/vibrant_ink.css new file mode 100644 index 00000000..a3a89402 --- /dev/null +++ b/lib/ace/theme/vibrant_ink.css @@ -0,0 +1,109 @@ +.ace-vibrant-ink .ace_gutter { + background: #1a1a1a; + color: #BEBEBE +} + +.ace-vibrant-ink .ace_print-margin { + width: 1px; + background: #1a1a1a +} + +.ace-vibrant-ink { + background-color: #0F0F0F; + color: #FFFFFF +} + +.ace-vibrant-ink .ace_cursor { + color: #FFFFFF +} + +.ace-vibrant-ink .ace_marker-layer .ace_selection { + background: #6699CC +} + +.ace-vibrant-ink.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #0F0F0F; +} + +.ace-vibrant-ink .ace_marker-layer .ace_step { + background: rgb(102, 82, 0) +} + +.ace-vibrant-ink .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #404040 +} + +.ace-vibrant-ink .ace_marker-layer .ace_active-line { + background: #333333 +} + +.ace-vibrant-ink .ace_gutter-active-line { + background-color: #333333 +} + +.ace-vibrant-ink .ace_marker-layer .ace_selected-word { + border: 1px solid #6699CC +} + +.ace-vibrant-ink .ace_invisible { + color: #404040 +} + +.ace-vibrant-ink .ace_keyword, +.ace-vibrant-ink .ace_meta { + color: #FF6600 +} + +.ace-vibrant-ink .ace_constant, +.ace-vibrant-ink .ace_constant.ace_character, +.ace-vibrant-ink .ace_constant.ace_character.ace_escape, +.ace-vibrant-ink .ace_constant.ace_other { + color: #339999 +} + +.ace-vibrant-ink .ace_constant.ace_numeric { + color: #99CC99 +} + +.ace-vibrant-ink .ace_invalid, +.ace-vibrant-ink .ace_invalid.ace_deprecated { + color: #CCFF33; + background-color: #000000 +} + +.ace-vibrant-ink .ace_fold { + background-color: #FFCC00; + border-color: #FFFFFF +} + +.ace-vibrant-ink .ace_entity.ace_name.ace_function, +.ace-vibrant-ink .ace_support.ace_function, +.ace-vibrant-ink .ace_variable { + color: #FFCC00 +} + +.ace-vibrant-ink .ace_variable.ace_parameter { + font-style: italic +} + +.ace-vibrant-ink .ace_string { + color: #66FF00 +} + +.ace-vibrant-ink .ace_string.ace_regexp { + color: #44B4CC +} + +.ace-vibrant-ink .ace_comment { + color: #9933CC +} + +.ace-vibrant-ink .ace_entity.ace_other.ace_attribute-name { + font-style: italic; + color: #99CC99 +} + +.ace-vibrant-ink .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYNDTc/oPAALPAZ7hxlbYAAAAAElFTkSuQmCC) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/vibrant_ink.js b/lib/ace/theme/vibrant_ink.js new file mode 100644 index 00000000..7156e5de --- /dev/null +++ b/lib/ace/theme/vibrant_ink.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = true; +exports.cssClass = "ace-vibrant-ink"; +exports.cssText = require("../requirejs/text!./vibrant_ink.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/theme/xcode.css b/lib/ace/theme/xcode.css new file mode 100644 index 00000000..a22bd169 --- /dev/null +++ b/lib/ace/theme/xcode.css @@ -0,0 +1,102 @@ +/* THIS THEME WAS AUTOGENERATED BY Theme.tmpl.css (UUID: EE3AD170-2B7F-4DE1-B724-C75F13FE0085) */ + +.ace-xcode .ace_gutter { + background: #e8e8e8; + color: #333 +} + +.ace-xcode .ace_print-margin { + width: 1px; + background: #e8e8e8 +} + +.ace-xcode { + background-color: #FFFFFF; + color: #000000 +} + +.ace-xcode .ace_cursor { + color: #000000 +} + +.ace-xcode .ace_marker-layer .ace_selection { + background: #B5D5FF +} + +.ace-xcode.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px #FFFFFF; +} + +.ace-xcode .ace_marker-layer .ace_step { + background: rgb(198, 219, 174) +} + +.ace-xcode .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid #BFBFBF +} + +.ace-xcode .ace_marker-layer .ace_active-line { + background: rgba(0, 0, 0, 0.071) +} + +.ace-xcode .ace_gutter-active-line { + background-color: rgba(0, 0, 0, 0.071) +} + +.ace-xcode .ace_marker-layer .ace_selected-word { + border: 1px solid #B5D5FF +} + +.ace-xcode .ace_constant.ace_language, +.ace-xcode .ace_keyword, +.ace-xcode .ace_meta, +.ace-xcode .ace_variable.ace_language { + color: #C800A4 +} + +.ace-xcode .ace_invisible { + color: #BFBFBF +} + +.ace-xcode .ace_constant.ace_character, +.ace-xcode .ace_constant.ace_other { + color: #275A5E +} + +.ace-xcode .ace_constant.ace_numeric { + color: #3A00DC +} + +.ace-xcode .ace_entity.ace_other.ace_attribute-name, +.ace-xcode .ace_support.ace_constant, +.ace-xcode .ace_support.ace_function { + color: #450084 +} + +.ace-xcode .ace_fold { + background-color: #C800A4; + border-color: #000000 +} + +.ace-xcode .ace_entity.ace_name.ace_tag, +.ace-xcode .ace_support.ace_class, +.ace-xcode .ace_support.ace_type { + color: #790EAD +} + +.ace-xcode .ace_storage { + color: #C900A4 +} + +.ace-xcode .ace_string { + color: #DF0002 +} + +.ace-xcode .ace_comment { + color: #008E00 +} + +.ace-xcode .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==) right repeat-y +} \ No newline at end of file diff --git a/lib/ace/theme/xcode.js b/lib/ace/theme/xcode.js new file mode 100644 index 00000000..e17d708d --- /dev/null +++ b/lib/ace/theme/xcode.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = false; +exports.cssClass = "ace-xcode"; +exports.cssText = require("../requirejs/text!./xcode.css"); + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/lib/ace/token_iterator.js b/lib/ace/token_iterator.js new file mode 100644 index 00000000..74376fb3 --- /dev/null +++ b/lib/ace/token_iterator.js @@ -0,0 +1,150 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +/** + * + * + * This class provides an essay way to treat the document as a stream of tokens, and provides methods to iterate over these tokens. + * @class TokenIterator + **/ + +/** + * Creates a new token iterator object. The inital token index is set to the provided row and column coordinates. + * @param {EditSession} session The session to associate with + * @param {Number} initialRow The row to start the tokenizing at + * @param {Number} initialColumn The column to start the tokenizing at + * + * @constructor + **/ +var TokenIterator = function(session, initialRow, initialColumn) { + this.$session = session; + this.$row = initialRow; + this.$rowTokens = session.getTokens(initialRow); + + var token = session.getTokenAt(initialRow, initialColumn); + this.$tokenIndex = token ? token.index : -1; +}; + +(function() { + + /** + * + * Tokenizes all the items from the current point to the row prior in the document. + * @returns {[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. + **/ + this.stepBackward = function() { + this.$tokenIndex -= 1; + + while (this.$tokenIndex < 0) { + this.$row -= 1; + if (this.$row < 0) { + this.$row = 0; + return null; + } + + this.$rowTokens = this.$session.getTokens(this.$row); + this.$tokenIndex = this.$rowTokens.length - 1; + } + + return this.$rowTokens[this.$tokenIndex]; + }; + + /** + * + * 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. + * @returns {String} + **/ + this.stepForward = function() { + this.$tokenIndex += 1; + var rowCount; + while (this.$tokenIndex >= this.$rowTokens.length) { + this.$row += 1; + if (!rowCount) + rowCount = this.$session.getLength(); + if (this.$row >= rowCount) { + this.$row = rowCount - 1; + return null; + } + + this.$rowTokens = this.$session.getTokens(this.$row); + this.$tokenIndex = 0; + } + + return this.$rowTokens[this.$tokenIndex]; + }; + + /** + * + * Returns the current tokenized string. + * @returns {String} + **/ + this.getCurrentToken = function () { + return this.$rowTokens[this.$tokenIndex]; + }; + + /** + * + * Returns the current row. + * @returns {Number} + **/ + this.getCurrentTokenRow = function () { + return this.$row; + }; + + /** + * + * Returns the current column. + * @returns {Number} + **/ + this.getCurrentTokenColumn = function() { + var rowTokens = this.$rowTokens; + var tokenIndex = this.$tokenIndex; + + // If a column was cached by EditSession.getTokenAt, then use it + var column = rowTokens[tokenIndex].start; + if (column !== undefined) + return column; + + column = 0; + while (tokenIndex > 0) { + tokenIndex -= 1; + column += rowTokens[tokenIndex].value.length; + } + + return column; + }; + +}).call(TokenIterator.prototype); + +exports.TokenIterator = TokenIterator; +}); diff --git a/lib/ace/token_iterator_test.js b/lib/ace/token_iterator_test.js new file mode 100644 index 00000000..c7202e84 --- /dev/null +++ b/lib/ace/token_iterator_test.js @@ -0,0 +1,212 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + + if (typeof process !== "undefined") { + require("amd-loader"); + } + +define(function(require, exports, module) { +"use strict"; + +var EditSession = require("./edit_session").EditSession; +var JavaScriptMode = require("./mode/javascript").Mode; +var TokenIterator = require("./token_iterator").TokenIterator; +var assert = require("./test/assertions"); + +module.exports = { + "test: token iterator initialization in JavaScript document" : function() { + var lines = [ + "function foo(items) {", + " for (var i=0; i= 0; i--) + assert.equal(iterator.stepBackward(), tokens[i]); + assert.equal(iterator.stepBackward(), null); + assert.equal(iterator.getCurrentToken(), null); + }, + + "test: token iterator reports correct row and column" : function() { + var lines = [ + "function foo(items) {", + " for (var i=0; i - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; +var config = require("./config"); +// tokenizing lines longer than this makes editor very slow +var MAX_TOKEN_COUNT = 2000; +/** + * 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). + * @class Tokenizer + **/ + +/** + * Constructs a new tokenizer based on the given rules and flags. + * @param {Object} rules The highlighting rules + * + * @constructor + **/ var Tokenizer = function(rules) { - this.rules = rules; + this.states = rules; this.regExps = {}; - for ( var key in this.rules) { - var rule = this.rules[key]; - var state = rule; + this.matchMappings = {}; + for (var key in this.states) { + var state = this.states[key]; var ruleRegExps = []; + var matchTotal = 0; + var mapping = this.matchMappings[key] = {defaultToken: "text"}; + var flag = "g"; - for ( var i = 0; i < state.length; i++) - ruleRegExps.push(state[i].regex); + var splitterRurles = []; + for (var i = 0; i < state.length; i++) { + var rule = state[i]; + if (rule.defaultToken) + mapping.defaultToken = rule.defaultToken; + if (rule.caseInsensitive) + flag = "gi"; + if (rule.regex == null) + continue; - this.regExps[key] = new RegExp("(?:(" + ruleRegExps.join(")|(") + ")|(.))", "g"); + if (rule.regex instanceof RegExp) + rule.regex = rule.regex.toString().slice(1, -1); + + // Count number of matching groups. 2 extra groups from the full match + // And the catch-all on the end (used to force a match); + var adjustedregex = rule.regex; + var matchcount = new RegExp("(?:(" + adjustedregex + ")|(.))").exec("a").length - 2; + if (Array.isArray(rule.token)) { + if (rule.token.length == 1 || matchcount == 1) { + rule.token = rule.token[0]; + } else if (matchcount - 1 != rule.token.length) { + this.reportError("number of classes and regexp groups doesn't match", { + rule: rule, + groupCount: matchcount - 1 + }); + rule.token = rule.token[0]; + } else { + rule.tokenArray = rule.token; + rule.token = null; + rule.onMatch = this.$arrayTokens; + } + } else if (typeof rule.token == "function" && !rule.onMatch) { + if (matchcount > 1) + rule.onMatch = this.$applyToken; + else + rule.onMatch = rule.token; + } + + if (matchcount > 1) { + if (/\\\d/.test(rule.regex)) { + // Replace any backreferences and offset appropriately. + adjustedregex = rule.regex.replace(/\\([0-9]+)/g, function(match, digit) { + return "\\" + (parseInt(digit, 10) + matchTotal + 1); + }); + } else { + matchcount = 1; + adjustedregex = this.removeCapturingGroups(rule.regex); + } + if (!rule.splitRegex && typeof rule.token != "string") + splitterRurles.push(rule); // flag will be known only at the very end + } + + mapping[matchTotal] = i; + matchTotal += matchcount; + + ruleRegExps.push(adjustedregex); + + // makes property access faster + if (!rule.onMatch) + rule.onMatch = null; + } + if (!ruleRegExps.length) { + mapping[0] = 0; + ruleRegExps.push("$"); + } + + splitterRurles.forEach(function(rule) { + rule.splitRegex = this.createSplitterRegexp(rule.regex, flag); + }, this); + + this.regExps[key] = new RegExp("(" + ruleRegExps.join(")|(") + ")|($)", flag); } }; (function() { + this.$setMaxTokenCount = function(m) { + MAX_TOKEN_COUNT = m | 0; + }; + + this.$applyToken = function(str) { + var values = this.splitRegex.exec(str).slice(1); + var types = this.token.apply(this, values); + // required for compatibility with old modes + if (typeof types === "string") + return [{type: types, value: str}]; + + var tokens = []; + for (var i = 0, l = types.length; i < l; i++) { + if (values[i]) + tokens[tokens.length] = { + type: types[i], + value: values[i] + }; + } + return tokens; + }, + + this.$arrayTokens = function(str) { + if (!str) + return []; + var values = this.splitRegex.exec(str); + if (!values) + return "text"; + var tokens = []; + var types = this.tokenArray; + for (var i = 0, l = types.length; i < l; i++) { + if (values[i + 1]) + tokens[tokens.length] = { + type: types[i], + value: values[i + 1] + }; + } + return tokens; + }; + + this.removeCapturingGroups = function(src) { + var r = src.replace( + /\[(?:\\.|[^\]])*?\]|\\.|\(\?[:=!]|(\()/g, + function(x, y) {return y ? "(?:" : x;} + ); + return r; + }; + + this.createSplitterRegexp = function(src, flag) { + if (src.indexOf("(?=") != -1) { + var stack = 0; + var inChClass = false; + var lastCapture = {}; + src.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([\[\]])/g, function( + m, esc, parenOpen, parenClose, square, index + ) { + if (inChClass) { + inChClass = square != "]"; + } else if (square) { + inChClass = true; + } else if (parenClose) { + if (stack == lastCapture.stack) { + lastCapture.end = index+1; + lastCapture.stack = -1; + } + stack--; + } else if (parenOpen) { + stack++; + if (parenOpen.length != 1) { + lastCapture.stack = stack + lastCapture.start = index; + } + } + return m; + }); + + if (lastCapture.end != null && /^\)*$/.test(src.substr(lastCapture.end))) + src = src.substring(0, lastCapture.start) + src.substr(lastCapture.end); + } + return new RegExp(src, (flag||"").replace("g", "")); + }; + + /** + * Returns an object containing two properties: `tokens`, which contains all the tokens; and `state`, the current state. + * @returns {Object} + **/ this.getLineTokens = function(line, startState) { - var currentState = startState; - var state = this.rules[currentState]; + if (startState && typeof startState != "string") { + var stack = startState.slice(0); + startState = stack[0]; + if (startState === "#tmp") { + stack.shift() + startState = stack.shift() + } + } else + var stack = []; + + var currentState = startState || "start"; + var state = this.states[currentState]; + if (!state) { + currentState = "start"; + state = this.states[currentState]; + } + var mapping = this.matchMappings[currentState]; var re = this.regExps[currentState]; re.lastIndex = 0; var match, tokens = []; - var lastIndex = 0; + var matchAttempts = 0; - var token = { - type: null, - value: "" - }; + var token = {type: null, value: ""}; while (match = re.exec(line)) { - var type = "text"; + var type = mapping.defaultToken; + var rule = null; var value = match[0]; + var index = re.lastIndex; - for ( var i = 0; i < state.length; i++) { - if (match[i + 1]) { - var rule = state[i]; - - if (typeof rule.token == "function") - type = rule.token(match[0]); - else - type = rule.token; - - if (rule.next && rule.next !== currentState) { - currentState = rule.next; - state = this.rules[currentState]; - lastIndex = re.lastIndex; - - re = this.regExps[currentState]; - re.lastIndex = lastIndex; - } - break; + if (index - value.length > lastIndex) { + var skipped = line.substring(lastIndex, index - value.length); + if (token.type == type) { + token.value += skipped; + } else { + if (token.type) + tokens.push(token); + token = {type: type, value: skipped}; } - }; - - - if (token.type !== type) { - if (token.type) - tokens.push(token); - - token = { - type: type, - value: value - }; - } else { - token.value += value; } - + + for (var i = 0; i < match.length-2; i++) { + if (match[i + 1] === undefined) + continue; + + rule = state[mapping[i]]; + + if (rule.onMatch) + type = rule.onMatch(value, currentState, stack); + else + type = rule.token; + + if (rule.next) { + if (typeof rule.next == "string") { + currentState = rule.next; + } else { + currentState = rule.next(currentState, stack); + } + + state = this.states[currentState]; + if (!state) { + this.reportError("state doesn't exist", currentState); + currentState = "start"; + state = this.states[currentState]; + } + mapping = this.matchMappings[currentState]; + lastIndex = index; + re = this.regExps[currentState]; + re.lastIndex = index; + } + break; + } + + if (value) { + if (typeof type === "string") { + if ((!rule || rule.merge !== false) && token.type === type) { + token.value += value; + } else { + if (token.type) + tokens.push(token); + token = {type: type, value: value}; + } + } else if (type) { + if (token.type) + tokens.push(token); + token = {type: null, value: ""}; + for (var i = 0; i < type.length; i++) + tokens.push(type[i]); + } + } + if (lastIndex == line.length) break; - - lastIndex = re.lastIndex; - }; + + lastIndex = index; + + if (matchAttempts++ > MAX_TOKEN_COUNT) { + if (matchAttempts > 2 * line.length) { + this.reportError("infinite loop with in ace tokenizer", { + startState: startState, + line: line + }); + } + // chrome doens't show contents of text nodes with very long text + while (lastIndex < line.length) { + if (token.type) + tokens.push(token); + token = { + value: line.substring(lastIndex, lastIndex += 2000), + type: "overflow" + }; + } + currentState = "start"; + stack = []; + break; + } + } if (token.type) tokens.push(token); - + + if (stack.length > 1) { + if (stack[0] !== currentState) + stack.unshift("#tmp", currentState); + } return { tokens : tokens, - state : currentState + state : stack.length ? stack : currentState }; }; - + + this.reportError = config.reportError; + }).call(Tokenizer.prototype); exports.Tokenizer = Tokenizer; diff --git a/lib/ace/tokenizer_dev.js b/lib/ace/tokenizer_dev.js new file mode 100644 index 00000000..61821f60 --- /dev/null +++ b/lib/ace/tokenizer_dev.js @@ -0,0 +1,183 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +var BaseTokenizer = require("./tokenizer").Tokenizer; + +// tokenizing lines longer than this makes editor very slow +var MAX_TOKEN_COUNT = 100000; +/* + * version of Tokenizer with additional logging + * and infinite loop checks + * can be used for developing/testing new modes + **/ + +var Tokenizer = function(rules) { + BaseTokenizer.call(this, rules); + + /** + * Returns an object containing two properties: `tokens`, which contains all the tokens; and `state`, the current state. + * @returns {Object} + **/ + this.getLineTokens = function(line, startState) { + if (startState && typeof startState != "string") { + var stack = startState.slice(0); + startState = stack[0]; + } else + var stack = []; + + var currentState = startState || "start"; + var state = this.states[currentState]; + var mapping = this.matchMappings[currentState]; + var re = this.regExps[currentState]; + re.lastIndex = 0; + + var match, tokens = []; + + var lastIndex = 0; + + var stateTransitions = []; + function onStateChange() { + stateTransitions.push(startState+"@"+lastIndex); + } + function initState() { + onStateChange(); + stateTransitions = []; + onStateChange(); + } + + var token = { + type: null, + value: "", + state: currentState + }; + initState(); + + var maxRecur = 100000; + + while (match = re.exec(line)) { + var type = mapping.defaultToken; + var rule = null; + var value = match[0]; + var index = re.lastIndex; + + if (index - value.length > lastIndex) { + var skipped = line.substring(lastIndex, index - value.length); + if (token.type == type) { + token.value += skipped; + } else { + if (token.type) + tokens.push(token); + token = {type: type, value: skipped}; + } + } + + for (var i = 0; i < match.length-2; i++) { + if (match[i + 1] === undefined) + continue; + + if (!maxRecur--) { + throw "infinite" + state[mapping[i]] + currentState + } + + rule = state[mapping[i]]; + + if (rule.onMatch) + type = rule.onMatch(value, currentState, stack); + else + type = rule.token; + + if (rule.next) { + if (typeof rule.next == "string") + currentState = rule.next; + else + currentState = rule.next(currentState, stack); + + state = this.states[currentState]; + if (!state) { + window.console && console.error && console.error(currentState, "doesn't exist"); + currentState = "start"; + state = this.states[currentState]; + } + mapping = this.matchMappings[currentState]; + lastIndex = index; + re = this.regExps[currentState]; + re.lastIndex = index; + + onStateChange(); + } + break; + } + + if (value) { + if (typeof type == "string") { + if ((!rule || rule.merge !== false) && token.type === type) { + token.value += value; + } else { + if (token.type) + tokens.push(token); + token = {type: type, value: value}; + } + } else { + if (token.type) + tokens.push(token); + token = {type: null, value: ""}; + for (var i = 0; i < type.length; i++) + tokens.push(type[i]); + } + } + + if (lastIndex == line.length) + break; + + lastIndex = index; + + if (tokens.length > MAX_TOKEN_COUNT) { + token.value += line.substr(lastIndex); + currentState = "start" + break; + } + } + + if (token.type) + tokens.push(token); + + return { + tokens : tokens, + state : stack.length ? stack : currentState + }; + }; + +}; + +Tokenizer.prototype = BaseTokenizer.prototype; + +exports.Tokenizer = Tokenizer; +}); diff --git a/lib/ace/tokenizer_test.js b/lib/ace/tokenizer_test.js new file mode 100644 index 00000000..41bf01c8 --- /dev/null +++ b/lib/ace/tokenizer_test.js @@ -0,0 +1,97 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + + if (typeof process !== "undefined") { + require("amd-loader"); + } + +define(function(require, exports, module) { +"use strict"; + +var Tokenizer = require("./tokenizer").Tokenizer; +var assert = require("./test/assertions"); + +module.exports = { + "test: createSplitterRegexp" : function() { + var t = new Tokenizer({}); + var re = t.createSplitterRegexp("(a)(b)(?=[x)(])"); + assert.equal(re.source, "(a)(b)"); + var re = t.createSplitterRegexp("xc(?=([x)(]))"); + assert.equal(re.source, "xc"); + var re = t.createSplitterRegexp("(xc(?=([x)(])))"); + assert.equal(re.source, "(xc)"); + var re = t.createSplitterRegexp("(?=r)[(?=)](?=([x)(]))"); + assert.equal(re.source, "(?=r)[(?=)]"); + var re = t.createSplitterRegexp("(?=r)[(?=)](\\?=t)"); + assert.equal(re.source, "(?=r)[(?=)](\\?=t)"); + var re = t.createSplitterRegexp("[(?=)](\\?=t)"); + assert.equal(re.source, "[(?=)](\\?=t)"); + }, + + "test: removeCapturingGroups" : function() { + var t = new Tokenizer({}); + var re = t.removeCapturingGroups("(ax(by))[()]"); + assert.equal(re, "(?:ax(?:by))[()]"); + }, + + "test: broken highlight rules": function() { + var t = new Tokenizer({ + start: [{ + token: 's', + regex: '&&&|^^^' + }, { + defaultToken: "def" + }], + state1: [{ + token: 'x', + regex: /\b([\w]*)(\s*)((?::)?)/ + }] + }); + var errorReports = 0; + t.reportError = function() { errorReports++; }; + var tokens = t.getLineTokens("x|", "start"); + assert.deepEqual(tokens, { + tokens: [{value: 'x|', type: 'overflow'}], + state: 'start' + }); + var tokens = t.getLineTokens("x|", "state1"); + assert.deepEqual(tokens, { + tokens: [{value: 'x', type: 'x'}, {value: '|', type: 'overflow'}], + state: 'start' + }); + assert.equal(errorReports, 2); + }, +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} diff --git a/lib/ace/tooltip.js b/lib/ace/tooltip.js new file mode 100644 index 00000000..1f5502d6 --- /dev/null +++ b/lib/ace/tooltip.js @@ -0,0 +1,138 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var dom = require("./lib/dom"); + +/** + * @class Tooltip + **/ + +/** + * @param {Element} parentNode + * + * @constructor + **/ +function Tooltip (parentNode) { + this.isOpen = false; + this.$element = null; + this.$parentNode = parentNode; +} + +(function() { + this.$init = function() { + this.$element = dom.createElement("div"); + this.$element.className = "ace_tooltip"; + this.$element.style.display = "none"; + this.$parentNode.appendChild(this.$element); + return this.$element; + }; + + /** + * @returns {Element} + **/ + this.getElement = function() { + return this.$element || this.$init(); + }; + + /** + * @param {String} text + **/ + this.setText = function(text) { + dom.setInnerText(this.getElement(), text); + }; + + /** + * @param {String} html + **/ + this.setHtml = function(html) { + this.getElement().innerHTML = html; + }; + + /** + * @param {Number} x + * @param {Number} y + **/ + this.setPosition = function(x, y) { + this.getElement().style.left = x + "px"; + this.getElement().style.top = y + "px"; + }; + + /** + * @param {String} className + **/ + this.setClassName = function(className) { + dom.addCssClass(this.getElement(), className); + }; + + /** + * @param {String} text + * @param {Number} x + * @param {Number} y + **/ + this.show = function(text, x, y) { + if (text != null) + this.setText(text); + if (x != null && y != null) + this.setPosition(x, y); + if (!this.isOpen) { + this.getElement().style.display = "block"; + this.isOpen = true; + } + }; + + this.hide = function() { + if (this.isOpen) { + this.getElement().style.display = "none"; + this.isOpen = false; + } + }; + + /** + * @returns {Number} + **/ + this.getHeight = function() { + return this.getElement().offsetHeight; + }; + + /** + * @returns {Number} + **/ + this.getWidth = function() { + return this.getElement().offsetWidth; + }; + +}).call(Tooltip.prototype); + +exports.Tooltip = Tooltip; +}); diff --git a/lib/ace/undomanager.js b/lib/ace/undomanager.js index e157032b..6da50a8b 100644 --- a/lib/ace/undomanager.js +++ b/lib/ace/undomanager.js @@ -1,85 +1,214 @@ -/* vim:ts=4:sts=4:sw=4: - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Mihai Sucan - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; +/** + * + * + * This object maintains the undo stack for an [[EditSession `EditSession`]]. + * @class UndoManager + **/ + +/** + * + * + * Resets the current undo state and creates a new `UndoManager`. + * + * @constructor + **/ var UndoManager = function() { this.reset(); }; (function() { + /** + * 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 + * + * @param {Object} options Contains additional properties + * + **/ this.execute = function(options) { - var deltas = options.args[0]; + // Normalize deltas for storage. + // var deltaSets = this.$serializeDeltas(options.args[0]); + var deltaSets = options.args[0]; + // Add deltas to undo stack. this.$doc = options.args[1]; - this.$undoStack.push(deltas); + if (options.merge && this.hasUndo()){ + this.dirtyCounter--; + deltaSets = this.$undoStack.pop().concat(deltaSets); + } + this.$undoStack.push(deltaSets); + + // Reset redo stack. + this.$redoStack = []; + if (this.dirtyCounter < 0) { + // The user has made a change after undoing past the last clean state. + // We can never get back to a clean state now until markClean() is called. + this.dirtyCounter = NaN; + } + this.dirtyCounter++; }; - this.undo = function() { - var deltas = this.$undoStack.pop(); - if (deltas) { - this.$doc.undoChanges(deltas); - this.$redoStack.push(deltas); + /** + * [Perform an undo operation on the document, reverting the last change.]{: #UndoManager.undo} + * @param {Boolean} dontSelect {:dontSelect} + * + * + * @returns {Range} The range of the undo. + **/ + this.undo = function(dontSelect) { + var deltaSets = this.$undoStack.pop(); + var undoSelectionRange = null; + if (deltaSets) { + undoSelectionRange = this.$doc.undoChanges(this.$deserializeDeltas(deltaSets), dontSelect); + this.$redoStack.push(deltaSets); + this.dirtyCounter--; } + + return undoSelectionRange; }; - this.redo = function() { - var deltas = this.$redoStack.pop(); - if (deltas) { - this.$doc.redoChanges(deltas); - this.$undoStack.push(deltas); + /** + * [Perform a redo operation on the document, reimplementing the last change.]{: #UndoManager.redo} + * @param {Boolean} dontSelect {:dontSelect} + * + * + **/ + this.redo = function(dontSelect) { + var deltaSets = this.$redoStack.pop(); + var redoSelectionRange = null; + if (deltaSets) { + redoSelectionRange = + this.$doc.redoChanges(this.$deserializeDeltas(deltaSets), dontSelect); + this.$undoStack.push(deltaSets); + this.dirtyCounter++; } + return redoSelectionRange; }; - + + /** + * + * Destroys the stack of undo and redo redo operations. + **/ this.reset = function() { this.$undoStack = []; this.$redoStack = []; + this.dirtyCounter = 0; }; + /** + * + * Returns `true` if there are undo operations left to perform. + * @returns {Boolean} + **/ this.hasUndo = function() { return this.$undoStack.length > 0; }; + /** + * + * Returns `true` if there are redo operations left to perform. + * @returns {Boolean} + **/ this.hasRedo = function() { return this.$redoStack.length > 0; }; + /** + * + * Marks the current status clean + **/ + this.markClean = function() { + this.dirtyCounter = 0; + }; + + /** + * + * Returns if the current status is clean + * @returns {Boolean} + **/ + this.isClean = function() { + return this.dirtyCounter === 0; + }; + + // Serializes deltaSets to reduce memory usage. + this.$serializeDeltas = function(deltaSets) { + return cloneDeltaSetsObj(deltaSets, $serializeDelta); + }; + + // Deserializes deltaSets to allow application to the document. + this.$deserializeDeltas = function(deltaSets) { + return cloneDeltaSetsObj(deltaSets, $deserializeDelta); + }; + + function $serializeDelta(delta){ + return { + action: delta.action, + start: delta.start, + end: delta.end, + lines: delta.lines.length == 1 ? null : delta.lines, + text: delta.lines.length == 1 ? delta.lines[0] : null, + }; + } + + function $deserializeDelta(delta) { + return { + action: delta.action, + start: delta.start, + end: delta.end, + lines: delta.lines || [delta.text] + }; + } + + function cloneDeltaSetsObj(deltaSets_old, fnGetModifiedDelta) { + var deltaSets_new = new Array(deltaSets_old.length); + for (var i = 0; i < deltaSets_old.length; i++) { + var deltaSet_old = deltaSets_old[i]; + var deltaSet_new = { group: deltaSet_old.group, deltas: new Array(deltaSet_old.length)}; + + for (var j = 0; j < deltaSet_old.deltas.length; j++) { + var delta_old = deltaSet_old.deltas[j]; + deltaSet_new.deltas[j] = fnGetModifiedDelta(delta_old); + } + + deltaSets_new[i] = deltaSet_new; + } + return deltaSets_new; + } + }).call(UndoManager.prototype); exports.UndoManager = UndoManager; diff --git a/lib/ace/unicode.js b/lib/ace/unicode.js new file mode 100644 index 00000000..5c291744 --- /dev/null +++ b/lib/ace/unicode.js @@ -0,0 +1,107 @@ +define(function(require, exports, module) { +"use strict"; + +/* +XRegExp Unicode plugin pack: Categories 1.0 +(c) 2010 Steven Levithan +MIT License + +Uses the Unicode 5.2 character database + +This package for the XRegExp Unicode plugin enables the following Unicode categories (aka properties): + +L - Letter (the top-level Letter category is included in the Unicode plugin base script) + Ll - Lowercase letter + Lu - Uppercase letter + Lt - Titlecase letter + Lm - Modifier letter + Lo - Letter without case +M - Mark + Mn - Non-spacing mark + Mc - Spacing combining mark + Me - Enclosing mark +N - Number + Nd - Decimal digit + Nl - Letter number + No - Other number +P - Punctuation + Pd - Dash punctuation + Ps - Open punctuation + Pe - Close punctuation + Pi - Initial punctuation + Pf - Final punctuation + Pc - Connector punctuation + Po - Other punctuation +S - Symbol + Sm - Math symbol + Sc - Currency symbol + Sk - Modifier symbol + So - Other symbol +Z - Separator + Zs - Space separator + Zl - Line separator + Zp - Paragraph separator +C - Other + Cc - Control + Cf - Format + Co - Private use + Cs - Surrogate + Cn - Unassigned + +Example usage: + + \p{N} + \p{Cn} +*/ + + +// will be populated by addUnicodePackage +exports.packages = {}; + +addUnicodePackage({ + L: "0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05250531-055605590561-058705D0-05EA05F0-05F20621-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280904-0939093D09500958-0961097109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510D0-10FA10FC1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209421022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2D00-2D252D30-2D652D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A65FA662-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78BA78CA7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC", + Ll: "0061-007A00AA00B500BA00DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02AF037103730377037B-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F0521052305250561-05871D00-1D2B1D62-1D771D79-1D9A1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF7210A210E210F2113212F21342139213C213D2146-2149214E21842C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7C2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2D00-2D25A641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76FA771-A778A77AA77CA77FA781A783A785A787A78CFB00-FB06FB13-FB17FF41-FF5A", + Lu: "0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E0520052205240531-055610A0-10C51E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F214521832C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CEDA640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BFF21-FF3A", + Lt: "01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC", + Lm: "02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F", + Lo: "01BB01C0-01C3029405D0-05EA05F0-05F20621-063F0641-064A066E066F0671-06D306D506EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA0800-08150904-0939093D09500958-096109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E450E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10D0-10FA1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317DC1820-18421844-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C771CE9-1CEC1CEE-1CF12135-21382D30-2D652D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE3006303C3041-3096309F30A1-30FA30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A014A016-A48CA4D0-A4F7A500-A60BA610-A61FA62AA62BA66EA6A0-A6E5A7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2AA00-AA28AA40-AA42AA44-AA4BAA60-AA6FAA71-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADBAADCABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF66-FF6FFF71-FF9DFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC", + M: "0300-036F0483-04890591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DE-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0903093C093E-094E0951-0955096209630981-098309BC09BE-09C409C709C809CB-09CD09D709E209E30A01-0A030A3C0A3E-0A420A470A480A4B-0A4D0A510A700A710A750A81-0A830ABC0ABE-0AC50AC7-0AC90ACB-0ACD0AE20AE30B01-0B030B3C0B3E-0B440B470B480B4B-0B4D0B560B570B620B630B820BBE-0BC20BC6-0BC80BCA-0BCD0BD70C01-0C030C3E-0C440C46-0C480C4A-0C4D0C550C560C620C630C820C830CBC0CBE-0CC40CC6-0CC80CCA-0CCD0CD50CD60CE20CE30D020D030D3E-0D440D46-0D480D4A-0D4D0D570D620D630D820D830DCA0DCF-0DD40DD60DD8-0DDF0DF20DF30E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F3E0F3F0F71-0F840F860F870F90-0F970F99-0FBC0FC6102B-103E1056-1059105E-10601062-10641067-106D1071-10741082-108D108F109A-109D135F1712-17141732-1734175217531772177317B6-17D317DD180B-180D18A91920-192B1930-193B19B0-19C019C819C91A17-1A1B1A55-1A5E1A60-1A7C1A7F1B00-1B041B34-1B441B6B-1B731B80-1B821BA1-1BAA1C24-1C371CD0-1CD21CD4-1CE81CED1CF21DC0-1DE61DFD-1DFF20D0-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66F-A672A67CA67DA6F0A6F1A802A806A80BA823-A827A880A881A8B4-A8C4A8E0-A8F1A926-A92DA947-A953A980-A983A9B3-A9C0AA29-AA36AA43AA4CAA4DAA7BAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE3-ABEAABECABEDFB1EFE00-FE0FFE20-FE26", + Mn: "0300-036F0483-04870591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0902093C0941-0948094D0951-095509620963098109BC09C1-09C409CD09E209E30A010A020A3C0A410A420A470A480A4B-0A4D0A510A700A710A750A810A820ABC0AC1-0AC50AC70AC80ACD0AE20AE30B010B3C0B3F0B41-0B440B4D0B560B620B630B820BC00BCD0C3E-0C400C46-0C480C4A-0C4D0C550C560C620C630CBC0CBF0CC60CCC0CCD0CE20CE30D41-0D440D4D0D620D630DCA0DD2-0DD40DD60E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F71-0F7E0F80-0F840F860F870F90-0F970F99-0FBC0FC6102D-10301032-10371039103A103D103E10581059105E-10601071-1074108210851086108D109D135F1712-17141732-1734175217531772177317B7-17BD17C617C9-17D317DD180B-180D18A91920-19221927192819321939-193B1A171A181A561A58-1A5E1A601A621A65-1A6C1A73-1A7C1A7F1B00-1B031B341B36-1B3A1B3C1B421B6B-1B731B801B811BA2-1BA51BA81BA91C2C-1C331C361C371CD0-1CD21CD4-1CE01CE2-1CE81CED1DC0-1DE61DFD-1DFF20D0-20DC20E120E5-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66FA67CA67DA6F0A6F1A802A806A80BA825A826A8C4A8E0-A8F1A926-A92DA947-A951A980-A982A9B3A9B6-A9B9A9BCAA29-AA2EAA31AA32AA35AA36AA43AA4CAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE5ABE8ABEDFB1EFE00-FE0FFE20-FE26", + Mc: "0903093E-09400949-094C094E0982098309BE-09C009C709C809CB09CC09D70A030A3E-0A400A830ABE-0AC00AC90ACB0ACC0B020B030B3E0B400B470B480B4B0B4C0B570BBE0BBF0BC10BC20BC6-0BC80BCA-0BCC0BD70C01-0C030C41-0C440C820C830CBE0CC0-0CC40CC70CC80CCA0CCB0CD50CD60D020D030D3E-0D400D46-0D480D4A-0D4C0D570D820D830DCF-0DD10DD8-0DDF0DF20DF30F3E0F3F0F7F102B102C10311038103B103C105610571062-10641067-106D108310841087-108C108F109A-109C17B617BE-17C517C717C81923-19261929-192B193019311933-193819B0-19C019C819C91A19-1A1B1A551A571A611A631A641A6D-1A721B041B351B3B1B3D-1B411B431B441B821BA11BA61BA71BAA1C24-1C2B1C341C351CE11CF2A823A824A827A880A881A8B4-A8C3A952A953A983A9B4A9B5A9BAA9BBA9BD-A9C0AA2FAA30AA33AA34AA4DAA7BABE3ABE4ABE6ABE7ABE9ABEAABEC", + Me: "0488048906DE20DD-20E020E2-20E4A670-A672", + N: "0030-003900B200B300B900BC-00BE0660-066906F0-06F907C0-07C90966-096F09E6-09EF09F4-09F90A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BF20C66-0C6F0C78-0C7E0CE6-0CEF0D66-0D750E50-0E590ED0-0ED90F20-0F331040-10491090-10991369-137C16EE-16F017E0-17E917F0-17F91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C5920702074-20792080-20892150-21822185-21892460-249B24EA-24FF2776-27932CFD30073021-30293038-303A3192-31953220-32293251-325F3280-328932B1-32BFA620-A629A6E6-A6EFA830-A835A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19", + Nd: "0030-00390660-066906F0-06F907C0-07C90966-096F09E6-09EF0A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BEF0C66-0C6F0CE6-0CEF0D66-0D6F0E50-0E590ED0-0ED90F20-0F291040-10491090-109917E0-17E91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C59A620-A629A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19", + Nl: "16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF", + No: "00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835", + P: "0021-00230025-002A002C-002F003A003B003F0040005B-005D005F007B007D00A100AB00B700BB00BF037E0387055A-055F0589058A05BE05C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F3A-0F3D0F850FD0-0FD4104A-104F10FB1361-13681400166D166E169B169C16EB-16ED1735173617D4-17D617D8-17DA1800-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD32010-20272030-20432045-20512053-205E207D207E208D208E2329232A2768-277527C527C627E6-27EF2983-299829D8-29DB29FC29FD2CF9-2CFC2CFE2CFF2E00-2E2E2E302E313001-30033008-30113014-301F3030303D30A030FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFD3EFD3FFE10-FE19FE30-FE52FE54-FE61FE63FE68FE6AFE6BFF01-FF03FF05-FF0AFF0C-FF0FFF1AFF1BFF1FFF20FF3B-FF3DFF3FFF5BFF5DFF5F-FF65", + Pd: "002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D", + Ps: "0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62", + Pe: "0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63", + Pi: "00AB2018201B201C201F20392E022E042E092E0C2E1C2E20", + Pf: "00BB2019201D203A2E032E052E0A2E0D2E1D2E21", + Pc: "005F203F20402054FE33FE34FE4D-FE4FFF3F", + Po: "0021-00230025-0027002A002C002E002F003A003B003F0040005C00A100B700BF037E0387055A-055F058905C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F850FD0-0FD4104A-104F10FB1361-1368166D166E16EB-16ED1735173617D4-17D617D8-17DA1800-18051807-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD3201620172020-20272030-2038203B-203E2041-20432047-205120532055-205E2CF9-2CFC2CFE2CFF2E002E012E06-2E082E0B2E0E-2E162E182E192E1B2E1E2E1F2E2A-2E2E2E302E313001-3003303D30FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFE10-FE16FE19FE30FE45FE46FE49-FE4CFE50-FE52FE54-FE57FE5F-FE61FE68FE6AFE6BFF01-FF03FF05-FF07FF0AFF0CFF0EFF0FFF1AFF1BFF1FFF20FF3CFF61FF64FF65", + S: "0024002B003C-003E005E0060007C007E00A2-00A900AC00AE-00B100B400B600B800D700F702C2-02C502D2-02DF02E5-02EB02ED02EF-02FF03750384038503F604820606-0608060B060E060F06E906FD06FE07F609F209F309FA09FB0AF10B700BF3-0BFA0C7F0CF10CF20D790E3F0F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-139917DB194019E0-19FF1B61-1B6A1B74-1B7C1FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE20442052207A-207C208A-208C20A0-20B8210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B2140-2144214A-214D214F2190-2328232B-23E82400-24262440-244A249C-24E92500-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE27C0-27C427C7-27CA27CC27D0-27E527F0-29822999-29D729DC-29FB29FE-2B4C2B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F309B309C319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A700-A716A720A721A789A78AA828-A82BA836-A839AA77-AA79FB29FDFCFDFDFE62FE64-FE66FE69FF04FF0BFF1C-FF1EFF3EFF40FF5CFF5EFFE0-FFE6FFE8-FFEEFFFCFFFD", + Sm: "002B003C-003E007C007E00AC00B100D700F703F60606-060820442052207A-207C208A-208C2140-2144214B2190-2194219A219B21A021A321A621AE21CE21CF21D221D421F4-22FF2308-230B23202321237C239B-23B323DC-23E125B725C125F8-25FF266F27C0-27C427C7-27CA27CC27D0-27E527F0-27FF2900-29822999-29D729DC-29FB29FE-2AFF2B30-2B442B47-2B4CFB29FE62FE64-FE66FF0BFF1C-FF1EFF5CFF5EFFE2FFE9-FFEC", + Sc: "002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6", + Sk: "005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3", + So: "00A600A700A900AE00B000B60482060E060F06E906FD06FE07F609FA0B700BF3-0BF80BFA0C7F0CF10CF20D790F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-1399194019E0-19FF1B61-1B6A1B74-1B7C210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B214A214C214D214F2195-2199219C-219F21A121A221A421A521A7-21AD21AF-21CD21D021D121D321D5-21F32300-2307230C-231F2322-2328232B-237B237D-239A23B4-23DB23E2-23E82400-24262440-244A249C-24E92500-25B625B8-25C025C2-25F72600-266E2670-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE2800-28FF2B00-2B2F2B452B462B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A828-A82BA836A837A839AA77-AA79FDFDFFE4FFE8FFEDFFEEFFFCFFFD", + Z: "002000A01680180E2000-200A20282029202F205F3000", + Zs: "002000A01680180E2000-200A202F205F3000", + Zl: "2028", + Zp: "2029", + C: "0000-001F007F-009F00AD03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-0605061C061D0620065F06DD070E070F074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17B417B517DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF200B-200F202A-202E2060-206F20722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-F8FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFD-FF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFFBFFFEFFFF", + Cc: "0000-001F007F-009F", + Cf: "00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB", + Co: "E000-F8FF", + Cs: "D800-DFFF", + Cn: "03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-05FF06040605061C061D0620065F070E074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF2065-206920722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-D7FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFDFEFEFF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFF8FFFEFFFF" +}); + +function addUnicodePackage (pack) { + var codePoint = /\w{4}/g; + for (var name in pack) + exports.packages[name] = pack[name].replace(codePoint, "\\u$&"); +}; + +}); diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 385348d8..45226a1d 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -1,63 +1,79 @@ -/* vim:ts=4:sts=4:sw=4: - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * Irakli Gozalishvili (http://jeditoolkit.com) - * Julian Viereck - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var oop = require("pilot/oop"); -var dom = require("pilot/dom"); -var event = require("pilot/event"); -var useragent = require("pilot/useragent"); -var GutterLayer = require("ace/layer/gutter").Gutter; -var MarkerLayer = require("ace/layer/marker").Marker; -var TextLayer = require("ace/layer/text").Text; -var CursorLayer = require("ace/layer/cursor").Cursor; -var ScrollBar = require("ace/scrollbar").ScrollBar; -var RenderLoop = require("ace/renderloop").RenderLoop; -var EventEmitter = require("pilot/event_emitter").EventEmitter; -var editorCss = require("text!ace/css/editor.css"); +var oop = require("./lib/oop"); +var dom = require("./lib/dom"); +var config = require("./config"); +var useragent = require("./lib/useragent"); +var GutterLayer = require("./layer/gutter").Gutter; +var MarkerLayer = require("./layer/marker").Marker; +var TextLayer = require("./layer/text").Text; +var CursorLayer = require("./layer/cursor").Cursor; +var HScrollBar = require("./scrollbar").HScrollBar; +var VScrollBar = require("./scrollbar").VScrollBar; +var RenderLoop = require("./renderloop").RenderLoop; +var FontMetrics = require("./layer/font_metrics").FontMetrics; +var EventEmitter = require("./lib/event_emitter").EventEmitter; +var editorCss = require("./requirejs/text!./css/editor.css"); -// import CSS once -dom.importCssString(editorCss); +dom.importCssString(editorCss, "ace_editor.css"); + +/** + * The class that is responsible for drawing everything you see on the screen! + * @related editor.renderer + * @class VirtualRenderer + **/ + +/** + * Constructs a new `VirtualRenderer` within the `container` specified, applying the given `theme`. + * @param {DOMElement} container The root element of the editor + * @param {String} theme The starting theme + * + * @constructor + **/ var VirtualRenderer = function(container, theme) { - this.container = container; + var _self = this; + + this.container = container || dom.createElement("div"); + + // 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.isOldIE; + dom.addCssClass(this.container, "ace_editor"); this.setTheme(theme); @@ -75,6 +91,8 @@ var VirtualRenderer = function(container, theme) { this.scroller.appendChild(this.content); this.$gutterLayer = new GutterLayer(this.$gutter); + this.$gutterLayer.on("changeGutterWidth", this.onGutterResize.bind(this)); + this.$markerBack = new MarkerLayer(this.content); var textLayer = this.$textLayer = new TextLayer(this.content); @@ -82,54 +100,85 @@ var VirtualRenderer = function(container, theme) { this.$markerFront = new MarkerLayer(this.content); - this.characterWidth = textLayer.getCharacterWidth(); - this.lineHeight = textLayer.getLineHeight(); - this.$cursorLayer = new CursorLayer(this.content); - this.$cursorPadding = 8; // Indicates whether the horizontal scrollbar is visible - this.$horizScroll = true; - this.$horizScrollAlwaysVisible = true; + this.$horizScroll = false; + this.$vScroll = false; - this.scrollBar = new ScrollBar(container); - this.scrollBar.addEventListener("scroll", this.onScroll.bind(this)); + this.scrollBar = + this.scrollBarV = new VScrollBar(this.container, this); + this.scrollBarH = new HScrollBar(this.container, this); + this.scrollBarV.addEventListener("scroll", function(e) { + if (!_self.$scrollAnimation) + _self.session.setScrollTop(e.data - _self.scrollMargin.top); + }); + this.scrollBarH.addEventListener("scroll", function(e) { + if (!_self.$scrollAnimation) + _self.session.setScrollLeft(e.data - _self.scrollMargin.left); + }); this.scrollTop = 0; + this.scrollLeft = 0; this.cursorPos = { row : 0, column : 0 }; - var _self = this; - this.$textLayer.addEventListener("changeCharaterSize", function() { - _self.characterWidth = textLayer.getCharacterWidth(); - _self.lineHeight = textLayer.getLineHeight(); - _self.$updatePrintMargin(); - _self.onResize(true); - - _self.$loop.schedule(_self.CHANGE_FULL); + this.$fontMetrics = new FontMetrics(this.container, 500); + this.$textLayer.$setFontMetrics(this.$fontMetrics); + this.$textLayer.addEventListener("changeCharacterSize", function(e) { + _self.updateCharacterSize(); + _self.onResize(true, _self.gutterWidth, _self.$size.width, _self.$size.height); + _self._signal("changeCharacterSize", e); }); - event.addListener(this.$gutter, "click", this.$onGutterClick.bind(this)); - event.addListener(this.$gutter, "dblclick", this.$onGutterClick.bind(this)); this.$size = { width: 0, height: 0, scrollerHeight: 0, - scrollerWidth: 0 + scrollerWidth: 0, + $dirty: true }; - this.$loop = new RenderLoop(this.$renderChanges.bind(this)); + this.layerConfig = { + width : 1, + padding : 0, + firstRow : 0, + firstRowScreen: 0, + lastRow : 0, + lineHeight : 0, + characterWidth : 0, + minHeight : 1, + maxHeight : 1, + offset : 0, + height : 1, + gutterOffset: 1 + }; + + this.scrollMargin = { + left: 0, + right: 0, + top: 0, + bottom: 0, + v: 0, + h: 0 + }; + + this.$loop = new RenderLoop( + this.$renderChanges.bind(this), + this.container.ownerDocument.defaultView + ); this.$loop.schedule(this.CHANGE_FULL); + this.updateCharacterSize(); this.setPadding(4); - this.$updatePrintMargin(); + config.resetOptions(this); + config._emit("renderer", this); }; (function() { - this.showGutter = true; this.CHANGE_CURSOR = 1; this.CHANGE_MARKER = 2; @@ -141,23 +190,75 @@ var VirtualRenderer = function(container, theme) { this.CHANGE_MARKER_BACK = 128; this.CHANGE_MARKER_FRONT = 256; this.CHANGE_FULL = 512; + this.CHANGE_H_SCROLL = 1024; + + // this.$logChanges = function(changes) { + // var a = "" + // if (changes & this.CHANGE_CURSOR) a += " cursor"; + // if (changes & this.CHANGE_MARKER) a += " marker"; + // if (changes & this.CHANGE_GUTTER) a += " gutter"; + // if (changes & this.CHANGE_SCROLL) a += " scroll"; + // if (changes & this.CHANGE_LINES) a += " lines"; + // if (changes & this.CHANGE_TEXT) a += " text"; + // if (changes & this.CHANGE_SIZE) a += " size"; + // if (changes & this.CHANGE_MARKER_BACK) a += " marker_back"; + // if (changes & this.CHANGE_MARKER_FRONT) a += " marker_front"; + // if (changes & this.CHANGE_FULL) a += " full"; + // if (changes & this.CHANGE_H_SCROLL) a += " h_scroll"; + // console.log(a.trim()) + // }; oop.implement(this, EventEmitter); + this.updateCharacterSize = function() { + if (this.$textLayer.allowBoldFonts != this.$allowBoldFonts) { + this.$allowBoldFonts = this.$textLayer.allowBoldFonts; + this.setStyle("ace_nobold", !this.$allowBoldFonts); + } + + this.layerConfig.characterWidth = + this.characterWidth = this.$textLayer.getCharacterWidth(); + this.layerConfig.lineHeight = + this.lineHeight = this.$textLayer.getLineHeight(); + this.$updatePrintMargin(); + }; + + /** + * + * Associates the renderer with an [[EditSession `EditSession`]]. + **/ this.setSession = function(session) { + if (this.session) + this.session.doc.off("changeNewLineMode", this.onChangeNewLineMode); + this.session = session; + if (session && this.scrollMargin.top && session.getScrollTop() <= 0) + session.setScrollTop(-this.scrollMargin.top); + this.$cursorLayer.setSession(session); this.$markerBack.setSession(session); this.$markerFront.setSession(session); this.$gutterLayer.setSession(session); this.$textLayer.setSession(session); + if (!session) + return; + this.$loop.schedule(this.CHANGE_FULL); + this.session.$setFontMetrics(this.$fontMetrics); + + this.onChangeNewLineMode = this.onChangeNewLineMode.bind(this); + this.onChangeNewLineMode() + this.session.doc.on("changeNewLineMode", this.onChangeNewLineMode); }; /** - * Triggers partial update of the text layer - */ - this.updateLines = function(firstRow, lastRow) { + * Triggers a partial update of the text, from the range given by the two parameters. + * @param {Number} firstRow The first row to update + * @param {Number} lastRow The last row to update + * + * + **/ + this.updateLines = function(firstRow, lastRow, force) { if (lastRow === undefined) lastRow = Infinity; @@ -175,318 +276,714 @@ var VirtualRenderer = function(container, theme) { this.$changedLines.lastRow = lastRow; } + // If the change happened offscreen above us then it's possible + // that a new line wrap will affect the position of the lines on our + // screen so they need redrawn. + // TODO: better solution is to not change scroll position when text is changed outside of visible area + if (this.$changedLines.lastRow < this.layerConfig.firstRow) { + if (force) + this.$changedLines.lastRow = this.layerConfig.lastRow; + else + return; + } + if (this.$changedLines.firstRow > this.layerConfig.lastRow) + return; this.$loop.schedule(this.CHANGE_LINES); }; + this.onChangeNewLineMode = function() { + this.$loop.schedule(this.CHANGE_TEXT); + this.$textLayer.$updateEolChar(); + }; + + this.onChangeTabSize = function() { + this.$loop.schedule(this.CHANGE_TEXT | this.CHANGE_MARKER); + this.$textLayer.onChangeTabSize(); + }; + /** - * Triggers full update of the text layer - */ + * 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 - */ - this.updateFull = function() { - this.$loop.schedule(this.CHANGE_FULL); + * Triggers a full update of all the layers, for all the rows. + * @param {Boolean} force If `true`, forces the changes through + * + * + **/ + this.updateFull = function(force) { + if (force) + this.$renderChanges(this.CHANGE_FULL, true); + else + this.$loop.schedule(this.CHANGE_FULL); }; /** - * Triggers resize of the editor - */ - this.onResize = function(force) { - var changes = this.CHANGE_SIZE; - - var height = dom.getInnerHeight(this.container); - if (force || this.$size.height != height) { - this.$size.height = height; - - this.scroller.style.height = height + "px"; - this.scrollBar.setHeight(this.scroller.clientHeight); - - if (this.session) { - this.scrollToY(this.getScrollTop()); - changes = changes | this.CHANGE_FULL; - } - } - - var width = dom.getInnerWidth(this.container); - if (force || this.$size.width != width) { - this.$size.width = width; - - var gutterWidth = this.showGutter ? this.$gutter.offsetWidth : 0; - this.scroller.style.left = gutterWidth + "px"; - this.scroller.style.width = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()) + "px"; - - if (this.session.getUseWrapMode()) { - var availableWidth = this.scroller.clientWidth - this.$padding * 2; - var limit = Math.floor(availableWidth / this.characterWidth) - 1; - if (this.session.adjustWrapLimit(limit) || force) { - changes = changes | this.CHANGE_FULL; - } - } - } - - this.$size.scrollerWidth = this.scroller.clientWidth; - this.$size.scrollerHeight = this.scroller.clientHeight; - this.$loop.schedule(changes); + * + * Updates the font size. + **/ + this.updateFontSize = function() { + this.$textLayer.checkForSizeChanges(); }; - this.setTokenizer = function(tokenizer) { - this.$tokenizer = tokenizer; - this.$textLayer.setTokenizer(tokenizer); - this.$loop.schedule(this.CHANGE_TEXT); + this.$changes = 0; + this.$updateSizeAsync = function() { + if (this.$loop.pending) + this.$size.$dirty = true; + else + this.onResize(); }; - - this.$onGutterClick = function(e) { - var pageX = event.getDocumentX(e); - var pageY = event.getDocumentY(e); - - this._dispatchEvent("gutter" + e.type, { - row: this.screenToTextCoordinates(pageX, pageY).row, - htmlEvent: e - }); - }; - - this.setShowInvisibles = function(showInvisibles) { - if (this.$textLayer.setShowInvisibles(showInvisibles)) - this.$loop.schedule(this.CHANGE_TEXT); - }; - - this.getShowInvisibles = function() { - return this.$textLayer.showInvisibles; - }; - - this.$showPrintMargin = true; - this.setShowPrintMargin = function(showPrintMargin) { - this.$showPrintMargin = showPrintMargin; - this.$updatePrintMargin(); - }; - - this.getShowPrintMargin = function() { - return this.$showPrintMargin; - }; - - this.$printMarginColumn = 80; - this.setPrintMarginColumn = function(showPrintMargin) { - this.$printMarginColumn = showPrintMargin; - this.$updatePrintMargin(); - }; - - this.getPrintMarginColumn = function() { - return this.$printMarginColumn; - }; - - this.getShowGutter = function(){ - return this.showGutter; - } - - this.setShowGutter = function(show){ - if(this.showGutter === show) + /** + * [Triggers a resize of the editor.]{: #VirtualRenderer.onResize} + * @param {Boolean} force If `true`, recomputes the size, even if the height and width haven't changed + * @param {Number} gutterWidth The width of the gutter in pixels + * @param {Number} width The width of the editor in pixels + * @param {Number} height The hiehgt of the editor, in pixels + * + * + **/ + this.onResize = function(force, gutterWidth, width, height) { + if (this.resizing > 2) return; - this.$gutter.style.display = show ? "block" : "none"; - this.showGutter = show; - this.onResize(true); - } + else if (this.resizing > 0) + this.resizing++; + else + this.resizing = force ? 1 : 0; + // `|| el.scrollHeight` is required for outosizing editors on ie + // where elements with clientHeight = 0 alsoe have clientWidth = 0 + var el = this.container; + if (!height) + height = el.clientHeight || el.scrollHeight; + if (!width) + width = el.clientWidth || el.scrollWidth; + var changes = this.$updateCachedSize(force, gutterWidth, width, height); + + + if (!this.$size.scrollerHeight || (!width && !height)) + return this.resizing = 0; + + if (force) + this.$gutterLayer.$padding = null; + + if (force) + this.$renderChanges(changes | this.$changes, true); + else + this.$loop.schedule(changes | this.$changes); + + if (this.resizing) + this.resizing = 0; + // reset cached values on scrollbars, needs to be removed when switching to non-native scrollbars + // see https://github.com/ajaxorg/ace/issues/2195 + this.scrollBarV.scrollLeft = this.scrollBarV.scrollTop = null; + }; + + this.$updateCachedSize = function(force, gutterWidth, width, height) { + height -= (this.$extraHeight || 0); + var changes = 0; + var size = this.$size; + var oldSize = { + width: size.width, + height: size.height, + scrollerHeight: size.scrollerHeight, + scrollerWidth: size.scrollerWidth + }; + if (height && (force || size.height != height)) { + size.height = height; + changes |= this.CHANGE_SIZE; + + size.scrollerHeight = size.height; + if (this.$horizScroll) + size.scrollerHeight -= this.scrollBarH.getHeight(); + + // this.scrollBarV.setHeight(size.scrollerHeight); + this.scrollBarV.element.style.bottom = this.scrollBarH.getHeight() + "px"; + + changes = changes | this.CHANGE_SCROLL; + } + + if (width && (force || size.width != width)) { + changes |= this.CHANGE_SIZE; + size.width = width; + + if (gutterWidth == null) + gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0; + + this.gutterWidth = gutterWidth; + + this.scrollBarH.element.style.left = + this.scroller.style.left = gutterWidth + "px"; + size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBarV.getWidth()); + + this.scrollBarH.element.style.right = + this.scroller.style.right = this.scrollBarV.getWidth() + "px"; + this.scroller.style.bottom = this.scrollBarH.getHeight() + "px"; + + // this.scrollBarH.element.style.setWidth(size.scrollerWidth); + + if (this.session && this.session.getUseWrapMode() && this.adjustWrapLimit() || force) + changes |= this.CHANGE_FULL; + } + + size.$dirty = !width || !height; + + if (changes) + this._signal("resize", oldSize); + + return changes; + }; + + this.onGutterResize = function() { + var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0; + if (gutterWidth != this.gutterWidth) + this.$changes |= this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height); + + if (this.session.getUseWrapMode() && this.adjustWrapLimit()) { + this.$loop.schedule(this.CHANGE_FULL); + } else if (this.$size.$dirty) { + this.$loop.schedule(this.CHANGE_FULL); + } else { + this.$computeLayerConfig(); + this.$loop.schedule(this.CHANGE_MARKER); + } + }; + + /** + * 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, this.$showPrintMargin && this.$printMarginColumn); + }; + + /** + * Identifies whether you want to have an animated scroll or not. + * @param {Boolean} shouldAnimate Set to `true` to show animated scrolls + * + **/ + this.setAnimatedScroll = function(shouldAnimate){ + this.setOption("animatedScroll", shouldAnimate); + }; + + /** + * Returns whether an animated scroll happens or not. + * @returns {Boolean} + **/ + this.getAnimatedScroll = function() { + return this.$animatedScroll; + }; + + /** + * Identifies whether you want to show invisible characters or not. + * @param {Boolean} showInvisibles Set to `true` to show invisibles + * + **/ + this.setShowInvisibles = function(showInvisibles) { + this.setOption("showInvisibles", showInvisibles); + }; + + /** + * Returns whether invisible characters are being shown or not. + * @returns {Boolean} + **/ + this.getShowInvisibles = function() { + return this.getOption("showInvisibles"); + }; + this.getDisplayIndentGuides = function() { + return this.getOption("displayIndentGuides"); + }; + + this.setDisplayIndentGuides = function(display) { + this.setOption("displayIndentGuides", display); + }; + + /** + * Identifies whether you want to show the print margin or not. + * @param {Boolean} showPrintMargin Set to `true` to show the print margin + * + **/ + this.setShowPrintMargin = function(showPrintMargin) { + this.setOption("showPrintMargin", showPrintMargin); + }; + + /** + * Returns whether the print margin is being shown or not. + * @returns {Boolean} + **/ + this.getShowPrintMargin = function() { + return this.getOption("showPrintMargin"); + }; + /** + * Identifies whether you want to show the print margin column or not. + * @param {Boolean} showPrintMargin Set to `true` to show the print margin column + * + **/ + this.setPrintMarginColumn = function(showPrintMargin) { + this.setOption("printMarginColumn", showPrintMargin); + }; + + /** + * Returns whether the print margin column is being shown or not. + * @returns {Boolean} + **/ + this.getPrintMarginColumn = function() { + return this.getOption("printMarginColumn"); + }; + + /** + * Returns `true` if the gutter is being shown. + * @returns {Boolean} + **/ + this.getShowGutter = function(){ + return this.getOption("showGutter"); + }; + + /** + * Identifies whether you want to show the gutter or not. + * @param {Boolean} show Set to `true` to show the gutter + * + **/ + this.setShowGutter = function(show){ + return this.setOption("showGutter", show); + }; + + this.getFadeFoldWidgets = function(){ + return this.getOption("fadeFoldWidgets") + }; + + this.setFadeFoldWidgets = function(show) { + this.setOption("fadeFoldWidgets", show); + }; + + this.setHighlightGutterLine = function(shouldHighlight) { + this.setOption("highlightGutterLine", shouldHighlight); + }; + + this.getHighlightGutterLine = function() { + return this.getOption("highlightGutterLine"); + }; + + this.$updateGutterLineHighlight = function() { + var pos = this.$cursorLayer.$pixelPos; + var height = this.layerConfig.lineHeight; + if (this.session.getUseWrapMode()) { + var cursor = this.session.selection.getCursor(); + cursor.column = 0; + pos = this.$cursorLayer.getPixelPosition(cursor, true); + height *= this.session.getRowLength(cursor.row); + } + this.$gutterLineHighlight.style.top = pos.top - this.layerConfig.offset + "px"; + this.$gutterLineHighlight.style.height = height + "px"; + }; this.$updatePrintMargin = function() { - var containerEl - if (!this.$showPrintMargin && !this.$printMarginEl) return; if (!this.$printMarginEl) { - containerEl = dom.createElement("div"); - containerEl.className = "ace_print_margin_layer"; - this.$printMarginEl = dom.createElement("div") - this.$printMarginEl.className = "ace_print_margin"; + var containerEl = dom.createElement("div"); + containerEl.className = "ace_layer ace_print-margin-layer"; + this.$printMarginEl = dom.createElement("div"); + this.$printMarginEl.className = "ace_print-margin"; containerEl.appendChild(this.$printMarginEl); - this.content.insertBefore(containerEl, this.$textLayer.element); + this.content.insertBefore(containerEl, this.content.firstChild); } var style = this.$printMarginEl.style; - style.left = ((this.characterWidth * this.$printMarginColumn) + this.$padding * 2) + "px"; + style.left = ((this.characterWidth * this.$printMarginColumn) + this.$padding) + "px"; style.visibility = this.$showPrintMargin ? "visible" : "hidden"; + + if (this.session && this.session.$wrap == -1) + this.adjustWrapLimit(); }; + /** + * + * Returns the root element containing this renderer. + * @returns {DOMElement} + **/ this.getContainerElement = function() { return this.container; }; + /** + * + * Returns the element that the mouse events are attached to + * @returns {DOMElement} + **/ this.getMouseEventTarget = function() { - return this.content; + return this.scroller; }; + /** + * + * Returns the element to which the hidden text area is added. + * @returns {DOMElement} + **/ this.getTextAreaContainer = function() { - // Let's make it play nice wit iPad. Otherwise the default padding of - // the container will make the cursor shift to the left. - return useragent.isIPad ? this.content : this.container; - + return this.container; }; - this.moveTextAreaToCursor = function(textarea) { - if (!this.layerConfig) + // move text input over the cursor + // this is required for iOS and IME + this.$moveTextAreaToCursor = function() { + if (!this.$keepTextAreaAtCursor) return; + var config = this.layerConfig; + var posTop = this.$cursorLayer.$pixelPos.top; + var posLeft = this.$cursorLayer.$pixelPos.left; + posTop -= config.offset; - var pos, left, top; - if (useragent.isIPad) { - pos = this.$cursorLayer.getPixelPosition(true); - if (!pos) - return; - - left = pos.left + this.$padding - 3; - top = pos.top; - } else { - pos = this.$cursorLayer.getPixelPosition(); - if (!pos) - return; - - var bounds = this.content.getBoundingClientRect(); - var offset = this.layerConfig.offset; - - left = bounds.left + pos.left + this.$padding; - top = bounds.top + pos.top - this.scrollTop + offset; + var style = this.textarea.style; + var h = this.lineHeight; + if (posTop < 0 || posTop > config.height - h) { + style.top = style.left = "0"; + return; } - textarea.style.left = left + "px"; - textarea.style.top = top + "px"; - textarea.style.lineHeight = this.layerConfig.lineHeight + "px"; + var w = this.characterWidth; + if (this.$composition) { + var val = this.textarea.value.replace(/^\x01+/, ""); + w *= (this.session.$getStringScreenWidth(val)[0]+2); + h += 2; + } + posLeft -= this.scrollLeft; + if (posLeft > this.$size.scrollerWidth - w) + posLeft = this.$size.scrollerWidth - w; + + posLeft += this.gutterWidth; + style.height = h + "px"; + style.width = w + "px"; + style.left = Math.min(posLeft, this.$size.scrollerWidth - w) + "px"; + style.top = Math.min(posTop, this.$size.height - h) + "px"; }; + /** + * + * [Returns the index of the first visible row.]{: #VirtualRenderer.getFirstVisibleRow} + * @returns {Number} + **/ this.getFirstVisibleRow = function() { - return (this.layerConfig || {}).firstRow || 0; + return this.layerConfig.firstRow; }; - this.getFirstFullyVisibleRow = function(){ - if (!this.layerConfig) - return 0; - - return this.layerConfig.firstRow + (this.layerConfig.offset == 0 ? 0 : 1); - } + /** + * + * Returns the index of the first fully visible row. "Fully" here means that the characters in the row are not truncated; that the top and the bottom of the row are on the screen. + * @returns {Number} + **/ + this.getFirstFullyVisibleRow = function() { + return this.layerConfig.firstRow + (this.layerConfig.offset === 0 ? 0 : 1); + }; + /** + * + * 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. + * @returns {Number} + **/ this.getLastFullyVisibleRow = function() { - if (!this.layerConfig) - return 0; - var flint = Math.floor((this.layerConfig.height + this.layerConfig.offset) / this.layerConfig.lineHeight); return this.layerConfig.firstRow - 1 + flint; - } + }; + /** + * + * [Returns the index of the last visible row.]{: #VirtualRenderer.getLastVisibleRow} + * @returns {Number} + **/ this.getLastVisibleRow = function() { - return (this.layerConfig || {}).lastRow || 0; + return this.layerConfig.lastRow; }; this.$padding = null; + + /** + * Sets the padding for all the layers. + * @param {Number} padding A new padding value (in pixels) + * + * + * + **/ this.setPadding = function(padding) { this.$padding = padding; - this.content.style.padding = "0 " + padding + "px"; + this.$textLayer.setPadding(padding); + this.$cursorLayer.setPadding(padding); + this.$markerFront.setPadding(padding); + this.$markerBack.setPadding(padding); this.$loop.schedule(this.CHANGE_FULL); this.$updatePrintMargin(); }; + + this.setScrollMargin = function(top, bottom, left, right) { + var sm = this.scrollMargin; + sm.top = top|0; + sm.bottom = bottom|0; + sm.right = right|0; + sm.left = left|0; + sm.v = sm.top + sm.bottom; + sm.h = sm.left + sm.right; + if (sm.top && this.scrollTop <= 0 && this.session) + this.session.setScrollTop(-sm.top); + this.updateFull(); + }; + /** + * Returns whether the horizontal scrollbar is set to be always visible. + * @returns {Boolean} + **/ this.getHScrollBarAlwaysVisible = function() { - return this.$horizScrollAlwaysVisible; - } + return this.$hScrollBarAlwaysVisible; + }; + /** + * Identifies whether you want to show the horizontal scrollbar or not. + * @param {Boolean} alwaysVisible Set to `true` to make the horizontal scroll bar visible + **/ this.setHScrollBarAlwaysVisible = function(alwaysVisible) { - if (this.$horizScrollAlwaysVisible != alwaysVisible) { - this.$horizScrollAlwaysVisible = alwaysVisible; - if (!this.$horizScrollAlwaysVisible || !this.$horizScroll) - this.$loop.schedule(this.CHANGE_SCROLL); + this.setOption("hScrollBarAlwaysVisible", alwaysVisible); + }; + /** + * Returns whether the horizontal scrollbar is set to be always visible. + * @returns {Boolean} + **/ + this.getVScrollBarAlwaysVisible = function() { + return this.$vScrollBarAlwaysVisible; + }; + + /** + * Identifies whether you want to show the horizontal scrollbar or not. + * @param {Boolean} alwaysVisible Set to `true` to make the horizontal scroll bar visible + **/ + this.setVScrollBarAlwaysVisible = function(alwaysVisible) { + this.setOption("vScrollBarAlwaysVisible", alwaysVisible); + }; + + this.$updateScrollBarV = function() { + var scrollHeight = this.layerConfig.maxHeight; + var scrollerHeight = this.$size.scrollerHeight; + if (!this.$maxLines && this.$scrollPastEnd) { + scrollHeight -= (scrollerHeight - this.lineHeight) * this.$scrollPastEnd; + if (this.scrollTop > scrollHeight - scrollerHeight) { + scrollHeight = this.scrollTop + scrollerHeight; + this.scrollBarV.scrollTop = null; + } } - } - - this.onScroll = function(e) { - this.scrollToY(e.data); + this.scrollBarV.setScrollHeight(scrollHeight + this.scrollMargin.v); + this.scrollBarV.setScrollTop(this.scrollTop + this.scrollMargin.top); + }; + this.$updateScrollBarH = function() { + this.scrollBarH.setScrollWidth(this.layerConfig.width + 2 * this.$padding + this.scrollMargin.h); + this.scrollBarH.setScrollLeft(this.scrollLeft + this.scrollMargin.left); + }; + + this.$frozen = false; + this.freeze = function() { + this.$frozen = true; + }; + + this.unfreeze = function() { + this.$frozen = false; }; - this.$updateScrollBar = function() { - this.scrollBar.setInnerHeight(this.session.getScreenLength() * this.lineHeight); - this.scrollBar.setScrollTop(this.scrollTop); - }; - - this.$renderChanges = function(changes) { - if (!changes || !this.session || !this.$tokenizer) - return; - + this.$renderChanges = function(changes, force) { + if (this.$changes) { + changes |= this.$changes; + this.$changes = 0; + } + if ((!this.session || !this.container.offsetWidth || this.$frozen) || (!changes && !force)) { + this.$changes |= changes; + return; + } + if (this.$size.$dirty) { + this.$changes |= changes; + return this.onResize(true); + } + if (!this.lineHeight) { + this.$textLayer.checkForSizeChanges(); + } + // this.$logChanges(changes); + + this._signal("beforeRender"); + var config = this.layerConfig; // text, scrolling and resize changes can cause the view port size to change - if (!this.layerConfig || - changes & this.CHANGE_FULL || + if (changes & this.CHANGE_FULL || changes & this.CHANGE_SIZE || changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES || - changes & this.CHANGE_SCROLL - ) - this.$computeLayerConfig(); + changes & this.CHANGE_SCROLL || + changes & this.CHANGE_H_SCROLL + ) { + changes |= this.$computeLayerConfig(); + // If a change is made offscreen and wrapMode is on, then the onscreen + // lines may have been pushed down. If so, the first screen row will not + // have changed, but the first actual row will. In that case, adjust + // scrollTop so that the cursor and onscreen content stays in the same place. + // TODO: find a better way to handle this, that works non wrapped case and doesn't compute layerConfig twice + if (config.firstRow != this.layerConfig.firstRow && config.firstRowScreen == this.layerConfig.firstRowScreen) { + var st = this.scrollTop + (config.firstRow - this.layerConfig.firstRow) * this.lineHeight; + if (st > 0) { + // this check is needed as a workaround for the documentToScreenRow returning -1 if document.length == 0 + this.scrollTop = st; + changes = changes | this.CHANGE_SCROLL; + changes |= this.$computeLayerConfig(); + } + } + config = this.layerConfig; + // update scrollbar first to not lose scroll position when gutter calls resize + this.$updateScrollBarV(); + if (changes & this.CHANGE_H_SCROLL) + this.$updateScrollBarH(); + this.$gutterLayer.element.style.marginTop = (-config.offset) + "px"; + this.content.style.marginTop = (-config.offset) + "px"; + this.content.style.width = config.width + 2 * this.$padding + "px"; + this.content.style.height = config.minHeight + "px"; + } + + // horizontal scrolling + if (changes & this.CHANGE_H_SCROLL) { + this.content.style.marginLeft = -this.scrollLeft + "px"; + this.scroller.className = this.scrollLeft <= 0 ? "ace_scroller" : "ace_scroller ace_scroll-left"; + } // full if (changes & this.CHANGE_FULL) { - 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.$updateScrollBar(); - this.scrollCursorIntoView(); + this.$textLayer.update(config); + if (this.$showGutter) + this.$gutterLayer.update(config); + this.$markerBack.update(config); + this.$markerFront.update(config); + this.$cursorLayer.update(config); + this.$moveTextAreaToCursor(); + this.$highlightGutterLine && this.$updateGutterLineHighlight(); + this._signal("afterRender"); return; } // scrolling if (changes & this.CHANGE_SCROLL) { if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES) - this.$textLayer.update(this.layerConfig); + this.$textLayer.update(config); else - 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.$updateScrollBar(); + this.$textLayer.scrollLines(config); + + if (this.$showGutter) + this.$gutterLayer.update(config); + this.$markerBack.update(config); + this.$markerFront.update(config); + this.$cursorLayer.update(config); + this.$highlightGutterLine && this.$updateGutterLineHighlight(); + this.$moveTextAreaToCursor(); + this._signal("afterRender"); return; } if (changes & this.CHANGE_TEXT) { - this.$textLayer.update(this.layerConfig); - this.showGutter && this.$gutterLayer.update(this.layerConfig); + this.$textLayer.update(config); + if (this.$showGutter) + this.$gutterLayer.update(config); } else if (changes & this.CHANGE_LINES) { - this.$updateLines(); - this.$updateScrollBar(); - this.showGutter && this.$gutterLayer.update(this.layerConfig); - } else if (changes & this.CHANGE_GUTTER) { - this.showGutter && this.$gutterLayer.update(this.layerConfig); + if (this.$updateLines() || (changes & this.CHANGE_GUTTER) && this.$showGutter) + this.$gutterLayer.update(config); + } + else if (changes & this.CHANGE_TEXT || changes & this.CHANGE_GUTTER) { + if (this.$showGutter) + this.$gutterLayer.update(config); } - if (changes & this.CHANGE_CURSOR) - this.$cursorLayer.update(this.layerConfig); + if (changes & this.CHANGE_CURSOR) { + this.$cursorLayer.update(config); + this.$moveTextAreaToCursor(); + this.$highlightGutterLine && this.$updateGutterLineHighlight(); + } if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) { - this.$markerFront.update(this.layerConfig); + this.$markerFront.update(config); } if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) { - this.$markerBack.update(this.layerConfig); + this.$markerBack.update(config); } - if (changes & this.CHANGE_SIZE) - this.$updateScrollBar(); + this._signal("afterRender"); }; + + this.$autosize = function() { + var height = this.session.getScreenLength() * this.lineHeight; + var maxHeight = this.$maxLines * this.lineHeight; + var desiredHeight = Math.max( + (this.$minLines||1) * this.lineHeight, + Math.min(maxHeight, height) + ) + this.scrollMargin.v + (this.$extraHeight || 0); + if (this.$horizScroll) + desiredHeight += this.scrollBarH.getHeight(); + var vScroll = height > maxHeight; + + if (desiredHeight != this.desiredHeight || + this.$size.height != this.desiredHeight || vScroll != this.$vScroll) { + if (vScroll != this.$vScroll) { + this.$vScroll = vScroll; + this.scrollBarV.setVisible(vScroll); + } + + var w = this.container.clientWidth; + this.container.style.height = desiredHeight + "px"; + this.$updateCachedSize(true, this.$gutterWidth, w, desiredHeight); + // this.$loop.changes = 0; + this.desiredHeight = desiredHeight; + + this._signal("autosize"); + } + }; + this.$computeLayerConfig = function() { var session = this.session; - - var offset = this.scrollTop % this.lineHeight; - var minHeight = this.$size.scrollerHeight + this.lineHeight; + var size = this.$size; + + var hideScrollbars = size.height <= 2 * this.lineHeight; + var screenLines = this.session.getScreenLength(); + var maxHeight = screenLines * this.lineHeight; var longestLine = this.$getLongestLine(); - var widthChanged = !this.layerConfig ? true : (this.layerConfig.width != longestLine); + + var horizScroll = !hideScrollbars && (this.$hScrollBarAlwaysVisible || + size.scrollerWidth - longestLine - 2 * this.$padding < 0); - var horizScroll = this.$horizScrollAlwaysVisible || this.$size.scrollerWidth - longestLine < 0; - var horizScrollChanged = this.$horizScroll !== horizScroll; - this.$horizScroll = horizScroll; - if (horizScrollChanged) - this.scroller.style.overflowX = horizScroll ? "scroll" : "hidden"; + var hScrollChanged = this.$horizScroll !== horizScroll; + if (hScrollChanged) { + this.$horizScroll = horizScroll; + this.scrollBarH.setVisible(horizScroll); + } + // autoresize only after updating hscroll to include scrollbar height in desired height + if (this.$maxLines && this.lineHeight > 1) + this.$autosize(); + + var offset = this.scrollTop % this.lineHeight; + var minHeight = size.scrollerHeight + this.lineHeight; + + var scrollPastEnd = !this.$maxLines && this.$scrollPastEnd + ? (size.scrollerHeight - this.lineHeight) * this.$scrollPastEnd + : 0; + maxHeight += scrollPastEnd; + + var sm = this.scrollMargin; + this.session.setScrollTop(Math.max(-sm.top, + Math.min(this.scrollTop, maxHeight - size.scrollerHeight + sm.bottom))); + + this.session.setScrollLeft(Math.max(-sm.left, Math.min(this.scrollLeft, + longestLine + 2 * this.$padding - size.scrollerWidth + sm.right))); + + var vScroll = !hideScrollbars && (this.$vScrollBarAlwaysVisible || + size.scrollerHeight - maxHeight + scrollPastEnd < 0 || this.scrollTop > sm.top); + var vScrollChanged = this.$vScroll !== vScroll; + if (vScrollChanged) { + this.$vScroll = vScroll; + this.scrollBarV.setVisible(vScroll); + } var lineCount = Math.ceil(minHeight / this.lineHeight) - 1; var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight)); @@ -494,39 +991,56 @@ var VirtualRenderer = function(container, theme) { // Map lines on the screen to lines in the document. var firstRowScreen, firstRowHeight; - var lineHeight = { lineHeight: this.lineHeight }; - firstRow = session.screenToDocumentRow(firstRow); - firstRowScreen = session.documentToScreenRow(firstRow); - firstRowHeight = session.getRowHeight(lineHeight, firstRow); + var lineHeight = this.lineHeight; + firstRow = session.screenToDocumentRow(firstRow, 0); - lastRow = Math.min(session.screenToDocumentRow(lastRow), session.getLength() - 1); - minHeight = this.$size.scrollerHeight + session.getRowHeight(lineHeight, lastRow)+ + // Check if firstRow is inside of a foldLine. If true, then use the first + // row of the foldLine. + var foldLine = session.getFoldLine(firstRow); + if (foldLine) { + firstRow = foldLine.start.row; + } + + firstRowScreen = session.documentToScreenRow(firstRow, 0); + firstRowHeight = session.getRowLength(firstRow) * lineHeight; + + lastRow = Math.min(session.screenToDocumentRow(lastRow, 0), session.getLength() - 1); + minHeight = size.scrollerHeight + session.getRowLength(lastRow) * lineHeight + firstRowHeight; - offset = this.scrollTop - firstRowScreen * this.lineHeight; + offset = this.scrollTop - firstRowScreen * lineHeight; - var layerConfig = this.layerConfig = { + var changes = 0; + if (this.layerConfig.width != longestLine) + changes = this.CHANGE_H_SCROLL; + // Horizontal scrollbar visibility may have changed, which changes + // the client height of the scroller + if (hScrollChanged || vScrollChanged) { + changes = this.$updateCachedSize(true, this.gutterWidth, size.width, size.height); + this._signal("scrollbarVisibilityChanged"); + if (vScrollChanged) + longestLine = this.$getLongestLine(); + } + + this.layerConfig = { width : longestLine, padding : this.$padding, firstRow : firstRow, firstRowScreen: firstRowScreen, lastRow : lastRow, - lineHeight : this.lineHeight, + lineHeight : lineHeight, characterWidth : this.characterWidth, minHeight : minHeight, + maxHeight : maxHeight, offset : offset, + gutterOffset : Math.max(0, Math.ceil((offset + size.height - size.scrollerHeight) / lineHeight)), height : this.$size.scrollerHeight }; - this.$gutterLayer.element.style.marginTop = (-offset) + "px"; - this.content.style.marginTop = (-offset) + "px"; - this.content.style.width = longestLine + "px"; - this.content.style.height = minHeight + "px"; + // For debugging. + // console.log(JSON.stringify(this.layerConfig)); - // Horizontal scrollbar visibility may have changed, which changes - // the client height of the scroller - if (horizScrollChanged) - this.onResize(true); + return changes; }; this.$updateLines = function() { @@ -536,172 +1050,399 @@ var VirtualRenderer = function(container, theme) { var layerConfig = this.layerConfig; - // if the update changes the width of the document do a full redraw - if (layerConfig.width != this.$getLongestLine()) - return this.$textLayer.update(layerConfig); - if (firstRow > layerConfig.lastRow + 1) { return; } if (lastRow < layerConfig.firstRow) { return; } // if the last row is unknown -> redraw everything if (lastRow === Infinity) { - this.showGutter && this.$gutterLayer.update(layerConfig); + if (this.$showGutter) + this.$gutterLayer.update(layerConfig); this.$textLayer.update(layerConfig); return; } // else update only the changed rows this.$textLayer.updateLines(layerConfig, firstRow, lastRow); + return true; }; this.$getLongestLine = function() { - var charCount = this.session.getScreenWidth() + 1; - if (this.$textLayer.showInvisibles) + var charCount = this.session.getScreenWidth(); + if (this.showInvisibles && !this.session.$useWrapMode) charCount += 1; - return Math.max(this.$size.scrollerWidth - this.$padding * 2, Math.round(charCount * this.characterWidth)); + return Math.max(this.$size.scrollerWidth - 2 * this.$padding, Math.round(charCount * this.characterWidth)); }; + /** + * + * 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); }; + /** + * + * 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); }; + /** + * + * Deprecated; (moved to [[EditSession]]) + * @deprecated + **/ this.addGutterDecoration = function(row, className){ this.$gutterLayer.addGutterDecoration(row, className); - this.$loop.schedule(this.CHANGE_GUTTER); - } + }; + /** + * Deprecated; (moved to [[EditSession]]) + * @deprecated + **/ this.removeGutterDecoration = function(row, className){ this.$gutterLayer.removeGutterDecoration(row, className); - this.$loop.schedule(this.CHANGE_GUTTER); - } + }; - this.setBreakpoints = function(rows) { - this.$gutterLayer.setBreakpoints(rows); + /** + * + * Redraw breakpoints. + **/ + this.updateBreakpoints = function(rows) { this.$loop.schedule(this.CHANGE_GUTTER); }; + /** + * + * Sets annotations for the gutter. + * @param {Array} annotations An array containing annotations + * + * + **/ this.setAnnotations = function(annotations) { this.$gutterLayer.setAnnotations(annotations); this.$loop.schedule(this.CHANGE_GUTTER); }; + /** + * + * Updates the cursor icon. + **/ this.updateCursor = function() { this.$loop.schedule(this.CHANGE_CURSOR); }; + /** + * + * Hides the cursor icon. + **/ this.hideCursor = function() { this.$cursorLayer.hideCursor(); }; + /** + * + * Shows the cursor icon. + **/ this.showCursor = function() { this.$cursorLayer.showCursor(); }; - this.scrollCursorIntoView = function() { + this.scrollSelectionIntoView = function(anchor, lead, offset) { + // first scroll anchor into view then scroll lead into view + this.scrollCursorIntoView(anchor, offset); + this.scrollCursorIntoView(lead, offset); + }; + + /** + * + * Scrolls the cursor into the first visibile area of the editor + **/ + this.scrollCursorIntoView = function(cursor, offset, $viewMargin) { // the editor is not visible if (this.$size.scrollerHeight === 0) return; - var pos = this.$cursorLayer.getPixelPosition(); + var pos = this.$cursorLayer.getPixelPosition(cursor); - var left = pos.left + this.$padding; + var left = pos.left; var top = pos.top; - - if (this.getScrollTop() > top) { - this.scrollToY(top); + + var topMargin = $viewMargin && $viewMargin.top || 0; + var bottomMargin = $viewMargin && $viewMargin.bottom || 0; + + var scrollTop = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop; + + if (scrollTop + topMargin > top) { + if (offset) + top -= offset * this.$size.scrollerHeight; + if (top === 0) + top = -this.scrollMargin.top; + this.session.setScrollTop(top); + } else if (scrollTop + this.$size.scrollerHeight - bottomMargin < top + this.lineHeight) { + if (offset) + top += offset * this.$size.scrollerHeight; + this.session.setScrollTop(top + this.lineHeight - this.$size.scrollerHeight); } - if (this.getScrollTop() + this.$size.scrollerHeight < top - + this.lineHeight) { - this.scrollToY(top + this.lineHeight - this.$size.scrollerHeight); + var scrollLeft = this.scrollLeft; + + if (scrollLeft > left) { + if (left < this.$padding + 2 * this.layerConfig.characterWidth) + left = -this.scrollMargin.left; + this.session.setScrollLeft(left); + } else if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) { + this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth)); + } else if (scrollLeft <= this.$padding && left - scrollLeft < this.characterWidth) { + this.session.setScrollLeft(0); } + }; - if (this.scroller.scrollLeft > left) { - this.scrollToX(left); - } - - if (this.scroller.scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) { - - if (left + this.characterWidth > this.scroller.scrollWidth) - this.$renderChanges(this.CHANGE_SIZE); - - this.scrollToX(Math.round(left + this.characterWidth - this.$size.scrollerWidth)); - } - }, - + /** + * {:EditSession.getScrollTop} + * @related EditSession.getScrollTop + * @returns {Number} + **/ this.getScrollTop = function() { - return this.scrollTop; + return this.session.getScrollTop(); }; + /** + * {:EditSession.getScrollLeft} + * @related EditSession.getScrollLeft + * @returns {Number} + **/ this.getScrollLeft = function() { - return this.scroller.scrollLeft; + return this.session.getScrollLeft(); }; + /** + * + * Returns the first visible row, regardless of whether it's fully visible or not. + * @returns {Number} + **/ this.getScrollTopRow = function() { return this.scrollTop / this.lineHeight; }; + /** + * + * Returns the last visible row, regardless of whether it's fully visible or not. + * @returns {Number} + **/ this.getScrollBottomRow = function() { return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1); - } + }; + /** + * Gracefully scrolls from the top of the editor to the row indicated. + * @param {Number} row A row id + * + * + * @related EditSession.setScrollTop + **/ this.scrollToRow = function(row) { - this.scrollToY(row * this.lineHeight); + this.session.setScrollTop(row * this.lineHeight); }; - this.scrollToLine = function(line, center) { - var lineHeight = { lineHeight: this.lineHeight }; - var offset = 0; - for (var l = 1; l < line; l++) { - offset += this.session.getRowHeight(lineHeight, l-1); - } + this.alignCursor = function(cursor, alignment) { + if (typeof cursor == "number") + cursor = {row: cursor, column: 0}; - if (center) { + var pos = this.$cursorLayer.getPixelPosition(cursor); + var h = this.$size.scrollerHeight - this.lineHeight; + var offset = pos.top - h * (alignment || 0); + + this.session.setScrollTop(offset); + return offset; + }; + + this.STEPS = 8; + this.$calcSteps = function(fromValue, toValue){ + var i = 0; + var l = this.STEPS; + var steps = []; + + var func = function(t, x_min, dx) { + 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)); + + return steps; + }; + + /** + * Gracefully scrolls the editor to the row indicated. + * @param {Number} line A line number + * @param {Boolean} center If `true`, centers the editor the to indicated line + * @param {Boolean} animate If `true` animates scrolling + * @param {Function} callback Function to be called after the animation has finished + * + * + **/ + 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; - } - this.scrollToY(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) + return; + var _self = this; + + if (fromValue == toValue) + return; + + if (this.$scrollAnimation) { + var oldSteps = this.$scrollAnimation.steps; + if (oldSteps.length) { + fromValue = oldSteps[0]; + if (fromValue == toValue) + return; + } + } + + var steps = _self.$calcSteps(fromValue, toValue); + this.$scrollAnimation = {from: fromValue, to: toValue, steps: steps}; + + clearInterval(this.$timer); + + _self.session.setScrollTop(steps.shift()); + // trick session to think it's already scrolled to not loose toValue + _self.session.$scrollTop = toValue; + this.$timer = setInterval(function() { + if (steps.length) { + _self.session.setScrollTop(steps.shift()); + _self.session.$scrollTop = toValue; + } else if (toValue != null) { + _self.session.$scrollTop = -1; + _self.session.setScrollTop(toValue); + toValue = null; + } else { + // do this on separate step to not get spurious scroll event from scrollbar + _self.$timer = clearInterval(_self.$timer); + _self.$scrollAnimation = null; + callback && callback(); + } + }, 10); + }; + + /** + * Scrolls the editor to the y pixel indicated. + * @param {Number} scrollTop The position to scroll to + * + * + * @returns {Number} + **/ this.scrollToY = function(scrollTop) { - var maxHeight = this.session.getScreenLength() * this.lineHeight - this.$size.scrollerHeight; - var scrollTop = Math.max(0, Math.min(maxHeight, scrollTop)); - + // after calling scrollBar.setScrollTop + // scrollbar sends us event with same scrollTop. ignore it if (this.scrollTop !== scrollTop) { - this.scrollTop = scrollTop; this.$loop.schedule(this.CHANGE_SCROLL); + this.scrollTop = scrollTop; } }; + /** + * Scrolls the editor across the x-axis to the pixel indicated. + * @param {Number} scrollLeft The position to scroll to + * + * + * @returns {Number} + **/ this.scrollToX = function(scrollLeft) { - if (scrollLeft <= this.$padding) - scrollLeft = 0; - - this.scroller.scrollLeft = scrollLeft; + if (this.scrollLeft !== scrollLeft) + this.scrollLeft = scrollLeft; + this.$loop.schedule(this.CHANGE_H_SCROLL); }; + /** + * Scrolls the editor across both x- and y-axes. + * @param {Number} x The x value to scroll to + * @param {Number} y The y value to scroll to + **/ + this.scrollTo = function(x, y) { + this.session.setScrollTop(y); + this.session.setScrollLeft(y); + }; + + /** + * Scrolls the editor across both x- and y-axes. + * @param {Number} deltaX The x value to scroll by + * @param {Number} deltaY The y value to scroll by + **/ this.scrollBy = function(deltaX, deltaY) { - deltaY && this.scrollToY(this.scrollTop + deltaY); - deltaX && this.scrollToX(this.scroller.scrollLeft + deltaX); + deltaY && this.session.setScrollTop(this.session.getScrollTop() + deltaY); + deltaX && this.session.setScrollLeft(this.session.getScrollLeft() + deltaX); }; - this.screenToTextCoordinates = function(pageX, pageY) { + /** + * Returns `true` if you can still scroll by either parameter; in other words, you haven't reached the end of the file or line. + * @param {Number} deltaX The x value to scroll by + * @param {Number} deltaY The y value to scroll by + * + * + * @returns {Boolean} + **/ + this.isScrollableBy = function(deltaX, deltaY) { + if (deltaY < 0 && this.session.getScrollTop() >= 1 - this.scrollMargin.top) + return true; + if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight + - this.layerConfig.maxHeight < -1 + this.scrollMargin.bottom) + return true; + if (deltaX < 0 && this.session.getScrollLeft() >= 1 - this.scrollMargin.left) + return true; + if (deltaX > 0 && this.session.getScrollLeft() + this.$size.scrollerWidth + - this.layerConfig.width < -1 + this.scrollMargin.right) + return true; + }; + + this.pixelToScreenCoordinates = function(x, y) { var canvasPos = this.scroller.getBoundingClientRect(); - var col = Math.round((pageX + this.scroller.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, side: offset - col > 0 ? 1 : -1}; + }; + + this.screenToTextCoordinates = function(x, y) { + var canvasPos = this.scroller.getBoundingClientRect(); + + var col = Math.round( + (x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth + ); + + var row = (y + this.scrollTop - canvasPos.top) / this.lineHeight; return this.session.screenToDocumentPosition(row, Math.max(col, 0)); }; + /** + * Returns an object containing the `pageX` and `pageY` coordinates of the document position. + * @param {Number} row The document row position + * @param {Number} column The document column position + * + * + * + * @returns {Object} + **/ this.textToScreenCoordinates = function(row, column) { var canvasPos = this.scroller.getBoundingClientRect(); var pos = this.session.documentToScreenPosition(row, column); @@ -710,94 +1451,317 @@ var VirtualRenderer = function(container, theme) { var y = pos.row * this.lineHeight; return { - pageX: canvasPos.left + x - this.getScrollLeft(), - pageY: canvasPos.top + y - this.getScrollTop() - } + pageX: canvasPos.left + x - this.scrollLeft, + pageY: canvasPos.top + y - this.scrollTop + }; }; + /** + * + * Focuses the current container. + **/ this.visualizeFocus = function() { dom.addCssClass(this.container, "ace_focus"); }; + /** + * + * Blurs the current container. + **/ this.visualizeBlur = function() { dom.removeCssClass(this.container, "ace_focus"); }; + /** + * @param {Number} position + * + * @private + **/ this.showComposition = function(position) { - if (!this.$composition) { - this.$composition = dom.createElement("div"); - this.$composition.className = "ace_composition"; - this.content.appendChild(this.$composition); - } + if (!this.$composition) + this.$composition = { + keepTextAreaAtCursor: this.$keepTextAreaAtCursor, + cssText: this.textarea.style.cssText + }; - this.$composition.innerHTML = " "; - - var pos = this.$cursorLayer.getPixelPosition(); - var style = this.$composition.style; - style.top = pos.top + "px"; - style.left = (pos.left + this.$padding) + "px"; - style.height = this.lineHeight + "px"; - - this.hideCursor(); + this.$keepTextAreaAtCursor = true; + dom.addCssClass(this.textarea, "ace_composition"); + this.textarea.style.cssText = ""; + this.$moveTextAreaToCursor(); }; + /** + * @param {String} text 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); + this.$moveTextAreaToCursor(); }; + /** + * + * Hides the current composition. + **/ this.hideComposition = function() { - this.showCursor(); - if (!this.$composition) return; - var style = this.$composition.style; - style.top = "-10000px"; - style.left = "-10000px"; + dom.removeCssClass(this.textarea, "ace_composition"); + this.$keepTextAreaAtCursor = this.$composition.keepTextAreaAtCursor; + this.textarea.style.cssText = this.$composition.cssText; + this.$composition = null; }; - this.setTheme = function(theme) { + /** + * [Sets a new theme for the editor. `theme` should exist, and be a directory path, like `ace/theme/textmate`.]{: #VirtualRenderer.setTheme} + * @param {String} theme The path to a theme + * @param {Function} cb optional callback + * + **/ + this.setTheme = function(theme, cb) { var _self = this; + this.$themeId = theme; + _self._dispatchEvent('themeChange',{theme:theme}); + if (!theme || typeof theme == "string") { - theme = theme || "ace/theme/textmate"; - require([theme], function(theme) { - afterLoad(theme); - }); + var moduleName = theme || this.$options.theme.initialValue; + config.loadModule(["theme", moduleName], afterLoad); } else { afterLoad(theme); } - var _self = this; - function afterLoad(theme) { - if (_self.$theme) - dom.removeCssClass(_self.container, _self.$theme); + function afterLoad(module) { + if (_self.$themeId != theme) + return cb && cb(); + if (!module.cssClass) + return; + dom.importCssString( + module.cssText, + module.cssClass, + _self.container.ownerDocument + ); - _self.$theme = theme ? theme.cssClass : null; + if (_self.theme) + dom.removeCssClass(_self.container, _self.theme.cssClass); - if (_self.$theme) - dom.addCssClass(_self.container, _self.$theme); + var padding = "padding" in module ? module.padding + : "padding" in (_self.theme || {}) ? 4 : _self.$padding; + if (_self.$padding && padding != _self.$padding) + _self.setPadding(padding); + + // this is kept only for backwards compatibility + _self.$theme = module.cssClass; + + _self.theme = module; + dom.addCssClass(_self.container, module.cssClass); + dom.setCssClass(_self.container, "ace_dark", module.isDark); // force re-measure of the gutter width if (_self.$size) { _self.$size.width = 0; - _self.onResize(); + _self.$updateSizeAsync(); } + + _self._dispatchEvent('themeLoaded', {theme:module}); + cb && cb(); } }; + /** + * [Returns the path of the current theme.]{: #VirtualRenderer.getTheme} + * @returns {String} + **/ + this.getTheme = function() { + return this.$themeId; + }; + // Methods allows to add / remove CSS classnames to the editor element. // This feature can be used by plug-ins to provide a visual indication of // a certain mode that editor is in. - this.setStyle = function setStyle(style) { - dom.addCssClass(this.container, style) + /** + * [Adds a new class, `style`, to the editor.]{: #VirtualRenderer.setStyle} + * @param {String} style A class name + * + **/ + this.setStyle = function(style, include) { + dom.setCssClass(this.container, style, include !== false); }; - this.unsetStyle = function unsetStyle(style) { - dom.removeCssClass(this.container, style) + /** + * [Removes the class `style` from the editor.]{: #VirtualRenderer.unsetStyle} + * @param {String} style A class name + * + **/ + this.unsetStyle = function(style) { + dom.removeCssClass(this.container, style); + }; + + this.setCursorStyle = function(style) { + if (this.scroller.style.cursor != style) + this.scroller.style.cursor = style; + }; + + /** + * @param {String} cursorStyle A css cursor style + * + **/ + this.setMouseCursor = function(cursorStyle) { + this.scroller.style.cursor = cursorStyle; + }; + + /** + * Destroys the text and cursor layers for this renderer. + **/ + this.destroy = function() { + this.$textLayer.destroy(); + this.$cursorLayer.destroy(); }; }).call(VirtualRenderer.prototype); + +config.defineOptions(VirtualRenderer.prototype, "renderer", { + animatedScroll: {initialValue: false}, + showInvisibles: { + set: function(value) { + if (this.$textLayer.setShowInvisibles(value)) + this.$loop.schedule(this.CHANGE_TEXT); + }, + initialValue: false + }, + showPrintMargin: { + set: function() { this.$updatePrintMargin(); }, + initialValue: true + }, + printMarginColumn: { + set: function() { this.$updatePrintMargin(); }, + initialValue: 80 + }, + printMargin: { + set: function(val) { + if (typeof val == "number") + this.$printMarginColumn = val; + this.$showPrintMargin = !!val; + this.$updatePrintMargin(); + }, + get: function() { + return this.$showPrintMargin && this.$printMarginColumn; + } + }, + showGutter: { + set: function(show){ + this.$gutter.style.display = show ? "block" : "none"; + this.$loop.schedule(this.CHANGE_FULL); + this.onGutterResize(); + }, + initialValue: true + }, + fadeFoldWidgets: { + set: function(show) { + dom.setCssClass(this.$gutter, "ace_fade-fold-widgets", show); + }, + initialValue: false + }, + showFoldWidgets: { + set: function(show) {this.$gutterLayer.setShowFoldWidgets(show)}, + initialValue: true + }, + showLineNumbers: { + set: function(show) { + this.$gutterLayer.setShowLineNumbers(show); + this.$loop.schedule(this.CHANGE_GUTTER); + }, + initialValue: true + }, + displayIndentGuides: { + set: function(show) { + if (this.$textLayer.setDisplayIndentGuides(show)) + this.$loop.schedule(this.CHANGE_TEXT); + }, + initialValue: true + }, + highlightGutterLine: { + set: function(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"; + // if cursorlayer have never been updated there's nothing on screen to update + if (this.$cursorLayer.$pixelPos) + this.$updateGutterLineHighlight(); + }, + initialValue: false, + value: true + }, + hScrollBarAlwaysVisible: { + set: function(val) { + if (!this.$hScrollBarAlwaysVisible || !this.$horizScroll) + this.$loop.schedule(this.CHANGE_SCROLL); + }, + initialValue: false + }, + vScrollBarAlwaysVisible: { + set: function(val) { + if (!this.$vScrollBarAlwaysVisible || !this.$vScroll) + this.$loop.schedule(this.CHANGE_SCROLL); + }, + initialValue: false + }, + fontSize: { + set: function(size) { + if (typeof size == "number") + size = size + "px"; + this.container.style.fontSize = size; + this.updateFontSize(); + }, + initialValue: 12 + }, + fontFamily: { + set: function(name) { + this.container.style.fontFamily = name; + this.updateFontSize(); + } + }, + maxLines: { + set: function(val) { + this.updateFull(); + } + }, + minLines: { + set: function(val) { + this.updateFull(); + } + }, + scrollPastEnd: { + set: function(val) { + val = +val || 0; + if (this.$scrollPastEnd == val) + return; + this.$scrollPastEnd = val; + this.$loop.schedule(this.CHANGE_SCROLL); + }, + initialValue: 0, + handlesSet: true + }, + fixedWidthGutter: { + set: function(val) { + this.$gutterLayer.$fixedWidth = !!val; + this.$loop.schedule(this.CHANGE_GUTTER); + } + }, + theme: { + set: function(val) { this.setTheme(val) }, + get: function() { return this.$themeId || this.theme; }, + initialValue: "./theme/textmate", + handlesSet: true + } +}); + exports.VirtualRenderer = VirtualRenderer; }); diff --git a/lib/ace/virtual_renderer_test.js b/lib/ace/virtual_renderer_test.js new file mode 100644 index 00000000..9b1ed866 --- /dev/null +++ b/lib/ace/virtual_renderer_test.js @@ -0,0 +1,116 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); + require("./test/mockdom"); +} + +define(function(require, exports, module) { +"use strict"; + +var Editor = require("./edit_session").Editor; +var EditSession = require("./edit_session").EditSession; +var VirtualRenderer = require("./virtual_renderer").VirtualRenderer; +var assert = require("./test/assertions"); + +var editor = null; +module.exports = { + setUp: function() { + if (editor) + editor.destroy() + var el = document.createElement("div"); + if (!el.getBoundingClientRect) { + console.log("Skipping test: This test only runs in the browser"); + return; + } + el.style.left = "20px"; + el.style.top = "30px"; + el.style.width = "300px"; + el.style.height = "100px"; + document.body.appendChild(el); + var renderer = new VirtualRenderer(el); + var editor = new Editor(renderer); + editor.on("destroy", function() { + document.body.removeChild(el); + }); + }, + tearDown: function() { + editor && editor.destroy(); + editor = null; + }, + "test: screen2text the column should be rounded to the next character edge" : function(done) { + if (!editor) return done(); + var renderer = editor.renderer; + + renderer.setPadding(0); + renderer.setSession(new EditSession("1234")); + + var r = renderer.scroller.getBoundingClientRect(); + function testPixelToText(x, y, row, column) { + assert.position(renderer.screenToTextCoordinates(x+r.left, y+r.top), row, column); + } + + renderer.characterWidth = 10; + renderer.lineHeight = 15; + + testPixelToText(4, 0, 0, 0); + testPixelToText(5, 0, 0, 1); + testPixelToText(9, 0, 0, 1); + testPixelToText(10, 0, 0, 1); + testPixelToText(14, 0, 0, 1); + testPixelToText(15, 0, 0, 2); + done(); + }, + + "test scrollmargin + autosize": function(done) { + if (!editor) return done(); + editor.setOptions({ + maxLines: 100, + useWrapMode: true + }); + editor.renderer.setScrollMargin(10, 10); + editor.setValue("\n\n"); + editor.setValue("\n\n\n\n"); + editor.renderer.once("afterRender", function() { + setTimeout(function() { + done(); + }, 0); + }); + } + + // change tab size after setDocument (for text layer) +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} diff --git a/lib/ace/worker/jshint.js b/lib/ace/worker/jshint.js deleted file mode 100644 index fba105ea..00000000 --- a/lib/ace/worker/jshint.js +++ /dev/null @@ -1,5908 +0,0 @@ -define(function(require, exports, module) { -/* - * JSHint, by JSHint Community. - * - * Licensed under the same slightly modified MIT license that JSLint is. - * It stops evil-doers everywhere. - * - * JSHint is a derivative work of JSLint: - * - * Copyright (c) 2002 Douglas Crockford (www.JSLint.com) - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * The Software shall be used for Good, not Evil. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * JSHint was forked from 2010-12-16 edition of JSLint. - * - */ - -/* - JSHINT is a global function. It takes two parameters. - - var myResult = JSHINT(source, option); - - The first parameter is either a string or an array of strings. If it is a - string, it will be split on '\n' or '\r'. If it is an array of strings, it - is assumed that each string represents one line. The source can be a - JavaScript text, or HTML text, or a JSON text, or a CSS text. - - The second parameter is an optional object of options which control the - operation of JSHINT. Most of the options are booleans: They are all - optional and have a default value of false. One of the options, predef, - can be an array of names, which will be used to declare global variables, - or an object whose keys are used as global names, with a boolean value - that determines if they are assignable. - - If it checks out, JSHINT returns true. Otherwise, it returns false. - - If false, you can inspect JSHINT.errors to find out the problems. - JSHINT.errors is an array of objects containing these members: - - { - line : The line (relative to 0) at which the lint was found - character : The character (relative to 0) at which the lint was found - reason : The problem - evidence : The text line in which the problem occurred - raw : The raw message before the details were inserted - a : The first detail - b : The second detail - c : The third detail - d : The fourth detail - } - - If a fatal error was found, a null will be the last element of the - JSHINT.errors array. - - You can request a Function Report, which shows all of the functions - and the parameters and vars that they use. This can be used to find - implied global variables and other problems. The report is in HTML and - can be inserted in an HTML . - - var myReport = JSHINT.report(limited); - - If limited is true, then the report will be limited to only errors. - - You can request a data structure which contains JSHint's results. - - var myData = JSHINT.data(); - - It returns a structure with this form: - - { - errors: [ - { - line: NUMBER, - character: NUMBER, - reason: STRING, - evidence: STRING - } - ], - functions: [ - name: STRING, - line: NUMBER, - last: NUMBER, - param: [ - STRING - ], - closure: [ - STRING - ], - var: [ - STRING - ], - exception: [ - STRING - ], - outer: [ - STRING - ], - unused: [ - STRING - ], - global: [ - STRING - ], - label: [ - STRING - ] - ], - globals: [ - STRING - ], - member: { - STRING: NUMBER - }, - unuseds: [ - { - name: STRING, - line: NUMBER - } - ], - implieds: [ - { - name: STRING, - line: NUMBER - } - ], - urls: [ - STRING - ], - json: BOOLEAN - } - - Empty arrays will not be included. - -*/ - -/*jshint - evil: true, nomen: false, onevar: false, regexp: false, strict: true, boss: true -*/ - -/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%", - "(begin)", "(breakage)", "(context)", "(error)", "(global)", - "(identifier)", "(last)", "(line)", "(loopage)", "(name)", "(onevar)", - "(params)", "(scope)", "(statement)", "(verb)", "*", "+", "++", "-", - "--", "\/", "<", "<=", "==", "===", ">", ">=", $, ADSAFE, __filename, __dirname, - ActiveXObject, Array, Boolean, Buffer, COM, CScript, Canvas, CustomAnimation, - Date, Debug, E, Enumerator, Error, EvalError, FadeAnimation, Flash, - FormField, Frame, Function, HotKey, Image, JSON, LN10, LN2, LOG10E, - LOG2E, MAX_VALUE, MIN_VALUE, Math, MenuItem, MoveAnimation, - NEGATIVE_INFINITY, Number, Object, Option, PI, POSITIVE_INFINITY, Point, - RangeError, Rectangle, ReferenceError, RegExp, ResizeAnimation, - RotateAnimation, SQRT1_2, SQRT2, ScrollBar, String, Style, SyntaxError, - System, Text, TextArea, Timer, TypeError, URIError, URL, VBArray, - WScript, Web, Window, XMLDOM, XMLHttpRequest, "\\", a, abbr, acronym, - activeborder, activecaption, addEventListener, address, adsafe, alert, - aliceblue, all, animator, antiquewhite, appleScript, applet, apply, - approved, appworkspace, applicationCache, aqua, aquamarine, area, arguments, - arity, article, aside, audio, autocomplete, azure, b, background, - "background-attachment", "background-color", "background-image", - "background-position", "background-repeat", base, bdo, beep, beige, big, - bisque, bitwise, black, blanchedalmond, block, blockquote, blue, - blueviolet, blur, body, border, "border-bottom", "border-bottom-color", - "border-bottom-style", "border-bottom-width", "border-collapse", - "border-color", "border-left", "border-left-color", "border-left-style", - "border-left-width", "border-right", "border-right-color", - "border-right-style", "border-right-width", "border-spacing", - "border-style", "border-top", "border-top-color", "border-top-style", - "border-top-width", "border-width", bottom, boss, br, braille, brown, browser, - burlywood, button, buttonface, buttonhighlight, buttonshadow, - buttontext, bytesToUIString, c, cadetblue, call, callee, caller, canvas, - cap, caption, "caption-side", captiontext, cases, center, charAt, - charCodeAt, character, chartreuse, chocolate, chooseColor, chooseFile, - chooseFolder, cite, clear, clearInterval, clearTimeout, clip, close, - closeWidget, closed, closure, cm, code, col, colgroup, color, command, - comment, condition, confirm, console, constructor, content, - convertPathToHFS, convertPathToPlatform, coral, cornflowerblue, - cornsilk, couch, "counter-increment", "counter-reset", create, crimson, - css, curly, cursor, cyan, d, darkblue, darkcyan, darkgoldenrod, darkgray, - darkgreen, darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, - darkred, darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise, - darkviolet, data, datalist, dd, debug, decodeURI, decodeURIComponent, - deeppink, deepskyblue, defaultStatus, defineClass, del, deserialize, - details, devel, dfn, dialog, dimgray, dir, direction, display, div, dl, - document, dodgerblue, dt, edition, else, em, embed, embossed, emit, empty, - "empty-cells", encodeURI, encodeURIComponent, entityify, eqeqeq, errors, - es5, escape, eval, event, evidence, evil, ex, exception, exec, exps, exports, - fieldset, figure, filesystem, FileReader, firebrick, first, float, floor, - floralwhite, focus, focusWidget, font, "font-family", "font-size", - "font-size-adjust", "font-stretch", "font-style", "font-variant", - "font-weight", footer, forestgreen, forin, form, fragment, frame, - frames, frameset, from, fromCharCode, fuchsia, fud, funct, function, - functions, g, gainsboro, gc, getComputedStyle, getRow, ghostwhite, GLOBAL, global, - globals, gold, goldenrod, gray, graytext, green, greenyellow, h1, h2, - h3, h4, h5, h6, handheld, hasOwnProperty, head, header, height, help, - hgroup, highlight, highlighttext, history, honeydew, hotpink, hr, - "hta:application", html, i, iTunes, id, identifier, iframe, img, immed, - implieds, in, inactiveborder, inactivecaption, inactivecaptiontext, - include, indent, indexOf, indianred, indigo, infobackground, infotext, - init, input, ins, isAlpha, isApplicationRunning, isArray, isDigit, - isFinite, isNaN, ivory, join, jshint, JSHINT, json, jquery, jQuery, kbd, - keygen, keys, khaki, konfabulatorVersion, label, labelled, lang, last, - lavender, lavenderblush, lawngreen, laxbreak, lbp, led, left, legend, - lemonchiffon, length, "letter-spacing", li, lib, lightblue, lightcoral, - lightcyan, lightgoldenrodyellow, lightgreen, lightpink, lightsalmon, - lightseagreen, lightskyblue, lightslategray, lightsteelblue, - lightyellow, lime, limegreen, line, "line-height", linen, link, - "list-style", "list-style-image", "list-style-position", - "list-style-type", load, loadClass, localStorage, location, log, m, magenta, - map, margin, "margin-bottom", "margin-left", "margin-right", "margin-top", - mark, "marker-offset", maroon, match, "max-height", "max-width", maxerr, - maxlen, md5, mediumaquamarine, mediumblue, mediumorchid, mediumpurple, - mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise, - mediumvioletred, member, menu, menutext, message, meta, meter, - midnightblue, "min-height", "min-width", mintcream, mistyrose, mm, - moccasin, module, moveBy, moveTo, name, nav, navajowhite, navigator, navy, new, - newcap, noarg, node, noempty, noframes, nomen, nonew, noscript, nud, object, ol, - oldlace, olive, olivedrab, on, onbeforeunload, onblur, onerror, onevar, - onfocus, onload, onresize, onunload, opacity, open, openDatabase, openURL, opener, - opera, optgroup, option, orange, orangered, orchid, outer, outline, "outline-color", - "outline-style", "outline-width", output, overflow, "overflow-x", - "overflow-y", p, padding, "padding-bottom", "padding-left", - "padding-right", "padding-top", "page-break-after", "page-break-before", - palegoldenrod, palegreen, paleturquoise, palevioletred, papayawhip, - param, parent, parseFloat, parseInt, passfail, pc, peachpuff, peru, - pink, play, plum, plusplus, pop, popupMenu, position, powderblue, pre, - predef, preferenceGroups, preferences, print, process, progress, projection, - prompt, prototype, pt, purple, push, px, q, quit, quotes, random, range, - raw, reach, readFile, readUrl, reason, red, regexp, reloadWidget, - removeEventListener, replace, report, require, reserved, resizeBy, resizeTo, - resolvePath, resumeUpdates, respond, rhino, right, rosybrown, royalblue, - rp, rt, ruby, runCommand, runCommandInBg, saddlebrown, safe, salmon, samp, - sandybrown, saveAs, savePreferences, screen, script, scroll, scrollBy, - scrollTo, scrollbar, seagreen, seal, search, seashell, section, send, select, - serialize, setInterval, setTimeout, shift, showWidgetPreferences, - sienna, silver, skyblue, slateblue, slategray, sleep, slice, small, - snow, sort, source, span, spawn, speak, speech, split, springgreen, src, - stack, status, start, steelblue, strict, strong, style, styleproperty, sub, - substr, sum, sup, supplant, suppressUpdates, sync, system, table, - "table-layout", tan, tbody, td, teal, tellWidget, test, "text-align", - "text-decoration", "text-indent", "text-shadow", "text-transform", - textarea, tfoot, th, thead, thistle, threeddarkshadow, threedface, - threedhighlight, threedlightshadow, threedshadow, time, title, - toLowerCase, toString, toUpperCase, toint32, token, tomato, top, tr, tt, - tty, turquoise, tv, type, u, ul, undef, unescape, "unicode-bidi", - unused, unwatch, updateNow, urls, value, valueOf, var, version, - "vertical-align", video, violet, visibility, watch, WebSocket, wheat, white, - "white-space", whitesmoke, widget, width, window, windowframe, windows, - windowtext, Worker, "word-spacing", "word-wrap", yahooCheckLogin, - yahooLogin, yahooLogout, yellow, yellowgreen, "z-index" -*/ - -/*global exports: false */ - -// We build the application inside a function so that we produce only a single -// global variable. That function will be invoked immediately, and its return -// value is the JSHINT function itself. - -var JSHINT = (function () { - "use strict"; - - var adsafe_id, // The widget's ADsafe id. - adsafe_may, // The widget may load approved scripts. - adsafe_went, // ADSAFE.go has been called. - anonname, // The guessed name for anonymous functions. - approved, // ADsafe approved urls. - -// These are operators that should not be used with the ! operator. - - bang = { - '<' : true, - '<=' : true, - '==' : true, - '===': true, - '!==': true, - '!=' : true, - '>' : true, - '>=' : true, - '+' : true, - '-' : true, - '*' : true, - '/' : true, - '%' : true - }, - -// These are property names that should not be permitted in the safe subset. - - banned = { // the member names that ADsafe prohibits. - 'arguments' : true, - callee : true, - caller : true, - constructor : true, - 'eval' : true, - prototype : true, - stack : true, - unwatch : true, - valueOf : true, - watch : true - }, - - -// These are the JSHint boolean options. - - boolOptions = { - adsafe : true, // if ADsafe should be enforced - bitwise : true, // if bitwise operators should not be allowed - boss : true, // if advanced usage of assignments and == should be allowed - browser : true, // if the standard browser globals should be predefined - cap : true, // if upper case HTML should be allowed - couch : true, // if CouchDB globals should be predefined - css : true, // if CSS workarounds should be tolerated - curly : true, // if curly braces around blocks should be required (even in if/for/while) - debug : true, // if debugger statements should be allowed - devel : true, // if logging should be allowed (console, alert, etc.) - eqeqeq : true, // if === should be required - es5 : true, // if ES5 syntax should be allowed - evil : true, // if eval should be allowed - forin : true, // if for in statements must filter - fragment : true, // if HTML fragments should be allowed - immed : true, // if immediate invocations must be wrapped in parens - jquery : true, // if jQuery globals should be predefined - laxbreak : true, // if line breaks should not be checked - newcap : true, // if constructor names must be capitalized - noarg : true, // if arguments.caller and arguments.callee should be disallowed - node : true, // if the Node.js environment globals should be predefined - noempty : true, // if empty blocks should be disallowed - nonew : true, // if using `new` for side-effects should be disallowed - nomen : true, // if names should be checked - on : true, // if HTML event handlers should be allowed - onevar : true, // if only one var statement per function should be allowed - passfail : true, // if the scan should stop on first error - plusplus : true, // if increment/decrement should not be allowed - regexp : true, // if the . should not be allowed in regexp literals - rhino : true, // if the Rhino environment globals should be predefined - undef : true, // if variables should be declared before used - safe : true, // if use of some browser features should be restricted - windows : true, // if MS Windows-specigic globals should be predefined - strict : true, // require the "use strict"; pragma - sub : true, // if all forms of subscript notation are tolerated - white : true, // if strict whitespace rules apply - widget : true // if the Yahoo Widgets globals should be predefined - }, - -// browser contains a set of global names which are commonly provided by a -// web browser environment. - - browser = { - addEventListener: false, - applicationCache: false, - blur : false, - clearInterval : false, - clearTimeout : false, - close : false, - closed : false, - defaultStatus : false, - document : false, - event : false, - FileReader : false, - focus : false, - frames : false, - getComputedStyle: false, - history : false, - Image : false, - length : false, - localStorage : false, - location : false, - moveBy : false, - moveTo : false, - name : false, - navigator : false, - onbeforeunload : true, - onblur : true, - onerror : true, - onfocus : true, - onload : true, - onresize : true, - onunload : true, - open : false, - openDatabase : false, - opener : false, - Option : false, - parent : false, - print : false, - removeEventListener: false, - resizeBy : false, - resizeTo : false, - screen : false, - scroll : false, - scrollBy : false, - scrollTo : false, - setInterval : false, - setTimeout : false, - status : false, - top : false, - WebSocket : false, - window : false, - Worker : false, - XMLHttpRequest : false - }, - - couch = { - "require" : false, - respond : false, - getRow : false, - emit : false, - send : false, - start : false, - sum : false, - log : false, - exports : false, - module : false - }, - - cssAttributeData, - cssAny, - - cssColorData = { - "aliceblue" : true, - "antiquewhite" : true, - "aqua" : true, - "aquamarine" : true, - "azure" : true, - "beige" : true, - "bisque" : true, - "black" : true, - "blanchedalmond" : true, - "blue" : true, - "blueviolet" : true, - "brown" : true, - "burlywood" : true, - "cadetblue" : true, - "chartreuse" : true, - "chocolate" : true, - "coral" : true, - "cornflowerblue" : true, - "cornsilk" : true, - "crimson" : true, - "cyan" : true, - "darkblue" : true, - "darkcyan" : true, - "darkgoldenrod" : true, - "darkgray" : true, - "darkgreen" : true, - "darkkhaki" : true, - "darkmagenta" : true, - "darkolivegreen" : true, - "darkorange" : true, - "darkorchid" : true, - "darkred" : true, - "darksalmon" : true, - "darkseagreen" : true, - "darkslateblue" : true, - "darkslategray" : true, - "darkturquoise" : true, - "darkviolet" : true, - "deeppink" : true, - "deepskyblue" : true, - "dimgray" : true, - "dodgerblue" : true, - "firebrick" : true, - "floralwhite" : true, - "forestgreen" : true, - "fuchsia" : true, - "gainsboro" : true, - "ghostwhite" : true, - "gold" : true, - "goldenrod" : true, - "gray" : true, - "green" : true, - "greenyellow" : true, - "honeydew" : true, - "hotpink" : true, - "indianred" : true, - "indigo" : true, - "ivory" : true, - "khaki" : true, - "lavender" : true, - "lavenderblush" : true, - "lawngreen" : true, - "lemonchiffon" : true, - "lightblue" : true, - "lightcoral" : true, - "lightcyan" : true, - "lightgoldenrodyellow" : true, - "lightgreen" : true, - "lightpink" : true, - "lightsalmon" : true, - "lightseagreen" : true, - "lightskyblue" : true, - "lightslategray" : true, - "lightsteelblue" : true, - "lightyellow" : true, - "lime" : true, - "limegreen" : true, - "linen" : true, - "magenta" : true, - "maroon" : true, - "mediumaquamarine" : true, - "mediumblue" : true, - "mediumorchid" : true, - "mediumpurple" : true, - "mediumseagreen" : true, - "mediumslateblue" : true, - "mediumspringgreen" : true, - "mediumturquoise" : true, - "mediumvioletred" : true, - "midnightblue" : true, - "mintcream" : true, - "mistyrose" : true, - "moccasin" : true, - "navajowhite" : true, - "navy" : true, - "oldlace" : true, - "olive" : true, - "olivedrab" : true, - "orange" : true, - "orangered" : true, - "orchid" : true, - "palegoldenrod" : true, - "palegreen" : true, - "paleturquoise" : true, - "palevioletred" : true, - "papayawhip" : true, - "peachpuff" : true, - "peru" : true, - "pink" : true, - "plum" : true, - "powderblue" : true, - "purple" : true, - "red" : true, - "rosybrown" : true, - "royalblue" : true, - "saddlebrown" : true, - "salmon" : true, - "sandybrown" : true, - "seagreen" : true, - "seashell" : true, - "sienna" : true, - "silver" : true, - "skyblue" : true, - "slateblue" : true, - "slategray" : true, - "snow" : true, - "springgreen" : true, - "steelblue" : true, - "tan" : true, - "teal" : true, - "thistle" : true, - "tomato" : true, - "turquoise" : true, - "violet" : true, - "wheat" : true, - "white" : true, - "whitesmoke" : true, - "yellow" : true, - "yellowgreen" : true, - - "activeborder" : true, - "activecaption" : true, - "appworkspace" : true, - "background" : true, - "buttonface" : true, - "buttonhighlight" : true, - "buttonshadow" : true, - "buttontext" : true, - "captiontext" : true, - "graytext" : true, - "highlight" : true, - "highlighttext" : true, - "inactiveborder" : true, - "inactivecaption" : true, - "inactivecaptiontext" : true, - "infobackground" : true, - "infotext" : true, - "menu" : true, - "menutext" : true, - "scrollbar" : true, - "threeddarkshadow" : true, - "threedface" : true, - "threedhighlight" : true, - "threedlightshadow" : true, - "threedshadow" : true, - "window" : true, - "windowframe" : true, - "windowtext" : true - }, - - cssBorderStyle, - cssBreak, - - cssLengthData = { - '%': true, - 'cm': true, - 'em': true, - 'ex': true, - 'in': true, - 'mm': true, - 'pc': true, - 'pt': true, - 'px': true - }, - - cssMedia, - cssOverflow, - - devel = { - alert : false, - confirm : false, - console : false, - Debug : false, - opera : false, - prompt : false - }, - - escapes = { - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"' : '\\"', - '/' : '\\/', - '\\': '\\\\' - }, - - funct, // The current function - - functionicity = [ - 'closure', 'exception', 'global', 'label', - 'outer', 'unused', 'var' - ], - - functions, // All of the functions - - global, // The global scope - htmltag = { - a: {}, - abbr: {}, - acronym: {}, - address: {}, - applet: {}, - area: {empty: true, parent: ' map '}, - article: {}, - aside: {}, - audio: {}, - b: {}, - base: {empty: true, parent: ' head '}, - bdo: {}, - big: {}, - blockquote: {}, - body: {parent: ' html noframes '}, - br: {empty: true}, - button: {}, - canvas: {parent: ' body p div th td '}, - caption: {parent: ' table '}, - center: {}, - cite: {}, - code: {}, - col: {empty: true, parent: ' table colgroup '}, - colgroup: {parent: ' table '}, - command: {parent: ' menu '}, - datalist: {}, - dd: {parent: ' dl '}, - del: {}, - details: {}, - dialog: {}, - dfn: {}, - dir: {}, - div: {}, - dl: {}, - dt: {parent: ' dl '}, - em: {}, - embed: {}, - fieldset: {}, - figure: {}, - font: {}, - footer: {}, - form: {}, - frame: {empty: true, parent: ' frameset '}, - frameset: {parent: ' html frameset '}, - h1: {}, - h2: {}, - h3: {}, - h4: {}, - h5: {}, - h6: {}, - head: {parent: ' html '}, - header: {}, - hgroup: {}, - hr: {empty: true}, - 'hta:application': - {empty: true, parent: ' head '}, - html: {parent: '*'}, - i: {}, - iframe: {}, - img: {empty: true}, - input: {empty: true}, - ins: {}, - kbd: {}, - keygen: {}, - label: {}, - legend: {parent: ' details fieldset figure '}, - li: {parent: ' dir menu ol ul '}, - link: {empty: true, parent: ' head '}, - map: {}, - mark: {}, - menu: {}, - meta: {empty: true, parent: ' head noframes noscript '}, - meter: {}, - nav: {}, - noframes: {parent: ' html body '}, - noscript: {parent: ' body head noframes '}, - object: {}, - ol: {}, - optgroup: {parent: ' select '}, - option: {parent: ' optgroup select '}, - output: {}, - p: {}, - param: {empty: true, parent: ' applet object '}, - pre: {}, - progress: {}, - q: {}, - rp: {}, - rt: {}, - ruby: {}, - samp: {}, - script: {empty: true, parent: ' body div frame head iframe p pre span '}, - section: {}, - select: {}, - small: {}, - span: {}, - source: {}, - strong: {}, - style: {parent: ' head ', empty: true}, - sub: {}, - sup: {}, - table: {}, - tbody: {parent: ' table '}, - td: {parent: ' tr '}, - textarea: {}, - tfoot: {parent: ' table '}, - th: {parent: ' tr '}, - thead: {parent: ' table '}, - time: {}, - title: {parent: ' head '}, - tr: {parent: ' table tbody thead tfoot '}, - tt: {}, - u: {}, - ul: {}, - 'var': {}, - video: {} - }, - - ids, // HTML ids - implied, // Implied globals - inblock, - indent, - jsonmode, - - jquery = { - '$' : false, - jQuery : false - }, - - lines, - lookahead, - member, - membersOnly, - nexttoken, - - node = { - __filename : false, - __dirname : false, - Buffer : false, - GLOBAL : false, - global : false, - module : false, - process : false, - require : false - }, - - noreach, - option, - predefined, // Global variables defined by option - prereg, - prevtoken, - - rhino = { - defineClass : false, - deserialize : false, - gc : false, - help : false, - load : false, - loadClass : false, - print : false, - quit : false, - readFile : false, - readUrl : false, - runCommand : false, - seal : false, - serialize : false, - spawn : false, - sync : false, - toint32 : false, - version : false - }, - - scope, // The current scope - src, - stack, - -// standard contains the global names that are provided by the -// ECMAScript standard. - - standard = { - Array : false, - Boolean : false, - Date : false, - decodeURI : false, - decodeURIComponent : false, - encodeURI : false, - encodeURIComponent : false, - Error : false, - 'eval' : false, - EvalError : false, - Function : false, - hasOwnProperty : false, - isFinite : false, - isNaN : false, - JSON : false, - Math : false, - Number : false, - Object : false, - parseInt : false, - parseFloat : false, - RangeError : false, - ReferenceError : false, - RegExp : false, - String : false, - SyntaxError : false, - TypeError : false, - URIError : false - }, - - standard_member = { - E : true, - LN2 : true, - LN10 : true, - LOG2E : true, - LOG10E : true, - MAX_VALUE : true, - MIN_VALUE : true, - NEGATIVE_INFINITY : true, - PI : true, - POSITIVE_INFINITY : true, - SQRT1_2 : true, - SQRT2 : true - }, - - strict_mode, - syntax = {}, - tab, - token, - urls, - warnings, - -// widget contains the global names which are provided to a Yahoo -// (fna Konfabulator) widget. - - widget = { - alert : true, - animator : true, - appleScript : true, - beep : true, - bytesToUIString : true, - Canvas : true, - chooseColor : true, - chooseFile : true, - chooseFolder : true, - closeWidget : true, - COM : true, - convertPathToHFS : true, - convertPathToPlatform : true, - CustomAnimation : true, - escape : true, - FadeAnimation : true, - filesystem : true, - Flash : true, - focusWidget : true, - form : true, - FormField : true, - Frame : true, - HotKey : true, - Image : true, - include : true, - isApplicationRunning : true, - iTunes : true, - konfabulatorVersion : true, - log : true, - md5 : true, - MenuItem : true, - MoveAnimation : true, - openURL : true, - play : true, - Point : true, - popupMenu : true, - preferenceGroups : true, - preferences : true, - print : true, - prompt : true, - random : true, - Rectangle : true, - reloadWidget : true, - ResizeAnimation : true, - resolvePath : true, - resumeUpdates : true, - RotateAnimation : true, - runCommand : true, - runCommandInBg : true, - saveAs : true, - savePreferences : true, - screen : true, - ScrollBar : true, - showWidgetPreferences : true, - sleep : true, - speak : true, - Style : true, - suppressUpdates : true, - system : true, - tellWidget : true, - Text : true, - TextArea : true, - Timer : true, - unescape : true, - updateNow : true, - URL : true, - Web : true, - widget : true, - Window : true, - XMLDOM : true, - XMLHttpRequest : true, - yahooCheckLogin : true, - yahooLogin : true, - yahooLogout : true - }, - - windows = { - ActiveXObject: false, - CScript : false, - Debug : false, - Enumerator : false, - System : false, - VBArray : false, - WScript : false - }, - -// xmode is used to adapt to the exceptions in html parsing. -// It can have these states: -// false .js script file -// html -// outer -// script -// style -// scriptstring -// styleproperty - - xmode, - xquote, - -// Regular expressions. Some of these are stupidly long. - -// unsafe comment or string - ax = /@cc|<\/?|script|\]\s*\]|<\s*!|</i, -// unsafe characters that are silently deleted by one or more browsers - cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/, -// token - tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jshint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/, -// html token - hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-:]*|[0-9]+|--)/, -// characters in strings that need escapement - nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/, - nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, -// outer html token - ox = /[>&]|<[\/!]?|--/, -// star slash - lx = /\*\/|\/\*/, -// identifier - ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/, -// javascript url - jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i, -// url badness - ux = /&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i, -// style - sx = /^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/, - ssx = /^\s*([@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/, -// attributes characters - qx = /[^a-zA-Z0-9+\-_\/ ]/, -// query characters for ids - dx = /[\[\]\/\\"'*<>.&:(){}+=#]/, - - rx = { - outer: hx, - html: hx, - style: sx, - styleproperty: ssx - }; - - - function F() {} // Used by Object.create - - function is_own(object, name) { - -// The object.hasOwnProperty method fails when the property under consideration -// is named 'hasOwnProperty'. So we have to use this more convoluted form. - - return Object.prototype.hasOwnProperty.call(object, name); - } - -// Provide critical ES5 functions to ES3. - - if (typeof Array.isArray !== 'function') { - Array.isArray = function (o) { - return Object.prototype.toString.apply(o) === '[object Array]'; - }; - } - - if (typeof Object.create !== 'function') { - Object.create = function (o) { - F.prototype = o; - return new F(); - }; - } - - if (typeof Object.keys !== 'function') { - Object.keys = function (o) { - var a = [], k; - for (k in o) { - if (is_own(o, k)) { - a.push(k); - } - } - return a; - }; - } - -// Non standard methods - - if (typeof String.prototype.entityify !== 'function') { - String.prototype.entityify = function () { - return this - .replace(/&/g, '&') - .replace(//g, '>'); - }; - } - - if (typeof String.prototype.isAlpha !== 'function') { - String.prototype.isAlpha = function () { - return (this >= 'a' && this <= 'z\uffff') || - (this >= 'A' && this <= 'Z\uffff'); - }; - } - - if (typeof String.prototype.isDigit !== 'function') { - String.prototype.isDigit = function () { - return (this >= '0' && this <= '9'); - }; - } - - if (typeof String.prototype.supplant !== 'function') { - String.prototype.supplant = function (o) { - return this.replace(/\{([^{}]*)\}/g, function (a, b) { - var r = o[b]; - return typeof r === 'string' || typeof r === 'number' ? r : a; - }); - }; - } - - if (typeof String.prototype.name !== 'function') { - String.prototype.name = function () { - -// If the string looks like an identifier, then we can return it as is. -// If the string contains no control characters, no quote characters, and no -// backslash characters, then we can simply slap some quotes around it. -// Otherwise we must also replace the offending characters with safe -// sequences. - - if (ix.test(this)) { - return this; - } - if (nx.test(this)) { - return '"' + this.replace(nxg, function (a) { - var c = escapes[a]; - if (c) { - return c; - } - return '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4); - }) + '"'; - } - return '"' + this + '"'; - }; - } - - - function combine(t, o) { - var n; - for (n in o) { - if (is_own(o, n)) { - t[n] = o[n]; - } - } - } - - function assume() { - if (option.safe) - return; - - if (option.couch) - combine(predefined, couch); - - if (option.rhino) - combine(predefined, rhino); - - if (option.node) - combine(predefined, node); - - if (option.devel) - combine(predefined, devel); - - if (option.browser) - combine(predefined, browser); - - if (option.jquery) - combine(predefined, jquery); - - if (option.windows) - combine(predefined, windows); - - if (option.widget) - combine(predefined, widget); - } - - -// Produce an error warning. - - function quit(m, l, ch) { - throw { - name: 'JSHintError', - line: l, - character: ch, - message: m + " (" + Math.floor((l / lines.length) * 100) + - "% scanned)." - }; - } - - function warning(m, t, a, b, c, d) { - var ch, l, w; - t = t || nexttoken; - if (t.id === '(end)') { // `~ - t = token; - } - l = t.line || 0; - ch = t.from || 0; - w = { - id: '(error)', - raw: m, - evidence: lines[l - 1] || '', - line: l, - character: ch, - a: a, - b: b, - c: c, - d: d - }; - w.reason = m.supplant(w); - JSHINT.errors.push(w); - if (option.passfail) { - quit('Stopping. ', l, ch); - } - warnings += 1; - if (warnings >= option.maxerr) { - quit("Too many errors.", l, ch); - } - return w; - } - - function warningAt(m, l, ch, a, b, c, d) { - return warning(m, { - line: l, - from: ch - }, a, b, c, d); - } - - function error(m, t, a, b, c, d) { - var w = warning(m, t, a, b, c, d); - quit("Stopping, unable to continue.", w.line, w.character); - } - - function errorAt(m, l, ch, a, b, c, d) { - return error(m, { - line: l, - from: ch - }, a, b, c, d); - } - - - -// lexical analysis and token construction - - var lex = (function lex() { - var character, from, line, s; - -// Private lex methods - - function nextLine() { - var at; - if (line >= lines.length) { - return false; - } - character = 1; - s = lines[line]; - line += 1; - at = s.search(/ \t/); - if (at >= 0) { - warningAt("Mixed spaces and tabs.", line, at + 1); - } - s = s.replace(/\t/g, tab); - at = s.search(cx); - if (at >= 0) { - warningAt("Unsafe character.", line, at); - } - if (option.maxlen && option.maxlen < s.length) { - warningAt("Line too long.", line, s.length); - } - return true; - } - -// Produce a token object. The token inherits from a syntax symbol. - - function it(type, value) { - var i, t; - if (type === '(color)' || type === '(range)') { - t = {type: type}; - } else if (type === '(punctuator)' || - (type === '(identifier)' && is_own(syntax, value))) { - t = syntax[value] || syntax['(error)']; - } else { - t = syntax[type]; - } - t = Object.create(t); - if (type === '(string)' || type === '(range)') { - if (jx.test(value)) { - warningAt("Script URL.", line, from); - } - } - if (type === '(identifier)') { - t.identifier = true; - if (value === '__iterator__' || value === '__proto__') { - errorAt("Reserved name '{a}'.", - line, from, value); - } else if (option.nomen && - (value.charAt(0) === '_' || - value.charAt(value.length - 1) === '_')) { - warningAt("Unexpected {a} in '{b}'.", line, from, - "dangling '_'", value); - } - } - t.value = value; - t.line = line; - t.character = character; - t.from = from; - i = t.id; - if (i !== '(endline)') { - prereg = i && - (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) || - i === 'return'); - } - return t; - } - -// Public lex methods - - return { - init: function (source) { - if (typeof source === 'string') { - lines = source - .replace(/\r\n/g, '\n') - .replace(/\r/g, '\n') - .split('\n'); - } else { - lines = source; - } - line = 0; - nextLine(); - from = 1; - }, - - range: function (begin, end) { - var c, value = ''; - from = character; - if (s.charAt(0) !== begin) { - errorAt("Expected '{a}' and instead saw '{b}'.", - line, character, begin, s.charAt(0)); - } - for (;;) { - s = s.slice(1); - character += 1; - c = s.charAt(0); - switch (c) { - case '': - errorAt("Missing '{a}'.", line, character, c); - break; - case end: - s = s.slice(1); - character += 1; - return it('(range)', value); - case xquote: - case '\\': - warningAt("Unexpected '{a}'.", line, character, c); - } - value += c; - } - - }, - -// token -- this is called by advance to get the next token. - - token: function () { - var b, c, captures, d, depth, high, i, l, low, q, t; - - function match(x) { - var r = x.exec(s), r1; - if (r) { - l = r[0].length; - r1 = r[1]; - c = r1.charAt(0); - s = s.substr(l); - from = character + l - r1.length; - character += l; - return r1; - } - } - - function string(x) { - var c, j, r = ''; - - if (jsonmode && x !== '"') { - warningAt("Strings must use doublequote.", - line, character); - } - - if (xquote === x || (xmode === 'scriptstring' && !xquote)) { - return it('(punctuator)', x); - } - - function esc(n) { - var i = parseInt(s.substr(j + 1, n), 16); - j += n; - if (i >= 32 && i <= 126 && - i !== 34 && i !== 92 && i !== 39) { - warningAt("Unnecessary escapement.", line, character); - } - character += n; - c = String.fromCharCode(i); - } - j = 0; - for (;;) { - while (j >= s.length) { - j = 0; - if (xmode !== 'html' || !nextLine()) { - errorAt("Unclosed string.", line, from); - } - } - c = s.charAt(j); - if (c === x) { - character += 1; - s = s.substr(j + 1); - return it('(string)', r, x); - } - if (c < ' ') { - if (c === '\n' || c === '\r') { - break; - } - warningAt("Control character in string: {a}.", - line, character + j, s.slice(0, j)); - } else if (c === xquote) { - warningAt("Bad HTML string", line, character + j); - } else if (c === '<') { - if (option.safe && xmode === 'html') { - warningAt("ADsafe string violation.", - line, character + j); - } else if (s.charAt(j + 1) === '/' && (xmode || option.safe)) { - warningAt("Expected '<\\/' and instead saw ' 0) { - character += 1; - s = s.slice(i); - break; - } else { - if (!nextLine()) { - return it('(end)', ''); - } - } - } - t = match(rx[xmode] || tx); - if (!t) { - t = ''; - c = ''; - while (s && s < '!') { - s = s.substr(1); - } - if (s) { - if (xmode === 'html') { - return it('(error)', s.charAt(0)); - } else { - errorAt("Unexpected '{a}'.", - line, character, s.substr(0, 1)); - } - } - } else { - - // identifier - - if (c.isAlpha() || c === '_' || c === '$') { - return it('(identifier)', t); - } - - // number - - if (c.isDigit()) { - if (xmode !== 'style' && !isFinite(Number(t))) { - warningAt("Bad number '{a}'.", - line, character, t); - } - if (xmode !== 'style' && - xmode !== 'styleproperty' && - s.substr(0, 1).isAlpha()) { - warningAt("Missing space after '{a}'.", - line, character, t); - } - if (c === '0') { - d = t.substr(1, 1); - if (d.isDigit()) { - if (token.id !== '.' && xmode !== 'styleproperty') { - warningAt("Don't use extra leading zeros '{a}'.", - line, character, t); - } - } else if (jsonmode && (d === 'x' || d === 'X')) { - warningAt("Avoid 0x-. '{a}'.", - line, character, t); - } - } - if (t.substr(t.length - 1) === '.') { - warningAt( -"A trailing decimal point can be confused with a dot '{a}'.", line, character, t); - } - return it('(number)', t); - } - switch (t) { - - // string - - case '"': - case "'": - return string(t); - - // // comment - - case '//': - if (src || (xmode && xmode !== 'script')) { - warningAt("Unexpected comment.", line, character); - } else if (xmode === 'script' && /<\s*\//i.test(s)) { - warningAt("Unexpected <\/ in comment.", line, character); - } else if ((option.safe || xmode === 'script') && ax.test(s)) { - warningAt("Dangerous comment.", line, character); - } - s = ''; - token.comment = true; - break; - - // /* comment - - case '/*': - if (src || (xmode && xmode !== 'script' && xmode !== 'style' && xmode !== 'styleproperty')) { - warningAt("Unexpected comment.", line, character); - } - if (option.safe && ax.test(s)) { - warningAt("ADsafe comment violation.", line, character); - } - for (;;) { - i = s.search(lx); - if (i >= 0) { - break; - } - if (!nextLine()) { - errorAt("Unclosed comment.", line, character); - } else { - if (option.safe && ax.test(s)) { - warningAt("ADsafe comment violation.", - line, character); - } - } - } - character += i + 2; - if (s.substr(i, 1) === '/') { - errorAt("Nested comment.", line, character); - } - s = s.substr(i + 2); - token.comment = true; - break; - - // /*members /*jshint /*global - - case '/*members': - case '/*member': - case '/*jshint': - case '/*global': - case '*/': - return { - value: t, - type: 'special', - line: line, - character: character, - from: from - }; - - case '': - break; - // / - case '/': - if (token.id === '/=') { - errorAt( -"A regular expression literal can be confused with '/='.", line, from); - } - if (prereg) { - depth = 0; - captures = 0; - l = 0; - for (;;) { - b = true; - c = s.charAt(l); - l += 1; - switch (c) { - case '': - errorAt("Unclosed regular expression.", - line, from); - return; - case '/': - if (depth > 0) { - warningAt("Unescaped '{a}'.", - line, from + l, '/'); - } - c = s.substr(0, l - 1); - q = { - g: true, - i: true, - m: true - }; - while (q[s.charAt(l)] === true) { - q[s.charAt(l)] = false; - l += 1; - } - character += l; - s = s.substr(l); - q = s.charAt(0); - if (q === '/' || q === '*') { - errorAt("Confusing regular expression.", - line, from); - } - return it('(regexp)', c); - case '\\': - c = s.charAt(l); - if (c < ' ') { - warningAt( -"Unexpected control character in regular expression.", line, from + l); - } else if (c === '<') { - warningAt( -"Unexpected escaped character '{a}' in regular expression.", line, from + l, c); - } - l += 1; - break; - case '(': - depth += 1; - b = false; - if (s.charAt(l) === '?') { - l += 1; - switch (s.charAt(l)) { - case ':': - case '=': - case '!': - l += 1; - break; - default: - warningAt( -"Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l)); - } - } else { - captures += 1; - } - break; - case '|': - b = false; - break; - case ')': - if (depth === 0) { - warningAt("Unescaped '{a}'.", - line, from + l, ')'); - } else { - depth -= 1; - } - break; - case ' ': - q = 1; - while (s.charAt(l) === ' ') { - l += 1; - q += 1; - } - if (q > 1) { - warningAt( -"Spaces are hard to count. Use {{a}}.", line, from + l, q); - } - break; - case '[': - c = s.charAt(l); - if (c === '^') { - l += 1; - if (option.regexp) { - warningAt("Insecure '{a}'.", - line, from + l, c); - } else if (s.charAt(l) === ']') { - errorAt("Unescaped '{a}'.", - line, from + l, '^'); - } - } - q = false; - if (c === ']') { - warningAt("Empty class.", line, - from + l - 1); - q = true; - } -klass: do { - c = s.charAt(l); - l += 1; - switch (c) { - case '[': - case '^': - warningAt("Unescaped '{a}'.", - line, from + l, c); - q = true; - break; - case '-': - if (q) { - q = false; - } else { - warningAt("Unescaped '{a}'.", - line, from + l, '-'); - q = true; - } - break; - case ']': - if (!q) { - warningAt("Unescaped '{a}'.", - line, from + l - 1, '-'); - } - break klass; - case '\\': - c = s.charAt(l); - if (c < ' ') { - warningAt( -"Unexpected control character in regular expression.", line, from + l); - } else if (c === '<') { - warningAt( -"Unexpected escaped character '{a}' in regular expression.", line, from + l, c); - } - l += 1; - q = true; - break; - case '/': - warningAt("Unescaped '{a}'.", - line, from + l - 1, '/'); - q = true; - break; - case '<': - if (xmode === 'script') { - c = s.charAt(l); - if (c === '!' || c === '/') { - warningAt( -"HTML confusion in regular expression '<{a}'.", line, from + l, c); - } - } - q = true; - break; - default: - q = true; - } - } while (c); - break; - case '.': - if (option.regexp) { - warningAt("Insecure '{a}'.", line, - from + l, c); - } - break; - case ']': - case '?': - case '{': - case '}': - case '+': - case '*': - warningAt("Unescaped '{a}'.", line, - from + l, c); - break; - case '<': - if (xmode === 'script') { - c = s.charAt(l); - if (c === '!' || c === '/') { - warningAt( -"HTML confusion in regular expression '<{a}'.", line, from + l, c); - } - } - } - if (b) { - switch (s.charAt(l)) { - case '?': - case '+': - case '*': - l += 1; - if (s.charAt(l) === '?') { - l += 1; - } - break; - case '{': - l += 1; - c = s.charAt(l); - if (c < '0' || c > '9') { - warningAt( -"Expected a number and instead saw '{a}'.", line, from + l, c); - } - l += 1; - low = +c; - for (;;) { - c = s.charAt(l); - if (c < '0' || c > '9') { - break; - } - l += 1; - low = +c + (low * 10); - } - high = low; - if (c === ',') { - l += 1; - high = Infinity; - c = s.charAt(l); - if (c >= '0' && c <= '9') { - l += 1; - high = +c; - for (;;) { - c = s.charAt(l); - if (c < '0' || c > '9') { - break; - } - l += 1; - high = +c + (high * 10); - } - } - } - if (s.charAt(l) !== '}') { - warningAt( -"Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c); - } else { - l += 1; - } - if (s.charAt(l) === '?') { - l += 1; - } - if (low > high) { - warningAt( -"'{a}' should not be greater than '{b}'.", line, from + l, low, high); - } - } - } - } - c = s.substr(0, l - 1); - character += l; - s = s.substr(l); - return it('(regexp)', c); - } - return it('(punctuator)', t); - - // punctuator - - case '.", line, character); - } - character += 3; - s = s.slice(i + 3); - break; - case '#': - if (xmode === 'html' || xmode === 'styleproperty') { - for (;;) { - c = s.charAt(0); - if ((c < '0' || c > '9') && - (c < 'a' || c > 'f') && - (c < 'A' || c > 'F')) { - break; - } - character += 1; - s = s.substr(1); - t += c; - } - if (t.length !== 4 && t.length !== 7) { - warningAt("Bad hex color '{a}'.", line, - from + l, t); - } - return it('(color)', t); - } - return it('(punctuator)', t); - default: - if (xmode === 'outer' && c === '&') { - character += 1; - s = s.substr(1); - for (;;) { - c = s.charAt(0); - character += 1; - s = s.substr(1); - if (c === ';') { - break; - } - if (!((c >= '0' && c <= '9') || - (c >= 'a' && c <= 'z') || - c === '#')) { - errorAt("Bad entity", line, from + l, - character); - } - } - break; - } - return it('(punctuator)', t); - } - } - } - } - }; - }()); - - - function addlabel(t, type) { - - if (option.safe && funct['(global)'] && - typeof predefined[t] !== 'boolean') { - warning('ADsafe global: ' + t + '.', token); - } else if (t === 'hasOwnProperty') { - warning("'hasOwnProperty' is a really bad name."); - } - -// Define t in the current function in the current scope. - - if (is_own(funct, t) && !funct['(global)']) { - warning(funct[t] === true ? - "'{a}' was used before it was defined." : - "'{a}' is already defined.", - nexttoken, t); - } - funct[t] = type; - if (funct['(global)']) { - global[t] = funct; - if (is_own(implied, t)) { - warning("'{a}' was used before it was defined.", nexttoken, t); - delete implied[t]; - } - } else { - scope[t] = funct; - } - } - - - function doOption() { - var b, obj, filter, o = nexttoken.value, t, v; - switch (o) { - case '*/': - error("Unbegun comment."); - break; - case '/*members': - case '/*member': - o = '/*members'; - if (!membersOnly) { - membersOnly = {}; - } - obj = membersOnly; - break; - case '/*jshint': - if (option.safe) { - warning("ADsafe restriction."); - } - obj = option; - filter = boolOptions; - break; - case '/*global': - if (option.safe) { - warning("ADsafe restriction."); - } - obj = predefined; - break; - default: - error("What?"); - } - t = lex.token(); -loop: for (;;) { - for (;;) { - if (t.type === 'special' && t.value === '*/') { - break loop; - } - if (t.id !== '(endline)' && t.id !== ',') { - break; - } - t = lex.token(); - } - if (t.type !== '(string)' && t.type !== '(identifier)' && - o !== '/*members') { - error("Bad option.", t); - } - v = lex.token(); - if (v.id === ':') { - v = lex.token(); - if (obj === membersOnly) { - error("Expected '{a}' and instead saw '{b}'.", - t, '*/', ':'); - } - if (t.value === 'indent' && o === '/*jshint') { - b = +v.value; - if (typeof b !== 'number' || !isFinite(b) || b <= 0 || - Math.floor(b) !== b) { - error("Expected a small integer and instead saw '{a}'.", - v, v.value); - } - obj.white = true; - obj.indent = b; - } else if (t.value === 'maxerr' && o === '/*jshint') { - b = +v.value; - if (typeof b !== 'number' || !isFinite(b) || b <= 0 || - Math.floor(b) !== b) { - error("Expected a small integer and instead saw '{a}'.", - v, v.value); - } - obj.maxerr = b; - } else if (t.value === 'maxlen' && o === '/*jshint') { - b = +v.value; - if (typeof b !== 'number' || !isFinite(b) || b <= 0 || - Math.floor(b) !== b) { - error("Expected a small integer and instead saw '{a}'.", - v, v.value); - } - obj.maxlen = b; - } else if (v.value === 'true') { - obj[t.value] = true; - } else if (v.value === 'false') { - obj[t.value] = false; - } else { - error("Bad option value.", v); - } - t = lex.token(); - } else { - if (o === '/*jshint') { - error("Missing option value.", t); - } - obj[t.value] = false; - t = v; - } - } - if (filter) { - assume(); - } - } - - -// We need a peek function. If it has an argument, it peeks that much farther -// ahead. It is used to distinguish -// for ( var i in ... -// from -// for ( var i = ... - - function peek(p) { - var i = p || 0, j = 0, t; - - while (j <= i) { - t = lookahead[j]; - if (!t) { - t = lookahead[j] = lex.token(); - } - j += 1; - } - return t; - } - - - -// Produce the next token. It looks for programming errors. - - function advance(id, t) { - switch (token.id) { - case '(number)': - if (nexttoken.id === '.') { - warning( -"A dot following a number can be confused with a decimal point.", token); - } - break; - case '-': - if (nexttoken.id === '-' || nexttoken.id === '--') { - warning("Confusing minusses."); - } - break; - case '+': - if (nexttoken.id === '+' || nexttoken.id === '++') { - warning("Confusing plusses."); - } - break; - } - if (token.type === '(string)' || token.identifier) { - anonname = token.value; - } - - if (id && nexttoken.id !== id) { - if (t) { - if (nexttoken.id === '(end)') { - warning("Unmatched '{a}'.", t, t.id); - } else { - warning( -"Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", - nexttoken, id, t.id, t.line, nexttoken.value); - } - } else if (nexttoken.type !== '(identifier)' || - nexttoken.value !== id) { - warning("Expected '{a}' and instead saw '{b}'.", - nexttoken, id, nexttoken.value); - } - } - prevtoken = token; - token = nexttoken; - for (;;) { - nexttoken = lookahead.shift() || lex.token(); - if (nexttoken.id === '(end)' || nexttoken.id === '(error)') { - return; - } - if (nexttoken.type === 'special') { - doOption(); - } else { - if (nexttoken.id !== '(endline)') { - break; - } - } - } - } - - -// This is the heart of JSHINT, the Pratt parser. In addition to parsing, it -// is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is -// like .nud except that it is only used on the first token of a statement. -// Having .fud makes it much easier to define statement-oriented languages like -// JavaScript. I retained Pratt's nomenclature. - -// .nud Null denotation -// .fud First null denotation -// .led Left denotation -// lbp Left binding power -// rbp Right binding power - -// They are elements of the parsing method called Top Down Operator Precedence. - - function expression(rbp, initial) { - var left; - if (nexttoken.id === '(end)') { - error("Unexpected early end of program.", token); - } - advance(); - if (option.safe && typeof predefined[token.value] === 'boolean' && - (nexttoken.id !== '(' && nexttoken.id !== '.')) { - warning('ADsafe violation.', token); - } - if (initial) { - anonname = 'anonymous'; - funct['(verb)'] = token.value; - } - if (initial === true && token.fud) { - left = token.fud(); - } else { - if (token.nud) { - left = token.nud(); - } else { - if (nexttoken.type === '(number)' && token.id === '.') { - warning( -"A leading decimal point can be confused with a dot: '.{a}'.", - token, nexttoken.value); - advance(); - return token; - } else { - error("Expected an identifier and instead saw '{a}'.", - token, token.id); - } - } - while (rbp < nexttoken.lbp) { - advance(); - if (token.led) { - left = token.led(left); - } else { - error("Expected an operator and instead saw '{a}'.", - token, token.id); - } - } - } - return left; - } - - -// Functions for conformance of style. - - function adjacent(left, right) { - left = left || token; - right = right || nexttoken; - if (option.white || xmode === 'styleproperty' || xmode === 'style') { - if (left.character !== right.from && left.line === right.line) { - warning("Unexpected space after '{a}'.", right, left.value); - } - } - } - - function nobreak(left, right) { - left = left || token; - right = right || nexttoken; - if (option.white && (left.character !== right.from || left.line !== right.line)) { - warning("Unexpected space before '{a}'.", right, right.value); - } - } - - function nospace(left, right) { - left = left || token; - right = right || nexttoken; - if (option.white && !left.comment) { - if (left.line === right.line) { - adjacent(left, right); - } - } - } - - function nonadjacent(left, right) { - if (option.white) { - left = left || token; - right = right || nexttoken; - if (left.line === right.line && left.character === right.from) { - warning("Missing space after '{a}'.", - nexttoken, left.value); - } - } - } - - function nobreaknonadjacent(left, right) { - left = left || token; - right = right || nexttoken; - if (!option.laxbreak && left.line !== right.line) { - warning("Bad line breaking before '{a}'.", right, right.id); - } else if (option.white) { - left = left || token; - right = right || nexttoken; - if (left.character === right.from) { - warning("Missing space after '{a}'.", - nexttoken, left.value); - } - } - } - - function indentation(bias) { - var i; - if (option.white && nexttoken.id !== '(end)') { - i = indent + (bias || 0); - if (nexttoken.from !== i) { - warning( -"Expected '{a}' to have an indentation at {b} instead at {c}.", - nexttoken, nexttoken.value, i, nexttoken.from); - } - } - } - - function nolinebreak(t) { - t = t || token; - if (t.line !== nexttoken.line) { - warning("Line breaking error '{a}'.", t, t.value); - } - } - - - function comma() { - if (token.line !== nexttoken.line) { - if (!option.laxbreak) { - warning("Bad line breaking before '{a}'.", token, nexttoken.id); - } - } else if (token.character !== nexttoken.from && option.white) { - warning("Unexpected space after '{a}'.", nexttoken, token.value); - } - advance(','); - nonadjacent(token, nexttoken); - } - - -// Functional constructors for making the symbols that will be inherited by -// tokens. - - function symbol(s, p) { - var x = syntax[s]; - if (!x || typeof x !== 'object') { - syntax[s] = x = { - id: s, - lbp: p, - value: s - }; - } - return x; - } - - - function delim(s) { - return symbol(s, 0); - } - - - function stmt(s, f) { - var x = delim(s); - x.identifier = x.reserved = true; - x.fud = f; - return x; - } - - - function blockstmt(s, f) { - var x = stmt(s, f); - x.block = true; - return x; - } - - - function reserveName(x) { - var c = x.id.charAt(0); - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { - x.identifier = x.reserved = true; - } - return x; - } - - - function prefix(s, f) { - var x = symbol(s, 150); - reserveName(x); - x.nud = (typeof f === 'function') ? f : function () { - this.right = expression(150); - this.arity = 'unary'; - if (this.id === '++' || this.id === '--') { - if (option.plusplus) { - warning("Unexpected use of '{a}'.", this, this.id); - } else if ((!this.right.identifier || this.right.reserved) && - this.right.id !== '.' && this.right.id !== '[') { - warning("Bad operand.", this); - } - } - return this; - }; - return x; - } - - - function type(s, f) { - var x = delim(s); - x.type = s; - x.nud = f; - return x; - } - - - function reserve(s, f) { - var x = type(s, f); - x.identifier = x.reserved = true; - return x; - } - - - function reservevar(s, v) { - return reserve(s, function () { - if (typeof v === 'function') { - v(this); - } - return this; - }); - } - - - function infix(s, f, p, w) { - var x = symbol(s, p); - reserveName(x); - x.led = function (left) { - if (!w) { - nobreaknonadjacent(prevtoken, token); - nonadjacent(token, nexttoken); - } - if (typeof f === 'function') { - return f(left, this); - } else { - this.left = left; - this.right = expression(p); - return this; - } - }; - return x; - } - - - function relation(s, f) { - var x = symbol(s, 100); - x.led = function (left) { - nobreaknonadjacent(prevtoken, token); - nonadjacent(token, nexttoken); - var right = expression(100); - if ((left && left.id === 'NaN') || (right && right.id === 'NaN')) { - warning("Use the isNaN function to compare with NaN.", this); - } else if (f) { - f.apply(this, [left, right]); - } - if (left.id === '!') { - warning("Confusing use of '{a}'.", left, '!'); - } - if (right.id === '!') { - warning("Confusing use of '{a}'.", left, '!'); - } - this.left = left; - this.right = right; - return this; - }; - return x; - } - - - function isPoorRelation(node) { - return node && - ((node.type === '(number)' && +node.value === 0) || - (node.type === '(string)' && node.value === '') || - (node.type === 'null' && !option.boss) || - node.type === 'true' || - node.type === 'false' || - node.type === 'undefined'); - } - - - function assignop(s, f) { - symbol(s, 20).exps = true; - return infix(s, function (left, that) { - var l; - that.left = left; - if (predefined[left.value] === false && - scope[left.value]['(global)'] === true) { - warning("Read only.", left); - } else if (left['function']) { - warning("'{a}' is a function.", left, left.value); - } - if (option.safe) { - l = left; - do { - if (typeof predefined[l.value] === 'boolean') { - warning('ADsafe violation.', l); - } - l = l.left; - } while (l); - } - if (left) { - if (left.id === '.' || left.id === '[') { - if (!left.left || left.left.value === 'arguments') { - warning('Bad assignment.', that); - } - that.right = expression(19); - return that; - } else if (left.identifier && !left.reserved) { - if (funct[left.value] === 'exception') { - warning("Do not assign to the exception parameter.", left); - } - that.right = expression(19); - return that; - } - if (left === syntax['function']) { - warning( -"Expected an identifier in an assignment and instead saw a function invocation.", - token); - } - } - error("Bad assignment.", that); - }, 20); - } - - - function bitwise(s, f, p) { - var x = symbol(s, p); - reserveName(x); - x.led = (typeof f === 'function') ? f : function (left) { - if (option.bitwise) { - warning("Unexpected use of '{a}'.", this, this.id); - } - this.left = left; - this.right = expression(p); - return this; - }; - return x; - } - - - function bitwiseassignop(s) { - symbol(s, 20).exps = true; - return infix(s, function (left, that) { - if (option.bitwise) { - warning("Unexpected use of '{a}'.", that, that.id); - } - nonadjacent(prevtoken, token); - nonadjacent(token, nexttoken); - if (left) { - if (left.id === '.' || left.id === '[' || - (left.identifier && !left.reserved)) { - expression(19); - return that; - } - if (left === syntax['function']) { - warning( -"Expected an identifier in an assignment, and instead saw a function invocation.", - token); - } - return that; - } - error("Bad assignment.", that); - }, 20); - } - - - function suffix(s, f) { - var x = symbol(s, 150); - x.led = function (left) { - if (option.plusplus) { - warning("Unexpected use of '{a}'.", this, this.id); - } else if ((!left.identifier || left.reserved) && - left.id !== '.' && left.id !== '[') { - warning("Bad operand.", this); - } - this.left = left; - return this; - }; - return x; - } - - - // fnparam means that this identifier is being defined as a function - // argument (see identifier()) - function optionalidentifier(fnparam) { - if (nexttoken.identifier) { - advance(); - if (option.safe && banned[token.value]) { - warning("ADsafe violation: '{a}'.", token, token.value); - } else if (token.reserved && !option.es5) { - // `undefined` as a function param is a common pattern to protect - // against the case when somebody does `undefined = true` and - // help with minification. More info: https://gist.github.com/315916 - if (!fnparam || token.value != 'undefined') { - warning("Expected an identifier and instead saw '{a}' (a reserved word).", - token, token.id); - } - } - return token.value; - } - } - - // fnparam means that this identifier is being defined as a function - // argument - function identifier(fnparam) { - var i = optionalidentifier(fnparam); - if (i) { - return i; - } - if (token.id === 'function' && nexttoken.id === '(') { - warning("Missing name in function statement."); - } else { - error("Expected an identifier and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - } - - - function reachable(s) { - var i = 0, t; - if (nexttoken.id !== ';' || noreach) { - return; - } - for (;;) { - t = peek(i); - if (t.reach) { - return; - } - if (t.id !== '(endline)') { - if (t.id === 'function') { - warning( -"Inner functions should be listed at the top of the outer function.", t); - break; - } - warning("Unreachable '{a}' after '{b}'.", t, t.value, s); - break; - } - i += 1; - } - } - - - function statement(noindent) { - var i = indent, r, s = scope, t = nexttoken; - -// We don't like the empty statement. - - if (t.id === ';') { - warning("Unnecessary semicolon.", t); - advance(';'); - return; - } - -// Is this a labelled statement? - - if (t.identifier && !t.reserved && peek().id === ':') { - advance(); - advance(':'); - scope = Object.create(s); - addlabel(t.value, 'label'); - if (!nexttoken.labelled) { - warning("Label '{a}' on {b} statement.", - nexttoken, t.value, nexttoken.value); - } - if (jx.test(t.value + ':')) { - warning("Label '{a}' looks like a javascript url.", - t, t.value); - } - nexttoken.label = t.value; - t = nexttoken; - } - -// Parse the statement. - - if (!noindent) { - indentation(); - } - r = expression(0, true); - -// Look for the final semicolon. - - if (!t.block) { - if (!r || !r.exps) { - warning("Expected an assignment or function call and instead saw an expression.", token); - } else if (option.nonew && r.id === '(' && r.left.id === 'new') { - warning("Do not use 'new' for side effects."); - } - if (nexttoken.id !== ';') { - warningAt("Missing semicolon.", token.line, token.from + token.value.length); - } else { - adjacent(token, nexttoken); - advance(';'); - nonadjacent(token, nexttoken); - } - } - -// Restore the indentation. - - indent = i; - scope = s; - return r; - } - - - function use_strict() { - if (nexttoken.value === 'use strict') { - if (strict_mode) { - warning("Unnecessary \"use strict\"."); - } - advance(); - advance(';'); - strict_mode = true; - option.newcap = true; - option.undef = true; - return true; - } else { - return false; - } - } - - - function statements(begin) { - var a = [], f, p; - if (option.adsafe) { - switch (begin) { - case 'script': - -// JSHint is also the static analizer for ADsafe. See www.ADsafe.org. - - if (!adsafe_may) { - if (nexttoken.value !== 'ADSAFE' || - peek(0).id !== '.' || - (peek(1).value !== 'id' && - peek(1).value !== 'go')) { - error('ADsafe violation: Missing ADSAFE.id or ADSAFE.go.', - nexttoken); - } - } - if (nexttoken.value === 'ADSAFE' && - peek(0).id === '.' && - peek(1).value === 'id') { - if (adsafe_may) { - error('ADsafe violation.', nexttoken); - } - advance('ADSAFE'); - advance('.'); - advance('id'); - advance('('); - if (nexttoken.value !== adsafe_id) { - error('ADsafe violation: id does not match.', nexttoken); - } - advance('(string)'); - advance(')'); - advance(';'); - adsafe_may = true; - } - break; - case 'lib': - if (nexttoken.value === 'ADSAFE') { - advance('ADSAFE'); - advance('.'); - advance('lib'); - advance('('); - advance('(string)'); - comma(); - f = expression(0); - if (f.id !== 'function') { - error('The second argument to lib must be a function.', f); - } - p = f.funct['(params)']; - p = p && p.join(', '); - if (p && p !== 'lib') { - error("Expected '{a}' and instead saw '{b}'.", - f, '(lib)', '(' + p + ')'); - } - advance(')'); - advance(';'); - return a; - } else { - error("ADsafe lib violation."); - } - } - } - while (!nexttoken.reach && nexttoken.id !== '(end)') { - if (nexttoken.id === ';') { - warning("Unnecessary semicolon."); - advance(';'); - } else { - a.push(statement()); - } - } - return a; - } - - - /* - * Parses a single block. A block is a sequence of statements wrapped in - * braces. - * - * ordinary - true for everything but function bodies and try blocks. - * stmt - true if block can be a single statement (e.g. in if/for/while). - */ - function block(ordinary, stmt) { - var a, - b = inblock, - old_indent = indent, - m = strict_mode, - s = scope, - t; - - inblock = ordinary; - scope = Object.create(scope); - nonadjacent(token, nexttoken); - t = nexttoken; - - if (nexttoken.id === '{') { - advance('{'); - if (nexttoken.id !== '}' || token.line !== nexttoken.line) { - indent += option.indent; - while (!ordinary && nexttoken.from > indent) { - indent += option.indent; - } - if (!ordinary && !use_strict() && !m && option.strict && - funct['(context)']['(global)']) { - warning("Missing \"use strict\" statement."); - } - a = statements(); - strict_mode = m; - indent -= option.indent; - indentation(); - } - advance('}', t); - indent = old_indent; - } else if (!ordinary) { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, '{', nexttoken.value); - } else { - if (!stmt || option.curly) - warning("Expected '{a}' and instead saw '{b}'.", - nexttoken, '{', nexttoken.value); - - noreach = true; - a = [statement()]; - noreach = false; - } - funct['(verb)'] = null; - scope = s; - inblock = b; - if (ordinary && option.noempty && (!a || a.length === 0)) { - warning("Empty block."); - } - return a; - } - - - function countMember(m) { - if (membersOnly && typeof membersOnly[m] !== 'boolean') { - warning("Unexpected /*member '{a}'.", token, m); - } - if (typeof member[m] === 'number') { - member[m] += 1; - } else { - member[m] = 1; - } - } - - - function note_implied(token) { - var name = token.value, line = token.line, a = implied[name]; - if (typeof a === 'function') { - a = false; - } - if (!a) { - a = [line]; - implied[name] = a; - } else if (a[a.length - 1] !== line) { - a.push(line); - } - } - - -// CSS parsing. - - function cssName() { - if (nexttoken.identifier) { - advance(); - return true; - } - } - - - function cssNumber() { - if (nexttoken.id === '-') { - advance('-'); - adjacent(); - nolinebreak(); - } - if (nexttoken.type === '(number)') { - advance('(number)'); - return true; - } - } - - - function cssString() { - if (nexttoken.type === '(string)') { - advance(); - return true; - } - } - - - function cssColor() { - var i, number, value; - if (nexttoken.identifier) { - value = nexttoken.value; - if (value === 'rgb' || value === 'rgba') { - advance(); - advance('('); - for (i = 0; i < 3; i += 1) { - if (i) { - advance(','); - } - number = nexttoken.value; - if (nexttoken.type !== '(number)' || number < 0) { - warning("Expected a positive number and instead saw '{a}'", - nexttoken, number); - advance(); - } else { - advance(); - if (nexttoken.id === '%') { - advance('%'); - if (number > 100) { - warning("Expected a percentage and instead saw '{a}'", - token, number); - } - } else { - if (number > 255) { - warning("Expected a small number and instead saw '{a}'", - token, number); - } - } - } - } - if (value === 'rgba') { - advance(','); - number = +nexttoken.value; - if (nexttoken.type !== '(number)' || number < 0 || number > 1) { - warning("Expected a number between 0 and 1 and instead saw '{a}'", - nexttoken, number); - } - advance(); - if (nexttoken.id === '%') { - warning("Unexpected '%'."); - advance('%'); - } - } - advance(')'); - return true; - } else if (cssColorData[nexttoken.value] === true) { - advance(); - return true; - } - } else if (nexttoken.type === '(color)') { - advance(); - return true; - } - return false; - } - - - function cssLength() { - if (nexttoken.id === '-') { - advance('-'); - adjacent(); - nolinebreak(); - } - if (nexttoken.type === '(number)') { - advance(); - if (nexttoken.type !== '(string)' && - cssLengthData[nexttoken.value] === true) { - adjacent(); - advance(); - } else if (+token.value !== 0) { - warning("Expected a linear unit and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - return true; - } - return false; - } - - - function cssLineHeight() { - if (nexttoken.id === '-') { - advance('-'); - adjacent(); - } - if (nexttoken.type === '(number)') { - advance(); - if (nexttoken.type !== '(string)' && - cssLengthData[nexttoken.value] === true) { - adjacent(); - advance(); - } - return true; - } - return false; - } - - - function cssWidth() { - if (nexttoken.identifier) { - switch (nexttoken.value) { - case 'thin': - case 'medium': - case 'thick': - advance(); - return true; - } - } else { - return cssLength(); - } - } - - - function cssMargin() { - if (nexttoken.identifier) { - if (nexttoken.value === 'auto') { - advance(); - return true; - } - } else { - return cssLength(); - } - } - - function cssAttr() { - if (nexttoken.identifier && nexttoken.value === 'attr') { - advance(); - advance('('); - if (!nexttoken.identifier) { - warning("Expected a name and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - advance(); - advance(')'); - return true; - } - return false; - } - - - function cssCommaList() { - while (nexttoken.id !== ';') { - if (!cssName() && !cssString()) { - warning("Expected a name and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - if (nexttoken.id !== ',') { - return true; - } - comma(); - } - } - - - function cssCounter() { - if (nexttoken.identifier && nexttoken.value === 'counter') { - advance(); - advance('('); - advance(); - if (nexttoken.id === ',') { - comma(); - if (nexttoken.type !== '(string)') { - warning("Expected a string and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - advance(); - } - advance(')'); - return true; - } - if (nexttoken.identifier && nexttoken.value === 'counters') { - advance(); - advance('('); - if (!nexttoken.identifier) { - warning("Expected a name and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - advance(); - if (nexttoken.id === ',') { - comma(); - if (nexttoken.type !== '(string)') { - warning("Expected a string and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - advance(); - } - if (nexttoken.id === ',') { - comma(); - if (nexttoken.type !== '(string)') { - warning("Expected a string and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - advance(); - } - advance(')'); - return true; - } - return false; - } - - - function cssShape() { - var i; - if (nexttoken.identifier && nexttoken.value === 'rect') { - advance(); - advance('('); - for (i = 0; i < 4; i += 1) { - if (!cssLength()) { - warning("Expected a number and instead saw '{a}'.", - nexttoken, nexttoken.value); - break; - } - } - advance(')'); - return true; - } - return false; - } - - - function cssUrl() { - var c, url; - if (nexttoken.identifier && nexttoken.value === 'url') { - nexttoken = lex.range('(', ')'); - url = nexttoken.value; - c = url.charAt(0); - if (c === '"' || c === '\'') { - if (url.slice(-1) !== c) { - warning("Bad url string."); - } else { - url = url.slice(1, -1); - if (url.indexOf(c) >= 0) { - warning("Bad url string."); - } - } - } - if (!url) { - warning("Missing url."); - } - advance(); - if (option.safe && ux.test(url)) { - error("ADsafe URL violation."); - } - urls.push(url); - return true; - } - return false; - } - - - cssAny = [cssUrl, function () { - for (;;) { - if (nexttoken.identifier) { - switch (nexttoken.value.toLowerCase()) { - case 'url': - cssUrl(); - break; - case 'expression': - warning("Unexpected expression '{a}'.", - nexttoken, nexttoken.value); - advance(); - break; - default: - advance(); - } - } else { - if (nexttoken.id === ';' || nexttoken.id === '!' || - nexttoken.id === '(end)' || nexttoken.id === '}') { - return true; - } - advance(); - } - } - }]; - - - cssBorderStyle = [ - 'none', 'dashed', 'dotted', 'double', 'groove', - 'hidden', 'inset', 'outset', 'ridge', 'solid' - ]; - - cssBreak = [ - 'auto', 'always', 'avoid', 'left', 'right' - ]; - - cssMedia = { - 'all': true, - 'braille': true, - 'embossed': true, - 'handheld': true, - 'print': true, - 'projection': true, - 'screen': true, - 'speech': true, - 'tty': true, - 'tv': true - }; - - cssOverflow = [ - 'auto', 'hidden', 'scroll', 'visible' - ]; - - cssAttributeData = { - background: [ - true, 'background-attachment', 'background-color', - 'background-image', 'background-position', 'background-repeat' - ], - 'background-attachment': ['scroll', 'fixed'], - 'background-color': ['transparent', cssColor], - 'background-image': ['none', cssUrl], - 'background-position': [ - 2, [cssLength, 'top', 'bottom', 'left', 'right', 'center'] - ], - 'background-repeat': [ - 'repeat', 'repeat-x', 'repeat-y', 'no-repeat' - ], - 'border': [true, 'border-color', 'border-style', 'border-width'], - 'border-bottom': [ - true, 'border-bottom-color', 'border-bottom-style', - 'border-bottom-width' - ], - 'border-bottom-color': cssColor, - 'border-bottom-style': cssBorderStyle, - 'border-bottom-width': cssWidth, - 'border-collapse': ['collapse', 'separate'], - 'border-color': ['transparent', 4, cssColor], - 'border-left': [ - true, 'border-left-color', 'border-left-style', 'border-left-width' - ], - 'border-left-color': cssColor, - 'border-left-style': cssBorderStyle, - 'border-left-width': cssWidth, - 'border-right': [ - true, 'border-right-color', 'border-right-style', - 'border-right-width' - ], - 'border-right-color': cssColor, - 'border-right-style': cssBorderStyle, - 'border-right-width': cssWidth, - 'border-spacing': [2, cssLength], - 'border-style': [4, cssBorderStyle], - 'border-top': [ - true, 'border-top-color', 'border-top-style', 'border-top-width' - ], - 'border-top-color': cssColor, - 'border-top-style': cssBorderStyle, - 'border-top-width': cssWidth, - 'border-width': [4, cssWidth], - bottom: [cssLength, 'auto'], - 'caption-side' : ['bottom', 'left', 'right', 'top'], - clear: ['both', 'left', 'none', 'right'], - clip: [cssShape, 'auto'], - color: cssColor, - content: [ - 'open-quote', 'close-quote', 'no-open-quote', 'no-close-quote', - cssString, cssUrl, cssCounter, cssAttr - ], - 'counter-increment': [ - cssName, 'none' - ], - 'counter-reset': [ - cssName, 'none' - ], - cursor: [ - cssUrl, 'auto', 'crosshair', 'default', 'e-resize', 'help', 'move', - 'n-resize', 'ne-resize', 'nw-resize', 'pointer', 's-resize', - 'se-resize', 'sw-resize', 'w-resize', 'text', 'wait' - ], - direction: ['ltr', 'rtl'], - display: [ - 'block', 'compact', 'inline', 'inline-block', 'inline-table', - 'list-item', 'marker', 'none', 'run-in', 'table', 'table-caption', - 'table-cell', 'table-column', 'table-column-group', - 'table-footer-group', 'table-header-group', 'table-row', - 'table-row-group' - ], - 'empty-cells': ['show', 'hide'], - 'float': ['left', 'none', 'right'], - font: [ - 'caption', 'icon', 'menu', 'message-box', 'small-caption', - 'status-bar', true, 'font-size', 'font-style', 'font-weight', - 'font-family' - ], - 'font-family': cssCommaList, - 'font-size': [ - 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', - 'xx-large', 'larger', 'smaller', cssLength - ], - 'font-size-adjust': ['none', cssNumber], - 'font-stretch': [ - 'normal', 'wider', 'narrower', 'ultra-condensed', - 'extra-condensed', 'condensed', 'semi-condensed', - 'semi-expanded', 'expanded', 'extra-expanded' - ], - 'font-style': [ - 'normal', 'italic', 'oblique' - ], - 'font-variant': [ - 'normal', 'small-caps' - ], - 'font-weight': [ - 'normal', 'bold', 'bolder', 'lighter', cssNumber - ], - height: [cssLength, 'auto'], - left: [cssLength, 'auto'], - 'letter-spacing': ['normal', cssLength], - 'line-height': ['normal', cssLineHeight], - 'list-style': [ - true, 'list-style-image', 'list-style-position', 'list-style-type' - ], - 'list-style-image': ['none', cssUrl], - 'list-style-position': ['inside', 'outside'], - 'list-style-type': [ - 'circle', 'disc', 'square', 'decimal', 'decimal-leading-zero', - 'lower-roman', 'upper-roman', 'lower-greek', 'lower-alpha', - 'lower-latin', 'upper-alpha', 'upper-latin', 'hebrew', 'katakana', - 'hiragana-iroha', 'katakana-oroha', 'none' - ], - margin: [4, cssMargin], - 'margin-bottom': cssMargin, - 'margin-left': cssMargin, - 'margin-right': cssMargin, - 'margin-top': cssMargin, - 'marker-offset': [cssLength, 'auto'], - 'max-height': [cssLength, 'none'], - 'max-width': [cssLength, 'none'], - 'min-height': cssLength, - 'min-width': cssLength, - opacity: cssNumber, - outline: [true, 'outline-color', 'outline-style', 'outline-width'], - 'outline-color': ['invert', cssColor], - 'outline-style': [ - 'dashed', 'dotted', 'double', 'groove', 'inset', 'none', - 'outset', 'ridge', 'solid' - ], - 'outline-width': cssWidth, - overflow: cssOverflow, - 'overflow-x': cssOverflow, - 'overflow-y': cssOverflow, - padding: [4, cssLength], - 'padding-bottom': cssLength, - 'padding-left': cssLength, - 'padding-right': cssLength, - 'padding-top': cssLength, - 'page-break-after': cssBreak, - 'page-break-before': cssBreak, - position: ['absolute', 'fixed', 'relative', 'static'], - quotes: [8, cssString], - right: [cssLength, 'auto'], - 'table-layout': ['auto', 'fixed'], - 'text-align': ['center', 'justify', 'left', 'right'], - 'text-decoration': [ - 'none', 'underline', 'overline', 'line-through', 'blink' - ], - 'text-indent': cssLength, - 'text-shadow': ['none', 4, [cssColor, cssLength]], - 'text-transform': ['capitalize', 'uppercase', 'lowercase', 'none'], - top: [cssLength, 'auto'], - 'unicode-bidi': ['normal', 'embed', 'bidi-override'], - 'vertical-align': [ - 'baseline', 'bottom', 'sub', 'super', 'top', 'text-top', 'middle', - 'text-bottom', cssLength - ], - visibility: ['visible', 'hidden', 'collapse'], - 'white-space': [ - 'normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'inherit' - ], - width: [cssLength, 'auto'], - 'word-spacing': ['normal', cssLength], - 'word-wrap': ['break-word', 'normal'], - 'z-index': ['auto', cssNumber] - }; - - function styleAttribute() { - var v; - while (nexttoken.id === '*' || nexttoken.id === '#' || - nexttoken.value === '_') { - if (!option.css) { - warning("Unexpected '{a}'.", nexttoken, nexttoken.value); - } - advance(); - } - if (nexttoken.id === '-') { - if (!option.css) { - warning("Unexpected '{a}'.", nexttoken, nexttoken.value); - } - advance('-'); - if (!nexttoken.identifier) { - warning( -"Expected a non-standard style attribute and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - advance(); - return cssAny; - } else { - if (!nexttoken.identifier) { - warning("Excepted a style attribute, and instead saw '{a}'.", - nexttoken, nexttoken.value); - } else { - if (is_own(cssAttributeData, nexttoken.value)) { - v = cssAttributeData[nexttoken.value]; - } else { - v = cssAny; - if (!option.css) { - warning("Unrecognized style attribute '{a}'.", - nexttoken, nexttoken.value); - } - } - } - advance(); - return v; - } - } - - - function styleValue(v) { - var i = 0, - n, - once, - match, - round, - start = 0, - vi; - switch (typeof v) { - case 'function': - return v(); - case 'string': - if (nexttoken.identifier && nexttoken.value === v) { - advance(); - return true; - } - return false; - } - for (;;) { - if (i >= v.length) { - return false; - } - vi = v[i]; - i += 1; - if (vi === true) { - break; - } else if (typeof vi === 'number') { - n = vi; - vi = v[i]; - i += 1; - } else { - n = 1; - } - match = false; - while (n > 0) { - if (styleValue(vi)) { - match = true; - n -= 1; - } else { - break; - } - } - if (match) { - return true; - } - } - start = i; - once = []; - for (;;) { - round = false; - for (i = start; i < v.length; i += 1) { - if (!once[i]) { - if (styleValue(cssAttributeData[v[i]])) { - match = true; - round = true; - once[i] = true; - break; - } - } - } - if (!round) { - return match; - } - } - } - - function styleChild() { - if (nexttoken.id === '(number)') { - advance(); - if (nexttoken.value === 'n' && nexttoken.identifier) { - adjacent(); - advance(); - if (nexttoken.id === '+') { - adjacent(); - advance('+'); - adjacent(); - advance('(number)'); - } - } - return; - } else { - switch (nexttoken.value) { - case 'odd': - case 'even': - if (nexttoken.identifier) { - advance(); - return; - } - } - } - warning("Unexpected token '{a}'.", nexttoken, nexttoken.value); - } - - function substyle() { - var v; - for (;;) { - if (nexttoken.id === '}' || nexttoken.id === '(end)' || - xquote && nexttoken.id === xquote) { - return; - } - while (nexttoken.id === ';') { - warning("Misplaced ';'."); - advance(';'); - } - v = styleAttribute(); - advance(':'); - if (nexttoken.identifier && nexttoken.value === 'inherit') { - advance(); - } else { - if (!styleValue(v)) { - warning("Unexpected token '{a}'.", nexttoken, - nexttoken.value); - advance(); - } - } - if (nexttoken.id === '!') { - advance('!'); - adjacent(); - if (nexttoken.identifier && nexttoken.value === 'important') { - advance(); - } else { - warning("Expected '{a}' and instead saw '{b}'.", - nexttoken, 'important', nexttoken.value); - } - } - if (nexttoken.id === '}' || nexttoken.id === xquote) { - warning("Missing '{a}'.", nexttoken, ';'); - } else { - advance(';'); - } - } - } - - function styleSelector() { - if (nexttoken.identifier) { - if (!is_own(htmltag, option.cap ? - nexttoken.value.toLowerCase() : nexttoken.value)) { - warning("Expected a tagName, and instead saw {a}.", - nexttoken, nexttoken.value); - } - advance(); - } else { - switch (nexttoken.id) { - case '>': - case '+': - advance(); - styleSelector(); - break; - case ':': - advance(':'); - switch (nexttoken.value) { - case 'active': - case 'after': - case 'before': - case 'checked': - case 'disabled': - case 'empty': - case 'enabled': - case 'first-child': - case 'first-letter': - case 'first-line': - case 'first-of-type': - case 'focus': - case 'hover': - case 'last-child': - case 'last-of-type': - case 'link': - case 'only-of-type': - case 'root': - case 'target': - case 'visited': - advance(); - break; - case 'lang': - advance(); - advance('('); - if (!nexttoken.identifier) { - warning("Expected a lang code, and instead saw :{a}.", - nexttoken, nexttoken.value); - } - advance(')'); - break; - case 'nth-child': - case 'nth-last-child': - case 'nth-last-of-type': - case 'nth-of-type': - advance(); - advance('('); - styleChild(); - advance(')'); - break; - case 'not': - advance(); - advance('('); - if (nexttoken.id === ':' && peek(0).value === 'not') { - warning("Nested not."); - } - styleSelector(); - advance(')'); - break; - default: - warning("Expected a pseudo, and instead saw :{a}.", - nexttoken, nexttoken.value); - } - break; - case '#': - advance('#'); - if (!nexttoken.identifier) { - warning("Expected an id, and instead saw #{a}.", - nexttoken, nexttoken.value); - } - advance(); - break; - case '*': - advance('*'); - break; - case '.': - advance('.'); - if (!nexttoken.identifier) { - warning("Expected a class, and instead saw #.{a}.", - nexttoken, nexttoken.value); - } - advance(); - break; - case '[': - advance('['); - if (!nexttoken.identifier) { - warning("Expected an attribute, and instead saw [{a}].", - nexttoken, nexttoken.value); - } - advance(); - if (nexttoken.id === '=' || nexttoken.value === '~=' || - nexttoken.value === '$=' || - nexttoken.value === '|=' || - nexttoken.id === '*=' || - nexttoken.id === '^=') { - advance(); - if (nexttoken.type !== '(string)') { - warning("Expected a string, and instead saw {a}.", - nexttoken, nexttoken.value); - } - advance(); - } - advance(']'); - break; - default: - error("Expected a CSS selector, and instead saw {a}.", - nexttoken, nexttoken.value); - } - } - } - - function stylePattern() { - if (nexttoken.id === '{') { - warning("Expected a style pattern, and instead saw '{a}'.", nexttoken, - nexttoken.id); - } - for (;;) { - styleSelector(); - if (nexttoken.id === ' fragments and .js files.", token); - } - if (option.fragment) { - if (n !== 'div') { - error("ADsafe violation: Wrap the widget in a div.", token); - } - } else { - error("Use the fragment option.", token); - } - } - option.browser = true; - assume(); - } - - function doAttribute(n, a, v) { - var u, x; - if (a === 'id') { - u = typeof v === 'string' ? v.toUpperCase() : ''; - if (ids[u] === true) { - warning("Duplicate id='{a}'.", nexttoken, v); - } - if (!/^[A-Za-z][A-Za-z0-9._:\-]*$/.test(v)) { - warning("Bad id: '{a}'.", nexttoken, v); - } else if (option.adsafe) { - if (adsafe_id) { - if (v.slice(0, adsafe_id.length) !== adsafe_id) { - warning("ADsafe violation: An id must have a '{a}' prefix", - nexttoken, adsafe_id); - } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) { - warning("ADSAFE violation: bad id."); - } - } else { - adsafe_id = v; - if (!/^[A-Z]+_$/.test(v)) { - warning("ADSAFE violation: bad id."); - } - } - } - x = v.search(dx); - if (x >= 0) { - warning("Unexpected character '{a}' in {b}.", token, v.charAt(x), a); - } - ids[u] = true; - } else if (a === 'class' || a === 'type' || a === 'name') { - x = v.search(qx); - if (x >= 0) { - warning("Unexpected character '{a}' in {b}.", token, v.charAt(x), a); - } - ids[u] = true; - } else if (a === 'href' || a === 'background' || - a === 'content' || a === 'data' || - a.indexOf('src') >= 0 || a.indexOf('url') >= 0) { - if (option.safe && ux.test(v)) { - error("ADsafe URL violation."); - } - urls.push(v); - } else if (a === 'for') { - if (option.adsafe) { - if (adsafe_id) { - if (v.slice(0, adsafe_id.length) !== adsafe_id) { - warning("ADsafe violation: An id must have a '{a}' prefix", - nexttoken, adsafe_id); - } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) { - warning("ADSAFE violation: bad id."); - } - } else { - warning("ADSAFE violation: bad id."); - } - } - } else if (a === 'name') { - if (option.adsafe && v.indexOf('_') >= 0) { - warning("ADsafe name violation."); - } - } - } - - function doTag(n, a) { - var i, t = htmltag[n], x; - src = false; - if (!t) { - error("Unrecognized tag '<{a}>'.", - nexttoken, - n === n.toLowerCase() ? n : - n + ' (capitalization error)'); - } - if (stack.length > 0) { - if (n === 'html') { - error("Too many tags.", token); - } - x = t.parent; - if (x) { - if (x.indexOf(' ' + stack[stack.length - 1].name + ' ') < 0) { - error("A '<{a}>' must be within '<{b}>'.", - token, n, x); - } - } else if (!option.adsafe && !option.fragment) { - i = stack.length; - do { - if (i <= 0) { - error("A '<{a}>' must be within '<{b}>'.", - token, n, 'body'); - } - i -= 1; - } while (stack[i].name !== 'body'); - } - } - switch (n) { - case 'div': - if (option.adsafe && stack.length === 1 && !adsafe_id) { - warning("ADSAFE violation: missing ID_."); - } - break; - case 'script': - xmode = 'script'; - advance('>'); - indent = nexttoken.from; - if (a.lang) { - warning("lang is deprecated.", token); - } - if (option.adsafe && stack.length !== 1) { - warning("ADsafe script placement violation.", token); - } - if (a.src) { - if (option.adsafe && (!adsafe_may || !approved[a.src])) { - warning("ADsafe unapproved script source.", token); - } - if (a.type) { - warning("type is unnecessary.", token); - } - } else { - if (adsafe_went) { - error("ADsafe script violation.", token); - } - use_strict(); - statements('script'); - } - xmode = 'html'; - advance(''); - styles(); - xmode = 'html'; - advance(''; - } - - function html() { - var a, attributes, e, n, q, t, v, w = option.white, wmode; - xmode = 'html'; - xquote = ''; - stack = null; - for (;;) { - switch (nexttoken.value) { - case '<': - xmode = 'html'; - advance('<'); - attributes = {}; - t = nexttoken; - if (!t.identifier) { - warning("Bad identifier {a}.", t, t.value); - } - n = t.value; - if (option.cap) { - n = n.toLowerCase(); - } - t.name = n; - advance(); - if (!stack) { - stack = []; - doBegin(n); - } - v = htmltag[n]; - if (typeof v !== 'object') { - error("Unrecognized tag '<{a}>'.", t, n); - } - e = v.empty; - t.type = n; - for (;;) { - if (nexttoken.id === '/') { - advance('/'); - if (nexttoken.id !== '>') { - warning("Expected '{a}' and instead saw '{b}'.", - nexttoken, '>', nexttoken.value); - } - break; - } - if (nexttoken.id && nexttoken.id.substr(0, 1) === '>') { - break; - } - if (!nexttoken.identifier) { - if (nexttoken.id === '(end)' || nexttoken.id === '(error)') { - error("Missing '>'.", nexttoken); - } - warning("Bad identifier."); - } - option.white = true; - nonadjacent(token, nexttoken); - a = nexttoken.value; - option.white = w; - advance(); - if (!option.cap && a !== a.toLowerCase()) { - warning("Attribute '{a}' not all lower case.", nexttoken, a); - } - a = a.toLowerCase(); - xquote = ''; - if (is_own(attributes, a)) { - warning("Attribute '{a}' repeated.", nexttoken, a); - } - if (a.slice(0, 2) === 'on') { - if (!option.on) { - warning("Avoid HTML event handlers."); - } - xmode = 'scriptstring'; - advance('='); - q = nexttoken.id; - if (q !== '"' && q !== "'") { - error("Missing quote."); - } - xquote = q; - wmode = option.white; - option.white = false; - advance(q); - use_strict(); - statements('on'); - option.white = wmode; - if (nexttoken.id !== q) { - error("Missing close quote on script attribute."); - } - xmode = 'html'; - xquote = ''; - advance(q); - v = false; - } else if (a === 'style') { - xmode = 'scriptstring'; - advance('='); - q = nexttoken.id; - if (q !== '"' && q !== "'") { - error("Missing quote."); - } - xmode = 'styleproperty'; - xquote = q; - advance(q); - substyle(); - xmode = 'html'; - xquote = ''; - advance(q); - v = false; - } else { - if (nexttoken.id === '=') { - advance('='); - v = nexttoken.value; - if (!nexttoken.identifier && - nexttoken.id !== '"' && - nexttoken.id !== '\'' && - nexttoken.type !== '(string)' && - nexttoken.type !== '(number)' && - nexttoken.type !== '(color)') { - warning("Expected an attribute value and instead saw '{a}'.", token, a); - } - advance(); - } else { - v = true; - } - } - attributes[a] = v; - doAttribute(n, a, v); - } - doTag(n, attributes); - if (!e) { - stack.push(t); - } - xmode = 'outer'; - advance('>'); - break; - case '') { - error("Missing '{a}'.", nexttoken, '>'); - } - xmode = 'outer'; - advance('>'); - break; - case '' || nexttoken.id === '(end)') { - break; - } - if (nexttoken.value.indexOf('--') >= 0) { - error("Unexpected --."); - } - if (nexttoken.value.indexOf('<') >= 0) { - error("Unexpected <."); - } - if (nexttoken.value.indexOf('>') >= 0) { - error("Unexpected >."); - } - } - xmode = 'outer'; - advance('>'); - break; - case '(end)': - return; - default: - if (nexttoken.id === '(end)') { - error("Missing '{a}'.", nexttoken, - ''); - } else { - advance(); - } - } - if (stack && stack.length === 0 && (option.adsafe || - !option.fragment || nexttoken.id === '(end)')) { - break; - } - } - if (nexttoken.id !== '(end)') { - error("Unexpected material after the end."); - } - } - - -// Build the syntax table by declaring the syntactic elements of the language. - - type('(number)', function () { - return this; - }); - type('(string)', function () { - return this; - }); - - syntax['(identifier)'] = { - type: '(identifier)', - lbp: 0, - identifier: true, - nud: function () { - var v = this.value, - s = scope[v], - f; - if (typeof s === 'function') { - -// Protection against accidental inheritance. - - s = undefined; - } else if (typeof s === 'boolean') { - f = funct; - funct = functions[0]; - addlabel(v, 'var'); - s = funct; - funct = f; - } - -// The name is in scope and defined in the current function. - - if (funct === s) { - -// Change 'unused' to 'var', and reject labels. - - switch (funct[v]) { - case 'unused': - funct[v] = 'var'; - break; - case 'unction': - funct[v] = 'function'; - this['function'] = true; - break; - case 'function': - this['function'] = true; - break; - case 'label': - warning("'{a}' is a statement label.", token, v); - break; - } - -// The name is not defined in the function. If we are in the global scope, -// then we have an undefined variable. -// -// Operators typeof and delete do not raise runtime errors even if the base -// object of a reference is null so no need to display warning if we're -// inside of typeof or delete. - - } else if (funct['(global)']) { - if (anonname != 'typeof' && anonname != 'delete' && - option.undef && typeof predefined[v] !== 'boolean') { - warning("'{a}' is not defined.", token, v); - } - note_implied(token); - -// If the name is already defined in the current -// function, but not as outer, then there is a scope error. - - } else { - switch (funct[v]) { - case 'closure': - case 'function': - case 'var': - case 'unused': - warning("'{a}' used out of scope.", token, v); - break; - case 'label': - warning("'{a}' is a statement label.", token, v); - break; - case 'outer': - case 'global': - break; - default: - -// If the name is defined in an outer function, make an outer entry, and if -// it was unused, make it var. - - if (s === true) { - funct[v] = true; - } else if (s === null) { - warning("'{a}' is not allowed.", token, v); - note_implied(token); - } else if (typeof s !== 'object') { - -// Operators typeof and delete do not raise runtime errors even if the base object of -// a reference is null so no need to display warning if we're inside of typeof or delete. - - if (anonname != 'typeof' && anonname != 'delete' && option.undef) { - warning("'{a}' is not defined.", token, v); - } else { - funct[v] = true; - } - note_implied(token); - } else { - switch (s[v]) { - case 'function': - case 'unction': - this['function'] = true; - s[v] = 'closure'; - funct[v] = s['(global)'] ? 'global' : 'outer'; - break; - case 'var': - case 'unused': - s[v] = 'closure'; - funct[v] = s['(global)'] ? 'global' : 'outer'; - break; - case 'closure': - case 'parameter': - funct[v] = s['(global)'] ? 'global' : 'outer'; - break; - case 'label': - warning("'{a}' is a statement label.", token, v); - } - } - } - } - return this; - }, - led: function () { - error("Expected an operator and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - }; - - type('(regexp)', function () { - return this; - }); - - -// ECMAScript parser - - delim('(endline)'); - delim('(begin)'); - delim('(end)').reach = true; - delim(''); - delim('(error)').reach = true; - delim('}').reach = true; - delim(')'); - delim(']'); - delim('"').reach = true; - delim("'").reach = true; - delim(';'); - delim(':').reach = true; - delim(','); - delim('#'); - delim('@'); - reserve('else'); - reserve('case').reach = true; - reserve('catch'); - reserve('default').reach = true; - reserve('finally'); - reservevar('arguments', function (x) { - if (strict_mode && funct['(global)']) { - warning("Strict violation.", x); - } else if (option.safe) { - warning("ADsafe violation.", x); - } - }); - reservevar('eval', function (x) { - if (option.safe) { - warning("ADsafe violation.", x); - } - }); - reservevar('false'); - reservevar('Infinity'); - reservevar('NaN'); - reservevar('null'); - reservevar('this', function (x) { - if (strict_mode && ((funct['(statement)'] && - funct['(name)'].charAt(0) > 'Z') || funct['(global)'])) { - warning("Strict violation.", x); - } else if (option.safe) { - warning("ADsafe violation.", x); - } - }); - reservevar('true'); - reservevar('undefined'); - assignop('=', 'assign', 20); - assignop('+=', 'assignadd', 20); - assignop('-=', 'assignsub', 20); - assignop('*=', 'assignmult', 20); - assignop('/=', 'assigndiv', 20).nud = function () { - error("A regular expression literal can be confused with '/='."); - }; - assignop('%=', 'assignmod', 20); - bitwiseassignop('&=', 'assignbitand', 20); - bitwiseassignop('|=', 'assignbitor', 20); - bitwiseassignop('^=', 'assignbitxor', 20); - bitwiseassignop('<<=', 'assignshiftleft', 20); - bitwiseassignop('>>=', 'assignshiftright', 20); - bitwiseassignop('>>>=', 'assignshiftrightunsigned', 20); - infix('?', function (left, that) { - that.left = left; - that.right = expression(10); - advance(':'); - that['else'] = expression(10); - return that; - }, 30); - - infix('||', 'or', 40); - infix('&&', 'and', 50); - bitwise('|', 'bitor', 70); - bitwise('^', 'bitxor', 80); - bitwise('&', 'bitand', 90); - relation('==', function (left, right) { - if (option.eqeqeq) { - warning("Expected '{a}' and instead saw '{b}'.", - this, '===', '=='); - } else if (isPoorRelation(left)) { - warning("Use '{a}' to compare with '{b}'.", - this, '===', left.value); - } else if (isPoorRelation(right)) { - warning("Use '{a}' to compare with '{b}'.", - this, '===', right.value); - } - return this; - }); - relation('==='); - relation('!=', function (left, right) { - if (option.eqeqeq) { - warning("Expected '{a}' and instead saw '{b}'.", - this, '!==', '!='); - } else if (isPoorRelation(left)) { - warning("Use '{a}' to compare with '{b}'.", - this, '!==', left.value); - } else if (isPoorRelation(right)) { - warning("Use '{a}' to compare with '{b}'.", - this, '!==', right.value); - } - return this; - }); - relation('!=='); - relation('<'); - relation('>'); - relation('<='); - relation('>='); - bitwise('<<', 'shiftleft', 120); - bitwise('>>', 'shiftright', 120); - bitwise('>>>', 'shiftrightunsigned', 120); - infix('in', 'in', 120); - infix('instanceof', 'instanceof', 120); - infix('+', function (left, that) { - var right = expression(130); - if (left && right && left.id === '(string)' && right.id === '(string)') { - left.value += right.value; - left.character = right.character; - if (jx.test(left.value)) { - warning("JavaScript URL.", left); - } - return left; - } - that.left = left; - that.right = right; - return that; - }, 130); - prefix('+', 'num'); - prefix('+++', function () { - warning("Confusing pluses."); - this.right = expression(150); - this.arity = 'unary'; - return this; - }); - infix('+++', function (left) { - warning("Confusing pluses."); - this.left = left; - this.right = expression(130); - return this; - }, 130); - infix('-', 'sub', 130); - prefix('-', 'neg'); - prefix('---', function () { - warning("Confusing minuses."); - this.right = expression(150); - this.arity = 'unary'; - return this; - }); - infix('---', function (left) { - warning("Confusing minuses."); - this.left = left; - this.right = expression(130); - return this; - }, 130); - infix('*', 'mult', 140); - infix('/', 'div', 140); - infix('%', 'mod', 140); - - suffix('++', 'postinc'); - prefix('++', 'preinc'); - syntax['++'].exps = true; - - suffix('--', 'postdec'); - prefix('--', 'predec'); - syntax['--'].exps = true; - prefix('delete', function () { - var p = expression(0); - if (!p || (p.id !== '.' && p.id !== '[')) { - warning("Variables should not be deleted."); - } - this.first = p; - return this; - }).exps = true; - - - prefix('~', function () { - if (option.bitwise) { - warning("Unexpected '{a}'.", this, '~'); - } - expression(150); - return this; - }); - prefix('!', function () { - this.right = expression(150); - this.arity = 'unary'; - if (bang[this.right.id] === true) { - warning("Confusing use of '{a}'.", this, '!'); - } - return this; - }); - prefix('typeof', 'typeof'); - prefix('new', function () { - var c = expression(155), i; - if (c && c.id !== 'function') { - if (c.identifier) { - c['new'] = true; - switch (c.value) { - case 'Object': - warning("Use the object literal notation {}.", token); - break; - case 'Array': - if (nexttoken.id !== '(') { - warning("Use the array literal notation [].", token); - } else { - advance('('); - if (nexttoken.id === ')') { - warning("Use the array literal notation [].", token); - } - advance(')'); - } - this.first = c; - return this; - case 'Number': - case 'String': - case 'Boolean': - case 'Math': - case 'JSON': - warning("Do not use {a} as a constructor.", token, c.value); - break; - case 'Function': - if (!option.evil) { - warning("The Function constructor is eval."); - } - break; - case 'Date': - case 'RegExp': - break; - default: - if (c.id !== 'function') { - i = c.value.substr(0, 1); - if (option.newcap && (i < 'A' || i > 'Z')) { - warning( - "A constructor name should start with an uppercase letter.", - token); - } - } - } - } else { - if (c.id !== '.' && c.id !== '[' && c.id !== '(') { - warning("Bad constructor.", token); - } - } - } else { - warning("Weird construction. Delete 'new'.", this); - } - adjacent(token, nexttoken); - if (nexttoken.id !== '(') { - warning("Missing '()' invoking a constructor."); - } - this.first = c; - return this; - }); - syntax['new'].exps = true; - - infix('.', function (left, that) { - adjacent(prevtoken, token); - nobreak(); - var m = identifier(); - if (typeof m === 'string') { - countMember(m); - } - that.left = left; - that.right = m; - if (option.noarg && left && left.value === 'arguments' && - (m === 'callee' || m === 'caller')) { - warning("Avoid arguments.{a}.", left, m); - } else if (!option.evil && left && left.value === 'document' && - (m === 'write' || m === 'writeln')) { - warning("document.write can be a form of eval.", left); - } else if (option.adsafe) { - if (left && left.value === 'ADSAFE') { - if (m === 'id' || m === 'lib') { - warning("ADsafe violation.", that); - } else if (m === 'go') { - if (xmode !== 'script') { - warning("ADsafe violation.", that); - } else if (adsafe_went || nexttoken.id !== '(' || - peek(0).id !== '(string)' || - peek(0).value !== adsafe_id || - peek(1).id !== ',') { - error("ADsafe violation: go.", that); - } - adsafe_went = true; - adsafe_may = false; - } - } - } - if (!option.evil && (m === 'eval' || m === 'execScript')) { - warning('eval is evil.'); - } else if (option.safe) { - for (;;) { - if (banned[m] === true) { - warning("ADsafe restricted word '{a}'.", token, m); - } - if (typeof predefined[left.value] !== 'boolean' || - nexttoken.id === '(') { - break; - } - if (standard_member[m] === true) { - if (nexttoken.id === '.') { - warning("ADsafe violation.", that); - } - break; - } - if (nexttoken.id !== '.') { - warning("ADsafe violation.", that); - break; - } - advance('.'); - token.left = that; - token.right = m; - that = token; - m = identifier(); - if (typeof m === 'string') { - countMember(m); - } - } - } - return that; - }, 160, true); - - infix('(', function (left, that) { - if (prevtoken.id !== '}' && prevtoken.id !== ')') { - nobreak(prevtoken, token); - } - nospace(); - if (option.immed && !left.immed && left.id === 'function') { - warning("Wrap an immediate function invocation in parentheses " + - "to assist the reader in understanding that the expression " + - "is the result of a function, and not the function itself."); - } - var n = 0, - p = []; - if (left) { - if (left.type === '(identifier)') { - if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) { - if (left.value !== 'Number' && left.value !== 'String' && - left.value !== 'Boolean' && - left.value !== 'Date') { - if (left.value === 'Math') { - warning("Math is not a function.", left); - } else if (option.newcap) { - warning( -"Missing 'new' prefix when invoking a constructor.", left); - } - } - } - } else if (left.id === '.') { - if (option.safe && left.left.value === 'Math' && - left.right === 'random') { - warning("ADsafe violation.", left); - } - } - } - if (nexttoken.id !== ')') { - for (;;) { - p[p.length] = expression(10); - n += 1; - if (nexttoken.id !== ',') { - break; - } - comma(); - } - } - advance(')'); - nospace(prevtoken, token); - if (typeof left === 'object') { - if (left.value === 'parseInt' && n === 1) { - warning("Missing radix parameter.", left); - } - if (!option.evil) { - if (left.value === 'eval' || left.value === 'Function' || - left.value === 'execScript') { - warning("eval is evil.", left); - } else if (p[0] && p[0].id === '(string)' && - (left.value === 'setTimeout' || - left.value === 'setInterval')) { - warning( - "Implied eval is evil. Pass a function instead of a string.", left); - } - } - if (!left.identifier && left.id !== '.' && left.id !== '[' && - left.id !== '(' && left.id !== '&&' && left.id !== '||' && - left.id !== '?') { - warning("Bad invocation.", left); - } - } - that.left = left; - return that; - }, 155, true).exps = true; - - prefix('(', function () { - nospace(); - if (nexttoken.id === 'function') { - nexttoken.immed = true; - } - var v = expression(0); - advance(')', this); - nospace(prevtoken, token); - if (option.immed && v.id === 'function') { - if (nexttoken.id === '(') { - warning( -"Move the invocation into the parens that contain the function.", nexttoken); - } else { - warning( -"Do not wrap function literals in parens unless they are to be immediately invoked.", - this); - } - } - return v; - }); - - infix('[', function (left, that) { - nobreak(prevtoken, token); - nospace(); - var e = expression(0), s; - if (e && e.type === '(string)') { - if (option.safe && banned[e.value] === true) { - warning("ADsafe restricted word '{a}'.", that, e.value); - } else if (!option.evil && - (e.value === 'eval' || e.value === 'execScript')) { - warning("eval is evil.", that); - } else if (option.safe && - (e.value.charAt(0) === '_' || e.value.charAt(0) === '-')) { - warning("ADsafe restricted subscript '{a}'.", that, e.value); - } - countMember(e.value); - if (!option.sub && ix.test(e.value)) { - s = syntax[e.value]; - if (!s || !s.reserved) { - warning("['{a}'] is better written in dot notation.", - e, e.value); - } - } - } else if (!e || e.type !== '(number)' || e.value < 0) { - if (option.safe) { - warning('ADsafe subscripting.'); - } - } - advance(']', that); - nospace(prevtoken, token); - that.left = left; - that.right = e; - return that; - }, 160, true); - - prefix('[', function () { - var b = token.line !== nexttoken.line; - this.first = []; - if (b) { - indent += option.indent; - if (nexttoken.from === indent + option.indent) { - indent += option.indent; - } - } - while (nexttoken.id !== '(end)') { - while (nexttoken.id === ',') { - warning("Extra comma."); - advance(','); - } - if (nexttoken.id === ']') { - break; - } - if (b && token.line !== nexttoken.line) { - indentation(); - } - this.first.push(expression(10)); - if (nexttoken.id === ',') { - comma(); - if (nexttoken.id === ']' && !option.es5) { - warning("Extra comma.", token); - break; - } - } else { - break; - } - } - if (b) { - indent -= option.indent; - indentation(); - } - advance(']', this); - return this; - }, 160); - - - function property_name() { - var id = optionalidentifier(true); - if (!id) { - if (nexttoken.id === '(string)') { - id = nexttoken.value; - if (option.adsafe && - (id.charAt(0) === '_' || - id.charAt(id.length - 1) === '_')) { - warning("Unexpected {a} in '{b}'.", token, - "dangling '_'", id); - } - advance(); - } else if (nexttoken.id === '(number)') { - id = nexttoken.value.toString(); - advance(); - } - } - return id; - } - - - function functionparams() { - var i, t = nexttoken, p = []; - advance('('); - nospace(); - if (nexttoken.id === ')') { - advance(')'); - nospace(prevtoken, token); - return; - } - for (;;) { - i = identifier(true); - p.push(i); - addlabel(i, 'parameter'); - if (nexttoken.id === ',') { - comma(); - } else { - advance(')', t); - nospace(prevtoken, token); - return p; - } - } - } - - - function doFunction(i, statement) { - var f, s = scope; - scope = Object.create(s); - funct = { - '(name)' : i || '"' + anonname + '"', - '(line)' : nexttoken.line, - '(context)' : funct, - '(breakage)' : 0, - '(loopage)' : 0, - '(scope)' : scope, - '(statement)': statement - }; - f = funct; - token.funct = funct; - functions.push(funct); - if (i) { - addlabel(i, 'function'); - } - funct['(params)'] = functionparams(); - - block(false); - scope = s; - funct['(last)'] = token.line; - funct = funct['(context)']; - return f; - } - - - (function (x) { - x.nud = function () { - var b, f, i, j, p, seen = {}, t; - b = token.line !== nexttoken.line; - if (b) { - indent += option.indent; - if (nexttoken.from === indent + option.indent) { - indent += option.indent; - } - } - for (;;) { - if (nexttoken.id === '}') { - break; - } - if (b) { - indentation(); - } - if (nexttoken.value === 'get' && peek().id !== ':') { - advance('get'); - if (!option.es5) { - error("get/set are ES5 features."); - } - i = property_name(); - if (!i) { - error("Missing property name."); - } - t = nexttoken; - adjacent(token, nexttoken); - f = doFunction(i); - if (funct['(loopage)']) { - warning("Don't make functions within a loop.", t); - } - p = f['(params)']; - if (p) { - warning("Unexpected parameter '{a}' in get {b} function.", t, p[0], i); - } - adjacent(token, nexttoken); - advance(','); - indentation(); - advance('set'); - j = property_name(); - if (i !== j) { - error("Expected {a} and instead saw {b}.", token, i, j); - } - t = nexttoken; - adjacent(token, nexttoken); - f = doFunction(i); - p = f['(params)']; - if (!p || p.length !== 1 || p[0] !== 'value') { - warning("Expected (value) in set {a} function.", t, i); - } - } else { - i = property_name(); - if (typeof i !== 'string') { - break; - } - advance(':'); - nonadjacent(token, nexttoken); - expression(10); - } - if (seen[i] === true) { - warning("Duplicate member '{a}'.", nexttoken, i); - } - seen[i] = true; - countMember(i); - if (nexttoken.id === ',') { - comma(); - if (nexttoken.id === ',') { - warning("Extra comma.", token); - } else if (nexttoken.id === '}' && !option.es5) { - warning("Extra comma.", token); - } - } else { - break; - } - } - if (b) { - indent -= option.indent; - indentation(); - } - advance('}', this); - return this; - }; - x.fud = function () { - error("Expected to see a statement and instead saw a block.", token); - }; - }(delim('{'))); - - - var varstatement = function varstatement(prefix) { - -// JavaScript does not have block scope. It only has function scope. So, -// declaring a variable in a block can have unexpected consequences. - - var id, name, value; - - if (funct['(onevar)'] && option.onevar) { - warning("Too many var statements."); - } else if (!funct['(global)']) { - funct['(onevar)'] = true; - } - this.first = []; - for (;;) { - nonadjacent(token, nexttoken); - id = identifier(); - if (funct['(global)'] && predefined[id] === false) { - warning("Redefinition of '{a}'.", token, id); - } - addlabel(id, 'unused'); - if (prefix) { - break; - } - name = token; - this.first.push(token); - if (nexttoken.id === '=') { - nonadjacent(token, nexttoken); - advance('='); - nonadjacent(token, nexttoken); - if (nexttoken.id === 'undefined') { - warning("It is not necessary to initialize '{a}' to 'undefined'.", token, id); - } - if (peek(0).id === '=' && nexttoken.identifier) { - error("Variable {a} was not declared correctly.", - nexttoken, nexttoken.value); - } - value = expression(0); - name.first = value; - } - if (nexttoken.id !== ',') { - break; - } - comma(); - } - return this; - }; - - - stmt('var', varstatement).exps = true; - - - blockstmt('function', function () { - if (inblock) { - warning( -"Function statements should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.", token); - - } - var i = identifier(); - adjacent(token, nexttoken); - addlabel(i, 'unction'); - doFunction(i, true); - if (nexttoken.id === '(' && nexttoken.line === token.line) { - error( -"Function statements are not invocable. Wrap the whole function invocation in parens."); - } - return this; - }); - - prefix('function', function () { - var i = optionalidentifier(); - if (i) { - adjacent(token, nexttoken); - } else { - nonadjacent(token, nexttoken); - } - doFunction(i); - if (funct['(loopage)']) { - warning("Don't make functions within a loop."); - } - return this; - }); - - blockstmt('if', function () { - var t = nexttoken; - advance('('); - nonadjacent(this, t); - nospace(); - expression(20); - if (nexttoken.id === '=') { - if (!option.boss) - warning("Expected a conditional expression and instead saw an assignment."); - advance('='); - expression(20); - } - advance(')', t); - nospace(prevtoken, token); - block(true, true); - if (nexttoken.id === 'else') { - nonadjacent(token, nexttoken); - advance('else'); - if (nexttoken.id === 'if' || nexttoken.id === 'switch') { - statement(true); - } else { - block(true, true); - } - } - return this; - }); - - blockstmt('try', function () { - var b, e, s; - if (option.adsafe) { - warning("ADsafe try violation.", this); - } - block(false); - if (nexttoken.id === 'catch') { - advance('catch'); - nonadjacent(token, nexttoken); - advance('('); - s = scope; - scope = Object.create(s); - e = nexttoken.value; - if (nexttoken.type !== '(identifier)') { - warning("Expected an identifier and instead saw '{a}'.", - nexttoken, e); - } else { - addlabel(e, 'exception'); - } - advance(); - advance(')'); - block(false); - b = true; - scope = s; - } - if (nexttoken.id === 'finally') { - advance('finally'); - block(false); - return; - } else if (!b) { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, 'catch', nexttoken.value); - } - return this; - }); - - blockstmt('while', function () { - var t = nexttoken; - funct['(breakage)'] += 1; - funct['(loopage)'] += 1; - advance('('); - nonadjacent(this, t); - nospace(); - expression(20); - if (nexttoken.id === '=') { - if (!option.boss) - warning("Expected a conditional expression and instead saw an assignment."); - advance('='); - expression(20); - } - advance(')', t); - nospace(prevtoken, token); - block(true, true); - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - }).labelled = true; - - reserve('with'); - - blockstmt('switch', function () { - var t = nexttoken, - g = false; - funct['(breakage)'] += 1; - advance('('); - nonadjacent(this, t); - nospace(); - this.condition = expression(20); - advance(')', t); - nospace(prevtoken, token); - nonadjacent(token, nexttoken); - t = nexttoken; - advance('{'); - nonadjacent(token, nexttoken); - indent += option.indent; - this.cases = []; - for (;;) { - switch (nexttoken.id) { - case 'case': - switch (funct['(verb)']) { - case 'break': - case 'case': - case 'continue': - case 'return': - case 'switch': - case 'throw': - break; - default: - warning( - "Expected a 'break' statement before 'case'.", - token); - } - indentation(-option.indent); - advance('case'); - this.cases.push(expression(20)); - g = true; - advance(':'); - funct['(verb)'] = 'case'; - break; - case 'default': - switch (funct['(verb)']) { - case 'break': - case 'continue': - case 'return': - case 'throw': - break; - default: - warning( - "Expected a 'break' statement before 'default'.", - token); - } - indentation(-option.indent); - advance('default'); - g = true; - advance(':'); - break; - case '}': - indent -= option.indent; - indentation(); - advance('}', t); - if (this.cases.length === 1 || this.condition.id === 'true' || - this.condition.id === 'false') { - warning("This 'switch' should be an 'if'.", this); - } - funct['(breakage)'] -= 1; - funct['(verb)'] = undefined; - return; - case '(end)': - error("Missing '{a}'.", nexttoken, '}'); - return; - default: - if (g) { - switch (token.id) { - case ',': - error("Each value should have its own case label."); - return; - case ':': - statements(); - break; - default: - error("Missing ':' on a case clause.", token); - } - } else { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, 'case', nexttoken.value); - } - } - } - }).labelled = true; - - stmt('debugger', function () { - if (!option.debug) { - warning("All 'debugger' statements should be removed."); - } - return this; - }).exps = true; - - (function () { - var x = stmt('do', function () { - funct['(breakage)'] += 1; - funct['(loopage)'] += 1; - this.first = block(true); - advance('while'); - var t = nexttoken; - nonadjacent(token, t); - advance('('); - nospace(); - expression(20); - if (nexttoken.id === '=') { - if (!option.boss) - warning("Expected a conditional expression and instead saw an assignment."); - advance('='); - expression(20); - } - advance(')', t); - nospace(prevtoken, token); - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - }); - x.labelled = true; - x.exps = true; - }()); - - blockstmt('for', function () { - var f = option.forin, s, t = nexttoken; - funct['(breakage)'] += 1; - funct['(loopage)'] += 1; - advance('('); - nonadjacent(this, t); - nospace(); - if (peek(nexttoken.id === 'var' ? 1 : 0).id === 'in') { - if (nexttoken.id === 'var') { - advance('var'); - varstatement(true); - } else { - switch (funct[nexttoken.value]) { - case 'unused': - funct[nexttoken.value] = 'var'; - break; - case 'var': - break; - default: - warning("Bad for in variable '{a}'.", - nexttoken, nexttoken.value); - } - advance(); - } - advance('in'); - expression(20); - advance(')', t); - s = block(true, true); - if (!f && (s.length > 1 || typeof s[0] !== 'object' || - s[0].value !== 'if')) { - warning("The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.", this); - } - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - } else { - if (nexttoken.id !== ';') { - if (nexttoken.id === 'var') { - advance('var'); - varstatement(); - } else { - for (;;) { - expression(0, 'for'); - if (nexttoken.id !== ',') { - break; - } - comma(); - } - } - } - nolinebreak(token); - advance(';'); - if (nexttoken.id !== ';') { - expression(20); - if (nexttoken.id === '=') { - if (!option.boss) - warning("Expected a conditional expression and instead saw an assignment."); - advance('='); - expression(20); - } - } - nolinebreak(token); - advance(';'); - if (nexttoken.id === ';') { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, ')', ';'); - } - if (nexttoken.id !== ')') { - for (;;) { - expression(0, 'for'); - if (nexttoken.id !== ',') { - break; - } - comma(); - } - } - advance(')', t); - nospace(prevtoken, token); - block(true, true); - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - } - }).labelled = true; - - - stmt('break', function () { - var v = nexttoken.value; - if (funct['(breakage)'] === 0) { - warning("Unexpected '{a}'.", nexttoken, this.value); - } - nolinebreak(this); - if (nexttoken.id !== ';') { - if (token.line === nexttoken.line) { - if (funct[v] !== 'label') { - warning("'{a}' is not a statement label.", nexttoken, v); - } else if (scope[v] !== funct) { - warning("'{a}' is out of scope.", nexttoken, v); - } - this.first = nexttoken; - advance(); - } - } - reachable('break'); - return this; - }).exps = true; - - - stmt('continue', function () { - var v = nexttoken.value; - if (funct['(breakage)'] === 0) { - warning("Unexpected '{a}'.", nexttoken, this.value); - } - nolinebreak(this); - if (nexttoken.id !== ';') { - if (token.line === nexttoken.line) { - if (funct[v] !== 'label') { - warning("'{a}' is not a statement label.", nexttoken, v); - } else if (scope[v] !== funct) { - warning("'{a}' is out of scope.", nexttoken, v); - } - this.first = nexttoken; - advance(); - } - } else if (!funct['(loopage)']) { - warning("Unexpected '{a}'.", nexttoken, this.value); - } - reachable('continue'); - return this; - }).exps = true; - - - stmt('return', function () { - nolinebreak(this); - if (nexttoken.id === '(regexp)') { - warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator."); - } - if (nexttoken.id !== ';' && !nexttoken.reach) { - nonadjacent(token, nexttoken); - this.first = expression(20); - } - reachable('return'); - return this; - }).exps = true; - - - stmt('throw', function () { - nolinebreak(this); - nonadjacent(token, nexttoken); - this.first = expression(20); - reachable('throw'); - return this; - }).exps = true; - - reserve('void'); - -// Superfluous reserved words - - reserve('class'); - reserve('const'); - reserve('enum'); - reserve('export'); - reserve('extends'); - reserve('import'); - reserve('super'); - - reserve('let'); - reserve('yield'); - reserve('implements'); - reserve('interface'); - reserve('package'); - reserve('private'); - reserve('protected'); - reserve('public'); - reserve('static'); - - -// Parse JSON - - function jsonValue() { - - function jsonObject() { - var o = {}, t = nexttoken; - advance('{'); - if (nexttoken.id !== '}') { - for (;;) { - if (nexttoken.id === '(end)') { - error("Missing '}' to match '{' from line {a}.", - nexttoken, t.line); - } else if (nexttoken.id === '}') { - warning("Unexpected comma.", token); - break; - } else if (nexttoken.id === ',') { - error("Unexpected comma.", nexttoken); - } else if (nexttoken.id !== '(string)') { - warning("Expected a string and instead saw {a}.", - nexttoken, nexttoken.value); - } - if (o[nexttoken.value] === true) { - warning("Duplicate key '{a}'.", - nexttoken, nexttoken.value); - } else if (nexttoken.value === '__proto__') { - warning("Stupid key '{a}'.", - nexttoken, nexttoken.value); - } else { - o[nexttoken.value] = true; - } - advance(); - advance(':'); - jsonValue(); - if (nexttoken.id !== ',') { - break; - } - advance(','); - } - } - advance('}'); - } - - function jsonArray() { - var t = nexttoken; - advance('['); - if (nexttoken.id !== ']') { - for (;;) { - if (nexttoken.id === '(end)') { - error("Missing ']' to match '[' from line {a}.", - nexttoken, t.line); - } else if (nexttoken.id === ']') { - warning("Unexpected comma.", token); - break; - } else if (nexttoken.id === ',') { - error("Unexpected comma.", nexttoken); - } - jsonValue(); - if (nexttoken.id !== ',') { - break; - } - advance(','); - } - } - advance(']'); - } - - switch (nexttoken.id) { - case '{': - jsonObject(); - break; - case '[': - jsonArray(); - break; - case 'true': - case 'false': - case 'null': - case '(number)': - case '(string)': - advance(); - break; - case '-': - advance('-'); - if (token.character !== nexttoken.from) { - warning("Unexpected space after '-'.", token); - } - adjacent(token, nexttoken); - advance('(number)'); - break; - default: - error("Expected a JSON value.", nexttoken); - } - } - - -// The actual JSHINT function itself. - - var itself = function (s, o) { - var a, i, k; - JSHINT.errors = []; - predefined = Object.create(standard); - if (o) { - a = o.predef; - if (a) { - if (Array.isArray(a)) { - for (i = 0; i < a.length; i += 1) { - predefined[a[i]] = true; - } - } else if (typeof a === 'object') { - k = Object.keys(a); - for (i = 0; i < k.length; i += 1) { - predefined[k[i]] = !!a[k]; - } - } - } - if (o.adsafe) { - o.safe = true; - } - if (o.safe) { - o.browser = - o.css = - o.debug = - o.devel = - o.evil = - o.forin = - o.on = - o.rhino = - o.windows = - o.sub = - o.widget = false; - - o.eqeqeq = - o.nomen = - o.safe = - o.undef = true; - - predefined.Date = - predefined['eval'] = - predefined.Function = - predefined.Object = null; - - predefined.ADSAFE = - predefined.lib = false; - } - option = o; - } else { - option = {}; - } - option.indent = option.indent || 4; - option.maxerr = option.maxerr || 50; - adsafe_id = ''; - adsafe_may = false; - adsafe_went = false; - approved = {}; - if (option.approved) { - for (i = 0; i < option.approved.length; i += 1) { - approved[option.approved[i]] = option.approved[i]; - } - } else { - approved.test = 'test'; - } - tab = ''; - for (i = 0; i < option.indent; i += 1) { - tab += ' '; - } - indent = 1; - global = Object.create(predefined); - scope = global; - funct = { - '(global)': true, - '(name)': '(global)', - '(scope)': scope, - '(breakage)': 0, - '(loopage)': 0 - }; - functions = [funct]; - ids = {}; - urls = []; - src = false; - xmode = false; - stack = null; - member = {}; - membersOnly = null; - implied = {}; - inblock = false; - lookahead = []; - jsonmode = false; - warnings = 0; - lex.init(s); - prereg = true; - strict_mode = false; - - prevtoken = token = nexttoken = syntax['(begin)']; - assume(); - - try { - advance(); - if (nexttoken.value.charAt(0) === '<') { - html(); - if (option.adsafe && !adsafe_went) { - warning("ADsafe violation: Missing ADSAFE.go.", this); - } - } else { - switch (nexttoken.id) { - case '{': - case '[': - option.laxbreak = true; - jsonmode = true; - jsonValue(); - break; - case '@': - case '*': - case '#': - case '.': - case ':': - xmode = 'style'; - advance(); - if (token.id !== '@' || !nexttoken.identifier || - nexttoken.value !== 'charset' || token.line !== 1 || - token.from !== 1) { - error("A css file should begin with @charset 'UTF-8';"); - } - advance(); - if (nexttoken.type !== '(string)' && - nexttoken.value !== 'UTF-8') { - error("A css file should begin with @charset 'UTF-8';"); - } - advance(); - advance(';'); - styles(); - break; - - default: - if (option.adsafe && option.fragment) { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, '
    ', nexttoken.value); - } - if (nexttoken.value === 'use strict') { - warning("Use the function form of \"use strict\"."); - use_strict(); - } - statements('lib'); - } - } - advance('(end)'); - } catch (e) { - if (e) { - JSHINT.errors.push({ - reason : e.message, - line : e.line || nexttoken.line, - character : e.character || nexttoken.from - }, null); - } - } - return JSHINT.errors.length === 0; - }; - - -// Data summary. - - itself.data = function () { - - var data = {functions: []}, fu, globals, implieds = [], f, i, j, - members = [], n, unused = [], v; - if (itself.errors.length) { - data.errors = itself.errors; - } - - if (jsonmode) { - data.json = true; - } - - for (n in implied) { - if (is_own(implied, n)) { - implieds.push({ - name: n, - line: implied[n] - }); - } - } - if (implieds.length > 0) { - data.implieds = implieds; - } - - if (urls.length > 0) { - data.urls = urls; - } - - globals = Object.keys(scope); - if (globals.length > 0) { - data.globals = globals; - } - - for (i = 1; i < functions.length; i += 1) { - f = functions[i]; - fu = {}; - for (j = 0; j < functionicity.length; j += 1) { - fu[functionicity[j]] = []; - } - for (n in f) { - if (is_own(f, n) && n.charAt(0) !== '(') { - v = f[n]; - if (v === 'unction') { - v = 'unused'; - } - if (Array.isArray(fu[v])) { - fu[v].push(n); - if (v === 'unused') { - unused.push({ - name: n, - line: f['(line)'], - 'function': f['(name)'] - }); - } - } - } - } - for (j = 0; j < functionicity.length; j += 1) { - if (fu[functionicity[j]].length === 0) { - delete fu[functionicity[j]]; - } - } - fu.name = f['(name)']; - fu.param = f['(params)']; - fu.line = f['(line)']; - fu.last = f['(last)']; - data.functions.push(fu); - } - - if (unused.length > 0) { - data.unused = unused; - } - - members = []; - for (n in member) { - if (typeof member[n] === 'number') { - data.member = member; - break; - } - } - - return data; - }; - - itself.report = function (option) { - var data = itself.data(); - - var a = [], c, e, err, f, i, k, l, m = '', n, o = [], s; - - function detail(h, array) { - var b, i, singularity; - if (array) { - o.push('
    ' + h + ' '); - array = array.sort(); - for (i = 0; i < array.length; i += 1) { - if (array[i] !== singularity) { - singularity = array[i]; - o.push((b ? ', ' : '') + singularity); - b = true; - } - } - o.push('
    '); - } - } - - - if (data.errors || data.implieds || data.unused) { - err = true; - o.push('
    Error:'); - if (data.errors) { - for (i = 0; i < data.errors.length; i += 1) { - c = data.errors[i]; - if (c) { - e = c.evidence || ''; - o.push('

    Problem' + (isFinite(c.line) ? ' at line ' + - c.line + ' character ' + c.character : '') + - ': ' + c.reason.entityify() + - '

    ' + - (e && (e.length > 80 ? e.slice(0, 77) + '...' : - e).entityify()) + '

    '); - } - } - } - - if (data.implieds) { - s = []; - for (i = 0; i < data.implieds.length; i += 1) { - s[i] = '' + data.implieds[i].name + ' ' + - data.implieds[i].line + ''; - } - o.push('

    Implied global: ' + s.join(', ') + '

    '); - } - - if (data.unused) { - s = []; - for (i = 0; i < data.unused.length; i += 1) { - s[i] = '' + data.unused[i].name + ' ' + - data.unused[i].line + ' ' + - data.unused[i]['function'] + ''; - } - o.push('

    Unused variable: ' + s.join(', ') + '

    '); - } - if (data.json) { - o.push('

    JSON: bad.

    '); - } - o.push('
    '); - } - - if (!option) { - - o.push('
    '); - - if (data.urls) { - detail("URLs
    ", data.urls, '
    '); - } - - if (xmode === 'style') { - o.push('

    CSS.

    '); - } else if (data.json && !err) { - o.push('

    JSON: good.

    '); - } else if (data.globals) { - o.push('
    Global ' + - data.globals.sort().join(', ') + '
    '); - } else { - o.push('
    No new global variables introduced.
    '); - } - - for (i = 0; i < data.functions.length; i += 1) { - f = data.functions[i]; - - o.push('
    ' + f.line + '-' + - f.last + ' ' + (f.name || '') + '(' + - (f.param ? f.param.join(', ') : '') + ')
    '); - detail('Unused', f.unused); - detail('Closure', f.closure); - detail('Variable', f['var']); - detail('Exception', f.exception); - detail('Outer', f.outer); - detail('Global', f.global); - detail('Label', f.label); - } - - if (data.member) { - a = Object.keys(data.member); - if (a.length) { - a = a.sort(); - m = '
    /*members ';
    -                    l = 10;
    -                    for (i = 0; i < a.length; i += 1) {
    -                        k = a[i];
    -                        n = k.name();
    -                        if (l + n.length > 72) {
    -                            o.push(m + '
    '); - m = ' '; - l = 1; - } - l += n.length + 2; - if (data.member[k] === 1) { - n = '' + n + ''; - } - if (i < a.length - 1) { - n += ', '; - } - m += n; - } - o.push(m + '
    */
    '); - } - o.push('
    '); - } - } - return o.join(''); - }; - itself.jshint = itself; - - itself.edition = '2011-02-19'; - - return itself; - -}()); - -// Make JSHINT a Node module, if possible. -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 deleted file mode 100644 index 78609cf0..00000000 --- a/lib/ace/worker/jslint.js +++ /dev/null @@ -1,5747 +0,0 @@ -// jslint.js -// 2011-01-09 - -/* -Copyright (c) 2002 Douglas Crockford (www.JSLint.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -/* - JSLINT is a global function. It takes two parameters. - - var myResult = JSLINT(source, option); - - The first parameter is either a string or an array of strings. If it is a - string, it will be split on '\n' or '\r'. If it is an array of strings, it - is assumed that each string represents one line. The source can be a - JavaScript text, or HTML text, or a JSON text, or a CSS text. - - The second parameter is an optional object of options which control the - operation of JSLINT. Most of the options are booleans: They are all - optional and have a default value of false. One of the options, predef, - can be an array of names, which will be used to declare global variables, - or an object whose keys are used as global names, with a boolean value - that determines if they are assignable. - - If it checks out, JSLINT returns true. Otherwise, it returns false. - - If false, you can inspect JSLINT.errors to find out the problems. - JSLINT.errors is an array of objects containing these members: - - { - line : The line (relative to 0) at which the lint was found - character : The character (relative to 0) at which the lint was found - reason : The problem - evidence : The text line in which the problem occurred - raw : The raw message before the details were inserted - a : The first detail - b : The second detail - c : The third detail - d : The fourth detail - } - - If a fatal error was found, a null will be the last element of the - JSLINT.errors array. - - You can request a Function Report, which shows all of the functions - and the parameters and vars that they use. This can be used to find - implied global variables and other problems. The report is in HTML and - can be inserted in an HTML . - - var myReport = JSLINT.report(limited); - - If limited is true, then the report will be limited to only errors. - - You can request a data structure which contains JSLint's results. - - var myData = JSLINT.data(); - - It returns a structure with this form: - - { - errors: [ - { - line: NUMBER, - character: NUMBER, - reason: STRING, - evidence: STRING - } - ], - functions: [ - name: STRING, - line: NUMBER, - last: NUMBER, - param: [ - STRING - ], - closure: [ - STRING - ], - var: [ - STRING - ], - exception: [ - STRING - ], - outer: [ - STRING - ], - unused: [ - STRING - ], - global: [ - STRING - ], - label: [ - STRING - ] - ], - globals: [ - STRING - ], - member: { - STRING: NUMBER - }, - unuseds: [ - { - name: STRING, - line: NUMBER - } - ], - implieds: [ - { - name: STRING, - line: NUMBER - } - ], - urls: [ - STRING - ], - json: BOOLEAN - } - - Empty arrays will not be included. - - You can obtain the parse tree that JSLint constructed while parsing. The - latest tree is kept in JSLINT.tree. A nice stringication can be produced - with - - JSON.stringify(JSLINT.tree, [ - 'value', 'arity', 'name', 'first', - 'second', 'third', 'block', 'else' - ], 4)); - -*/ - -/*jslint - evil: true, nomen: false, onevar: false, regexp: false, strict: true -*/ - -/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "'", "%", - "(begin)", "(breakage)", "(context)", "(end)", "(error)", "(global)", - "(identifier)", "(last)", "(line)", "(loopage)", "(name)", "(onevar)", - "(params)", "(scope)", "(statement)", "(token)", "(verb)", "*", "+", "++", "-", - "--", "\/", "<", "<=", "", ">=", - ADSAFE, ActiveXObject, Array, Boolean, COM, CScript, Canvas, - CustomAnimation, Date, Debug, E, Enumerator, Error, EvalError, - FadeAnimation, Flash, FormField, Frame, Function, HotKey, Image, JSON, - LN10, LN2, LOG10E, LOG2E, MAX_VALUE, MIN_VALUE, Math, MenuItem, - MoveAnimation, NEGATIVE_INFINITY, Number, Object, Option, PI, - POSITIVE_INFINITY, Point, RangeError, Rectangle, ReferenceError, RegExp, - ResizeAnimation, RotateAnimation, SQRT1_2, SQRT2, ScrollBar, String, - Style, SyntaxError, System, Text, TextArea, Timer, TypeError, URIError, - URL, VBArray, WScript, Web, Window, XMLDOM, XMLHttpRequest, "\\", a, - abbr, acronym, activeborder, activecaption, addEventListener, address, - adsafe, alert, aliceblue, all, animator, antiquewhite, appleScript, - applet, apply, approved, appworkspace, aqua, aquamarine, area, - arguments, arity, article, aside, assign, audio, autocomplete, azure, b, - background, "background-attachment", "background-color", - "background-image", "background-position", "background-repeat", base, - bdo, beep, beige, big, bisque, bitwise, black, blanchedalmond, block, - blockquote, blue, blueviolet, blur, body, border, "border-bottom", - "border-bottom-color", "border-bottom-style", "border-bottom-width", - "border-collapse", "border-color", "border-left", "border-left-color", - "border-left-style", "border-left-width", "border-right", - "border-right-color", "border-right-style", "border-right-width", - "border-spacing", "border-style", "border-top", "border-top-color", - "border-top-style", "border-top-width", "border-width", bottom, br, - braille, brown, browser, burlywood, button, buttonface, buttonhighlight, - buttonshadow, buttontext, bytesToUIString, c, cadetblue, call, callee, - caller, canvas, cap, caption, "caption-side", captiontext, case, catch, - center, charAt, charCodeAt, character, chartreuse, chocolate, - chooseColor, chooseFile, chooseFolder, cite, clear, clearInterval, - clearTimeout, clip, close, closeWidget, closed, closure, cm, code, col, - colgroup, color, command, comment, confirm, console, constructor, - content, convertPathToHFS, convertPathToPlatform, coral, cornflowerblue, - cornsilk, "counter-increment", "counter-reset", create, crimson, css, - cursor, cyan, d, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen, - darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred, - darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise, - darkviolet, data, datalist, dd, debug, decodeURI, decodeURIComponent, - deeppink, deepskyblue, default, defaultStatus, defineClass, del, - deserialize, details, devel, dfn, dialog, dimgray, dir, direction, - display, disrupt, div, dl, do, document, dodgerblue, - dt, edition, else, em, embed, embossed, empty, "empty-cells", encodeURI, - encodeURIComponent, entityify, errors, es5, escape, eval, event, - evidence, evil, ex, exception, exec, fieldset, figure, filesystem, - finally, firebrick, first, float, floor, floralwhite, focus, - focusWidget, font, "font-family", "font-size", "font-size-adjust", - "font-stretch", "font-style", "font-variant", "font-weight", footer, - for, forestgreen, forin, form, fragment, frame, frames, frameset, from, - fromCharCode, fuchsia, fud, funct, function, functions, g, gainsboro, - gc, getComputedStyle, ghostwhite, global, globals, gold, goldenrod, - gray, graytext, green, greenyellow, h1, h2, h3, h4, h5, h6, handheld, - hasOwnProperty, head, header, height, help, hgroup, highlight, - highlighttext, history, honeydew, hotpink, hr, "hta:application", html, - i, iTunes, id, identifier, iframe, img, immed, implieds, in, - inactiveborder, inactivecaption, inactivecaptiontext, include, indent, - indexOf, indianred, indigo, infobackground, infotext, init, initial, - input, ins, isAlpha, isApplicationRunning, isArray, isDigit, isFinite, - isNaN, ivory, join, jslint, json, kbd, keygen, keys, khaki, - konfabulatorVersion, label, lang, last, lavender, lavenderblush, - lawngreen, lbp, led, left, legend, lemonchiffon, length, - "letter-spacing", li, lib, lightblue, lightcoral, lightcyan, - lightgoldenrodyellow, lightgreen, lightpink, lightsalmon, lightseagreen, - lightskyblue, lightslategray, lightsteelblue, lightyellow, lime, - limegreen, line, "line-height", linen, link, "list-style", - "list-style-image", "list-style-position", "list-style-type", load, - loadClass, location, log, m, magenta, map, margin, "margin-bottom", - "margin-left", "margin-right", "margin-top", mark, "marker-offset", - maroon, match, "max-height", "max-width", maxerr, maxlen, md5, - mediumaquamarine, mediumblue, mediumorchid, mediumpurple, - mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise, - mediumvioletred, member, menu, menutext, message, meta, meter, - midnightblue, "min-height", "min-width", mintcream, mistyrose, mm, - moccasin, moveBy, moveTo, name, nav, navajowhite, navigator, navy, new, - newcap, noframes, nomen, noscript, nud, object, ol, oldlace, olive, - olivedrab, on, onbeforeunload, onblur, onerror, onevar, onfocus, onload, - onresize, onunload, opacity, open, openURL, opener, opera, optgroup, - option, orange, orangered, orchid, outer, outline, "outline-color", - "outline-style", "outline-width", output, overflow, "overflow-x", - "overflow-y", p, padding, "padding-bottom", "padding-left", - "padding-right", "padding-top", "page-break-after", "page-break-before", - palegoldenrod, palegreen, paleturquoise, palevioletred, papayawhip, - param, parent, parseFloat, parseInt, passfail, pc, peachpuff, peru, - pink, play, plum, plusplus, pop, popupMenu, position, powderblue, pre, - predef, preferenceGroups, preferences, print, progress, projection, - prompt, prototype, pt, purple, push, px, q, quit, quotes, random, range, - raw, readFile, readUrl, reason, red, regexp, reloadWidget, - removeEventListener, replace, report, reserved, resizeBy, resizeTo, - resolvePath, resumeUpdates, rhino, right, rosybrown, royalblue, rp, rt, - ruby, runCommand, runCommandInBg, saddlebrown, safe, salmon, samp, - sandybrown, saveAs, savePreferences, screen, script, scroll, scrollBy, - scrollTo, scrollbar, seagreen, seal, search, seashell, second, section, - select, serialize, setInterval, setTimeout, shift, - showWidgetPreferences, sienna, silver, skyblue, slateblue, slategray, - sleep, slice, small, snow, sort, source, span, spawn, speak, speech, - split, springgreen, src, stack, status, steelblue, strict, strong, - style, styleproperty, sub, substr, sup, supplant, suppressUpdates, - switch, sync, system, table, "table-layout", tan, tbody, td, teal, - tellWidget, test, "text-align", "text-decoration", "text-indent", - "text-shadow", "text-transform", textarea, tfoot, th, thead, third, - thistle, threeddarkshadow, threedface, threedhighlight, - threedlightshadow, threedshadow, thru, time, title, toLowerCase, toString, - toUpperCase, toint32, token, tomato, top, tr, tree, tt, tty, turquoise, tv, - type, u, ul, undef, unescape, "unicode-bidi", unused, unwatch, - updateNow, urls, value, valueOf, var, version, "vertical-align", video, - violet, visibility, watch, wheat, while, white, "white-space", - whitesmoke, widget, width, window, windowframe, windows, windowtext, - "word-spacing", "word-wrap", yahooCheckLogin, yahooLogin, yahooLogout, - yellow, yellowgreen, "z-index", "}" -*/ - -// We build the application inside a function so that we produce only a single -// global variable. That function will be invoked immediately, and its return -// value is the JSLINT function itself. That function is also an object that -// can contain data and other functions. - -define(function(require, exports, module) { - -var JSLINT = exports.JSLINT = (function () { - //"use strict"; - - var adsafe_id, // The widget's ADsafe id. - adsafe_may, // The widget may load approved scripts. - adsafe_went, // ADSAFE.go has been called. - anonname, // The guessed name for anonymous functions. - approved, // ADsafe approved urls. - -// These are operators that should not be used with the ! operator. - - bang = { - '<': true, - '<=': true, - '==': true, - '===': true, - '!==': true, - '!=': true, - '>': true, - '>=': true, - '+': true, - '-': true, - '*': true, - '/': true, - '%': true - }, - -// These are property names that should not be permitted in the safe subset. - - banned = { // the member names that ADsafe prohibits. - 'arguments' : true, - callee : true, - caller : true, - constructor : true, - 'eval' : true, - prototype : true, - stack : true, - unwatch : true, - valueOf : true, - watch : true - }, - - -// These are the JSLint boolean options. - - boolOptions = { - adsafe : true, // if ADsafe should be enforced - bitwise : true, // if bitwise operators should not be allowed - browser : true, // if the standard browser globals should be predefined - cap : true, // if upper case HTML should be allowed - css : true, // if CSS workarounds should be tolerated - debug : true, // if debugger statements should be allowed - devel : true, // if logging should be allowed (console, alert, etc.) - es5 : true, // if ES5 syntax should be allowed - evil : true, // if eval should be allowed - forin : true, // if for in statements must filter - fragment : true, // if HTML fragments should be allowed - newcap : true, // if constructor names must be capitalized - nomen : true, // if names should be checked - on : true, // if HTML event handlers should be allowed - onevar : true, // if only one var statement per function should be allowed - passfail : true, // if the scan should stop on first error - plusplus : true, // if increment/decrement should not be allowed - regexp : true, // if the . should not be allowed in regexp literals - rhino : true, // if the Rhino environment globals should be predefined - undef : true, // if variables should be declared before used - safe : true, // if use of some browser features should be restricted - windows : true, // if MS Windows-specigic globals should be predefined - strict : true, // require the "use strict"; pragma - sub : true, // if all forms of subscript notation are tolerated - white : true, // if strict whitespace rules apply - widget : true // if the Yahoo Widgets globals should be predefined - }, - -// browser contains a set of global names which are commonly provided by a -// web browser environment. - - browser = { - addEventListener: false, - blur : false, - clearInterval : false, - clearTimeout : false, - close : false, - closed : false, - defaultStatus : false, - document : false, - event : false, - focus : false, - frames : false, - getComputedStyle: false, - history : false, - Image : false, - length : false, - location : false, - moveBy : false, - moveTo : false, - name : false, - navigator : false, - onbeforeunload : true, - onblur : true, - onerror : true, - onfocus : true, - onload : true, - onresize : true, - onunload : true, - open : false, - opener : false, - Option : false, - parent : false, - print : false, - removeEventListener: false, - resizeBy : false, - resizeTo : false, - screen : false, - scroll : false, - scrollBy : false, - scrollTo : false, - setInterval : false, - setTimeout : false, - status : false, - top : false, - XMLHttpRequest : false - }, - - cssAttributeData, - cssAny, - - cssColorData = { - "aliceblue" : true, - "antiquewhite" : true, - "aqua" : true, - "aquamarine" : true, - "azure" : true, - "beige" : true, - "bisque" : true, - "black" : true, - "blanchedalmond" : true, - "blue" : true, - "blueviolet" : true, - "brown" : true, - "burlywood" : true, - "cadetblue" : true, - "chartreuse" : true, - "chocolate" : true, - "coral" : true, - "cornflowerblue" : true, - "cornsilk" : true, - "crimson" : true, - "cyan" : true, - "darkblue" : true, - "darkcyan" : true, - "darkgoldenrod" : true, - "darkgray" : true, - "darkgreen" : true, - "darkkhaki" : true, - "darkmagenta" : true, - "darkolivegreen" : true, - "darkorange" : true, - "darkorchid" : true, - "darkred" : true, - "darksalmon" : true, - "darkseagreen" : true, - "darkslateblue" : true, - "darkslategray" : true, - "darkturquoise" : true, - "darkviolet" : true, - "deeppink" : true, - "deepskyblue" : true, - "dimgray" : true, - "dodgerblue" : true, - "firebrick" : true, - "floralwhite" : true, - "forestgreen" : true, - "fuchsia" : true, - "gainsboro" : true, - "ghostwhite" : true, - "gold" : true, - "goldenrod" : true, - "gray" : true, - "green" : true, - "greenyellow" : true, - "honeydew" : true, - "hotpink" : true, - "indianred" : true, - "indigo" : true, - "ivory" : true, - "khaki" : true, - "lavender" : true, - "lavenderblush" : true, - "lawngreen" : true, - "lemonchiffon" : true, - "lightblue" : true, - "lightcoral" : true, - "lightcyan" : true, - "lightgoldenrodyellow" : true, - "lightgreen" : true, - "lightpink" : true, - "lightsalmon" : true, - "lightseagreen" : true, - "lightskyblue" : true, - "lightslategray" : true, - "lightsteelblue" : true, - "lightyellow" : true, - "lime" : true, - "limegreen" : true, - "linen" : true, - "magenta" : true, - "maroon" : true, - "mediumaquamarine" : true, - "mediumblue" : true, - "mediumorchid" : true, - "mediumpurple" : true, - "mediumseagreen" : true, - "mediumslateblue" : true, - "mediumspringgreen" : true, - "mediumturquoise" : true, - "mediumvioletred" : true, - "midnightblue" : true, - "mintcream" : true, - "mistyrose" : true, - "moccasin" : true, - "navajowhite" : true, - "navy" : true, - "oldlace" : true, - "olive" : true, - "olivedrab" : true, - "orange" : true, - "orangered" : true, - "orchid" : true, - "palegoldenrod" : true, - "palegreen" : true, - "paleturquoise" : true, - "palevioletred" : true, - "papayawhip" : true, - "peachpuff" : true, - "peru" : true, - "pink" : true, - "plum" : true, - "powderblue" : true, - "purple" : true, - "red" : true, - "rosybrown" : true, - "royalblue" : true, - "saddlebrown" : true, - "salmon" : true, - "sandybrown" : true, - "seagreen" : true, - "seashell" : true, - "sienna" : true, - "silver" : true, - "skyblue" : true, - "slateblue" : true, - "slategray" : true, - "snow" : true, - "springgreen" : true, - "steelblue" : true, - "tan" : true, - "teal" : true, - "thistle" : true, - "tomato" : true, - "turquoise" : true, - "violet" : true, - "wheat" : true, - "white" : true, - "whitesmoke" : true, - "yellow" : true, - "yellowgreen" : true, - - "activeborder" : true, - "activecaption" : true, - "appworkspace" : true, - "background" : true, - "buttonface" : true, - "buttonhighlight" : true, - "buttonshadow" : true, - "buttontext" : true, - "captiontext" : true, - "graytext" : true, - "highlight" : true, - "highlighttext" : true, - "inactiveborder" : true, - "inactivecaption" : true, - "inactivecaptiontext" : true, - "infobackground" : true, - "infotext" : true, - "menu" : true, - "menutext" : true, - "scrollbar" : true, - "threeddarkshadow" : true, - "threedface" : true, - "threedhighlight" : true, - "threedlightshadow" : true, - "threedshadow" : true, - "window" : true, - "windowframe" : true, - "windowtext" : true - }, - - cssBorderStyle, - cssBreak, - - cssLengthData = { - '%': true, - 'cm': true, - 'em': true, - 'ex': true, - 'in': true, - 'mm': true, - 'pc': true, - 'pt': true, - 'px': true - }, - - cssMedia, - cssOverflow, - - devel = { - alert : false, - confirm : false, - console : false, - Debug : false, - opera : false, - prompt : false - }, - - escapes = { - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"' : '\\"', - '/' : '\\/', - '\\': '\\\\' - }, - - funct, // The current function - - functionicity = [ - 'closure', 'exception', 'global', 'label', - 'outer', 'unused', 'var' - ], - - functions, // All of the functions - - global, // The global scope - htmltag = { - a: {}, - abbr: {}, - acronym: {}, - address: {}, - applet: {}, - area: {empty: true, parent: ' map '}, - article: {}, - aside: {}, - audio: {}, - b: {}, - base: {empty: true, parent: ' head '}, - bdo: {}, - big: {}, - blockquote: {}, - body: {parent: ' html noframes '}, - br: {empty: true}, - button: {}, - canvas: {parent: ' body p div th td '}, - caption: {parent: ' table '}, - center: {}, - cite: {}, - code: {}, - col: {empty: true, parent: ' table colgroup '}, - colgroup: {parent: ' table '}, - command: {parent: ' menu '}, - datalist: {}, - dd: {parent: ' dl '}, - del: {}, - details: {}, - dialog: {}, - dfn: {}, - dir: {}, - div: {}, - dl: {}, - dt: {parent: ' dl '}, - em: {}, - embed: {}, - fieldset: {}, - figure: {}, - font: {}, - footer: {}, - form: {}, - frame: {empty: true, parent: ' frameset '}, - frameset: {parent: ' html frameset '}, - h1: {}, - h2: {}, - h3: {}, - h4: {}, - h5: {}, - h6: {}, - head: {parent: ' html '}, - header: {}, - hgroup: {}, - hr: {empty: true}, - 'hta:application': - {empty: true, parent: ' head '}, - html: {parent: '*'}, - i: {}, - iframe: {}, - img: {empty: true}, - input: {empty: true}, - ins: {}, - kbd: {}, - keygen: {}, - label: {}, - legend: {parent: ' details fieldset figure '}, - li: {parent: ' dir menu ol ul '}, - link: {empty: true, parent: ' head '}, - map: {}, - mark: {}, - menu: {}, - meta: {empty: true, parent: ' head noframes noscript '}, - meter: {}, - nav: {}, - noframes: {parent: ' html body '}, - noscript: {parent: ' body head noframes '}, - object: {}, - ol: {}, - optgroup: {parent: ' select '}, - option: {parent: ' optgroup select '}, - output: {}, - p: {}, - param: {empty: true, parent: ' applet object '}, - pre: {}, - progress: {}, - q: {}, - rp: {}, - rt: {}, - ruby: {}, - samp: {}, - script: {empty: true, parent: ' body div frame head iframe p pre span '}, - section: {}, - select: {}, - small: {}, - span: {}, - source: {}, - strong: {}, - style: {parent: ' head ', empty: true}, - sub: {}, - sup: {}, - table: {}, - tbody: {parent: ' table '}, - td: {parent: ' tr '}, - textarea: {}, - tfoot: {parent: ' table '}, - th: {parent: ' tr '}, - thead: {parent: ' table '}, - time: {}, - title: {parent: ' head '}, - tr: {parent: ' table tbody thead tfoot '}, - tt: {}, - u: {}, - ul: {}, - 'var': {}, - video: {} - }, - - ids, // HTML ids - implied, // Implied globals - inblock, - jsonmode, - labelled = { - 'do': true, - 'for': true, - 'switch': true, - 'while': true - }, - lines, - lookahead, - member, - membersOnly, - nexttoken, - option, - postscript = { - '(end)': true, - '(error)': true, - '>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/, -// html token - hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-:]*|[0-9]+|--)/, -// characters in strings that need escapement - nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/, - nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, -// outer html token - ox = /[>&]|<[\/!]?|--/, -// star slash - lx = /\*\/|\/\*/, -// identifier - ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/, -// javascript url - jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i, -// url badness - ux = /&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i, -// style - sx = /^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/, - ssx = /^\s*([@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/, -// attributes characters - qx = /[^a-zA-Z0-9+\-_\/ ]/, -// query characters for ids - dx = /[\[\]\/\\"'*<>.&:(){}+=#]/, - - rx = { - outer: hx, - html: hx, - style: sx, - styleproperty: ssx - }; - - - function F() {} // Used by Object.create - - function is_own(object, name) { - -// The object.hasOwnProperty method fails when the property under consideration -// is named 'hasOwnProperty'. So we have to use this more convoluted form. - - return Object.prototype.hasOwnProperty.call(object, name); - } - -// Provide critical ES5 functions to ES3. - - if (typeof Array.isArray !== 'function') { - Array.isArray = function (o) { - return Object.prototype.toString.apply(o) === '[object Array]'; - }; - } - - if (typeof Object.create !== 'function') { - Object.create = function (o) { - F.prototype = o; - return new F(); - }; - } - - if (typeof Object.keys !== 'function') { - Object.keys = function (o) { - var a = [], k; - for (k in o) { - if (is_own(o, k)) { - a.push(k); - } - } - return a; - }; - } - -// Non standard methods - - if (typeof String.prototype.entityify !== 'function') { - String.prototype.entityify = function () { - return this - .replace(/&/g, '&') - .replace(//g, '>'); - }; - } - - if (typeof String.prototype.isAlpha !== 'function') { - String.prototype.isAlpha = function () { - return (this >= 'a' && this <= 'z\uffff') || - (this >= 'A' && this <= 'Z\uffff'); - }; - } - - if (typeof String.prototype.isDigit !== 'function') { - String.prototype.isDigit = function () { - return (this >= '0' && this <= '9'); - }; - } - - if (typeof String.prototype.supplant !== 'function') { - String.prototype.supplant = function (o) { - return this.replace(/\{([^{}]*)\}/g, function (a, b) { - var r = o[b]; - return typeof r === 'string' || typeof r === 'number' ? r : a; - }); - }; - } - - if (typeof String.prototype.name !== 'function') { - String.prototype.name = function () { - -// If the string looks like an identifier, then we can return it as is. -// If the string contains no control characters, no quote characters, and no -// backslash characters, then we can simply slap some quotes around it. -// Otherwise we must also replace the offending characters with safe -// sequences. - - if (ix.test(this)) { - return this; - } - if (nx.test(this)) { - return '"' + this.replace(nxg, function (a) { - var c = escapes[a]; - if (c) { - return c; - } - return '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4); - }) + '"'; - } - return '"' + this + '"'; - }; - } - - - function combine(t, o) { - var n; - for (n in o) { - if (is_own(o, n)) { - t[n] = o[n]; - } - } - } - - function assume() { - if (!option.safe) { - if (option.rhino) { - combine(predefined, rhino); - } - if (option.devel) { - combine(predefined, devel); - } - if (option.browser) { - combine(predefined, browser); - } - if (option.windows) { - combine(predefined, windows); - } - if (option.widget) { - combine(predefined, widget); - } - } - } - - -// Produce an error warning. - - function quit(m, l, ch) { - throw { - name: 'JSLintError', - line: l, - character: ch, - message: m + " (" + Math.floor((l / lines.length) * 100) + - "% scanned)." - }; - } - - function warning(m, t, a, b, c, d) { - var ch, l, w; - t = t || nexttoken; - if (t.id === '(end)') { // `~ - t = token; - } - l = t.line || 0; - ch = t.from || 0; - w = { - id: '(error)', - raw: m, - evidence: lines[l - 1] || '', - line: l, - character: ch, - a: a, - b: b, - c: c, - d: d - }; - w.reason = m.supplant(w); - JSLINT.errors.push(w); - if (option.passfail) { - quit('Stopping. ', l, ch); - } - warnings += 1; - if (warnings >= option.maxerr) { - quit("Too many errors.", l, ch); - } - return w; - } - - function warningAt(m, l, ch, a, b, c, d) { - return warning(m, { - line: l, - from: ch - }, a, b, c, d); - } - - function error(m, t, a, b, c, d) { - var w = warning(m, t, a, b, c, d); - quit("Stopping, unable to continue.", w.line, w.character); - } - - function errorAt(m, l, ch, a, b, c, d) { - return error(m, { - line: l, - from: ch - }, a, b, c, d); - } - - - -// lexical analysis and token construction - - var lex = (function lex() { - var character, from, line, s; - -// Private lex methods - - function nextLine() { - var at; - if (line >= lines.length) { - return false; - } - character = 1; - s = lines[line]; - line += 1; - at = s.search(/ \t/); - if (at >= 0) { - warningAt("Mixed spaces and tabs.", line, at + 1); - } - s = s.replace(/\t/g, tab); - at = s.search(cx); - if (at >= 0) { - warningAt("Unsafe character.", line, at); - } - if (option.maxlen && option.maxlen < s.length) { - warningAt("Line too long.", line, s.length); - } - return true; - } - -// Produce a token object. The token inherits from a syntax symbol. - - function it(type, value) { - var i, t; - if (type === '(color)' || type === '(range)') { - t = {type: type}; - } else if (type === '(punctuator)' || - (type === '(identifier)' && is_own(syntax, value))) { - t = syntax[value] || syntax['(error)']; - } else { - t = syntax[type]; - } - t = Object.create(t); - if (type === '(string)' || type === '(range)') { - if (jx.test(value)) { - warningAt("Script URL.", line, from); - } - } - if (type === '(identifier)') { - t.identifier = true; - if (value === '__iterator__' || value === '__proto__') { - errorAt("Reserved name '{a}'.", - line, from, value); - } else if (option.nomen && - (value.charAt(0) === '_' || - value.charAt(value.length - 1) === '_')) { - warningAt("Unexpected {a} in '{b}'.", line, from, - "dangling '_'", value); - } - } - if (value !== undefined) { - t.value = value; - } - t.line = line; - t.thru = character; - t.from = from; - i = t.id; - prereg = i && - (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) || - i === 'return'); - return t; - } - -// Public lex methods - - return { - init: function (source) { - if (typeof source === 'string') { - lines = source - .replace(/\r\n/g, '\n') - .replace(/\r/g, '\n') - .split('\n'); - } else { - lines = source; - } - line = 0; - nextLine(); - from = 1; - }, - - range: function (begin, end) { - var c, value = ''; - from = character; - if (s.charAt(0) !== begin) { - errorAt("Expected '{a}' and instead saw '{b}'.", - line, character, begin, s.charAt(0)); - } - for (;;) { - s = s.slice(1); - character += 1; - c = s.charAt(0); - switch (c) { - case '': - errorAt("Missing '{a}'.", line, character, c); - break; - case end: - s = s.slice(1); - character += 1; - return it('(range)', value); - case xquote: - case '\\': - warningAt("Unexpected '{a}'.", line, character, c); - break; - } - value += c; - } - }, - -// token -- this is called by advance to get the next token. - - token: function () { - var b, c, captures, d, depth, high, i, l, low, q, t; - - function match(x) { - var r = x.exec(s), r1; - if (r) { - l = r[0].length; - r1 = r[1]; - c = r1.charAt(0); - s = s.substr(l); - from = character + l - r1.length; - character += l; - return r1; - } - } - - function string(x) { - var c, j, r = ''; - - if (jsonmode && x !== '"') { - warningAt("Strings must use doublequote.", - line, character); - } - - if (xquote === x || (xmode === 'scriptstring' && !xquote)) { - return it('(punctuator)', x); - } - - function esc(n) { - var i = parseInt(s.substr(j + 1, n), 16); - j += n; - if (i >= 32 && i <= 126 && - i !== 34 && i !== 92 && i !== 39) { - warningAt("Unnecessary escapement.", line, character); - } - character += n; - c = String.fromCharCode(i); - } - j = 0; - for (;;) { - while (j >= s.length) { - j = 0; - if (xmode !== 'html' || !nextLine()) { - errorAt("Unclosed string.", line, from); - } - } - c = s.charAt(j); - if (c === x) { - character += 1; - s = s.substr(j + 1); - return it('(string)', r, x); - } - if (c < ' ') { - if (c === '\n' || c === '\r') { - break; - } - warningAt("Control character in string: {a}.", - line, character + j, s.slice(0, j)); - } else if (c === xquote) { - warningAt("Bad HTML string", line, character + j); - } else if (c === '<') { - if (option.safe && xmode === 'html') { - warningAt("ADsafe string violation.", - line, character + j); - } else if (s.charAt(j + 1) === '/' && (xmode || option.safe)) { - warningAt("Expected '<\\/' and instead saw ' 0) { - character += 1; - s = s.slice(i); - break; - } else { - if (!nextLine()) { - return it('(end)', ''); - } - } - } - t = match(rx[xmode] || tx); - if (!t) { - t = ''; - c = ''; - while (s && s < '!') { - s = s.substr(1); - } - if (s) { - if (xmode === 'html') { - return it('(error)', s.charAt(0)); - } else { - errorAt("Unexpected '{a}'.", - line, character, s.substr(0, 1)); - } - } - } else { - - // identifier - - if (c.isAlpha() || c === '_' || c === '$') { - return it('(identifier)', t); - } - - // number - - if (c.isDigit()) { - if (xmode !== 'style' && !isFinite(Number(t))) { - warningAt("Bad number '{a}'.", - line, character, t); - } - if (xmode !== 'style' && - xmode !== 'styleproperty' && - s.substr(0, 1).isAlpha()) { - warningAt("Missing space after '{a}'.", - line, character, t); - } - if (c === '0') { - d = t.substr(1, 1); - if (d.isDigit()) { - if (token.id !== '.' && xmode !== 'styleproperty') { - warningAt("Don't use extra leading zeros '{a}'.", - line, character, t); - } - } else if (jsonmode && (d === 'x' || d === 'X')) { - warningAt("Avoid 0x-. '{a}'.", - line, character, t); - } - } - if (t.substr(t.length - 1) === '.') { - warningAt( -"A trailing decimal point can be confused with a dot '{a}'.", line, character, t); - } - return it('(number)', t); - } - switch (t) { - - // string - - case '"': - case "'": - return string(t); - - // // comment - - case '//': - if (src || (xmode && xmode !== 'script')) { - warningAt("Unexpected comment.", line, character); - } else if (xmode === 'script' && /<\s*\//i.test(s)) { - warningAt("Unexpected <\/ in comment.", line, character); - } else if ((option.safe || xmode === 'script') && ax.test(s)) { - warningAt("Dangerous comment.", line, character); - } - s = ''; - token.comment = true; - break; - - // /* comment - - case '/*': - if (src || (xmode && xmode !== 'script' && xmode !== 'style' && xmode !== 'styleproperty')) { - warningAt("Unexpected comment.", line, character); - } - if (option.safe && ax.test(s)) { - warningAt("ADsafe comment violation.", line, character); - } - for (;;) { - i = s.search(lx); - if (i >= 0) { - break; - } - if (!nextLine()) { - errorAt("Unclosed comment.", line, character); - } else { - if (option.safe && ax.test(s)) { - warningAt("ADsafe comment violation.", - line, character); - } - } - } - character += i + 2; - if (s.substr(i, 1) === '/') { - errorAt("Nested comment.", line, character); - } - s = s.substr(i + 2); - token.comment = true; - break; - - // /*members /*jslint /*global - - case '/*members': - case '/*member': - case '/*jslint': - case '/*global': - case '*/': - return { - value: t, - type: 'special', - line: line, - thru: character, - from: from - }; - - case '': - break; - // / - case '/': - if (token.id === '/=') { - errorAt( -"A regular expression literal can be confused with '/='.", line, from); - } - if (prereg) { - depth = 0; - captures = 0; - l = 0; - for (;;) { - b = true; - c = s.charAt(l); - l += 1; - switch (c) { - case '': - errorAt("Unclosed regular expression.", - line, from); - return; - case '/': - if (depth > 0) { - warningAt("Unescaped '{a}'.", - line, from + l, '/'); - } - c = s.substr(0, l - 1); - q = { - g: true, - i: true, - m: true - }; - while (q[s.charAt(l)] === true) { - q[s.charAt(l)] = false; - l += 1; - } - character += l; - s = s.substr(l); - q = s.charAt(0); - if (q === '/' || q === '*') { - errorAt("Confusing regular expression.", - line, from); - } - return it('(regexp)', c); - case '\\': - c = s.charAt(l); - if (c < ' ') { - warningAt( -"Unexpected control character in regular expression.", line, from + l); - } else if (c === '<') { - warningAt( -"Unexpected escaped character '{a}' in regular expression.", line, from + l, c); - } - l += 1; - break; - case '(': - depth += 1; - b = false; - if (s.charAt(l) === '?') { - l += 1; - switch (s.charAt(l)) { - case ':': - case '=': - case '!': - l += 1; - break; - default: - warningAt( -"Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l)); - } - } else { - captures += 1; - } - break; - case '|': - b = false; - break; - case ')': - if (depth === 0) { - warningAt("Unescaped '{a}'.", - line, from + l, ')'); - } else { - depth -= 1; - } - break; - case ' ': - q = 1; - while (s.charAt(l) === ' ') { - l += 1; - q += 1; - } - if (q > 1) { - warningAt( -"Spaces are hard to count. Use {{a}}.", line, from + l, q); - } - break; - case '[': - c = s.charAt(l); - if (c === '^') { - l += 1; - if (option.regexp) { - warningAt("Insecure '{a}'.", - line, from + l, c); - } else if (s.charAt(l) === ']') { - errorAt("Unescaped '{a}'.", - line, from + l, '^'); - } - } - q = false; - if (c === ']') { - warningAt("Empty class.", line, - from + l - 1); - q = true; - } -klass: do { - c = s.charAt(l); - l += 1; - switch (c) { - case '[': - case '^': - warningAt("Unescaped '{a}'.", - line, from + l, c); - q = true; - break; - case '-': - if (q) { - q = false; - } else { - warningAt("Unescaped '{a}'.", - line, from + l, '-'); - q = true; - } - break; - case ']': - if (!q) { - warningAt("Unescaped '{a}'.", - line, from + l - 1, '-'); - } - break klass; - case '\\': - c = s.charAt(l); - if (c < ' ') { - warningAt( -"Unexpected control character in regular expression.", line, from + l); - } else if (c === '<') { - warningAt( -"Unexpected escaped character '{a}' in regular expression.", line, from + l, c); - } - l += 1; - q = true; - break; - case '/': - warningAt("Unescaped '{a}'.", - line, from + l - 1, '/'); - q = true; - break; - case '<': - if (xmode === 'script') { - c = s.charAt(l); - if (c === '!' || c === '/') { - warningAt( -"HTML confusion in regular expression '<{a}'.", line, from + l, c); - } - } - q = true; - break; - default: - q = true; - } - } while (c); - break; - case '.': - if (option.regexp) { - warningAt("Insecure '{a}'.", line, - from + l, c); - } - break; - case ']': - case '?': - case '{': - case '}': - case '+': - case '*': - warningAt("Unescaped '{a}'.", line, - from + l, c); - break; - case '<': - if (xmode === 'script') { - c = s.charAt(l); - if (c === '!' || c === '/') { - warningAt( -"HTML confusion in regular expression '<{a}'.", line, from + l, c); - } - } - break; - } - if (b) { - switch (s.charAt(l)) { - case '?': - case '+': - case '*': - l += 1; - if (s.charAt(l) === '?') { - l += 1; - } - break; - case '{': - l += 1; - c = s.charAt(l); - if (c < '0' || c > '9') { - warningAt( -"Expected a number and instead saw '{a}'.", line, from + l, c); - } - l += 1; - low = +c; - for (;;) { - c = s.charAt(l); - if (c < '0' || c > '9') { - break; - } - l += 1; - low = +c + (low * 10); - } - high = low; - if (c === ',') { - l += 1; - high = Infinity; - c = s.charAt(l); - if (c >= '0' && c <= '9') { - l += 1; - high = +c; - for (;;) { - c = s.charAt(l); - if (c < '0' || c > '9') { - break; - } - l += 1; - high = +c + (high * 10); - } - } - } - if (s.charAt(l) !== '}') { - warningAt( -"Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c); - } else { - l += 1; - } - if (s.charAt(l) === '?') { - l += 1; - } - if (low > high) { - warningAt( -"'{a}' should not be greater than '{b}'.", line, from + l, low, high); - } - break; - } - } - } - c = s.substr(0, l - 1); - character += l; - s = s.substr(l); - return it('(regexp)', c); - } - return it('(punctuator)', t); - - // punctuator - - case '.", line, character); - } - character += 3; - s = s.slice(i + 3); - break; - case '#': - if (xmode === 'html' || xmode === 'styleproperty') { - for (;;) { - c = s.charAt(0); - if ((c < '0' || c > '9') && - (c < 'a' || c > 'f') && - (c < 'A' || c > 'F')) { - break; - } - character += 1; - s = s.substr(1); - t += c; - } - if (t.length !== 4 && t.length !== 7) { - warningAt("Bad hex color '{a}'.", line, - from + l, t); - } - return it('(color)', t); - } - return it('(punctuator)', t); - default: - if (xmode === 'outer' && c === '&') { - character += 1; - s = s.substr(1); - for (;;) { - c = s.charAt(0); - character += 1; - s = s.substr(1); - if (c === ';') { - break; - } - if (!((c >= '0' && c <= '9') || - (c >= 'a' && c <= 'z') || - c === '#')) { - errorAt("Bad entity", line, from + l, - character); - } - } - break; - } - return it('(punctuator)', t); - } - } - } - } - }; - }()); - - - function addlabel(t, type) { - - if (option.safe && funct['(global)'] && - typeof predefined[t] !== 'boolean') { - warning('ADsafe global: ' + t + '.', token); - } else if (t === 'hasOwnProperty') { - warning("'hasOwnProperty' is a really bad name."); - } - -// Define t in the current function in the current scope. - - if (is_own(funct, t) && !funct['(global)']) { - warning(funct[t] === true ? - "'{a}' was used before it was defined." : - "'{a}' is already defined.", - nexttoken, t); - } - funct[t] = type; - if (funct['(global)']) { - global[t] = funct; - if (is_own(implied, t)) { - warning("'{a}' was used before it was defined.", nexttoken, t); - delete implied[t]; - } - } else { - scope[t] = funct; - } - } - - - function doOption() { - var b, obj, filter, o = nexttoken.value, t, v; - switch (o) { - case '*/': - error("Unbegun comment."); - break; - case '/*members': - case '/*member': - o = '/*members'; - if (!membersOnly) { - membersOnly = {}; - } - obj = membersOnly; - break; - case '/*jslint': - if (option.safe) { - warning("ADsafe restriction."); - } - obj = option; - filter = boolOptions; - break; - case '/*global': - if (option.safe) { - warning("ADsafe restriction."); - } - obj = predefined; - break; - default: - error("What?"); - } - t = lex.token(); -loop: for (;;) { - for (;;) { - if (t.type === 'special' && t.value === '*/') { - break loop; - } - if (t.id !== ',') { - break; - } - t = lex.token(); - } - if (t.type !== '(string)' && t.type !== '(identifier)' && - o !== '/*members') { - error("Bad option.", t); - } - v = lex.token(); - if (v.id === ':') { - v = lex.token(); - if (obj === membersOnly) { - error("Expected '{a}' and instead saw '{b}'.", - t, '*/', ':'); - } - if (t.value === 'indent' && o === '/*jslint') { - b = +v.value; - if (typeof b !== 'number' || !isFinite(b) || b <= 0 || - Math.floor(b) !== b) { - error("Expected a small integer and instead saw '{a}'.", - v, v.value); - } - obj.white = true; - obj.indent = b; - } else if (t.value === 'maxerr' && o === '/*jslint') { - b = +v.value; - if (typeof b !== 'number' || !isFinite(b) || b <= 0 || - Math.floor(b) !== b) { - error("Expected a small integer and instead saw '{a}'.", - v, v.value); - } - obj.maxerr = b; - } else if (t.value === 'maxlen' && o === '/*jslint') { - b = +v.value; - if (typeof b !== 'number' || !isFinite(b) || b <= 0 || - Math.floor(b) !== b) { - error("Expected a small integer and instead saw '{a}'.", - v, v.value); - } - obj.maxlen = b; - } else if (v.value === 'true') { - obj[t.value] = true; - } else if (v.value === 'false') { - obj[t.value] = false; - } else { - error("Bad option value.", v); - } - t = lex.token(); - } else { - if (o === '/*jslint') { - error("Missing option value.", t); - } - obj[t.value] = false; - t = v; - } - } - if (filter) { - assume(); - } - } - - -// We need a peek function. If it has an argument, it peeks that much farther -// ahead. It is used to distinguish -// for ( var i in ... -// from -// for ( var i = ... - - function peek(p) { - var i = p || 0, j = 0, t; - - while (j <= i) { - t = lookahead[j]; - if (!t) { - t = lookahead[j] = lex.token(); - } - j += 1; - } - return t; - } - - - -// Produce the next token. It looks for programming errors. - - function advance(id, t) { - switch (token.id) { - case '(number)': - if (nexttoken.id === '.') { - warning( -"A dot following a number can be confused with a decimal point.", token); - } - break; - case '-': - if (nexttoken.id === '-' || nexttoken.id === '--') { - warning("Confusing minusses."); - } - break; - case '+': - if (nexttoken.id === '+' || nexttoken.id === '++') { - warning("Confusing plusses."); - } - break; - } - if (token.type === '(string)' || token.identifier) { - anonname = token.value; - } - - if (id && nexttoken.id !== id) { - if (t) { - if (nexttoken.id === '(end)') { - warning("Unmatched '{a}'.", t, t.id); - } else { - warning( -"Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", - nexttoken, id, t.id, t.line, nexttoken.value); - } - } else if (nexttoken.type !== '(identifier)' || - nexttoken.value !== id) { - warning("Expected '{a}' and instead saw '{b}'.", - nexttoken, id, nexttoken.value); - } - } - prevtoken = token; - token = nexttoken; - for (;;) { - nexttoken = lookahead.shift() || lex.token(); - if (nexttoken.type !== 'special') { - break; - } - doOption(); - } - } - -// Functions for conformance of style. - - function one_space_only(left, right) { - left = left || token; - right = right || nexttoken; - if (right.id !== '(end)' && (left.line !== right.line || - (option.white && left.thru + 1 !== right.from))) { - warning("Expected exactly one space between '{a}' and '{b}'.", - right, left.value, right.value); - } - } - - function one_space(left, right) { - left = left || token; - right = right || nexttoken; - if (right.id !== '(end)' && option.white && - (token.line !== right.line || - token.thru + 1 !== right.from)) { - warning("Expected exactly one space between '{a}' and '{b}'.", - right, token.value, right.value); - } - } - - function no_space(left, right) { - left = left || token; - right = right || nexttoken; - if ((option.white || xmode === 'styleproperty' || xmode === 'style') && - left.thru !== right.from && left.line === right.line) { - warning("Unexpected space between '{a}' and '{b}'.", right, - left.value, right.value); - } - } - - function no_space_only(left, right) { - left = left || token; - right = right || nexttoken; - if (right.id !== '(end)' && (left.line !== right.line || - (option.white && left.thru !== right.from))) { - warning("Unexpected space between '{a}' and '{b}'.", - right, left.value, right.value); - } - } - - function spaces(left, right) { - if (option.white) { - left = left || token; - right = right || nexttoken; - if (left.thru === right.from && left.line === right.line) { - warning("Missing space between '{a}' and '{b}'.", - right, left.value, right.value); - } - } - } - - function comma() { - no_space_only(); - advance(','); - spaces(); - } - - - function semicolon() { - no_space_only(); - advance(';'); - switch (nexttoken.id) { - case ';': - case '"': - case '\'': - case ')': - break; - default: - spaces(); - } - } - - function use_strict() { - if (nexttoken.value === 'use strict') { - if (strict_mode) { - warning("Unnecessary \"use strict\"."); - } - advance(); - semicolon(); - strict_mode = true; - option.newcap = true; - option.undef = true; - return true; - } else { - return false; - } - } - - -// This is the heart of JSLINT, the Pratt parser. In addition to parsing, it -// is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is -// like .nud except that it is only used on the first token of a statement. -// Having .fud makes it much easier to define statement-oriented languages like -// JavaScript. I retained Pratt's nomenclature. - -// .nud Null denotation -// .fud First null denotation -// .led Left denotation -// lbp Left binding power -// rbp Right binding power - -// They are elements of the parsing method called Top Down Operator Precedence. - - function expression(rbp, initial) { - -// rbp is the right binding power. -// initial indicates that this is the first expression of a statement. - - var left; - if (nexttoken.id === '(end)') { - error("Unexpected early end of program.", token); - } - advance(); - if (option.safe && typeof predefined[token.value] === 'boolean' && - (nexttoken.id !== '(' && nexttoken.id !== '.')) { - warning('ADsafe violation.', token); - } - if (initial) { - anonname = 'anonymous'; - funct['(verb)'] = token.value; - } - if (initial === true && token.fud) { - left = token.fud(); - } else { - if (token.nud) { - left = token.nud(); - } else { - if (nexttoken.type === '(number)' && token.id === '.') { - warning( -"A leading decimal point can be confused with a dot: '.{a}'.", - token, nexttoken.value); - advance(); - return token; - } else { - error("Expected an identifier and instead saw '{a}'.", - token, token.id); - } - } - while (rbp < nexttoken.lbp) { - advance(); - if (token.led) { - left = token.led(left); - } else { - error("Expected an operator and instead saw '{a}'.", - token, token.id); - } - } - } - return left; - } - - -// Functional constructors for making the symbols that will be inherited by -// tokens. - - function symbol(s, p) { - var x = syntax[s]; - if (!x || typeof x !== 'object') { - syntax[s] = x = { - id: s, - lbp: p, - value: s - }; - } - return x; - } - - - function delim(s) { - return symbol(s, 0); - } - - - function ultimate(s) { - var x = symbol(s, 0); - x.from = 0; - x.thru = 0; - s.value = s; - return x; - } - - - function stmt(s, f) { - var x = delim(s); - x.identifier = x.reserved = true; - x.fud = f; - return x; - } - - function disruptstmt(s, f) { - var x = stmt(s, f); - x.disrupt = true; - } - - - function reserveName(x) { - var c = x.id.charAt(0); - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { - x.identifier = x.reserved = true; - } - return x; - } - - - function prefix(s, f) { - var x = symbol(s, 150); - reserveName(x); - x.nud = (typeof f === 'function') ? f : function () { - if (s === 'typeof') { - one_space(); - } else { - no_space_only(); - } - this.first = expression(150); - this.arity = 'prefix'; - if (this.id === '++' || this.id === '--') { - if (option.plusplus) { - warning("Unexpected use of '{a}'.", this, this.id); - } else if ((!this.first.identifier || this.first.reserved) && - this.first.id !== '.' && this.first.id !== '[') { - warning("Bad operand.", this); - } - } - return this; - }; - return x; - } - - - function type(s, f) { - var x = delim(s); - x.type = s; - x.nud = f; - return x; - } - - - function reserve(s, f) { - var x = type(s, f); - x.identifier = x.reserved = true; - return x; - } - - - function reservevar(s, v) { - return reserve(s, function () { - if (typeof v === 'function') { - v(this); - } - return this; - }); - } - - - function infix(s, p, f, w) { - var x = symbol(s, p); - reserveName(x); - x.led = function (left) { - this.arity = 'infix'; - if (!w) { - spaces(prevtoken, token); - spaces(); - } - if (typeof f === 'function') { - return f(left, this); - } else { - this.first = left; - this.second = expression(p); - return this; - } - }; - return x; - } - - - function relation(s, eqeq) { - var x = infix(s, 100, function (left, that) { - var right = expression(100); - if (eqeq) { - warning("Expected '{a}' and instead saw '{b}'.", - that, eqeq, that.id); - } else if (left.id === 'NaN' || right.id === 'NaN') { - warning("Use the isNaN function to compare with NaN.", that); - } - if (left.id === '!') { - warning("Confusing use of '{a}'.", left, '!'); - } - if (right.id === '!') { - warning("Confusing use of '{a}'.", left, '!'); - } - that.first = left; - that.second = right; - return that; - }); - return x; - } - - - function assignop(s, bit) { - var x = infix(s, 20, function (left, that) { - var l; - if (option.bitwise && bit) { - warning("Unexpected use of '{a}'.", that, that.id); - } - that.first = left; - if (predefined[left.value] === false && - scope[left.value]['(global)'] === true) { - warning("Read only.", left); - } else if (left['function']) { - warning("'{a}' is a function.", left, left.value); - } - if (option.safe) { - l = left; - do { - if (typeof predefined[l.value] === 'boolean') { - warning('ADsafe violation.', l); - } - l = l.first; - } while (l); - } - if (left) { - if (left.id === '.' || left.id === '[') { - if (!left.first || left.first.value === 'arguments') { - warning('Bad assignment.', that); - } - that.second = expression(19); - return that; - } else if (left.identifier && !left.reserved) { - if (funct[left.value] === 'exception') { - warning("Do not assign to the exception parameter.", left); - } - that.second = expression(19); - return that; - } - if (left === syntax['function']) { - warning( -"Expected an identifier in an assignment and instead saw a function invocation.", - token); - } - } - error("Bad assignment.", that); - }); - x.assign = true; - return x; - } - - - function bitwise(s, p) { - return infix(s, p, function (left, that) { - if (option.bitwise) { - warning("Unexpected use of '{a}'.", that, that.id); - } - that.first = left; - that.second = expression(p); - return that; - }); - } - - - function suffix(s, f) { - var x = symbol(s, 150); - x.led = function (left) { - no_space_only(prevtoken, token); - if (option.plusplus) { - warning("Unexpected use of '{a}'.", this, this.id); - } else if ((!left.identifier || left.reserved) && - left.id !== '.' && left.id !== '[') { - warning("Bad operand.", this); - } - this.first = left; - this.arity = 'suffix'; - return this; - }; - return x; - } - - - function optionalidentifier() { - if (nexttoken.identifier) { - advance(); - if (option.safe && banned[token.value]) { - warning("ADsafe violation: '{a}'.", token, token.value); - } else if (token.reserved && !option.es5) { - warning("Expected an identifier and instead saw '{a}' (a reserved word).", - token, token.id); - } - return token.value; - } - } - - - function identifier() { - var i = optionalidentifier(); - if (i) { - return i; - } - if (token.id === 'function' && nexttoken.id === '(') { - warning("Missing name in function statement."); - } else { - error("Expected an identifier and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - } - - - function statement(noindent) { - -// Usually a statement starts a line. Exceptions include the var statement in the -// initialization part of a for statement, and an if after an else. - - var r, s = scope, t = nexttoken; - -// We don't like the empty statement. - - if (t.id === ';') { - warning("Unnecessary semicolon.", t); - advance(';'); - return; - } - -// Is this a labelled statement? - - if (t.identifier && !t.reserved && peek().id === ':') { - advance(); - advance(':'); - scope = Object.create(s); - addlabel(t.value, 'label'); - if (labelled[nexttoken.id] !== true) { - warning("Label '{a}' on '{b}' statement.", - nexttoken, t.value, nexttoken.value); - } - if (jx.test(t.value + ':')) { - warning("Label '{a}' looks like a javascript url.", - t, t.value); - } - nexttoken.label = t.value; - t = nexttoken; - } - -// Parse the statement. - - r = expression(0, true); - -// Look for the final semicolon. - - if (r.arity === 'statement') { - if (r.id !== 'switch' && (!r.block || r.id === 'do')) { - semicolon(); - } else { - spaces(); - } - } else { - if (r.id === '(' && r.first.id === 'new') { - warning("Do not use 'new' for side effects."); - } else if (!r.assign && r.id !== 'delete' && r.id !== '++' && - r.id !== '--' && r.id !== '(') { - warning( -"Expected an assignment or function call and instead saw an expression.", - token); - } - if (nexttoken.id !== ';') { - warningAt("Missing semicolon.", token.line, - token.from + token.value.length); - } else { - semicolon(); - } - } - scope = s; - return r; - } - - - function statements(begin) { - var a = [], d, f, p, s; - if (option.adsafe) { - switch (begin) { - case 'script': - -// JSLint is also the static analizer for ADsafe. See www.ADsafe.org. - - if (!adsafe_may) { - if (nexttoken.value !== 'ADSAFE' || - peek(0).id !== '.' || - (peek(1).value !== 'id' && - peek(1).value !== 'go')) { - error('ADsafe violation: Missing ADSAFE.id or ADSAFE.go.', - nexttoken); - } - } - if (nexttoken.value === 'ADSAFE' && - peek(0).id === '.' && - peek(1).value === 'id') { - if (adsafe_may) { - error('ADsafe violation.', nexttoken); - } - advance('ADSAFE'); - advance('.'); - advance('id'); - advance('('); - if (nexttoken.value !== adsafe_id) { - error('ADsafe violation: id does not match.', nexttoken); - } - advance('(string)'); - advance(')'); - semicolon(); - adsafe_may = true; - } - break; - case 'lib': - if (nexttoken.value === 'ADSAFE') { - advance('ADSAFE'); - advance('.'); - advance('lib'); - advance('('); - advance('(string)'); - comma(); - f = expression(0); - if (f.id !== 'function') { - error('The second argument to lib must be a function.', f); - } - p = f.funct['(params)']; - p = p && p.join(', '); - if (p && p !== 'lib') { - error("Expected '{a}' and instead saw '{b}'.", - f, '(lib)', '(' + p + ')'); - } - advance(')'); - semicolon(); - return a; - } else { - error("ADsafe lib violation."); - } - break; - } - } - -// A disrupt statement may not be followed by any other statement. -// If the last statement is disrupt, then the sequence is disrupt. - - while (postscript[nexttoken.id] !== true) { - if (nexttoken.id === ';') { - warning("Unnecessary semicolon."); - advance(';'); - } else { - if (d) { - warning("Unreachable '{a}' after '{b}'.", nexttoken, - nexttoken.value, d.value); - d = null; - } - s = statement(); - a.push(s); - if (s.disrupt) { - d = s; - a.disrupt = true; - } - } - } - return a; - } - - - function block(ordinary) { - -// A block is a sequence of statements wrapped in braces. -// ordinary is false for function bodies and try blocks. -// ordinary is true for if statements, while, etc. - - var a, - b = inblock, - m = strict_mode, - s = scope, - t; - inblock = ordinary; - scope = Object.create(scope); - spaces(); - t = nexttoken; - if (nexttoken.id === '{') { - advance('{'); - if (!ordinary && !use_strict() && !m && option.strict && - funct['(context)']['(global)']) { - warning("Missing \"use strict\" statement."); - } - a = statements(); - strict_mode = m; - advance('}', t); - } else if (!ordinary) { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, '{', nexttoken.value); - } else { - warning("Expected '{a}' and instead saw '{b}'.", - nexttoken, '{', nexttoken.value); - a = [statement()]; - if (a[0].disrupt) { - a.disrupt = true; - } - } - funct['(verb)'] = null; - scope = s; - inblock = b; - if (ordinary && a.length === 0) { - warning("Empty block."); - } - return a; - } - - - function countMember(m) { - if (membersOnly && typeof membersOnly[m] !== 'boolean') { - warning("Unexpected /*member '{a}'.", token, m); - } - if (typeof member[m] === 'number') { - member[m] += 1; - } else { - member[m] = 1; - } - } - - - function note_implied(token) { - var name = token.value, line = token.line, a = implied[name]; - if (typeof a === 'function') { - a = false; - } - if (!a) { - a = [line]; - implied[name] = a; - } else if (a[a.length - 1] !== line) { - a.push(line); - } - } - - -// Build the syntax table by declaring the syntactic elements of the language. - - type('(number)', function () { - this.arity = 'number'; - return this; - }); - type('(string)', function () { - this.arity = 'string'; - return this; - }); - - syntax['(identifier)'] = { - type: '(identifier)', - lbp: 0, - identifier: true, - nud: function () { - var v = this.value, - s = scope[v], - f; - if (typeof s === 'function') { - -// Protection against accidental inheritance. - - s = undefined; - } else if (typeof s === 'boolean') { - f = funct; - funct = functions[0]; - addlabel(v, 'var'); - s = funct; - funct = f; - } - -// The name is in scope and defined in the current function. - - if (funct === s) { - -// Change 'unused' to 'var', and reject labels. - - switch (funct[v]) { - case 'unused': - funct[v] = 'var'; - break; - case 'unction': - funct[v] = 'function'; - this['function'] = true; - break; - case 'function': - this['function'] = true; - break; - case 'label': - warning("'{a}' is a statement label.", token, v); - break; - } - -// The name is not defined in the function. If we are in the global scope, -// then we have an undefined variable. - - } else if (funct['(global)']) { - if (option.undef && typeof predefined[v] !== 'boolean') { - warning("'{a}' is not defined.", token, v); - } - note_implied(token); - -// If the name is already defined in the current -// function, but not as outer, then there is a scope error. - - } else { - switch (funct[v]) { - case 'closure': - case 'function': - case 'var': - case 'unused': - warning("'{a}' used out of scope.", token, v); - break; - case 'label': - warning("'{a}' is a statement label.", token, v); - break; - case 'outer': - case 'global': - break; - default: - -// If the name is defined in an outer function, make an outer entry, and if -// it was unused, make it var. - - if (s === true) { - funct[v] = true; - } else if (s === null) { - warning("'{a}' is not allowed.", token, v); - note_implied(token); - } else if (typeof s !== 'object') { - if (option.undef) { - warning("'{a}' is not defined.", token, v); - } else { - funct[v] = true; - } - note_implied(token); - } else { - switch (s[v]) { - case 'function': - case 'unction': - this['function'] = true; - s[v] = 'closure'; - funct[v] = s['(global)'] ? 'global' : 'outer'; - break; - case 'var': - case 'unused': - s[v] = 'closure'; - funct[v] = s['(global)'] ? 'global' : 'outer'; - break; - case 'closure': - case 'parameter': - funct[v] = s['(global)'] ? 'global' : 'outer'; - break; - case 'label': - warning("'{a}' is a statement label.", token, v); - break; - } - } - } - } - return this; - }, - led: function () { - error("Expected an operator and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - }; - - type('(regexp)', function () { - return this; - }); - - -// ECMAScript parser - - ultimate('(begin)'); - ultimate('(end)'); - ultimate('(error)'); - delim(''); - delim('}'); - delim(')'); - delim(']'); - delim('"'); - delim("'"); - delim(';'); - delim(':'); - delim(','); - delim('#'); - delim('@'); - reserve('else'); - reserve('case'); - reserve('catch'); - reserve('default'); - reserve('finally'); - reservevar('arguments', function (x) { - if (strict_mode && funct['(global)']) { - warning("Strict violation.", x); - } else if (option.safe) { - warning("ADsafe violation.", x); - } - }); - reservevar('eval', function (x) { - if (option.safe) { - warning("ADsafe violation.", x); - } - }); - reservevar('false'); - reservevar('Infinity'); - reservevar('NaN'); - reservevar('null'); - reservevar('this', function (x) { - if (strict_mode && ((funct['(statement)'] && //// correct this test. - funct['(name)'].charAt(0) > 'Z') || funct['(global)'])) { - warning("Strict violation.", x); - } else if (option.safe) { - warning("ADsafe violation.", x); - } - }); - reservevar('true'); - reservevar('undefined'); - assignop('='); - assignop('+='); - assignop('-='); - assignop('*='); - assignop('/=').nud = function () { - error("A regular expression literal can be confused with '/='."); - }; - assignop('%='); - assignop('&=', true); - assignop('|=', true); - assignop('^=', true); - assignop('<<=', true); - assignop('>>=', true); - assignop('>>>=', true); - infix('?', 30, function (left, that) { - that.first = left; - that.second = expression(10); - spaces(); - advance(':'); - spaces(); - that.third = expression(10); - return that; - }); - - infix('||', 40); - infix('&&', 50); - bitwise('|', 70); - bitwise('^', 80); - bitwise('&', 90); - relation('==', '==='); - relation('==='); - relation('!=', '!=='); - relation('!=='); - relation('<'); - relation('>'); - relation('<='); - relation('>='); - bitwise('<<', 120); - bitwise('>>', 120); - bitwise('>>>', 120); - infix('in', 120); - infix('instanceof', 120); - infix('+', 130, function (left, that) { - var right = expression(130); - if (left && right && left.id === '(string)' && right.id === '(string)') { - left.value += right.value; - left.thru = right.thru; - if (jx.test(left.value)) { - warning("JavaScript URL.", left); - } - return left; - } - that.first = left; - that.second = right; - return that; - }); - prefix('+', 'num'); - prefix('+++', function () { - warning("Confusing pluses."); - this.first = expression(150); - this.arity = 'prefix'; - return this; - }); - infix('+++', 130, function (left) { - warning("Confusing pluses."); - this.first = left; - this.second = expression(130); - return this; - }); - infix('-', 130); - prefix('-'); - prefix('---', function () { - warning("Confusing minuses."); - this.first = expression(150); - this.arity = 'prefix'; - return this; - }); - infix('---', 130, function (left) { - warning("Confusing minuses."); - this.first = left; - this.second = expression(130); - return this; - }); - infix('*', 140); - infix('/', 140); - infix('%', 140); - - suffix('++'); - prefix('++'); - - suffix('--'); - prefix('--'); - prefix('delete', function () { - one_space(); - var p = expression(0); - if (!p || (p.id !== '.' && p.id !== '[')) { - warning("Only properties should be deleted."); - } - this.first = p; - return this; - }); - - - prefix('~', function () { - no_space_only(); - if (option.bitwise) { - warning("Unexpected '{a}'.", this, '~'); - } - expression(150); - return this; - }); - prefix('!', function () { - no_space_only(); - this.first = expression(150); - this.arity = 'prefix'; - if (bang[this.first.id] === true) { - warning("Confusing use of '{a}'.", this, '!'); - } - return this; - }); - prefix('typeof'); - prefix('new', function () { - one_space(); - var c = expression(160), i; - if (c.id !== 'function') { - if (c.identifier) { - switch (c.value) { - case 'Object': - warning("Use the object literal notation {}.", token); - break; - case 'Array': - if (nexttoken.id !== '(') { - warning("Use the array literal notation [].", token); - } else { - advance('('); - if (nexttoken.id === ')') { - warning("Use the array literal notation [].", token); - } - advance(')'); - } - this.first = c; - return this; - case 'Number': - case 'String': - case 'Boolean': - case 'Math': - case 'JSON': - warning("Do not use {a} as a constructor.", token, c.value); - break; - case 'Function': - if (!option.evil) { - warning("The Function constructor is eval."); - } - break; - case 'Date': - case 'RegExp': - break; - default: - if (c.id !== 'function') { - i = c.value.substr(0, 1); - if (option.newcap && (i < 'A' || i > 'Z')) { - warning( - "A constructor name should start with an uppercase letter.", - token); - } - } - } - } else { - if (c.id !== '.' && c.id !== '[' && c.id !== '(') { - warning("Bad constructor.", token); - } - } - } else { - warning("Weird construction. Delete 'new'.", this); - } - if (nexttoken.id !== '(') { - warning("Missing '()' invoking a constructor."); - } - this.first = c; - return this; - }); - - infix('(', 160, function (left, that) { - no_space_only(prevtoken, token); - if (!left.immed && left.id === 'function') { - warning("Wrap an immediate function invocation in parentheses " + - "to assist the reader in understanding that the expression " + - "is the result of a function, and not the function itself."); - } - var p = []; - if (left) { - if (left.type === '(identifier)') { - if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) { - if (left.value !== 'Number' && left.value !== 'String' && - left.value !== 'Boolean' && - left.value !== 'Date') { - if (left.value === 'Math') { - warning("Math is not a function.", left); - } else if (option.newcap) { - warning( -"Missing 'new' prefix when invoking a constructor.", left); - } - } - } - } else if (left.id === '.') { - if (option.safe && left.first.value === 'Math' && - left.second === 'random') { - warning("ADsafe violation.", left); - } - } - } - if (nexttoken.id !== ')') { - no_space(); - for (;;) { - p.push(expression(10)); - if (nexttoken.id !== ',') { - break; - } - comma(); - } - } - no_space(); - advance(')'); - if (typeof left === 'object') { - if (left.value === 'parseInt' && p.length === 1) { - warning("Missing radix parameter.", left); - } - if (!option.evil) { - if (left.value === 'eval' || left.value === 'Function' || - left.value === 'execScript') { - warning("eval is evil.", left); - } else if (p[0] && p[0].id === '(string)' && - (left.value === 'setTimeout' || - left.value === 'setInterval')) { - warning( - "Implied eval is evil. Pass a function instead of a string.", left); - } - } - if (!left.identifier && left.id !== '.' && left.id !== '[' && - left.id !== '(' && left.id !== '&&' && left.id !== '||' && - left.id !== '?') { - warning("Bad invocation.", left); - } - } - that.first = left; - that.second = p; - return that; - }, true); - - prefix('(', function () { - no_space(); - if (nexttoken.id === 'function') { - nexttoken.immed = true; - } - var v = expression(0); - no_space(); - advance(')', this); - if (v.id === 'function') { - if (nexttoken.id === '(') { - warning( -"Move the invocation into the parens that contain the function.", nexttoken); - } else { - warning( -"Do not wrap function literals in parens unless they are to be immediately invoked.", - this); - } - } - return v; - }); - - infix('.', 170, function (left, that) { - no_space(prevtoken, token); - no_space(); - var m = identifier(); - if (typeof m === 'string') { - countMember(m); - } - that.first = left; - that.second = m; - if (left && left.value === 'arguments' && - (m === 'callee' || m === 'caller')) { - warning("Avoid arguments.{a}.", left, m); - } else if (!option.evil && left && left.value === 'document' && - (m === 'write' || m === 'writeln')) { - warning("document.write can be a form of eval.", left); - } else if (option.adsafe) { - if (left && left.value === 'ADSAFE') { - if (m === 'id' || m === 'lib') { - warning("ADsafe violation.", that); - } else if (m === 'go') { - if (xmode !== 'script') { - warning("ADsafe violation.", that); - } else if (adsafe_went || nexttoken.id !== '(' || - peek(0).id !== '(string)' || - peek(0).value !== adsafe_id || - peek(1).id !== ',') { - error("ADsafe violation: go.", that); - } - adsafe_went = true; - adsafe_may = false; - } - } - } - if (!option.evil && (m === 'eval' || m === 'execScript')) { - warning('eval is evil.'); - } else if (option.safe) { - for (;;) { - if (banned[m] === true) { - warning("ADsafe restricted word '{a}'.", token, m); - } - if (typeof predefined[left.value] !== 'boolean' || - nexttoken.id === '(') { - break; - } - if (standard_member[m] === true) { - if (nexttoken.id === '.') { - warning("ADsafe violation.", that); - } - break; - } - if (nexttoken.id !== '.') { - warning("ADsafe violation.", that); - break; - } - advance('.'); - token.first = that; - token.second = m; - that = token; - m = identifier(); - if (typeof m === 'string') { - countMember(m); - } - } - } - return that; - }, true); - - infix('[', 170, function (left, that) { - no_space_only(prevtoken, token); - no_space(); - var e = expression(0), s; - if (e && e.type === '(string)') { - if (option.safe && banned[e.value] === true) { - warning("ADsafe restricted word '{a}'.", that, e.value); - } else if (!option.evil && - (e.value === 'eval' || e.value === 'execScript')) { - warning("eval is evil.", that); - } else if (option.safe && - (e.value.charAt(0) === '_' || e.value.charAt(0) === '-')) { - warning("ADsafe restricted subscript '{a}'.", that, e.value); - } - countMember(e.value); - if (!option.sub && ix.test(e.value)) { - s = syntax[e.value]; - if (!s || !s.reserved) { - warning("['{a}'] is better written in dot notation.", - e, e.value); - } - } - } else if (!e || e.type !== '(number)' || e.value < 0) { - if (option.safe) { - warning('ADsafe subscripting.'); - } - } - advance(']', that); - no_space(prevtoken, token); - that.first = left; - that.second = e; - return that; - }, true); - - prefix('[', function () { - this.first = []; - while (nexttoken.id !== '(end)') { - while (nexttoken.id === ',') { - warning("Extra comma."); - advance(','); - } - if (nexttoken.id === ']') { - break; - } - this.first.push(expression(10)); - if (nexttoken.id === ',') { - comma(); - if (nexttoken.id === ']' && !option.es5) { - warning("Extra comma.", token); - break; - } - } else { - break; - } - } - advance(']', this); - return this; - }, 170); - - - function property_name() { - var id = optionalidentifier(true); - if (!id) { - if (nexttoken.id === '(string)') { - id = nexttoken.value; - if (option.adsafe && - (id.charAt(0) === '_' || - id.charAt(id.length - 1) === '_')) { - warning("Unexpected {a} in '{b}'.", token, - "dangling '_'", id); - } - advance(); - } else if (nexttoken.id === '(number)') { - id = nexttoken.value.toString(); - advance(); - } - } - return id; - } - - - function functionparams() { - var i, t = nexttoken, p = []; - advance('('); - no_space(); - if (nexttoken.id === ')') { - no_space(); - advance(')'); - return; - } - for (;;) { - i = identifier(); - p.push(i); - addlabel(i, 'parameter'); - if (nexttoken.id === ',') { - comma(); - } else { - no_space(); - advance(')', t); - return p; - } - } - } - - - function doFunction(func, name) { - var s = scope; - scope = Object.create(s); - funct = { - '(name)' : name || '"' + anonname + '"', - '(line)' : nexttoken.line, - '(context)' : funct, - '(breakage)' : 0, - '(loopage)' : 0, - '(scope)' : scope, - '(token)' : func - }; - token.funct = funct; - functions.push(funct); - if (name) { - addlabel(name, 'function'); - } - func.name = name || ''; - func.first = funct['(params)'] = functionparams(); - func.block = block(false); - - scope = s; - funct['(last)'] = token.line; - funct = funct['(context)']; - return func; - } - - - prefix('{', function () { - var get, i, j, name, p, set, seen = {}, t; - this.arity = 'prefix'; - this.first = []; - while (nexttoken.id !== '}') { - -// JSLint recognizes the ES5 extension for get/set in object literals, -// but requires that they be used in pairs. - - if (nexttoken.value === 'get' && peek().id !== ':') { - if (!option.es5) { - warning("get/set are ES5 features."); - } - get = nexttoken; - one_space_only(); - advance('get'); - name = nexttoken; - i = property_name(); - if (!i) { - error("Missing property name."); - } - doFunction(get, ''); - if (funct['(loopage)']) { - warning("Don't make functions within a loop.", t); - } - p = get.first; - if (p) { - warning("Unexpected parameter '{a}' in get {b} function.", t, p[0], i); - } - comma(); - set = nexttoken; - spaces(); - advance('set'); - one_space_only(); - j = property_name(); - if (i !== j) { - error("Expected '{a}' and instead saw '{b}'.", token, i, j); - } - doFunction(set, ''); - p = set.first; - if (!p || p.length !== 1 || p[0] !== 'value') { - warning("Expected (value) in set {a} function.", t, i); - } - name.first = [get, set]; - } else { - name = nexttoken; - i = property_name(); - if (typeof i !== 'string') { - error("Missing property name."); - } - advance(':'); - spaces(); - name.first = expression(10); - } - this.first.push(name); - if (seen[i] === true) { - warning("Duplicate member '{a}'.", nexttoken, i); - } - seen[i] = true; - countMember(i); - if (nexttoken.id !== ',') { - break; - } - for (;;) { - comma(); - if (nexttoken.id !== ',') { - break; - } - warning("Extra comma."); - } - if (nexttoken.id === '}' && !option.es5) { - warning("Extra comma.", token); - } - } - advance('}', this); - return this; - }); - - stmt('{', function () { - warning("Expected to see a statement and instead saw a block."); - this.arity = 'statement'; - this.block = statements(); - this.disrupt = this.block.disrupt; - advance('}'); - return this; - }); - - - stmt('var', function () { - -// JavaScript does not have block scope. It only has function scope. So, -// declaring a variable in a block can have unexpected consequences. - -// var.first will contain an array, the array containing name tokens -// and assignment tokens. - - var assign, id, name; - - if (funct['(onevar)'] && option.onevar) { - warning("Too many var statements."); - } else if (!funct['(global)']) { - funct['(onevar)'] = true; - } - this.arity = 'statement'; - this.first = []; - for (;;) { - spaces(); - name = nexttoken; - id = identifier(); - if (funct['(global)'] && predefined[id] === false) { - warning("Redefinition of '{a}'.", token, id); - } - addlabel(id, 'unused'); - - if (nexttoken.id === '=') { - assign = nexttoken; - assign.first = name; - spaces(); - advance('='); - spaces(); - if (nexttoken.id === 'undefined') { - warning("It is not necessary to initialize '{a}' to 'undefined'.", token, id); - } - if (peek(0).id === '=' && nexttoken.identifier) { - error("Variable {a} was not declared correctly.", - nexttoken, nexttoken.value); - } - assign.second = expression(0); - assign.arity = 'infix'; - this.first.push(assign); - } else { - this.first.push(name); - } - if (nexttoken.id !== ',') { - break; - } - comma(); - } - return this; - }); - - stmt('function', function () { - one_space(); - if (inblock) { - warning( -"Function statements should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.", token); - } - var i = identifier(); - if (i) { - addlabel(i, 'unction'); - no_space_only(); - } - doFunction(this, i, true); - if (nexttoken.id === '(' && nexttoken.line === token.line) { - error( -"Function statements are not invocable. Wrap the whole function invocation in parens."); - } - this.arity = 'statement'; - return this; - }); - - prefix('function', function () { - one_space(); - var i = optionalidentifier(); - if (i) { - no_space_only(); - } - doFunction(this, i); - if (funct['(loopage)']) { - warning("Don't make functions within a loop."); - } - this.arity = 'function'; - return this; - }); - - stmt('if', function () { - var t = nexttoken; - one_space(); - advance('('); - no_space(); - this.arity = 'statement'; - this.first = expression(20); - if (nexttoken.id === '=') { - warning("Expected a conditional expression and instead saw an assignment."); - advance('='); - expression(20); - } - no_space(); - advance(')', t); - one_space_only(); - this.block = block(true); - if (nexttoken.id === 'else') { - one_space(); - advance('else'); - one_space_only(); - this['else'] = nexttoken.id === 'if' || nexttoken.id === 'switch' ? - statement(true) : block(true); - if (this['else'].disrupt && this.block.disrupt) { - this.disrupt = true; - } - } - return this; - }); - - stmt('try', function () { - -// try.first The catch variable -// try.second The catch clause -// try.third The finally clause -// try.block The try block - - var b, e, s, t; - if (option.adsafe) { - warning("ADsafe try violation.", this); - } - one_space_only(); - this.arity = 'statement'; - this.block = block(false); - if (nexttoken.id === 'catch') { - one_space(); - advance('catch'); - one_space(); - advance('('); - no_space_only(); - s = scope; - scope = Object.create(s); - e = nexttoken.value; - this.first = e; - if (nexttoken.type !== '(identifier)') { - warning("Expected an identifier and instead saw '{a}'.", - nexttoken, e); - } else { - addlabel(e, 'exception'); - } - advance(); - no_space_only(); - advance(')'); - one_space(); - this.second = block(false); - b = true; - scope = s; - } - if (nexttoken.id === 'finally') { - one_space(); - t = nexttoken; - advance('finally'); - one_space(); - this.third = block(false); - } else if (!b) { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, 'catch', nexttoken.value); - } - return this; - }); - - - stmt('while', function () { - one_space(); - var t = nexttoken; - funct['(breakage)'] += 1; - funct['(loopage)'] += 1; - advance('('); - no_space(); - this.arity = 'statement'; - this.first = expression(20); - if (nexttoken.id === '=') { - warning("Expected a conditional expression and instead saw an assignment."); - advance('='); - expression(20); - } - no_space(); - advance(')', t); - one_space_only(); - this.block = block(true); - if (this.block.disrupt) { - warning("Strange loop.", prevtoken); - } - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - }); - - reserve('with'); - - stmt('switch', function () { - -// switch.first the switch expression -// switch.second the array of cases. A case is 'case' or 'default' token: -// case.first the array of case expressions -// case.second the array of statements -// If all of the arrays of statements are disrupt, then the switch is disrupt. - - var b = true, - s, - t = nexttoken; - funct['(breakage)'] += 1; - one_space(); - advance('('); - no_space(); - this.arity = 'statement'; - this.first = expression(20); - no_space(); - advance(')', t); - one_space_only(); - advance('{'); - this.second = []; - while (nexttoken.id === 'case') { - t = nexttoken; - t.first = []; - do { - spaces(); - advance('case'); - one_space(); - t.first.push(expression(0)); - no_space_only(); - advance(':'); - } while (nexttoken.id === 'case'); - spaces(); - t.second = statements(); - if (t.second && t.second.length > 0) { - s = t.second[t.second.length - 1]; - if (s.disrupt) { - if (s.id === 'break') { - b = false; - } - } else { - warning("Missing break after case."); - } - } else { - warning("Empty case"); - } - this.second.push(t); - } - if (this.second.length === 0) { - warning("switch without cases."); - } - if (nexttoken.id === 'default') { - spaces(); - t = nexttoken; - advance('default'); - no_space_only(); - advance(':'); - spaces(); - t.second = statements(); - if (t.second && t.second.length > 0) { - s = t.second[t.second.length - 1]; - if (b && s.disrupt && s.id !== 'break') { - this.disrupt = true; - } - } - this.second.push(t); - } - funct['(breakage)'] -= 1; - spaces(); - advance('}'); - return this; - }); - - stmt('debugger', function () { - if (!option.debug) { - warning("All 'debugger' statements should be removed."); - } - this.arity = 'statement'; - return this; - }); - - stmt('do', function () { - funct['(breakage)'] += 1; - funct['(loopage)'] += 1; - one_space_only(); - this.arity = 'statement'; - this.block = block(true); - if (this.block.disrupt) { - warning("Strange loop.", prevtoken); - } - one_space(); - advance('while'); - var t = nexttoken; - one_space_only(); - advance('('); - no_space(); - this.first = expression(0); - if (this.first.id === '=') { - warning("Expected a conditional expression and instead saw an assignment."); - } - no_space(); - advance(')', t); - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - }); - - stmt('for', function () { - var f = option.forin, i, s, t = nexttoken, v; - this.arity = 'statement'; - funct['(breakage)'] += 1; - funct['(loopage)'] += 1; - advance('('); - spaces(this, t); - no_space(); -// if (nexttoken.id === 'var') { -// error("Move all 'var' declarations to the top of the function."); -// } - if (peek(0).id === 'in') { - v = nexttoken; - switch (funct[v.value]) { - case 'unused': - funct[v.value] = 'var'; - break; - case 'var': - break; - default: - warning("Bad for in variable '{a}'.", v, v.value); - } - advance(); - i = nexttoken; - advance('in'); - i.first = v; - i.second = expression(20); - advance(')', t); - this.first = i; - s = block(true); - if (!f && (s.length > 1 || typeof s[0] !== 'object' || - s[0].value !== 'if')) { - warning("The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.", this); - } - } else { - if (nexttoken.id !== ';') { - this.first = []; - for (;;) { - this.first.push(expression(0, 'for')); - if (nexttoken.id !== ',') { - break; - } - comma(); - } - } - semicolon(); - if (nexttoken.id !== ';') { - this.second = expression(20); - if (this.second.id === '=') { - warning("Expected a conditional expression and instead saw an assignment."); - } - } - semicolon(token); - if (nexttoken.id === ';') { - error("Expected '{a}' and instead saw '{b}'.", nexttoken, ')', ';'); - } - if (nexttoken.id !== ')') { - this.third = []; - for (;;) { - this.third.push(expression(0, 'for')); - if (nexttoken.id !== ',') { - break; - } - comma(); - } - } - no_space(); - advance(')', t); - one_space_only(); - s = block(true); - } - if (s.disrupt) { - warning("Strange loop.", prevtoken); - } - this.block = s; - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - }); - - - disruptstmt('break', function () { - var v = nexttoken.value; - this.arity = 'statement'; - if (funct['(breakage)'] === 0) { - warning("Unexpected '{a}'.", nexttoken, this.value); - } - if (nexttoken.identifier && token.line === nexttoken.line) { - one_space_only(); - if (funct[v] !== 'label') { - warning("'{a}' is not a label.", nexttoken, v); - } else if (scope[v] !== funct) { - warning("'{a}' is out of scope.", nexttoken, v); - } - this.first = nexttoken; - advance(); - } - return this; - }); - - - disruptstmt('continue', function () { - var v = nexttoken.value; - this.arity = 'statement'; - if (funct['(breakage)'] === 0) { - warning("Unexpected '{a}'.", nexttoken, this.value); - } - if (nexttoken.identifier && token.line === nexttoken.line) { - one_space_only(); - if (funct[v] !== 'label') { - warning("'{a}' is not a label.", nexttoken, v); - } else if (scope[v] !== funct) { - warning("'{a}' is out of scope.", nexttoken, v); - } - this.first = nexttoken; - advance(); - } - return this; - }); - - - disruptstmt('return', function () { - this.arity = 'statement'; - if (nexttoken.id !== ';' && nexttoken.line === token.line) { - one_space_only(); - if (nexttoken.id === '/' || nexttoken.id === '(regexp)') { - warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator."); - } - this.first = expression(20); - } - return this; - }); - - - disruptstmt('throw', function () { - this.arity = 'statement'; - one_space_only(); - this.first = expression(20); - return this; - }); - - reserve('void'); - -// Superfluous reserved words - - reserve('class'); - reserve('const'); - reserve('enum'); - reserve('export'); - reserve('extends'); - reserve('import'); - reserve('super'); - -// Harmony reserved words - - reserve('let'); - reserve('yield'); - reserve('implements'); - reserve('interface'); - reserve('package'); - reserve('private'); - reserve('protected'); - reserve('public'); - reserve('static'); - - -// Parse JSON - - function jsonValue() { - - function jsonObject() { - var o = {}, t = nexttoken; - advance('{'); - if (nexttoken.id !== '}') { - for (;;) { - if (nexttoken.id === '(end)') { - error("Missing '}' to match '{' from line {a}.", - nexttoken, t.line); - } else if (nexttoken.id === '}') { - warning("Unexpected comma.", token); - break; - } else if (nexttoken.id === ',') { - error("Unexpected comma.", nexttoken); - } else if (nexttoken.id !== '(string)') { - warning("Expected a string and instead saw {a}.", - nexttoken, nexttoken.value); - } - if (o[nexttoken.value] === true) { - warning("Duplicate key '{a}'.", - nexttoken, nexttoken.value); - } else if (nexttoken.value === '__proto__') { - warning("Stupid key '{a}'.", - nexttoken, nexttoken.value); - } else { - o[nexttoken.value] = true; - } - advance(); - advance(':'); - jsonValue(); - if (nexttoken.id !== ',') { - break; - } - advance(','); - } - } - advance('}'); - } - - function jsonArray() { - var t = nexttoken; - advance('['); - if (nexttoken.id !== ']') { - for (;;) { - if (nexttoken.id === '(end)') { - error("Missing ']' to match '[' from line {a}.", - nexttoken, t.line); - } else if (nexttoken.id === ']') { - warning("Unexpected comma.", token); - break; - } else if (nexttoken.id === ',') { - error("Unexpected comma.", nexttoken); - } - jsonValue(); - if (nexttoken.id !== ',') { - break; - } - advance(','); - } - } - advance(']'); - } - - switch (nexttoken.id) { - case '{': - jsonObject(); - break; - case '[': - jsonArray(); - break; - case 'true': - case 'false': - case 'null': - case '(number)': - case '(string)': - advance(); - break; - case '-': - advance('-'); - if (token.thru !== nexttoken.from) { - warning("Unexpected space after '-'.", token); - } - no_space_only(); - advance('(number)'); - break; - default: - error("Expected a JSON value.", nexttoken); - } - } - - -// CSS parsing. - - function cssName() { - if (nexttoken.identifier) { - advance(); - return true; - } - } - - - function cssNumber() { - if (nexttoken.id === '-') { - advance('-'); - no_space_only(); - } - if (nexttoken.type === '(number)') { - advance('(number)'); - return true; - } - } - - - function cssString() { - if (nexttoken.type === '(string)') { - advance(); - return true; - } - } - - function cssColor() { - var i, number, value; - if (nexttoken.identifier) { - value = nexttoken.value; - if (value === 'rgb' || value === 'rgba') { - advance(); - advance('('); - for (i = 0; i < 3; i += 1) { - if (i) { - comma(); - } - number = nexttoken.value; - if (nexttoken.type !== '(number)' || number < 0) { - warning("Expected a positive number and instead saw '{a}'", - nexttoken, number); - advance(); - } else { - advance(); - if (nexttoken.id === '%') { - advance('%'); - if (number > 100) { - warning("Expected a percentage and instead saw '{a}'", - token, number); - } - } else { - if (number > 255) { - warning("Expected a small number and instead saw '{a}'", - token, number); - } - } - } - } - if (value === 'rgba') { - comma(); - number = +nexttoken.value; - if (nexttoken.type !== '(number)' || number < 0 || number > 1) { - warning("Expected a number between 0 and 1 and instead saw '{a}'", - nexttoken, number); - } - advance(); - if (nexttoken.id === '%') { - warning("Unexpected '%'."); - advance('%'); - } - } - advance(')'); - return true; - } else if (cssColorData[nexttoken.value] === true) { - advance(); - return true; - } - } else if (nexttoken.type === '(color)') { - advance(); - return true; - } - return false; - } - - - function cssLength() { - if (nexttoken.id === '-') { - advance('-'); - no_space_only(); - } - if (nexttoken.type === '(number)') { - advance(); - if (nexttoken.type !== '(string)' && - cssLengthData[nexttoken.value] === true) { - no_space_only(); - advance(); - } else if (+token.value !== 0) { - warning("Expected a linear unit and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - return true; - } - return false; - } - - - function cssLineHeight() { - if (nexttoken.id === '-') { - advance('-'); - no_space_only(); - } - if (nexttoken.type === '(number)') { - advance(); - if (nexttoken.type !== '(string)' && - cssLengthData[nexttoken.value] === true) { - no_space_only(); - advance(); - } - return true; - } - return false; - } - - - function cssWidth() { - if (nexttoken.identifier) { - switch (nexttoken.value) { - case 'thin': - case 'medium': - case 'thick': - advance(); - return true; - } - } else { - return cssLength(); - } - } - - - function cssMargin() { - if (nexttoken.identifier) { - if (nexttoken.value === 'auto') { - advance(); - return true; - } - } else { - return cssLength(); - } - } - - function cssAttr() { - if (nexttoken.identifier && nexttoken.value === 'attr') { - advance(); - advance('('); - if (!nexttoken.identifier) { - warning("Expected a name and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - advance(); - advance(')'); - return true; - } - return false; - } - - - function cssCommaList() { - while (nexttoken.id !== ';') { - if (!cssName() && !cssString()) { - warning("Expected a name and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - if (nexttoken.id !== ',') { - return true; - } - comma(); - } - } - - - function cssCounter() { - if (nexttoken.identifier && nexttoken.value === 'counter') { - advance(); - advance('('); - advance(); - if (nexttoken.id === ',') { - comma(); - if (nexttoken.type !== '(string)') { - warning("Expected a string and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - advance(); - } - advance(')'); - return true; - } - if (nexttoken.identifier && nexttoken.value === 'counters') { - advance(); - advance('('); - if (!nexttoken.identifier) { - warning("Expected a name and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - advance(); - if (nexttoken.id === ',') { - comma(); - if (nexttoken.type !== '(string)') { - warning("Expected a string and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - advance(); - } - if (nexttoken.id === ',') { - comma(); - if (nexttoken.type !== '(string)') { - warning("Expected a string and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - advance(); - } - advance(')'); - return true; - } - return false; - } - - - function cssShape() { - var i; - if (nexttoken.identifier && nexttoken.value === 'rect') { - advance(); - advance('('); - for (i = 0; i < 4; i += 1) { - if (!cssLength()) { - warning("Expected a number and instead saw '{a}'.", - nexttoken, nexttoken.value); - break; - } - } - advance(')'); - return true; - } - return false; - } - - - function cssUrl() { - var c, url; - if (nexttoken.identifier && nexttoken.value === 'url') { - nexttoken = lex.range('(', ')'); - url = nexttoken.value; - c = url.charAt(0); - if (c === '"' || c === '\'') { - if (url.slice(-1) !== c) { - warning("Bad url string."); - } else { - url = url.slice(1, -1); - if (url.indexOf(c) >= 0) { - warning("Bad url string."); - } - } - } - if (!url) { - warning("Missing url."); - } - advance(); - if (option.safe && ux.test(url)) { - error("ADsafe URL violation."); - } - urls.push(url); - return true; - } - return false; - } - - - cssAny = [cssUrl, function () { - for (;;) { - if (nexttoken.identifier) { - switch (nexttoken.value.toLowerCase()) { - case 'url': - cssUrl(); - break; - case 'expression': - warning("Unexpected expression '{a}'.", - nexttoken, nexttoken.value); - advance(); - break; - default: - advance(); - } - } else { - if (nexttoken.id === ';' || nexttoken.id === '!' || - nexttoken.id === '(end)' || nexttoken.id === '}') { - return true; - } - advance(); - } - } - }]; - - - cssBorderStyle = [ - 'none', 'dashed', 'dotted', 'double', 'groove', - 'hidden', 'inset', 'outset', 'ridge', 'solid' - ]; - - cssBreak = [ - 'auto', 'always', 'avoid', 'left', 'right' - ]; - - cssMedia = { - 'all': true, - 'braille': true, - 'embossed': true, - 'handheld': true, - 'print': true, - 'projection': true, - 'screen': true, - 'speech': true, - 'tty': true, - 'tv': true - }; - - cssOverflow = [ - 'auto', 'hidden', 'scroll', 'visible' - ]; - - cssAttributeData = { - background: [ - true, 'background-attachment', 'background-color', - 'background-image', 'background-position', 'background-repeat' - ], - 'background-attachment': ['scroll', 'fixed'], - 'background-color': ['transparent', cssColor], - 'background-image': ['none', cssUrl], - 'background-position': [ - 2, [cssLength, 'top', 'bottom', 'left', 'right', 'center'] - ], - 'background-repeat': [ - 'repeat', 'repeat-x', 'repeat-y', 'no-repeat' - ], - 'border': [true, 'border-color', 'border-style', 'border-width'], - 'border-bottom': [ - true, 'border-bottom-color', 'border-bottom-style', - 'border-bottom-width' - ], - 'border-bottom-color': cssColor, - 'border-bottom-style': cssBorderStyle, - 'border-bottom-width': cssWidth, - 'border-collapse': ['collapse', 'separate'], - 'border-color': ['transparent', 4, cssColor], - 'border-left': [ - true, 'border-left-color', 'border-left-style', 'border-left-width' - ], - 'border-left-color': cssColor, - 'border-left-style': cssBorderStyle, - 'border-left-width': cssWidth, - 'border-right': [ - true, 'border-right-color', 'border-right-style', - 'border-right-width' - ], - 'border-right-color': cssColor, - 'border-right-style': cssBorderStyle, - 'border-right-width': cssWidth, - 'border-spacing': [2, cssLength], - 'border-style': [4, cssBorderStyle], - 'border-top': [ - true, 'border-top-color', 'border-top-style', 'border-top-width' - ], - 'border-top-color': cssColor, - 'border-top-style': cssBorderStyle, - 'border-top-width': cssWidth, - 'border-width': [4, cssWidth], - bottom: [cssLength, 'auto'], - 'caption-side' : ['bottom', 'left', 'right', 'top'], - clear: ['both', 'left', 'none', 'right'], - clip: [cssShape, 'auto'], - color: cssColor, - content: [ - 'open-quote', 'close-quote', 'no-open-quote', 'no-close-quote', - cssString, cssUrl, cssCounter, cssAttr - ], - 'counter-increment': [ - cssName, 'none' - ], - 'counter-reset': [ - cssName, 'none' - ], - cursor: [ - cssUrl, 'auto', 'crosshair', 'default', 'e-resize', 'help', 'move', - 'n-resize', 'ne-resize', 'nw-resize', 'pointer', 's-resize', - 'se-resize', 'sw-resize', 'w-resize', 'text', 'wait' - ], - direction: ['ltr', 'rtl'], - display: [ - 'block', 'compact', 'inline', 'inline-block', 'inline-table', - 'list-item', 'marker', 'none', 'run-in', 'table', 'table-caption', - 'table-cell', 'table-column', 'table-column-group', - 'table-footer-group', 'table-header-group', 'table-row', - 'table-row-group' - ], - 'empty-cells': ['show', 'hide'], - 'float': ['left', 'none', 'right'], - font: [ - 'caption', 'icon', 'menu', 'message-box', 'small-caption', - 'status-bar', true, 'font-size', 'font-style', 'font-weight', - 'font-family' - ], - 'font-family': cssCommaList, - 'font-size': [ - 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', - 'xx-large', 'larger', 'smaller', cssLength - ], - 'font-size-adjust': ['none', cssNumber], - 'font-stretch': [ - 'normal', 'wider', 'narrower', 'ultra-condensed', - 'extra-condensed', 'condensed', 'semi-condensed', - 'semi-expanded', 'expanded', 'extra-expanded' - ], - 'font-style': [ - 'normal', 'italic', 'oblique' - ], - 'font-variant': [ - 'normal', 'small-caps' - ], - 'font-weight': [ - 'normal', 'bold', 'bolder', 'lighter', cssNumber - ], - height: [cssLength, 'auto'], - left: [cssLength, 'auto'], - 'letter-spacing': ['normal', cssLength], - 'line-height': ['normal', cssLineHeight], - 'list-style': [ - true, 'list-style-image', 'list-style-position', 'list-style-type' - ], - 'list-style-image': ['none', cssUrl], - 'list-style-position': ['inside', 'outside'], - 'list-style-type': [ - 'circle', 'disc', 'square', 'decimal', 'decimal-leading-zero', - 'lower-roman', 'upper-roman', 'lower-greek', 'lower-alpha', - 'lower-latin', 'upper-alpha', 'upper-latin', 'hebrew', 'katakana', - 'hiragana-iroha', 'katakana-oroha', 'none' - ], - margin: [4, cssMargin], - 'margin-bottom': cssMargin, - 'margin-left': cssMargin, - 'margin-right': cssMargin, - 'margin-top': cssMargin, - 'marker-offset': [cssLength, 'auto'], - 'max-height': [cssLength, 'none'], - 'max-width': [cssLength, 'none'], - 'min-height': cssLength, - 'min-width': cssLength, - opacity: cssNumber, - outline: [true, 'outline-color', 'outline-style', 'outline-width'], - 'outline-color': ['invert', cssColor], - 'outline-style': [ - 'dashed', 'dotted', 'double', 'groove', 'inset', 'none', - 'outset', 'ridge', 'solid' - ], - 'outline-width': cssWidth, - overflow: cssOverflow, - 'overflow-x': cssOverflow, - 'overflow-y': cssOverflow, - padding: [4, cssLength], - 'padding-bottom': cssLength, - 'padding-left': cssLength, - 'padding-right': cssLength, - 'padding-top': cssLength, - 'page-break-after': cssBreak, - 'page-break-before': cssBreak, - position: ['absolute', 'fixed', 'relative', 'static'], - quotes: [8, cssString], - right: [cssLength, 'auto'], - 'table-layout': ['auto', 'fixed'], - 'text-align': ['center', 'justify', 'left', 'right'], - 'text-decoration': [ - 'none', 'underline', 'overline', 'line-through', 'blink' - ], - 'text-indent': cssLength, - 'text-shadow': ['none', 4, [cssColor, cssLength]], - 'text-transform': ['capitalize', 'uppercase', 'lowercase', 'none'], - top: [cssLength, 'auto'], - 'unicode-bidi': ['normal', 'embed', 'bidi-override'], - 'vertical-align': [ - 'baseline', 'bottom', 'sub', 'super', 'top', 'text-top', 'middle', - 'text-bottom', cssLength - ], - visibility: ['visible', 'hidden', 'collapse'], - 'white-space': [ - 'normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'inherit' - ], - width: [cssLength, 'auto'], - 'word-spacing': ['normal', cssLength], - 'word-wrap': ['break-word', 'normal'], - 'z-index': ['auto', cssNumber] - }; - - function styleAttribute() { - var v; - while (nexttoken.id === '*' || nexttoken.id === '#' || - nexttoken.value === '_') { - if (!option.css) { - warning("Unexpected '{a}'.", nexttoken, nexttoken.value); - } - advance(); - } - if (nexttoken.id === '-') { - if (!option.css) { - warning("Unexpected '{a}'.", nexttoken, nexttoken.value); - } - advance('-'); - if (!nexttoken.identifier) { - warning( -"Expected a non-standard style attribute and instead saw '{a}'.", - nexttoken, nexttoken.value); - } - advance(); - return cssAny; - } else { - if (!nexttoken.identifier) { - warning("Excepted a style attribute, and instead saw '{a}'.", - nexttoken, nexttoken.value); - } else { - if (is_own(cssAttributeData, nexttoken.value)) { - v = cssAttributeData[nexttoken.value]; - } else { - v = cssAny; - if (!option.css) { - warning("Unrecognized style attribute '{a}'.", - nexttoken, nexttoken.value); - } - } - } - advance(); - return v; - } - } - - - function styleValue(v) { - var i = 0, - n, - once, - match, - round, - start = 0, - vi; - switch (typeof v) { - case 'function': - return v(); - case 'string': - if (nexttoken.identifier && nexttoken.value === v) { - advance(); - return true; - } - return false; - } - for (;;) { - if (i >= v.length) { - return false; - } - vi = v[i]; - i += 1; - if (vi === true) { - break; - } else if (typeof vi === 'number') { - n = vi; - vi = v[i]; - i += 1; - } else { - n = 1; - } - match = false; - while (n > 0) { - if (styleValue(vi)) { - match = true; - n -= 1; - } else { - break; - } - } - if (match) { - return true; - } - } - start = i; - once = []; - for (;;) { - round = false; - for (i = start; i < v.length; i += 1) { - if (!once[i]) { - if (styleValue(cssAttributeData[v[i]])) { - match = true; - round = true; - once[i] = true; - break; - } - } - } - if (!round) { - return match; - } - } - } - - function styleChild() { - if (nexttoken.id === '(number)') { - advance(); - if (nexttoken.value === 'n' && nexttoken.identifier) { - no_space_only(); - advance(); - if (nexttoken.id === '+') { - no_space_only(); - advance('+'); - no_space_only(); - advance('(number)'); - } - } - return; - } else { - if (nexttoken.identifier && - (nexttoken.value === 'odd' || nexttoken.value === 'even')) { - advance(); - return; - } - } - warning("Unexpected token '{a}'.", nexttoken, nexttoken.value); - } - - function substyle() { - var v; - for (;;) { - if (nexttoken.id === '}' || nexttoken.id === '(end)' || - xquote && nexttoken.id === xquote) { - return; - } - while (nexttoken.id === ';') { - warning("Misplaced ';'."); - advance(';'); - } - v = styleAttribute(); - advance(':'); - if (nexttoken.identifier && nexttoken.value === 'inherit') { - advance(); - } else { - if (!styleValue(v)) { - warning("Unexpected token '{a}'.", nexttoken, - nexttoken.value); - advance(); - } - } - if (nexttoken.id === '!') { - advance('!'); - no_space_only(); - if (nexttoken.identifier && nexttoken.value === 'important') { - advance(); - } else { - warning("Expected '{a}' and instead saw '{b}'.", - nexttoken, 'important', nexttoken.value); - } - } - if (nexttoken.id === '}' || nexttoken.id === xquote) { - warning("Missing '{a}'.", nexttoken, ';'); - } else { - semicolon(); - } - } - } - - function styleSelector() { - if (nexttoken.identifier) { - if (!is_own(htmltag, option.cap ? - nexttoken.value.toLowerCase() : nexttoken.value)) { - warning("Expected a tagName, and instead saw {a}.", - nexttoken, nexttoken.value); - } - advance(); - } else { - switch (nexttoken.id) { - case '>': - case '+': - advance(); - styleSelector(); - break; - case ':': - advance(':'); - switch (nexttoken.value) { - case 'active': - case 'after': - case 'before': - case 'checked': - case 'disabled': - case 'empty': - case 'enabled': - case 'first-child': - case 'first-letter': - case 'first-line': - case 'first-of-type': - case 'focus': - case 'hover': - case 'last-child': - case 'last-of-type': - case 'link': - case 'only-of-type': - case 'root': - case 'target': - case 'visited': - advance(); - break; - case 'lang': - advance(); - advance('('); - if (!nexttoken.identifier) { - warning("Expected a lang code, and instead saw :{a}.", - nexttoken, nexttoken.value); - } - advance(')'); - break; - case 'nth-child': - case 'nth-last-child': - case 'nth-last-of-type': - case 'nth-of-type': - advance(); - advance('('); - styleChild(); - advance(')'); - break; - case 'not': - advance(); - advance('('); - if (nexttoken.id === ':' && peek(0).value === 'not') { - warning("Nested not."); - } - styleSelector(); - advance(')'); - break; - default: - warning("Expected a pseudo, and instead saw :{a}.", - nexttoken, nexttoken.value); - } - break; - case '#': - advance('#'); - if (!nexttoken.identifier) { - warning("Expected an id, and instead saw #{a}.", - nexttoken, nexttoken.value); - } - advance(); - break; - case '*': - advance('*'); - break; - case '.': - advance('.'); - if (!nexttoken.identifier) { - warning("Expected a class, and instead saw #.{a}.", - nexttoken, nexttoken.value); - } - advance(); - break; - case '[': - advance('['); - if (!nexttoken.identifier) { - warning("Expected an attribute, and instead saw [{a}].", - nexttoken, nexttoken.value); - } - advance(); - if (nexttoken.id === '=' || nexttoken.value === '~=' || - nexttoken.value === '$=' || - nexttoken.value === '|=' || - nexttoken.id === '*=' || - nexttoken.id === '^=') { - advance(); - if (nexttoken.type !== '(string)') { - warning("Expected a string, and instead saw {a}.", - nexttoken, nexttoken.value); - } - advance(); - } - advance(']'); - break; - default: - error("Expected a CSS selector, and instead saw {a}.", - nexttoken, nexttoken.value); - } - } - } - - function stylePattern() { - if (nexttoken.id === '{') { - warning("Expected a style pattern, and instead saw '{a}'.", nexttoken, - nexttoken.id); - } - for (;;) { - styleSelector(); - if (nexttoken.id === ' fragments and .js files.", token); - } - if (option.fragment) { - if (n !== 'div') { - error("ADsafe violation: Wrap the widget in a div.", token); - } - } else { - error("Use the fragment option.", token); - } - } - option.browser = true; - assume(); - } - - function doAttribute(n, a, v) { - var u, x; - if (a === 'id') { - u = typeof v === 'string' ? v.toUpperCase() : ''; - if (ids[u] === true) { - warning("Duplicate id='{a}'.", nexttoken, v); - } - if (!/^[A-Za-z][A-Za-z0-9._:\-]*$/.test(v)) { - warning("Bad id: '{a}'.", nexttoken, v); - } else if (option.adsafe) { - if (adsafe_id) { - if (v.slice(0, adsafe_id.length) !== adsafe_id) { - warning("ADsafe violation: An id must have a '{a}' prefix", - nexttoken, adsafe_id); - } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) { - warning("ADSAFE violation: bad id."); - } - } else { - adsafe_id = v; - if (!/^[A-Z]+_$/.test(v)) { - warning("ADSAFE violation: bad id."); - } - } - } - x = v.search(dx); - if (x >= 0) { - warning("Unexpected character '{a}' in {b}.", token, v.charAt(x), a); - } - ids[u] = true; - } else if (a === 'class' || a === 'type' || a === 'name') { - x = v.search(qx); - if (x >= 0) { - warning("Unexpected character '{a}' in {b}.", token, v.charAt(x), a); - } - ids[u] = true; - } else if (a === 'href' || a === 'background' || - a === 'content' || a === 'data' || - a.indexOf('src') >= 0 || a.indexOf('url') >= 0) { - if (option.safe && ux.test(v)) { - error("ADsafe URL violation."); - } - urls.push(v); - } else if (a === 'for') { - if (option.adsafe) { - if (adsafe_id) { - if (v.slice(0, adsafe_id.length) !== adsafe_id) { - warning("ADsafe violation: An id must have a '{a}' prefix", - nexttoken, adsafe_id); - } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) { - warning("ADSAFE violation: bad id."); - } - } else { - warning("ADSAFE violation: bad id."); - } - } - } else if (a === 'name') { - if (option.adsafe && v.indexOf('_') >= 0) { - warning("ADsafe name violation."); - } - } - } - - function doTag(n, a) { - var i, t = htmltag[n], x; - src = false; - if (!t) { - error("Unrecognized tag '<{a}>'.", - nexttoken, - n === n.toLowerCase() ? n : - n + ' (capitalization error)'); - } - if (stack.length > 0) { - if (n === 'html') { - error("Too many tags.", token); - } - x = t.parent; - if (x) { - if (x.indexOf(' ' + stack[stack.length - 1].name + ' ') < 0) { - error("A '<{a}>' must be within '<{b}>'.", - token, n, x); - } - } else if (!option.adsafe && !option.fragment) { - i = stack.length; - do { - if (i <= 0) { - error("A '<{a}>' must be within '<{b}>'.", - token, n, 'body'); - } - i -= 1; - } while (stack[i].name !== 'body'); - } - } - switch (n) { - case 'div': - if (option.adsafe && stack.length === 1 && !adsafe_id) { - warning("ADSAFE violation: missing ID_."); - } - break; - case 'script': - xmode = 'script'; - advance('>'); - ////indent = nexttoken.from; - if (a.lang) { - warning("lang is deprecated.", token); - } - if (option.adsafe && stack.length !== 1) { - warning("ADsafe script placement violation.", token); - } - if (a.src) { - if (option.adsafe && (!adsafe_may || !approved[a.src])) { - warning("ADsafe unapproved script source.", token); - } - if (a.type) { - warning("type is unnecessary.", token); - } - } else { - if (adsafe_went) { - error("ADsafe script violation.", token); - } - use_strict(); - statements('script'); - } - xmode = 'html'; - advance(''); - styles(); - xmode = 'html'; - advance(''; - } - - function html() { - var a, attributes, e, n, q, t, v, w = option.white, wmode; - xmode = 'html'; - xquote = ''; - stack = null; - for (;;) { - switch (nexttoken.value) { - case '<': - xmode = 'html'; - advance('<'); - attributes = {}; - t = nexttoken; - if (!t.identifier) { - warning("Bad identifier {a}.", t, t.value); - } - n = t.value; - if (option.cap) { - n = n.toLowerCase(); - } - t.name = n; - advance(); - if (!stack) { - stack = []; - doBegin(n); - } - v = htmltag[n]; - if (typeof v !== 'object') { - error("Unrecognized tag '<{a}>'.", t, n); - } - e = v.empty; - t.type = n; - for (;;) { - if (nexttoken.id === '/') { - advance('/'); - if (nexttoken.id !== '>') { - warning("Expected '{a}' and instead saw '{b}'.", - nexttoken, '>', nexttoken.value); - } - break; - } - if (nexttoken.id && nexttoken.id.substr(0, 1) === '>') { - break; - } - if (!nexttoken.identifier) { - if (nexttoken.id === '(end)' || nexttoken.id === '(error)') { - error("Missing '>'.", nexttoken); - } - warning("Bad identifier."); - } - option.white = true; - spaces(); - a = nexttoken.value; - option.white = w; - advance(); - if (!option.cap && a !== a.toLowerCase()) { - warning("Attribute '{a}' not all lower case.", nexttoken, a); - } - a = a.toLowerCase(); - xquote = ''; - if (is_own(attributes, a)) { - warning("Attribute '{a}' repeated.", nexttoken, a); - } - if (a.slice(0, 2) === 'on') { - if (!option.on) { - warning("Avoid HTML event handlers."); - } - xmode = 'scriptstring'; - advance('='); - q = nexttoken.id; - if (q !== '"' && q !== "'") { - error("Missing quote."); - } - xquote = q; - wmode = option.white; - option.white = false; - advance(q); - use_strict(); - statements('on'); - option.white = wmode; - if (nexttoken.id !== q) { - error("Missing close quote on script attribute."); - } - xmode = 'html'; - xquote = ''; - advance(q); - v = false; - } else if (a === 'style') { - xmode = 'scriptstring'; - advance('='); - q = nexttoken.id; - if (q !== '"' && q !== "'") { - error("Missing quote."); - } - xmode = 'styleproperty'; - xquote = q; - advance(q); - substyle(); - xmode = 'html'; - xquote = ''; - advance(q); - v = false; - } else { - if (nexttoken.id === '=') { - advance('='); - v = nexttoken.value; - if (!nexttoken.identifier && - nexttoken.id !== '"' && - nexttoken.id !== '\'' && - nexttoken.type !== '(string)' && - nexttoken.type !== '(number)' && - nexttoken.type !== '(color)') { - warning("Expected an attribute value and instead saw '{a}'.", token, a); - } - advance(); - } else { - v = true; - } - } - attributes[a] = v; - doAttribute(n, a, v); - } - doTag(n, attributes); - if (!e) { - stack.push(t); - } - xmode = 'outer'; - advance('>'); - break; - case '') { - error("Missing '{a}'.", nexttoken, '>'); - } - xmode = 'outer'; - advance('>'); - break; - case '' || nexttoken.id === '(end)') { - break; - } - if (nexttoken.value.indexOf('--') >= 0) { - error("Unexpected --."); - } - if (nexttoken.value.indexOf('<') >= 0) { - error("Unexpected <."); - } - if (nexttoken.value.indexOf('>') >= 0) { - error("Unexpected >."); - } - } - xmode = 'outer'; - advance('>'); - break; - case '(end)': - return; - default: - if (nexttoken.id === '(end)') { - error("Missing '{a}'.", nexttoken, - ''); - } else { - advance(); - } - } - if (stack && stack.length === 0 && (option.adsafe || - !option.fragment || nexttoken.id === '(end)')) { - break; - } - } - if (nexttoken.id !== '(end)') { - error("Unexpected material after the end."); - } - } - - -// The actual JSLINT function itself. - - var itself = function (s, o) { - var a, i, k; - JSLINT.errors = []; - JSLINT.tree = ''; - predefined = Object.create(standard); - if (o) { - a = o.predef; - if (a) { - if (Array.isArray(a)) { - for (i = 0; i < a.length; i += 1) { - predefined[a[i]] = true; - } - } else if (typeof a === 'object') { - k = Object.keys(a); - for (i = 0; i < k.length; i += 1) { - predefined[k[i]] = !!a[k]; - } - } - } - if (o.adsafe) { - o.safe = true; - } - if (o.safe) { - o.browser = - o.css = - o.debug = - o.devel = - o.evil = - o.forin = - o.on = - o.rhino = - o.windows = - o.sub = - o.widget = false; - - o.nomen = - o.safe = - o.undef = true; - - predefined.Date = - predefined['eval'] = - predefined.Function = - predefined.Object = null; - - predefined.ADSAFE = - predefined.lib = false; - } - option = o; - } else { - option = {}; - } - option.indent = option.indent || 4; - option.maxerr = option.maxerr || 50; - adsafe_id = ''; - adsafe_may = false; - adsafe_went = false; - approved = {}; - if (option.approved) { - for (i = 0; i < option.approved.length; i += 1) { - approved[option.approved[i]] = option.approved[i]; - } - } else { - approved.test = 'test'; - } - tab = ''; - for (i = 0; i < option.indent; i += 1) { - tab += ' '; - } - global = Object.create(predefined); - scope = global; - funct = { - '(global)': true, - '(name)': '(global)', - '(scope)': scope, - '(breakage)': 0, - '(loopage)': 0 - }; - functions = [funct]; - ids = {}; - urls = []; - src = false; - xmode = false; - stack = null; - member = {}; - membersOnly = null; - implied = {}; - inblock = false; - lookahead = []; - jsonmode = false; - warnings = 0; - lex.init(s); - prereg = true; - strict_mode = false; - - prevtoken = token = nexttoken = syntax['(begin)']; - assume(); - - try { - advance(); - if (nexttoken.value.charAt(0) === '<') { - html(); - if (option.adsafe && !adsafe_went) { - warning("ADsafe violation: Missing ADSAFE.go.", this); - } - } else { - switch (nexttoken.id) { - case '{': - case '[': - jsonmode = true; - jsonValue(); - break; - case '@': - case '*': - case '#': - case '.': - case ':': - xmode = 'style'; - advance(); - if (token.id !== '@' || !nexttoken.identifier || - nexttoken.value !== 'charset' || token.line !== 1 || - token.from !== 1) { - error("A css file should begin with @charset 'UTF-8';"); - } - advance(); - if (nexttoken.type !== '(string)' && - nexttoken.value !== 'UTF-8') { - error("A css file should begin with @charset 'UTF-8';"); - } - advance(); - semicolon(); - styles(); - break; - - default: - if (option.adsafe && option.fragment) { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, '
    ', nexttoken.value); - } - if (nexttoken.value === 'use strict') { - warning("Use the function form of \"use strict\"."); - use_strict(); - } - JSLINT.tree = statements('lib'); - if (JSLINT.tree.disrupt) { - warning("Weird program.", prevtoken); - } - } - } - advance('(end)'); - } catch (e) { - if (e) { - JSLINT.errors.push({ - reason : e.message, - line : e.line || nexttoken.line, - character : e.character || nexttoken.from - }, null); - } - } - return JSLINT.errors.length === 0; - }; - - -// Data summary. - - itself.data = function () { - - var data = {functions: []}, fu, globals, implieds = [], f, i, j, - members = [], n, unused = [], v; - if (itself.errors.length) { - data.errors = itself.errors; - } - - if (jsonmode) { - data.json = true; - } - - for (n in implied) { - if (is_own(implied, n)) { - implieds.push({ - name: n, - line: implied[n] - }); - } - } - if (implieds.length > 0) { - data.implieds = implieds; - } - - if (urls.length > 0) { - data.urls = urls; - } - - globals = Object.keys(scope); - if (globals.length > 0) { - data.globals = globals; - } - - for (i = 1; i < functions.length; i += 1) { - f = functions[i]; - fu = {}; - for (j = 0; j < functionicity.length; j += 1) { - fu[functionicity[j]] = []; - } - for (n in f) { - if (is_own(f, n) && n.charAt(0) !== '(') { - v = f[n]; - if (v === 'unction') { - v = 'unused'; - } - if (Array.isArray(fu[v])) { - fu[v].push(n); - if (v === 'unused') { - unused.push({ - name: n, - line: f['(line)'], - 'function': f['(name)'] - }); - } - } - } - } - for (j = 0; j < functionicity.length; j += 1) { - if (fu[functionicity[j]].length === 0) { - delete fu[functionicity[j]]; - } - } - fu.name = f['(name)']; - fu.param = f['(params)']; - fu.line = f['(line)']; - fu.last = f['(last)']; - data.functions.push(fu); - } - - if (unused.length > 0) { - data.unused = unused; - } - - members = []; - for (n in member) { - if (typeof member[n] === 'number') { - data.member = member; - break; - } - } - - return data; - }; - - itself.report = function (option) { - var data = itself.data(); - - var a = [], c, e, err, f, i, k, l, m = '', n, o = [], s; - - function detail(h, array) { - var b, i, singularity; - if (array) { - o.push('
    ' + h + ' '); - array = array.sort(); - for (i = 0; i < array.length; i += 1) { - if (array[i] !== singularity) { - singularity = array[i]; - o.push((b ? ', ' : '') + singularity); - b = true; - } - } - o.push('
    '); - } - } - - if (data.errors || data.implieds || data.unused) { - err = true; - o.push('
    Error:'); - if (data.errors) { - for (i = 0; i < data.errors.length; i += 1) { - c = data.errors[i]; - if (c) { - e = c.evidence || ''; - o.push('

    Problem' + (isFinite(c.line) ? ' at line ' + - c.line + ' character ' + c.character : '') + - ': ' + c.reason.entityify() + - '

    ' + - (e && (e.length > 80 ? e.slice(0, 77) + '...' : - e).entityify()) + '

    '); - } - } - } - - if (data.implieds) { - s = []; - for (i = 0; i < data.implieds.length; i += 1) { - s[i] = '' + data.implieds[i].name + ' ' + - data.implieds[i].line + ''; - } - o.push('

    Implied global: ' + s.join(', ') + '

    '); - } - - if (data.unused) { - s = []; - for (i = 0; i < data.unused.length; i += 1) { - s[i] = '' + data.unused[i].name + ' ' + - data.unused[i].line + ' ' + - data.unused[i]['function'] + ''; - } - o.push('

    Unused variable: ' + s.join(', ') + '

    '); - } - if (data.json) { - o.push('

    JSON: bad.

    '); - } - o.push('
    '); - } - - if (!option) { - - o.push('
    '); - - if (data.urls) { - detail("URLs
    ", data.urls, '
    '); - } - - if (xmode === 'style') { - o.push('

    CSS.

    '); - } else if (data.json && !err) { - o.push('

    JSON: good.

    '); - } else if (data.globals) { - o.push('
    Global ' + - data.globals.sort().join(', ') + '
    '); - } else { - o.push('
    No new global variables introduced.
    '); - } - - for (i = 0; i < data.functions.length; i += 1) { - f = data.functions[i]; - - o.push('
    ' + f.line + '-' + - f.last + ' ' + (f.name || '') + '(' + - (f.param ? f.param.join(', ') : '') + ')
    '); - detail('Unused', f.unused); - detail('Closure', f.closure); - detail('Variable', f['var']); - detail('Exception', f.exception); - detail('Outer', f.outer); - detail('Global', f.global); - detail('Label', f.label); - } - - if (data.member) { - a = Object.keys(data.member); - if (a.length) { - a = a.sort(); - m = '
    /*members ';
    -                    l = 10;
    -                    for (i = 0; i < a.length; i += 1) {
    -                        k = a[i];
    -                        n = k.name();
    -                        if (l + n.length > 72) {
    -                            o.push(m + '
    '); - m = ' '; - l = 1; - } - l += n.length + 2; - if (data.member[k] === 1) { - n = '' + n + ''; - } - if (i < a.length - 1) { - n += ', '; - } - m += n; - } - o.push(m + '
    */
    '); - } - o.push('
    '); - } - } - return o.join(''); - }; - itself.jslint = itself; - - itself.edition = '2011-01-09'; - - return itself; - -}()); - -}); \ No newline at end of file diff --git a/lib/ace/worker/mirror.js b/lib/ace/worker/mirror.js index cf543fd3..ef6e2aa3 100644 --- a/lib/ace/worker/mirror.js +++ b/lib/ace/worker/mirror.js @@ -1,19 +1,34 @@ - define(function(require, exports, module) { - -var Document = require("ace/document").Document; -var lang = require("pilot/lang"); +"use strict"; + +var Range = require("../range").Range; +var Document = require("../document").Document; +var lang = require("../lib/lang"); var Mirror = exports.Mirror = function(sender) { this.sender = sender; var doc = this.doc = new Document(""); - var deferredUpdate = this.deferredUpdate = lang.deferredCall(this.onUpdate.bind(this)); + var deferredUpdate = this.deferredUpdate = lang.delayedCall(this.onUpdate.bind(this)); var _self = this; sender.on("change", function(e) { - doc.applyDeltas([e.data]); - deferredUpdate.schedule(_self.$timeout); + var data = e.data; + if (data[0].start) { + doc.applyDeltas(data); + } else { + for (var i = 0; i < data.length; i += 2) { + if (Array.isArray(data[i+1])) { + var d = {action: "insert", start: data[i], lines: data[i+1]}; + } else { + var d = {action: "remove", start: data[i], end: data[i+1]}; + } + doc.applyDelta(d, true); + } + } + if (_self.$timeout) + return deferredUpdate.schedule(_self.$timeout); + _self.onUpdate(); }); }; @@ -38,6 +53,10 @@ var Mirror = exports.Mirror = function(sender) { // abstract method }; + this.isPending = function() { + return this.deferredUpdate.isPending(); + }; + }).call(Mirror.prototype); -}); \ No newline at end of file +}); diff --git a/lib/ace/worker/worker.js b/lib/ace/worker/worker.js index 04f43a04..28fc0fe2 100644 --- a/lib/ace/worker/worker.js +++ b/lib/ace/worker/worker.js @@ -1,67 +1,167 @@ -var console = { - log: function(msg) { - postMessage({type: "log", data: msg}); - } +"no use strict"; +;(function(window) { +if (typeof window.window != "undefined" && window.document) + return; +if (window.require && window.define) + return; + +window.console = function() { + var msgs = Array.prototype.slice.call(arguments, 0); + postMessage({type: "log", data: msgs}); }; -var window = { - console: console +window.console.error = +window.console.warn = +window.console.log = +window.console.trace = window.console; + +window.window = window; +window.ace = window; + +window.onerror = function(message, file, line, col, err) { + postMessage({type: "error", data: { + message: message, + data: err.data, + file: file, + line: line, + col: col, + stack: err.stack + }}); }; -var require = function(id) { - var module = require.modules[id]; +window.normalizeModule = function(parentId, moduleName) { + // normalize plugin requires + if (moduleName.indexOf("!") !== -1) { + var chunks = moduleName.split("!"); + return window.normalizeModule(parentId, chunks[0]) + "!" + window.normalizeModule(parentId, chunks[1]); + } + // normalize relative requires + if (moduleName.charAt(0) == ".") { + var base = parentId.split("/").slice(0, -1).join("/"); + moduleName = (base ? base + "/" : "") + moduleName; + + while (moduleName.indexOf(".") !== -1 && previous != moduleName) { + var previous = moduleName; + moduleName = moduleName.replace(/^\.\//, "").replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, ""); + } + } + + return moduleName; +}; + +window.require = function require(parentId, id) { + if (!id) { + id = parentId; + parentId = null; + } + if (!id.charAt) + throw new Error("worker.js require() accepts only (parentId, id) as arguments"); + + id = window.normalizeModule(parentId, id); + + var module = window.require.modules[id]; if (module) { if (!module.initialized) { - module.exports = module.factory().exports; module.initialized = true; + module.exports = module.factory().exports; } return module.exports; } + + if (!window.require.tlns) + return console.log("unable to load " + id); - var chunks = id.split("/"); - chunks[0] = require.tlns[chunks[0]] || chunks[0]; - path = chunks.join("/") + ".js"; + var path = resolveModuleId(id, window.require.tlns); + if (path.slice(-3) != ".js") path += ".js"; - require.id = id; -// console.log("require " + path + " " + id) + window.require.id = id; + window.require.modules[id] = {}; // prevent infinite loop on broken modules importScripts(path); - return require(id); + return window.require(parentId, id); }; +function resolveModuleId(id, paths) { + var testPath = id, tail = ""; + while (testPath) { + var alias = paths[testPath]; + if (typeof alias == "string") { + return alias + tail; + } else if (alias) { + return alias.location.replace(/\/*$/, "/") + (tail || alias.main || alias.name); + } else if (alias === false) { + return ""; + } + var i = testPath.lastIndexOf("/"); + if (i === -1) break; + tail = testPath.substr(i) + tail; + testPath = testPath.slice(0, i); + } + return id; +} +window.require.modules = {}; +window.require.tlns = {}; -require.modules = {}; -require.tlns = {}; - -var define = function(id, deps, factory) { +window.define = function(id, deps, factory) { if (arguments.length == 2) { factory = deps; + if (typeof id != "string") { + deps = id; + id = window.require.id; + } } else if (arguments.length == 1) { factory = id; - id = require.id; + deps = []; + id = window.require.id; } - if (id.indexOf("text!") === 0) + if (typeof factory != "function") { + window.require.modules[id] = { + exports: factory, + initialized: true + }; return; - - require.modules[id] = { + } + + if (!deps.length) + // If there is no dependencies, we inject "require", "exports" and + // "module" as dependencies, to provide CommonJS compatibility. + deps = ["require", "exports", "module"]; + + var req = function(childId) { + return window.require(id, childId); + }; + + window.require.modules[id] = { + exports: {}, factory: function() { - var module = { - exports: {} - }; - var returnExports = factory(require, module.exports, module); + var module = this; + var returnExports = factory.apply(this, deps.map(function(dep) { + switch (dep) { + // Because "require", "exports" and "module" aren't actual + // dependencies, we must handle them seperately. + case "require": return req; + case "exports": return module.exports; + case "module": return module; + // But for all other dependencies, we can just go ahead and + // require them. + default: return req(dep); + } + })); if (returnExports) - module.exports = exports; + module.exports = returnExports; return module; } }; }; +window.define.amd = {}; +require.tlns = {}; +window.initBaseUrls = function initBaseUrls(topLevelNamespaces) { + for (var i in topLevelNamespaces) + require.tlns[i] = topLevelNamespaces[i]; +}; -function initBaseUrls(topLevelNamespaces) { - require.tlns = topLevelNamespaces; -} +window.initSender = function initSender() { -function initSender() { - - var EventEmitter = require("pilot/event_emitter").EventEmitter; - var oop = require("pilot/oop"); + var EventEmitter = window.require("ace/lib/event_emitter").EventEmitter; + var oop = window.require("ace/lib/oop"); var Sender = function() {}; @@ -88,24 +188,30 @@ function initSender() { }).call(Sender.prototype); return new Sender(); -} +}; -var main; -var sender; +var main = window.main = null; +var sender = window.sender = null; -onmessage = function(e) { +window.onmessage = function(e) { var msg = e.data; - if (msg.command) { - main[msg.command].apply(main, msg.args); + if (msg.event && sender) { + sender._signal(msg.event, msg.data); } - else if (msg.init) { - initBaseUrls(msg.tlns); - require("pilot/fixoldbrowsers"); - sender = initSender(); + else if (msg.command) { + if (main[msg.command]) + main[msg.command].apply(main, msg.args); + else if (window[msg.command]) + window[msg.command].apply(window, msg.args); + else + throw new Error("Unknown command:" + msg.command); + } + else if (msg.init) { + window.initBaseUrls(msg.tlns); + require("ace/lib/es5-shim"); + sender = window.sender = window.initSender(); var clazz = require(msg.module)[msg.classname]; - main = new clazz(sender); - } - else if (msg.event) { - sender._dispatchEvent(msg.event, msg.data); + main = window.main = new clazz(sender); } -}; \ No newline at end of file +}; +})(this); \ No newline at end of file diff --git a/lib/ace/worker/worker_client.js b/lib/ace/worker/worker_client.js index 57564173..ba4f20a0 100644 --- a/lib/ace/worker/worker_client.js +++ b/lib/ace/worker/worker_client.js @@ -1,96 +1,132 @@ -/* vim:ts=4:sts=4:sw=4: +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: * - * Ajax.org Code Editor (ACE) + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. * - * @copyright 2010, Ajax.org Services B.V. - * @license LGPLv3 - * @author Fabian Jakobs - */ + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ define(function(require, exports, module) { +"use strict"; -var oop = require("pilot/oop"); -var EventEmitter = require("pilot/event_emitter").EventEmitter; +var oop = require("../lib/oop"); +var net = require("../lib/net"); +var EventEmitter = require("../lib/event_emitter").EventEmitter; +var config = require("../config"); -var WorkerClient = function(topLevelNamespaces, packagedJs, module, classname) { +var WorkerClient = function(topLevelNamespaces, mod, classname, workerUrl) { + this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this); + this.changeListener = this.changeListener.bind(this); + this.onMessage = this.onMessage.bind(this); - this.callbacks = []; - - if (require.packaged) { - var base = this.$guessBasePath(); - var worker = this.$worker = new Worker(base + packagedJs); - } - else { - var workerUrl = require.nameToUrl("ace/worker/worker", null, "_"); - var worker = this.$worker = new Worker(workerUrl); + // nameToUrl is renamed to toUrl in requirejs 2 + if (require.nameToUrl && !require.toUrl) + require.toUrl = require.nameToUrl; + + if (config.get("packaged") || !require.toUrl) { + workerUrl = workerUrl || config.moduleUrl(mod, "worker"); + } else { + var normalizePath = this.$normalizePath; + workerUrl = workerUrl || normalizePath(require.toUrl("ace/worker/worker.js", null, "_")); var tlns = {}; - for (var i=0; i 50 && q.length > this.$doc.getLength() >> 1) { + this.call("setValue", [this.$doc.getValue()]); + } else + this.emit("change", {data: q}); + }; + + this.$workerBlob = function(workerUrl) { + // workerUrl can be protocol relative + // importScripts only takes fully qualified urls + var script = "importScripts('" + net.qualifyURL(workerUrl) + "');"; + try { + return new Blob([script], {"type": "application/javascript"}); + } catch (e) { // Backwards-compatibility + var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder; + var blobBuilder = new BlobBuilder(); + blobBuilder.append(script); + return blobBuilder.getBlob("application/javascript"); + } }; }).call(WorkerClient.prototype); + +var UIWorkerClient = function(topLevelNamespaces, mod, classname) { + this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this); + this.changeListener = this.changeListener.bind(this); + this.callbackId = 1; + this.callbacks = {}; + this.messageBuffer = []; + + var main = null; + var emitSync = false; + var sender = Object.create(EventEmitter); + var _self = this; + + this.$worker = {}; + this.$worker.terminate = function() {}; + this.$worker.postMessage = function(e) { + _self.messageBuffer.push(e); + if (main) { + if (emitSync) + setTimeout(processNext); + else + processNext(); + } + }; + this.setEmitSync = function(val) { emitSync = val }; + + var processNext = function() { + var msg = _self.messageBuffer.shift(); + if (msg.command) + main[msg.command].apply(main, msg.args); + else if (msg.event) + sender._signal(msg.event, msg.data); + }; + + sender.postMessage = function(msg) { + _self.onMessage({data: msg}); + }; + sender.callback = function(data, callbackId) { + this.postMessage({type: "call", id: callbackId, data: data}); + }; + sender.emit = function(name, data) { + this.postMessage({type: "event", name: name, data: data}); + }; + + config.loadModule(["worker", mod], function(Main) { + main = new Main[classname](sender); + while (_self.messageBuffer.length) + processNext(); + }); +}; + +UIWorkerClient.prototype = WorkerClient.prototype; + +exports.UIWorkerClient = UIWorkerClient; exports.WorkerClient = WorkerClient; }); diff --git a/lib/ace/worker/worker_test.js b/lib/ace/worker/worker_test.js new file mode 100644 index 00000000..c0a5b0a7 --- /dev/null +++ b/lib/ace/worker/worker_test.js @@ -0,0 +1,125 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +// The loading of ace/worker/worker is complicated, because when we need to load +// it via RequireJS, it needs a shim to make it into a AMD-module. +// When using the AMD-loader it's just works, so we just it load the file now + +require("amd-loader"); + +define(function(require, exports, module) { +"use strict"; + +var assert = require("../test/assertions"); +var worker = require("./worker") + +module.exports = { + setUp : function() { + // And define a few mock dependency modules + worker.define("depA", [], function(require, exports, module) { + module.exports = 'dependency A'; + }) + worker.define("depB", [], function(require, exports, module) { + module.exports = 'dependency B'; + }) + }, + + "test: define() with no dependencies, and CommonJS-compatability require()-calls" : function() { + // We want to be able to call define without an id or deps, but + // since we aren't loading an external file, we must explicitly give + // it some kind of id, in this case 'test1'. + worker.require.id = 'test1'; + // Now define out module + worker.define(function(require, exports, module) { + var depA = require("depA"); + var depB = require("depB"); + assert.equal("dependency A", depA); + assert.equal("dependency B", depB); + module.exports = 'test 1'; + }) + // And then try and require it + var res = worker.require("test1") + assert.equal("test 1", res) + }, + "test: define() with dependencies" : function() { + // We want to be able to call define without an id, but since we aren't + // loading an external file, we must explicitly give it some kind of + // id, in this case 'test2'. + worker.require.id = 'test2'; + // Now define our module + worker.define(['depA', 'depB'], function(depA, depB) { + assert.equal("dependency A", depA); + assert.equal("dependency B", depB); + return 'test 2'; + }) + // And then try and require it + var res = worker.require("test2"); + assert.equal("test 2", res); + }, + "test: define() used require, exports and module as a dependency": function() { + // We want to be able to call define without an id, but since we aren't + // loading an external file, we must explicitly give it some kind of + // id, in this case 'test3'. + worker.require.id = 'test3'; + // Now define our module + worker.define(['require', 'exports', 'module', 'depA', 'depB'], function(require, exports, module) { + var depA = require("depA"); + var depB = require("depB"); + assert.equal("dependency A", depA); + assert.equal("dependency B", depB); + module.exports = 'test 3'; + }) + // And then try and require it + var res = worker.require("test3"); + assert.equal("test 3", res); + }, + "test: define() with a mix of require and actual dependecies": function() { + // We want to be able to call define without an id, but since we aren't + // loading an external file, we must explicitly give it some kind of + // id, in this case 'test4'. + worker.require.id = 'test4'; + // Now define our module + worker.define(['depA', 'require'], function(depA, require) { + var depB = require("depB"); + assert.equal("dependency A", depA); + assert.equal("dependency B", depB); + return 'test 4'; + }) + // And then try and require it + var res = worker.require("test4"); + assert.equal("test 4", res); + } +} + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} \ No newline at end of file diff --git a/package.json b/package.json index 1fdb73dc..41c40fce 100644 --- a/package.json +++ b/package.json @@ -1,46 +1,37 @@ { "name": "ace", "description": "Ajax.org Code Editor is a full featured source code highlighting editor that powers the Cloud9 IDE", - "version": "0.1.6", - "homepage" : "http://github.com/ajaxorg/ace", - "engines": {"node": ">= 0.2.0"}, - "author": "Fabian Jakobs ", + "version": "1.1.9", + "homepage": "http://github.com/ajaxorg/ace", + "engines": {"node": ">= 0.6.0"}, + "author": "Fabian Jakobs ", "main": "lib/ace", - "repository" : { - "type" : "git", - "url" : "http://github.com/ajaxorg/ace.git" - }, - "overlay": { - "teleport": { - "directories": { - "lib": "lib/ace", - "dependencies": { - "cockpit": ">=0.1.1", - "pilot": ">=0.1.1" - } - } - } + "repository": { + "type": "git", + "url": "http://github.com/ajaxorg/ace.git" }, "dependencies": { - "pilot": ">=0.1.1", - "cockpit": ">=0.1.1", - "teleport": ">=0.2.6", - "asyncjs": ">=0.0.2", - "jsdom": ">=0.1.23", - "htmlparser": ">=1.7.2", - "dryice": ">=0.2.2", - "mime": ">=1.2.1" + "mime": "1.2.x" + }, + "devDependencies": { + "asyncjs": "0.0.x", + "jsdom": "0.2.x", + "amd-loader": "~0.0.4", + "dryice": "0.4.11", + "architect-build": "https://github.com/c9/architect-build/tarball/a3bad51808" + }, + "mappings": { + "ace": "." }, "licenses": [{ - "type": "MPL", - "url": "http://www.mozilla.org/MPL/" + "type": "BSD New", + "url": "http://opensource.org/licenses/BSD-3-Clause" + }], + "directories": { + "lib": "lib/ace" }, - { - "type": "GPL", - "url": "http://www.gnu.org/licenses/gpl.html" - }, - { - "type": "LGPL", - "url": "http://www.gnu.org/licenses/lgpl.html" - }] + "scripts": { + "start": "node static.js", + "test": "node lib/ace/test/all.js" + } } diff --git a/static.js b/static.js index dee2a6aa..3b75c2b6 100755 --- a/static.js +++ b/static.js @@ -1,39 +1,110 @@ #!/usr/bin/env node -var http = require("http"), - url = require("url"), - path = require("path"), - fs = require("fs"), - mime = require("mime"), - port = process.env.C9_PORT || 8888; +var http = require("http") + , path = require("path") + , mime = require("mime") + , url = require("url") + , fs = require("fs") + , port = process.env.PORT || 8888 + , ip = process.env.IP || "0.0.0.0"; -http.createServer(function(request, response) { +// compatibility with node 0.6 +if (!fs.exists) + fs.exists = path.exists; - var uri = url.parse(request.url).pathname - , filename = path.join(process.cwd(), uri); - - path.exists(filename, function(exists) { - if(!exists) { - response.writeHead(404, {"Content-Type": "text/plain"}); - response.write("404 Not Found\n"); - response.end(); - return; +var allowSave = process.argv.indexOf("--allow-save") != -1; + +http.createServer(function(req, res) { + var uri = url.parse(req.url).pathname + , filename = path.join(process.cwd(), uri); + + if (req.method == "PUT") { + if (!allowSave) + return error(res, 404, "Saving not allowed pass --allow-save to enable"); + return save(req, res, filename); } - if (fs.statSync(filename).isDirectory()) filename += '/index.html'; + fs.exists(filename, function(exists) { + if (!exists) + return error(res, 404, "404 Not Found\n"); - fs.readFile(filename, "binary", function(err, file) { - if(err) { - response.writeHead(500, {"Content-Type": "text/plain"}); - response.write(err + "\n"); - response.end(); - return; - } + if (fs.statSync(filename).isDirectory()) { + var files = fs.readdirSync(filename); + res.writeHead(200, {"Content-Type": "text/html"}); + + files.push(".", ".."); + var html = files.map(function(name) { + var href = uri + "/" + name; + href = href.replace(/[\/\\]+/g, "/").replace(/\/$/g, ""); + if (fs.statSync(filename + "/" + name + "/").isDirectory()) + href += "/"; + return "" + name + "
    "; + }); - var contentType = mime.lookup(filename) || "text/plain"; - response.writeHead(200, {"Content-Type": contentType}); - response.write(file, "binary"); - response.end(); + res._hasBody && res.write(html.join("")); + res.end(); + return; + } + + fs.readFile(filename, "binary", function(err, file) { + if (err) { + res.writeHead(500, { "Content-Type": "text/plain" }); + res.write(err + "\n"); + res.end(); + return; + } + + var contentType = mime.lookup(filename) || "text/plain"; + res.writeHead(200, { "Content-Type": contentType }); + res.write(file, "binary"); + res.end(); + }); }); - }); -}).listen(port, "0.0.0.0"); +}).listen(port, ip); + +function error(res, status, message, error) { + console.error(error || message); + res.writeHead(status, { "Content-Type": "text/plain" }); + res.write(message); + res.end(); +} + +function save(req, res, filePath) { + var data = ""; + req.on("data", function(chunk) { + data += chunk; + }); + req.on("error", function() { + error(res, 404, "Could't save file"); + }); + req.on("end", function() { + try { + fs.writeFileSync(filePath, data); + } + catch (e) { + return error(res, 404, "Could't save file", e); + } + res.statusCode = 200; + res.end("OK"); + console.log("saved ", filePath); + }); +} + +function getLocalIps() { + var os = require("os"); + + var interfaces = os.networkInterfaces ? os.networkInterfaces() : {}; + var addresses = []; + for (var k in interfaces) { + for (var k2 in interfaces[k]) { + var address = interfaces[k][k2]; + if (address.family === "IPv4" && !address.internal) { + addresses.push(address.address); + } + } + } + return addresses; +} + +console.log("http://" + (ip == "0.0.0.0" ? getLocalIps()[0] : ip) + ":" + port); + diff --git a/static.py b/static.py index 801a70d7..7a2faf91 100755 --- a/static.py +++ b/static.py @@ -18,8 +18,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to: -The Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, +The Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Luke Arno can be found at http://lukearno.com/ @@ -32,7 +32,9 @@ import time import string import sys from os import path, stat, getcwd +from fnmatch import fnmatch from wsgiref import util +from wsgiref.validate import validator from wsgiref.headers import Headers from wsgiref.simple_server import make_server from optparse import OptionParser @@ -49,14 +51,14 @@ class MagicError(Exception): pass class StatusApp: """Used by WSGI apps to return some HTTP status.""" - + def __init__(self, status, message=None): self.status = status if message is None: self.message = status else: self.message = message - + def __call__(self, environ, start_response, headers=[]): if self.message: Headers(headers).add_header('Content-type', 'text/plain') @@ -69,9 +71,9 @@ class StatusApp: class Cling(object): """A stupidly simple way to serve static content via WSGI. - + Serve the file of the same path as PATH_INFO in self.datadir. - + Look up the Content-type in self.content_types by extension or use 'text/plain' if the extension is not found. @@ -84,6 +86,8 @@ class Cling(object): not_modified = StatusApp('304 Not Modified', "") moved_permanently = StatusApp('301 Moved Permanently') method_not_allowed = StatusApp('405 Method Not Allowed') + success_no_content = StatusApp('204 No Content', "") + server_error = StatusApp('500 Internal Server Error') def __init__(self, root, **kw): """Just set the root and any other attribs passes via **kw.""" @@ -93,9 +97,6 @@ class Cling(object): def __call__(self, environ, start_response): """Respond to a request when called in the usual WSGI way.""" - if environ['REQUEST_METHOD'] not in ('GET', 'HEAD'): - headers = [('Allow', 'GET, HEAD')] - return self.method_not_allowed(environ, start_response, headers) path_info = environ.get('PATH_INFO', '') full_path = self._full_path(path_info) if not self._is_under_root(full_path): @@ -109,6 +110,23 @@ class Cling(object): return self.moved_permanently(environ, start_response, headers) else: full_path = self._full_path(path_info + self.index_file) + try: + sz = int(environ['CONTENT_LENGTH']) + except: + sz = 0 + if environ['REQUEST_METHOD'] == 'PUT' and sz > 0: + for putglob in self.puttable: + if fnmatch(path_info, putglob): + data = environ['wsgi.input'].read(sz) + try: + with open(full_path, "wb") as f: f.write(data) + return self.success_no_content(environ, start_response) + except: + print sys.exc_info()[1] + return self.server_error(environ, start_response) + if environ['REQUEST_METHOD'] not in ('GET', 'HEAD'): + headers = [('Allow', 'GET, HEAD')] + return self.method_not_allowed(environ, start_response, headers) content_type = self._guess_type(full_path) try: etag, last_modified = self._conditions(full_path, environ) @@ -173,17 +191,17 @@ def iter_and_close(file_like, block_size): else: raise StopIteration except StopIteration, si: file_like.close() - return + return def cling_wrap(package_name, dir_name, **kw): """Return a Cling that serves from the given package and dir_name. - + This uses pkg_resources.resource_filename which is not the - recommended way, since it extracts the files. - - I think this works fine unless you have some _very_ serious - requirements for static content, in which case you probably + recommended way, since it extracts the files. + + I think this works fine unless you have some _very_ serious + requirements for static content, in which case you probably shouldn't be serving it through a WSGI app, IMHO. YMMV. """ resource = Requirement.parse(package_name) @@ -191,52 +209,90 @@ def cling_wrap(package_name, dir_name, **kw): def command(): - parser = OptionParser(usage="%prog DIR [HOST][:][PORT]", - version="static 0.3.6") + usage = "%prog [--help] [-d DIR] [-l [HOST][:PORT]] [-p GLOB[,GLOB...]]" + parser = OptionParser(usage=usage, version="static 0.3.6") + parser.add_option("-d", "--dir", dest="rootdir", default=".", + help="Root directory to serve. Defaults to '.' .", metavar="DIR") + parser.add_option("-l", "--listen", dest="listen", default="127.0.0.1:8888", + help="Listen on this interface (given by its hostname or IP) and port."+ + " HOST defaults to 127.0.0.1. PORT defaults to 8888. "+ + "Leave HOST empty to listen on all interfaces (INSECURE!).", + metavar="[HOST][:PORT]") + parser.add_option("-p", "--puttable", dest="puttable", default="", + help="Comma or space-separated list of request paths for which to"+ + " permit PUT requests. Each path is a glob pattern that may "+ + "contain wildcard characters '*' and/or '?'. "+ + "'*' matches any sequence of characters, including the empty"+ + " string. '?' matches exactly 1 arbitrary character. "+ + "NOTE: Both '*' and '?' match slashes and dots. "+ + "I.e. --puttable=* makes every file under DIR writable!", + metavar="GLOB[,GLOB...]") + parser.add_option("--validate", dest="validate", action="store_true", + default=False, + help="Enable HTTP validation. You don't need this unless "+ + "you're developing static.py itself.") + options, args = parser.parse_args() - if len(args) in (1, 2): - if len(args) == 2: - parts = args[1].split(":") - if len(parts) == 1: - host = parts[0] - port = None - elif len(parts) == 2: - host, port = parts - else: - sys.exit("Invalid host:port specification.") - elif len(args) == 1: - host, port = None, None - if not host: - host = '0.0.0.0' - if not port: - port = 9999 - try: - port = int(port) - except: - sys.exit("Invalid host:port specification.") - app = Cling(args[0]) - try: - make_server(host, port, app).serve_forever() - except KeyboardInterrupt, ki: - print "Cio, baby!" - except: - sys.exit("Problem initializing server.") - else: + if len(args) > 0: parser.print_help(sys.stderr) sys.exit(1) + parts = options.listen.split(":") + if len(parts) == 1: + try: # if the the listen argument consists only of a port number + port = int(parts[0]) + host = None + except: # could not parse as port number => must be a host IP or name + host = parts[0] + port = None + elif len(parts) == 2: + host, port = parts + else: + sys.exit("Invalid host:port specification.") -def test(): - from wsgiref.validate import validator - app = Cling(getcwd()) + if not host: + host = '0.0.0.0' + if not port: + port = 8888 try: - print "Serving " + getcwd() + " to http://localhost:9999" - make_server('0.0.0.0', 9999, validator(app)).serve_forever() + port = int(port) + if port <= 0 or port > 65535: raise ValueError + except: + sys.exit("Invalid host:port specification.") + + puttable = set(path.abspath(p) for p in + options.puttable.replace(","," ").split()) + if puttable and host not in ('127.0.0.1', 'localhost'): + print("Permitting PUT access for non-localhost connections may be unwise.") + + options.rootdir = path.abspath(options.rootdir) + + for p in puttable: + if not p.startswith(options.rootdir): + sys.exit("puttable path '%s' not under root '%s'" % (p, options.rootdir)) + + # cut off root prefix from puttable paths + puttable = set(p[len(options.rootdir):] for p in puttable) + + app = Cling(options.rootdir, puttable=puttable) + + if options.validate: + app = validator(app) + + try: + print "Serving %s to http://%s:%d" % (options.rootdir, host, port) + if puttable: + print("The following paths (relative to server root) may be "+ + "OVERWRITTEN via HTTP PUT.") + for p in puttable: + print p + make_server(host, port, app).serve_forever() except KeyboardInterrupt, ki: - print "" print "Ciao, baby!" + except: + sys.exit("Problem initializing server: %s" % sys.exc_info()[1]) if __name__ == '__main__': - test() + command() diff --git a/support/cockpit b/support/cockpit deleted file mode 160000 index 1fa3516d..00000000 --- a/support/cockpit +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1fa3516d4d553af9f6edd81c20023bcfab08c2a3 diff --git a/support/paths.js b/support/paths.js deleted file mode 100644 index c0dcee83..00000000 --- a/support/paths.js +++ /dev/null @@ -1,6 +0,0 @@ -require("./requireJS-node"); -require.paths.unshift(__dirname + "/../lib"); -require.paths.unshift(__dirname + "/pilot/lib"); -require.paths.unshift(__dirname + "/async/lib"); -require.paths.unshift(__dirname + "/jsdom/lib"); -require.paths.unshift(__dirname); diff --git a/support/pilot b/support/pilot deleted file mode 160000 index 1b6251c4..00000000 --- a/support/pilot +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1b6251c4bc1d24406d041c2949c3d3f99a112425 diff --git a/support/requireJS-node.js b/support/requireJS-node.js deleted file mode 100644 index debb0124..00000000 --- a/support/requireJS-node.js +++ /dev/null @@ -1,147 +0,0 @@ -var path = require("path"); -var fs = require("fs"); -var currentModule, defaultCompile = module.constructor.prototype._compile; - -module.constructor.prototype._compile = function(content, filename){ - currentModule = this; - try{ - return defaultCompile.call(this, content, filename); - } - finally { - currentModule = null; - } -}; - -var requireModule = module; - -global.define = function (id, injects, factory) { - if (currentModule == null) { - throw new Error("define() may only be called during module factory instantiation"); - } - - var module = currentModule; - - var req = function(relativeId, callback) { - if (Array.isArray(relativeId)) { - // async require - return callback.apply(this, relativeId.map(req)) - } - - var chunks = relativeId.split("!"); - if (chunks.length >= 2) { - var prefix = chunks[0]; - relativeId = chunks.slice(1).join("!") - } - - if (relativeId.charAt(0) === '.') { - var rootPath = path.dirname(path.dirname(requireModule.filename)) + "/", - absolutePath = path.dirname(module.filename) + "/" + relativeId; - - relativeId = "../" + absolutePath.match(new RegExp(rootPath + "(.*)"))[1]; - } - - if (prefix == "text") { - return fs.readFileSync(findModulePath(relativeId)) - } else - return require(relativeId); - }; - if (!factory) { - // two or less arguments - factory = injects; - if (factory) { - // two args - if (typeof id === "string") { - if (id !== module.id) { - throw new Error("Can not assign module to a different id than the current file"); - } - // default injects - injects = []; - } - else{ - // anonymous, deps included - injects = id; - } - } - else { - // only one arg, just the factory - factory = id; - injects = []; - } - } - injects.unshift("require", "exports", "module"); - - id = module.id; - if (typeof factory !== "function"){ - // we can just provide a plain object - return module.exports = factory; - } - var returned = factory.apply(module.exports, injects.map(function (injection) { - switch (injection) { - // check for CommonJS injection variables - case "require": return req; - case "exports": return module.exports; - case "module": return module; - default: - // a module dependency - return req(injection); - } - })); - if(returned){ - // since AMD encapsulates a function/callback, it can allow the factory to return the exports. - module.exports = returned; - } -}; - -// slighly modified version of -// https://github.com/ry/node/blob/1dad95a3a960c645ffec28f9ec023dad6a17c0d4/src/node.js#L159 -// -// given a module name, and a list of paths to test, returns the first -// matching file in the following precedence. -// -// require("a.") -// -> a. -// -// require("a") -// -> a -// -> a. -// -> a/index. -function findModulePath(request) { - var fs = require('fs'), - exts = ["js"], - paths = ['.'].concat(require.paths) - - paths = request.charAt(0) === '/' ? [''] : paths; - - // check if the file exists and is not a directory - var tryFile = function(requestPath) { - try { - var stats = fs.statSync(requestPath); - if (stats && !stats.isDirectory()) { - return requestPath; - } - } catch (e) {} - return false; - }; - - // given a path check a the file exists with any of the set extensions - var tryExtensions = function(p, extension) { - for (var i = 0, EL = exts.length; i < EL; i++) { - f = tryFile(p + exts[i]); - if (f) { return f; } - } - return false; - }; - - // For each path - for (var i = 0, PL = paths.length; i < PL; i++) { - var p = paths[i], - // try to join the request to the path - f = tryFile(path.join(p, request)) || - // try it with each of the extensions - tryExtensions(path.join(p, request)) || - // try it with each of the extensions at "index" - tryExtensions(path.join(p, request, 'index')); - if (f) { return f; } - } - return false; -} \ No newline at end of file diff --git a/tool/Readme.md b/tool/Readme.md new file mode 100644 index 00000000..28dd5166 --- /dev/null +++ b/tool/Readme.md @@ -0,0 +1,26 @@ +Helper Scripts for Ace +====================== + +To use this you need to install node.js. and run `npm install` in this directory. + + +# add_mode.js + + Run +``` +node add_mode.js ModeName "extension1|extension2|^FullName" +``` + to create all the files needed for a new mode named `ModeName` + this adds stubs for: + `ace/mode/mode_name.js` + `ace/mode/mode_name_hightlight_rules.js` + `ace/snippets/mode_name.js` + `ace/demo/kitchen_sink/docs/mode_name.extension1` + and adds entry for the new mode to `ace/ext/modelist.js` + + +# tmlanguage.js + +``` +node tmlanguage.js ./templates/dummy.JSON-tmLanguage +``` \ No newline at end of file diff --git a/tool/Theme.tmpl.css b/tool/Theme.tmpl.css deleted file mode 100644 index 64270089..00000000 --- a/tool/Theme.tmpl.css +++ /dev/null @@ -1,152 +0,0 @@ -.%cssClass% .ace_editor { - border: 2px solid rgb(159, 159, 159); -} - -.%cssClass% .ace_editor.ace_focus { - border: 2px solid #327fbd; -} - -.%cssClass% .ace_gutter { - width: 50px; - background: #e8e8e8; - color: #333; - overflow : hidden; -} - -.%cssClass% .ace_gutter-layer { - width: 100%; - text-align: right; -} - -.%cssClass% .ace_gutter-layer .ace_gutter-cell { - padding-right: 6px; -} - -.%cssClass% .ace_print_margin { - width: 1px; - background: %printMargin%; -} - -.%cssClass% .ace_scroller { - background-color: %background%; -} - -.%cssClass% .ace_text-layer { - cursor: text; - color: %foreground%; -} - -.%cssClass% .ace_cursor { - border-left: 2px solid %cursor%; -} - -.%cssClass% .ace_cursor.ace_overwrite { - border-left: 0px; - border-bottom: 1px solid %overwrite%; -} - -.%cssClass% .ace_marker-layer .ace_selection { - background: %selection%; -} - -.%cssClass% .ace_marker-layer .ace_step { - background: %step%; -} - -.%cssClass% .ace_marker-layer .ace_bracket { - margin: -1px 0 0 -1px; - border: 1px solid %bracket%; -} - -.%cssClass% .ace_marker-layer .ace_active_line { - background: %active_line%; -} - - -.%cssClass% .ace_invisible { - %invisible% -} - -.%cssClass% .ace_keyword { - %keyword% -} - -.%cssClass% .ace_keyword.ace_operator { - %keyword.operator% -} - -.%cssClass% .ace_constant { - %constant% -} - -.%cssClass% .ace_constant.ace_language { - %constant.language% -} - -.%cssClass% .ace_constant.ace_library { - %constant.library% -} - -.%cssClass% .ace_constant.ace_numeric { - %constant.numeric% -} - -.%cssClass% .ace_invalid { - %invalid% -} - -.%cssClass% .ace_invalid.ace_illegal { - %invalid.illegal% -} - -.%cssClass% .ace_invalid.ace_deprecated { - %invalid.deprecated% -} - -.%cssClass% .ace_support { - %support% -} - -.%cssClass% .ace_support.ace_function { - %support.function% -} - -.%cssClass% .ace_function.ace_buildin { - %function.buildin% -} - -.%cssClass% .ace_string { - %string% -} - -.%cssClass% .ace_string.ace_regexp { - %string.regexp% -} - -.%cssClass% .ace_comment { - %comment% -} - -.%cssClass% .ace_comment.ace_doc { - %comment.doc% -} - -.%cssClass% .ace_comment.ace_doc.ace_tag { - %comment.doc.tag% -} - -.%cssClass% .ace_variable { - %variable% -} - -.%cssClass% .ace_variable.ace_language { - %variable.language% -} - -.%cssClass% .ace_xml_pe { - %xml_pe% -} - -.%cssClass% .ace_collab.ace_user1 { - %collab.user1% -} \ No newline at end of file diff --git a/tool/add_mode.js b/tool/add_mode.js new file mode 100644 index 00000000..879b9204 --- /dev/null +++ b/tool/add_mode.js @@ -0,0 +1,106 @@ +var fs = require('fs'); +var lib = require('./lib'); +var path = require('path'); + +function main(displayName, extRe) { + var name = lib.snakeCase(displayName).replace(/[^\w]/g, ""); + + /** demo **/ + var demoFileExt = extRe.split("|")[0] || name; + var demoFileName = demoFileExt[0] == "^" ? demoFileExt.substr(1) : name + "." + demoFileExt; + var demoFilePath = lib.AceRoot + "demo/kitchen-sink/docs/" + demoFileName; + fs.writeFileSync(demoFilePath, "TODO add a nice demo!\nTry to keep it short!", "utf8"); + console.log("Created demo file at: " + path.normalize(demoFilePath)); + + /** mode **/ + var template = fs.readFileSync(__dirname + "/templates/mode.js", "utf8"); + var modePath = lib.AceLib + "ace/mode/" + name + ".js"; + var text = lib.fillTemplate(template, { + languageHighlightFilename: name, + languagename: name, + lineCommentStart: "TODO", + blockCommentStart: "TODO", + blockCommentEnd: "TODO" + }); + fs.writeFileSync(modePath, text); + console.log("Created mode file at: " + path.normalize(modePath)); + + /** highlight rules **/ + template = fs.readFileSync(__dirname + "/templates/highlight_rules.js", "utf8"); + var hlPath = lib.AceLib + "ace/mode/" + name + "_highlight_rules.js"; + template = template.replace(/\/\* THIS[\s\S]*?\*{3}\/\s*/, ""); + text = lib.fillTemplate(template, { + language: name, + languageTokens: '{\n\ + start: [{\n\ + token: "string.start",\n\ + regex: \'"\',\n\ + next: "qstring"\n\ + }],\n\ + qstring: [{\n\ + token: "escape",\n\ + regex: /\\\\./,\n\ + }, {\n\ + token: "string.end",\n\ + regex: \'"\',\n\ + next: "start"\n\ + }],\n\ + }' + }); + fs.writeFileSync(hlPath, text); + console.log("Created mode file at: " + path.normalize(hlPath)); + + /** snippets **/ + template = fs.readFileSync(__dirname + "/templates/snippets.js", "utf8"); + var snipetsPath = lib.AceLib + "ace/snippets/" + name + ".js"; + text = lib.fillTemplate(template, { + languagename: name, + snippets: "" + }); + fs.writeFileSync(snipetsPath, text); + console.log("Created snippets file at: " + path.normalize(snipetsPath)); + + /** modelist **/ + var modelistPath = lib.AceLib + "ace/ext/modelist.js"; + var modelist = fs.readFileSync(modelistPath, "utf8").replace(/\r\n?/g, "\n"); + modelist = modelist.replace(/(supportedModes = {\n)([\s\S]*?)(\n^};)/m, function(_, m1, m2, m3) { + var langs = m2.split(/,\n/); + var offset = langs[0].trim().indexOf("["); + var padding = Array(Math.max(offset - displayName.length - 1, 0) + 1).join(" "); + var newLang = " " + displayName + ":" + padding + "[\"" + extRe + "\"]"; + langs = langs.concat(newLang).map(function(x) { + return { + value: x, + id: x.match(/[^"':\s]+/)[0].toLowerCase() + }; + }); + langs[langs.length - 1].isNew = true; + + langs = langs.filter(function(x) { + console.log(x.id, displayName) + return x.id != displayName.toLowerCase() || x.isNew; + }); + langs = langs.sort(function(a, b) { + return a.id.localeCompare(b.id); + }).map(function(x) { + return x.value; + }); + + return m1 + langs.join(",\n") + m3; + }); + fs.writeFileSync(modelistPath, modelist, "utf8"); + console.log("Updated modelist at: " + path.normalize(modelistPath)); +} + +if (!module.parent) { + var args = process.argv.slice(2); + var displayName = args[0]; + var extRe = args[1]; + if (!displayName || ! extRe) { + console.log("Usage: ModeName ext1|ext2"); + process.exit(1); + } +} else { + module.exports = main; +} + diff --git a/tool/lib.js b/tool/lib.js new file mode 100644 index 00000000..3d57b6e0 --- /dev/null +++ b/tool/lib.js @@ -0,0 +1,182 @@ +var plist = require("plist"); +var util = require("util"); +var url = require("url"); +var cson = require("cson"); + +var https = require("https"); +var http = require("http"); + +exports.parsePlist = function(xmlOrJSON, callback) { + var json; + if (xmlOrJSON[0] == "<") { + plist.parseString(xmlOrJSON, function(_, result) { + json = result[0]; + }); + } else { + try { + xmlOrJSON = xmlOrJSON.replace( + /("(?:\\.|[^"])*")|(?:,\s*)+([\]\}])|(\w+)\s*:|([\]\}]\s*[\[\{])|(\/\/.*|\/\*(?:[^\*]|\*(?=[^\/]))*?\*\/)/g, + function(_, str, extraComma, noQuote, missingComma, comment) { + if (comment) + return ""; + if (missingComma) + return missingComma[0] + "," + missingComma.slice(1); + return str || extraComma || '"' + noQuote + '":'; + }); + json = JSON.parse(xmlOrJSON); + } catch(e) { + json = cson.parse(xmlOrJSON); + } + } + callback && callback(json); + return json; +}; + + +exports.formatJSON = function(object, initialIndent) { + return JSON.stringify(object, null, 4).replace(/^/gm, initialIndent||""); +}; + +exports.formatJS = function(object, initialIndent) { + return formatJS(object, 4, initialIndent); +}; + +function formatJS(object, indent, initialIndent) { + if (typeof indent == "number") + indent = Array(indent + 1).join(" "); + + function $format(buffer, totalIndent, state, o) { + if (typeof o != "object" || !o) { + if (typeof o == "string") + buffer.push(JSON.stringify(o)); + else + buffer.push("" + o); + } + else if (Array.isArray(o)) { + buffer.push("[") + + var len = totalIndent.length + var oneLine = true; + for (var i = 0; i < o.length; i++) { + if (typeof o[i] == "string") { + len += o[i].length + 2 + } else if (!o[i]) { + len += (o[i] + "").length + } else { + oneLine = false; + break; + } + len += 2; + if (len > 60) { + oneLine = false; + break; + } + } + + for (var i = 0; i < o.length; i++) { + if (o[i] && typeof o[i] == "object") { + $format(buffer, totalIndent, state, o[i]); + if (i < o.length - 1) + buffer.push(", "); + } else { + if (oneLine) + i && buffer.push(" "); + else + buffer.push("\n", totalIndent + indent) + $format(buffer, totalIndent + indent, state, o[i]); + if (i < o.length - 1) + buffer.push(","); + } + + } + if (!oneLine && buffer[buffer.length - 1] != "}") + buffer.push("\n" + totalIndent) + buffer.push("]") + } + else { + var keys = Object.keys(o); + buffer.push("{", "\n"); + for (var i = 0; i < keys.length; i++) { + buffer.push(totalIndent + indent); + if (/^\w+$/.test(keys[i])) + buffer.push(keys[i]); + else + buffer.push(JSON.stringify(keys[i])); + buffer.push(": ") + + if (keys[i] == "regex" && typeof o[keys[i]] == "string") { + try { + var re = new RegExp(o[keys[i]]); + buffer.push("/" + re.source.replace(/\\.|\//g, function(f) { + return f.length == 1 ? "\\" + f : f; + }) + "/"); + } catch(e) { + $format(buffer, totalIndent + indent, state, o[keys[i]]); + } + } else { + $format(buffer, totalIndent + indent, state, o[keys[i]]); + } + + if (i < keys.length - 1) + buffer.push(",", "\n"); + } + buffer.push("\n", totalIndent, "}"); + } + } + var buffer = []; + $format(buffer, initialIndent || "", {}, object); + return buffer.join(""); +} + +exports.fillTemplate = function(template, replacements) { + return template.replace(/%(.+?)%/g, function(str, m) { + return replacements[m] || ""; + }); +}; + +exports.hyphenate = function(str) { + return str.replace(/([A-Z])/g, "-$1").replace(/[_\s\-]+/g, "-").toLowerCase(); +}; + +exports.camelCase = function(str) { + return str.replace(/[\-_\s]+(.?)/g, function(x, y) {return y.toUpperCase()}); +}; + +exports.snakeCase = function(str) { + return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[_\s\-]+/g, "_").toLowerCase(); +}; + +exports.quoteString = function(str) { + return '"' + str.replace(/\\/, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\\n") + '"'; +}; + + +exports.restoreJSONComments = function(objStr) { + return objStr.replace(/^(\s*)comment: '(.*)'/gm, function(_, i, c) { + return i + "//" + c.replace(/\\n(\\t)*/g, "\n" + i + "//") + "\n" + i; + }).replace(/ \/\/ ERROR/g, '", // ERROR'); +}; + + +exports.download = function(href, callback) { + var options = url.parse(href); + var protocol = options.protocol === "https:" ? https : http; + console.log("connecting to " + options.host + " " + options.path); + var request = protocol.get(options, function(res) { + var data = ""; + res.setEncoding("utf-8"); + + res.on("data", function(chunk) { + data += chunk; + }); + + res.on("end", function(){ + callback(data); + }); + }); +}; + + +exports.AceRoot = __dirname + "/../"; +exports.AceLib = __dirname + "/../lib/"; + diff --git a/tool/mode_creator.html b/tool/mode_creator.html new file mode 100644 index 00000000..259ba64e --- /dev/null +++ b/tool/mode_creator.html @@ -0,0 +1,101 @@ + + + + + + + Ace Mode Creator + + + + + + + +
    + + + + + + + + + + \ No newline at end of file diff --git a/tool/mode_creator.js b/tool/mode_creator.js new file mode 100644 index 00000000..44aa67d0 --- /dev/null +++ b/tool/mode_creator.js @@ -0,0 +1,259 @@ +define(function(require, exports, module) { + +/** creates globals intentionally to make things easily accessible from console **/ + +require("ace/ext/language_tools"); +require("ace/config").setDefaultValues("editor", { + enableBasicAutocompletion: true, + enableSnippets: true +}); +var net = require("ace/lib/net"); +var Range = require("ace/range").Range; +var util = require("demo/kitchen-sink/util"); +var layout = require("demo/kitchen-sink/layout"); +var modelist = require("ace/ext/modelist"); +var doclist = require("demo/kitchen-sink/doclist"); +var TokenTooltip = require("demo/kitchen-sink/token_tooltip").TokenTooltip; + +var EditSession = require("ace/edit_session").EditSession; +var UndoManager = require("ace/undomanager").UndoManager; + +var DebugTokenizer = require("ace/tokenizer_dev").Tokenizer; +var Tokenizer = require("ace/tokenizer").Tokenizer; + +// createEditor +var splitEditor = window.splitEditor = util.createSplitEditor("editor"); + +var editor1 = window.editor1 = splitEditor.editor0; +var editor2 = window.editor2 = splitEditor.editor1; +new TokenTooltip(editor2); + +var timeout = null; +var schedule = function() { + if (timeout != null) { + clearTimeout(timeout); + } + timeout = setTimeout(run, 800); +}; + + +var setAutorunEnabled = function(val) { + if (val) + editor1.on('change', schedule); + else + editor1.removeEventListener('change', schedule); +}; + +util.bindCheckbox("autorunEl", setAutorunEnabled); + + +var docEl = document.getElementById("doc"); +util.fillDropdown(docEl, doclist.docs); +util.bindDropdown("doc", function(value) { + doclist.loadDoc(value, function(session) { + if (session) { + editor2.setSession(session); + updateSaveButtonState(null, editor2); + } + }); +}); + +var modeEl = document.getElementById("modeEl"); +util.fillDropdown(modeEl, modelist.modes); +var modeSessions = {}; + +util.bindDropdown(modeEl, function(value) { + if (modeSessions[value]) { + editor1.setSession(modeSessions[value]); + schedule(); + return; + } + var hp = "./lib/ace/mode/" + value + "_highlight_rules.js"; + net.get(hp, function(text) { + var session = new EditSession(text); + session.setUndoManager(new UndoManager()); + + modeSessions[value] = session; + session.setMode("ace/mode/javascript", function() { + if (session.getLine(0).match(/^\s*\//)) + session.toggleFoldWidget(0); // fold licence comment + }); + + editor1.setSession(modeSessions[value]); + updateSaveButtonState(null, editor1); + schedule(); + }); +}); + +document.getElementById("syncToMode").onclick = function() { + docEl.value = modelist.modesByName[modeEl.value].desc; + docEl.onchange(); + run(); +}; + +editor1.saveButton = document.getElementById("saveButton1"); +editor2.saveButton = document.getElementById("saveButton2"); +editor1.saveButton.editor = editor1; +editor2.saveButton.editor = editor2; + +editor1.saveButton.onclick = function() { + doclist.saveDoc({ + path: "./lib/ace/mode/" + modeEl.value + "_highlight_rules.js", + session: editor1.session + }, function(err) { + handleSaveResult(err, editor1); + }); +}; +editor1.commands.bindKey({ + win: "Ctrl-S", mac: "Cmd-s" +}, editor1.saveButton.onclick); +editor2.saveButton.onclick = function() { + doclist.saveDoc(docEl.value, function(err) { + handleSaveResult(err, editor2); + }); +}; +editor2.commands.bindKey({ + win: "Ctrl-S", mac: "Cmd-s" +}, editor2.saveButton.onclick); +function updateSaveButtonState(e, editor){ + editor.saveButton.disabled = editor.session.getUndoManager().isClean(); +} +editor1.on("input", updateSaveButtonState); +editor2.on("input", updateSaveButtonState); + +function handleSaveResult(err, editor) { + if (err) { + return log( + "Write access to this file is disabled.\n"+ + "To enable saving your changes to disk, clone the Ace repository\n"+ + "and run the included web server with the --allow-save option\n"+ + "`node static.js --allow-save` or `static.py --puttable=*`" + ); + } + editor.session.getUndoManager().markClean(); + updateSaveButtonState(null, editor); +} + +document.getElementById("perfTest").onclick = function() { + var lines = editor2.session.doc.getAllLines(); + if (!lines.length) + return; + while (lines.length < 1000) { + lines = lines.concat(lines); + } + + var tk = new Tokenizer(currentRules); + var testPerf = function(lines, tk) { + var state = "start"; + for (var i=0, l = lines.length; i + + + + + + Ace Profile util + + + + +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    + + + + +
    + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + + + +
    + +
    +
    + +
    +
    +
    +
    + + + + + + + + + diff --git a/tool/regexp_tokenizer.js b/tool/regexp_tokenizer.js new file mode 100644 index 00000000..ef302e9a --- /dev/null +++ b/tool/regexp_tokenizer.js @@ -0,0 +1,114 @@ +/***** regexp tokenizer */ +require("amd-loader"); +var lib = require("./lib"); + +var Tokenizer = require(lib.AceLib+ "ace/tokenizer").Tokenizer; +var Tokenizer = require(lib.AceLib + "ace/tokenizer_dev").Tokenizer; // todo can't use tokenizer because of max token count +var TextHighlightRules = require(lib.AceLib + "ace/mode/text_highlight_rules").TextHighlightRules; + +var r = new TextHighlightRules() +r.$rules = { + start: [ + {token: "anchor", regex: /[\^\$]|\\[bBAZzG]/, merge:false}, + {token: "backRef", regex: /\\([1-9]|k(<\w+\b[+-]?\d>|'\w+\b[+-]?\d'))/, merge:false}, + {include: "charTypes", merge:false}, + {token: "charclass", regex: /\[\^?/, push: "charclass", merge:false}, + {token: "alternation", regex: /\|/, merge:false}, + {include: "quantifiers", merge:false}, + {include: "groups", merge:false}, + {include: "xGroup", merge:true} + ], + charTypes: [ + {token: "char", regex: /\\([tvnrbfae]|[0-8]{1,3}|x[\dA-Fa-f]{2}|x7[\dA-Fa-f]{7})/, merge:false}, // todo \cx + {token: "charType", regex: /\.|\\[wWsSdDhH]/, merge:false}, + {token: "charProperty", regex: /\\p{\w+}/, merge:false}, + {token: "char", regex: /\\./, merge:false}, + ], + quantifiers: [ + {token: "quantifier", regex: /([?*+]|{\d+\b,?\d*}|{,\d+})[?+]?/, merge:false} + ], + charclass: [ + {include: "charTypes", merge:false}, + {token: "charclass.start", regex: /\[\^?/, push: "charclass", merge:false}, + {token: "charclass.end", regex: /\]/, next: "pop", merge:false} + ], + groups: [ + {token: "group", regex: /[(]([?](#|[imx\-]+:?|:|=|!|<=||<\w+>|'\w+'|))?|[)]/, + onMatch: function(val, state, stack) { + if (!stack.groupNumber) + stack.groupNumber = 1; + + var isStart = val !== ")"; + var t = {depth:0,type: isStart ? "group.start" : "group.end", value: val}; + t.groupType = val[2]; + + if (val == "(") { + t.number = stack.groupNumber++; + t.isGroup = true + } else if (t.groupType == "'" || (t.groupType == "<" && val.slice(-1) == ">")) { + t.name = val.slice(2, -1) + t.isGroup = true + } else if (t.groupType == ":") { + t.isGroup = true + } + + if (t.groupType && val.indexOf("x") != -1) { + var minus = val.indexOf("-"); + if (minus == -1 || minus > val.indexOf("x")) + stack.xGroup = t; + else + stack.xGroup = null; + } else if (!isStart && stack.xGroup && stack.xGroup == stack[0]) { + if (stack.xGroup.value.slice(-1) == ":") + stack.xGroup = null; + } + + if (isStart) { + if (stack.groupDepth) { + stack[0].hasChildren = true + } + stack.groupDepth = (stack.groupDepth||0)+1; + stack.unshift(t) + } else { + stack.groupDepth --; + t.start = stack.shift(t) + t.start.end = t + } + return [t] + }, merge:false + } + ], + xGroup: [ + {token: "text", regex:/\s+/, onMatch: function(val, state, stack) { + return stack.xGroup ? [] : "text" + }, merge: true}, + {token: "text", regex: /#/, onMatch: function(val, state, stack) { + if (stack.xGroup) { + this.next = "comment"; + stack.unshift(state); + return []; + } + this.next = ""; + return "text"; + }, merge: true} + ], + comment: [{ + regex: "[^\n\r]*|^", token: "", onMatch: function(val, state, stack) { + this.next = stack.shift(); + return []; + } + }] +} +r.normalizeRules() +var tmReTokenizer = new Tokenizer(r.getRules()); + +function tokenize(str) { + return tmReTokenizer.getLineTokens(str).tokens; +} + +function toStr(tokens) { return tokens.map(function(x){return x.value}).join("")} + + +exports.tokenize = tokenize; +exports.toStr = toStr; +exports.tmReTokenizer = tmReTokenizer; \ No newline at end of file diff --git a/tool/regexp_tokenizer_test.js b/tool/regexp_tokenizer_test.js new file mode 100644 index 00000000..aa09ff12 --- /dev/null +++ b/tool/regexp_tokenizer_test.js @@ -0,0 +1,30 @@ +require("amd-loader"); +var assert = require("assert"); + +var tk = require("./regexp_tokenizer"); +var tokenize = tk.tokenize; +var toStr = tk.toStr; + +var logTokens = function(tokens) { + tokens.forEach(function(x) { + delete x.end + delete x.start + }) + console.log(tokens) +} + +assert.equal(toStr( + tokenize("(?x)c + +\n\ + # comment\n\ + (?-x) # (?x: 1 \n\ + (2) [ ] # a \n\ + 3 4) c#" + )), + "(?x)c++(?-x) # (?x:1(2)[ ]34) c#" + ) +assert.equal(toStr( + tokenize("(?x)\n\ + u # comment\n\ + ")), + "(?x)u" + ) diff --git a/tool/release.sh b/tool/release.sh new file mode 100644 index 00000000..52376914 --- /dev/null +++ b/tool/release.sh @@ -0,0 +1,79 @@ +pause() { + while true; do + read -p "$1 " yn + case $yn in + [Yy]* ) break;; + [Nn]* ) exit;; + * ) echo "Please answer yes or no.";; + esac + done +} + + + +cd `dirname $0`/.. +SOURCE=`pwd` + +CUR_VERSION=`node -e 'console.log(require("./package.json").version)'` +git --no-pager log --first-parent --oneline v$CUR_VERSION..master +echo "current version is $CUR_VERSION" +read -p "enter version number for the build " VERSION_NUM + +node -e " + var fs = require('fs'); + var version = '$VERSION_NUM'; + function replaceVersion(str) { + return str.replace(/(['\"]?version['\"]?\s*[:=]\s*['\"])[\\d.\\w\\-]+(['\"])/, function(_, m1, m2) { + return m1 + version + m2; + }); + } + function update(path, replace) { + var pkg = fs.readFileSync(path, 'utf8'); + pkg = (replace || replaceVersion)(pkg); + fs.writeFileSync(path, pkg, 'utf8'); + } + update('package.json'); + update('build/package.json'); + update('./lib/ace/ext/menu_tools/generate_settings_menu.js'); + update('ChangeLog.txt', function(str) { + var date='"`date +%Y.%m.%d`"'; + return date + ' Version ' + version + '\n' + str.replace(/^\d+.*/, '').replace(/^\n/, ''); + }); +" + +pause "versions updated. do you want to start build script? [y/n]" + +node Makefile.dryice.js full +cd build +git add . +git commit --all -m "package `date +%d.%m.%y`" + + +echo "build task completed." +pause "continue creating the tag for v$VERSION_NUM [y/n]" +if [[ ${VERSION_NUM} != *"-"* ]]; then + git tag "v"$VERSION_NUM +fi + +pause "continue pushing to github? [y/n]" + +git push --progress --tags "origin" HEAD:gh-pages HEAD:master + +echo "build repository updated" + +pause "continue update ace repo? [y/n]" +cd .. + + +echo "new commit added" +pause "continue creating the tag for v$VERSION_NUM [y/n]" +if [[ ${VERSION_NUM} != *"-"* ]]; then + git tag "v"$VERSION_NUM +fi + +pause "continue pushing to github? [y/n]" + +git push --progress --tags "origin" HEAD:gh-pages HEAD:master +echo "All done!" +pause "May I go now? [y/n]" + diff --git a/tool/templates/dummy.JSON-tmLanguage b/tool/templates/dummy.JSON-tmLanguage new file mode 100644 index 00000000..cb58b29b --- /dev/null +++ b/tool/templates/dummy.JSON-tmLanguage @@ -0,0 +1,45 @@ +// [PackageDev] target_format: plist, ext: tmLanguage +{ + "name": "Dummy", + "scopeName": "source.dummy", + "fileTypes": ["dummy"], + "patterns": [ + { + "include": "#string" + }, { + "include": "#escapes" + } + ], + "repository": { + "escapes": { + "patterns": [ + { + "match": "\\\\[nrt\\\\\\$\\\"']", + "name": "keyword.dummy" + } + ] + }, + "string": { + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.dummy" + } + }, + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.dummy" + } + }, + "contentName": "meta.string-contents.quoted.double.dummy", + "name": "string.quoted.double.dummy", + "end": "'''", + "begin": "'''", + "patterns": [ + { + "include": "#escapes" + } + ], + "comment": "This is a comment" + } + } +} \ No newline at end of file diff --git a/tool/templates/highlight_rules.js b/tool/templates/highlight_rules.js new file mode 100644 index 00000000..db8f5630 --- /dev/null +++ b/tool/templates/highlight_rules.js @@ -0,0 +1,58 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/* This file was autogenerated from %name% (uuid: %uuid%) */ +/**************************************************************************************** + * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. * + * fileTypes * + ****************************************************************************************/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var %language%HighlightRules = function() { + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + + this.$rules = %languageTokens% + + this.normalizeRules(); +}; + +%language%HighlightRules.metaData = %metaData% + + +oop.inherits(%language%HighlightRules, TextHighlightRules); + +exports.%language%HighlightRules = %language%HighlightRules; +}); \ No newline at end of file diff --git a/tool/templates/mode.js b/tool/templates/mode.js new file mode 100644 index 00000000..1cdabf15 --- /dev/null +++ b/tool/templates/mode.js @@ -0,0 +1,58 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/* + THIS FILE WAS AUTOGENERATED BY mode.tmpl.js +*/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var %language%HighlightRules = require("./%languageHighlightFilename%_highlight_rules").%language%HighlightRules; +// TODO: pick appropriate fold mode +var FoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = %language%HighlightRules; + this.foldingRules = new FoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + // this.lineCommentStart = "%lineCommentStart%"; + // this.blockComment = {start: "%blockCommentStart%", end: "%blockCommentEnd%"}; + // Extra logic goes here. + this.$id = "ace/mode/%languageHighlightFilename%" +}).call(Mode.prototype); + +exports.Mode = Mode; +}); \ No newline at end of file diff --git a/tool/templates/snippets.js b/tool/templates/snippets.js new file mode 100644 index 00000000..6752d1db --- /dev/null +++ b/tool/templates/snippets.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./%modeName%.snippets"); +exports.scope = "%modeName%"; + +}); diff --git a/tool/templates/theme.css b/tool/templates/theme.css new file mode 100644 index 00000000..8515d0c3 --- /dev/null +++ b/tool/templates/theme.css @@ -0,0 +1,60 @@ +/* THIS THEME WAS AUTOGENERATED BY Theme.tmpl.css (UUID: %uuid%) */ + +.%cssClass% .ace_gutter { + background: %gutterBg%; + color: %gutterFg%; +} + +.%cssClass% .ace_print-margin { + width: 1px; + background: %printMargin%; +} + +.%cssClass% { + background-color: %background%; + color: %foreground%; +} + +.%cssClass% .ace_cursor { + color: %cursor%; +} + +.%cssClass% .ace_marker-layer .ace_selection { + background: %selection%; +} + +.%cssClass%.ace_multiselect .ace_selection.ace_start { + box-shadow: 0 0 3px 0px %background%; + border-radius: 2px; +} + +.%cssClass% .ace_marker-layer .ace_step { + background: %step%; +} + +.%cssClass% .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid %bracket%; +} + +.%cssClass% .ace_marker-layer .ace_active-line { + background: %active_line%; +} + +.%cssClass% .ace_gutter-active-line { + background-color: %active_line%; +} + +.%cssClass% .ace_marker-layer .ace_selected-word { + %selected_word_highlight% +} + +.%cssClass% .ace_fold { + background-color: %fold%; + border-color: %foreground%; +} + + + + + diff --git a/tool/templates/theme.js b/tool/templates/theme.js new file mode 100644 index 00000000..8e99f710 --- /dev/null +++ b/tool/templates/theme.js @@ -0,0 +1,39 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { + +exports.isDark = %isDark%; +exports.cssClass = "%cssClass%"; +exports.cssText = %css%; + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); diff --git a/tool/theme.tmpl.js b/tool/theme.tmpl.js deleted file mode 100644 index 3c965dac..00000000 --- a/tool/theme.tmpl.js +++ /dev/null @@ -1,48 +0,0 @@ -/* ***** 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 - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Ajax.org Code Editor (ACE). - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Fabian Jakobs - * - * 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 - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -define(function(require, exports, module) { - - var dom = require("pilot/dom"); - - var cssText = %css%; - - // import CSS once - dom.importCssString(cssText); - - exports.cssClass = "%cssClass%"; -}); \ No newline at end of file diff --git a/tool/tmlanguage.js b/tool/tmlanguage.js new file mode 100644 index 00000000..b5d8b851 --- /dev/null +++ b/tool/tmlanguage.js @@ -0,0 +1,697 @@ +require("amd-loader"); + +var fs = require("fs"); +var util = require("util"); +var lib = require("./lib"); +var pathlib = require("path"); +var parseLanguage = lib.parsePlist; + +var tk = require("./regexp_tokenizer"); +var tokenize = tk.tokenize; +var toStr = tk.toStr; + +function last(array) {return array[array.length - 1]} + +function convertHexEscape(tokens) { + var inChClass = false; + tokens.forEach(function(t) { + if (t.type == "charclass") + inChClass = true; + else if (t.type == "charclass.end") + inChClass = false; + else if (t.type == "charType"){ + if (t.value == "\\h") { + t.type = "text"; + t.value = inChClass ? "\\da-fA-F" : "[\\da-fA-F]"; + } + else if (t.value == "\\H") { + if (inChClass) { + console.warn("can't convert \\H in charclass"); + return; + } + t.type = "text"; + t.value = "[^\\da-fA-F]"; + } + } + }); + return tokens; +} + +function convertNewLinesTo$(str) { + var tokens = tokenize(str); + for (var i = 0; i < tokens.length; i++) { + var t= tokens[i]; + if (t.type == "char" && t.value == "\\n") { + var p = tokens[i + 1] || {}; + if (p.type != "quantifier") { + t.value = "$"; + while (p.value == "\\n" || p.type == "quantifier") { + p.value = ""; + p = tokens[++i + 1] || {}; + } + } else if (/\?|\*|{,|{0,/.test(p.value)) { + t.value = p.value = ""; + } else + p.value = ""; + } + } + return toStr(tokens).replace(/[$]+/g, "$"); +} + +function convertCharacterTypes(str) { + var tokens = tokenize(str); + tokens = convertHexEscape(tokens); + + var warn = false; + tokens.forEach(function(t){ + if (t.type == "quantifier") { + var val = t.value; + if (val.slice(-1) == "+" && val.length > 1) { + t.value = val.slice(0, -1); + warn = val; + } + } + }); + if (warn) + console.log("converted possesive quantifier " + warn + " to *"); + return toStr(tokens); +} + +function removeInlineFlags(str, rule) { + var tokens = tokenize(str); + var caseInsensitive = false; + tokens.forEach(function(t, i) { + if (t.type == "group.start" && /[imsx]/.test(t.value)) { + if (/i/.test(t.value)) + caseInsensitive = true; + t.value = t.value.replace(/[imsx\-]/g, ""); + var next = tokens[i + 1]; + if (next && next.type == "group.end") { + t.value = next.value = ""; + } + } + }); + if (caseInsensitive && rule) + rule.caseInsensitive = true; + return toStr(tokens); +} + +function convertToNonCapturingGroups(str) { + var tokens = tokenize(str); + tokens.forEach(function(t, i) { + if (t.type == "group.start" && t.value == "(") + t.value += "?:"; + }); + return toStr(tokens); +} + +function simplifyNonCapturingGroups(str) { + var tokens = tokenize(str); + var t = tokens[0] || {}; + if (t.type == "group.start" && t.value == "(?:" + && t.end == last(tokens)) { + t.value = t.end.value = ""; + } + var i = 0; + function iter(f) { + for (i = 0; i < tokens.length; i++) + f(tokens[i]); + } + function iterGroup(end, f) { + for (var i1 = i + 1; i1 < tokens.length; i1++) { + var t = tokens[i1]; + if (t == end) + break; + var index = f && f(t); + if (index > i1) + i1 = index; + } + return i1; + } + + iter(function (t) { + if (t.type == "group.start" && t.value == "(?:") { + if (!t.end) + return console.error("malformed regex: " + str); + + var canRemove = true; + var next = tokens[tokens.indexOf(t.end, i) + 1]; + if (next && next.type == "quantifier") + return; + iterGroup(t.end, function(t) { + if (t.type == "alternation") + canRemove = false; + else if (t.type == "group.start" && t.end) + return iterGroup(t.end); + }); + if (canRemove) + t.value = t.end.value = ""; + } + }); + + return toStr(tokens); +} + +function removeLookBehinds(str) { + var tokens = tokenize(str); + var toRemove = null; + tokens.forEach(function(t, i) { + if (!toRemove && t.type == "group.start" && / i) + i = i1; + } + function lst(t) {return t[t.length - 1]} + function iter(f) { + for (i = 0; i < tokens.length; i++) + f(tokens[i]); + } + function iterGroup(end, f) { + for (var i1 = i + 1; i1 < tokens.length; i1++) { + var t = tokens[i1]; + if (t == end) + break; + f(t); + } + } + function peek() { return tokens[i + 1] || {}} + + // groupify + iter(function(t){ + if (t.type == "group.start") { + tryClose(); + isStart = true; + if (!t.hasChildren || t.isSpecial) + skip(t); + } else if (t.type == "group.end") { + isStart = true; + tryClose(); + } else if (t.type == "alternation") { + isStart = true; + tryClose(); + } else if (t.type != "anchor" && t.type != "quantifier"){ + tryOpen(); + } + }); + tryClose(); + + // remove redundand groups + var names = [defaultName]; + iter(function(t){ + if (t.type == "group.start" && !t.isSpecial) { + var captureName = captures[t.number]; + + if (!t.hasChildren) { + t.tokenName = captureName || lst(names); + skip(t); + } else { + var hasCapture = false; + iterGroup(t.end, function(t1) { + if (t1.type == "group.start" && captures[t1.number]) + hasCapture = true; + }); + if (hasCapture) { + t.value = "(?:"; + if (captureName) { + names.push(captureName); + t.isTokenGroup = true; + } + } else { + t.tokenName = captureName || lst(names); + iterGroup(t.end, function(t1) { + if (t1.value == "(") + t1.value = "(?:"; + }); + } + } + } else if (t.type == "group.end") { + if (t.start.isTokenGroup) + names.pop(); + } + }); + + // wrap capturing groups with quantifier + iter(function(t){ + if (t.type == "group.end" && t.start.value == "(" && peek().type == "quantifier") { + peek().value += ")"; + t.start.value += "(?:"; + } + }); + + names = []; + tokens.forEach(function(t) { + if (t.value == "(" || t.value == "((?:" ) + t.tokenName && names.push(t.tokenName); + }); + return { + names: names, + regex: toStr(tokens) + }; +} + +/***** converter */ + +function logDebug(string, obj) { + console.log(string, obj); +} + + +// tmLanguage processor + +// for tracking token states +var states = {start: []}; + +function processRules(rules){ + if (rules.patterns) + states.start = processPatterns(rules.patterns); + if (rules.repository) + processRepository(rules.repository); + return states; +} +function processRepository(r) { + for (var key in r) { + var p = r[key]; + if (p.begin) + var stateObj = [processPattern(r[key])]; + else if (p.patterns && !p.repository) + var stateObj = processPatterns(p.patterns); + else + var stateObj = [processPattern(r[key])]; + + if (stateObj) + states["#" + key] = stateObj; + } +} +function processPatterns(pl) { + return pl.map(processPattern); +} +function processPattern(p) { + if (p.end == "(?!\\G)" && p.patterns && p.patterns.length == 1) { + var rule = processPattern(p.patterns[0]); + } + else if (p.begin != null && p.end != null) { + convertBeginEndBackrefs(p); + + var rule = simpleRule(p.begin, p.name, p.beginCaptures || p.captures); + + var next = processPatterns(p.patterns || []); + var endRule = simpleRule(p.end, p.name, p.endCaptures || p.captures); + endRule.next = "pop"; + if (p.applyEndPatternLast) + next.push(endRule); + else + next.unshift(endRule); + + if (p.name || p.contentName) + next.push({defaultToken: p.name || p.contentName}); + + rule.push = next; + + rule = removeIncludeSelf(rule); + } + else if (p.match) { + var rule = simpleRule(p.match, p.name, p.captures); + } + else if (p.include) { + var rule = {include: p.include}; + } + else { + var rule = {todo: p}; + } + + if (p.comment) + rule.comment = (rule.comment || "") + p.comment; + + if (p.repository) + processRepository(p.repository); + return rule; +} +function simpleRule(regex, name, captures) { + name = name || "text"; + var rule = {token: "", regex: ""}; + + var origRegex = regex; + regex = transformRegExp(origRegex, rule); + if (captures) { + var tokenArray = []; + Object.keys(captures).forEach(function(x){ + tokenArray[x] = captures[x] && captures[x].name; + }); + + if (tokenArray.length == 1) { + name = tokenArray[0]; + } else { + var fixed = fixGroups(tokenArray, name, regex); + name = fixed.names; + regex = fixed.regex; + if (name.length == 1) + name = name[0]; + } + } + + if (typeof name == "string") + regex = convertToNonCapturingGroups(regex); + + regex = simplifyNonCapturingGroups(regex); + + try {new RegExp(regex);} catch(e) { + rule.TODO = "FIXME: regexp doesn't have js equivalent"; + rule.originalRegex = origRegex; + + // lookbehinds are mostly used to force ordering + // regex = removeLookBehinds(regex); + } + rule.token = name; + rule.regex = regex; + return rule; +} + +function removeIncludeSelf(rule) { + if (!rule.push) + return rule; + var hasSelfInclude = false; + var escapeRule = null; + var complexSelfInclude = false; + rule.push.forEach(function(sub) { + if (sub.include == "$self") { + hasSelfInclude = true; + } else if (sub.defaultToken) { + return; + } else if (sub.next == "pop") { + escapeRule = sub; + } else + complexSelfInclude = true; + }); + + if (hasSelfInclude) { + console.warn("can't convert include $self"); + return {todo: rule}; + + if (complexSelfInclude) { + console.warn("can't convert include $self"); + rule.toDo = "include $self not fully supported"; + return rule; + } + console.warn("include $self not fully supported"); + delete rule.push; + delete escapeRule.next; + rule.includeSelf = true; + escapeRule.includeSelf = true; + return [rule, escapeRule]; + } + return rule; +} + +// regex transformation + +function removeXFlag(str) { + var tokens = tokenize(str); + return toStr(tokens); +} + +function transformRegExp(str, rule) { + str = convertNewLinesTo$(str); + + str = removeInlineFlags(str, rule); + + str = str.replace(/(\\[xu]){([a-fA-F\d]+)}/g, '$1$2'); + + str = convertCharacterTypes(str, rule); + + checkForNamedCaptures(str); + + return str; +} + +// +function extractPatterns(tmRules) { + return processRules(tmRules); +} + + +function detectLoops(states) { + var data = {}; + var keys = Object.keys(states); + var flattenedStates = {}; + function addRef(item, name) { + if (item.refs.indexOf(name) == -1) + item.refs.push(name); + } + function anonStateId(name, next) { + var i = 0, old = name; + while (flattenedStates[name] || states[name]) { + name = old + "_" + i++; + } + // console.log(old, name) + return name; + } + function addState(key, rules) { + if (rules && !flattenedStates[key]) + flattenedStates[key] = rules; + return rules || flattenedStates[key]; + } + + + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var state = addState(key, states[key]); + + var item = data[key] || (data[key] = {/* name: key, */ refs: []}); + state.forEach(function(rule) { + var next = rule.push || rule.next; + if (next == "pop") { + // nothing + } else if (typeof next == "string") { + addRef(item, next); + } else if (next) { + var anonId = anonStateId(key, next); + addState(anonId, next); + if (rule.push) + addRef(item, anonId); + keys.push(anonId); + } else if (rule.include) { + addRef(item, rule.include); + } + }); + } + + + var cycles = []; + function addPath(start, path) { + var node = data[start]; + path.push(start); + if (!node || !node.refs) + console.log(start); + var i = path.indexOf(start); + if (i > -1 && i != path.length - 1 || start == "$self" || start == "$base") { + if (i != -1) + path = path.slice(i); + for (var j = 0; j < cycles.length; j++) { + if (cycles[j] + "" == path + "") + return; + } + return cycles.push(path); + } + + if (!node || !node.refs || !node.refs.length || path.length>30) + return; + node.refs.forEach(function(x) { + addPath(x, path.concat()); + }); + } + addPath("start", []); + + console.error(cycles.join("\n")); +} + + +function test(fileName) { + console.log("testing highlighter"); + try { + var module = require(fileName); + var Mode = module[Object.keys(module)[0]]; + var mode = new Mode(); + mode.getTokenizer().getLineTokens("hello world"); + } catch(e) { + console.log(e); + } +} + +function guessComment(patterns) { + var comment = {}; + for (var i in patterns) { + var state = patterns[i]; + state.forEach(function(r) { + if (typeof r.token == "string") { + if (/\bcomment\b/.test(r.token)) { + comment.line = r.regex; + } + } + }); + } + + return comment; +} + +// cli stuff +var modeTemplate = fs.readFileSync(__dirname + "/templates/mode.js", "utf8"); +var modeHighlightTemplate = fs.readFileSync(__dirname + "/templates/highlight_rules.js", "utf8"); + +function fetchAndConvert(name) { + console.log("Converting " + name); + if (/^http/.test(name)) { + if (/:\/\/github.com/.test(name)) { + name = name.replace(/\/blob\//, "/").replace("github.com", "raw.github.com"); + } + return lib.download(name, function(data) { + convertTmLanguage(name, data); + }); + } + var path = /^(\/|\w:)/.test(name) ? name : process.cwd() + "/" + name; + var langStr = fs.readFileSync(path, "utf8"); + convertTmLanguage(name, langStr); +} + + +function convertTmLanguage(name, langStr) { + parseLanguage(langStr, function(language) { + var highlighterFilename = lib.snakeCase(language.name).replace(/[^\w]/g, ""); + var languageNameSanitized = lib.camelCase(language.name).replace(/[^\w]/g, ""); + + require("./add_mode")(languageNameSanitized, (language.fileTypes || []).join("|")); + + var highlighterFile = pathlib.normalize(lib.AceLib + "ace/mode/" + highlighterFilename + "_highlight_rules.js"); + var modeFile = pathlib.normalize(lib.AceLib + "ace/mode/" + highlighterFilename + ".js"); + + if (devMode) { + console.log(util.inspect(language.patterns, false, 4)); + console.log(util.inspect(language.repository, false, 4)); + } + + var patterns = extractPatterns(language); + detectLoops(patterns); + + // var uuid = language.uuid + delete language.uuid; + delete language.patterns; + delete language.repository; + + var comment = guessComment(patterns); + var languageMode = lib.fillTemplate(modeTemplate, { + language: languageNameSanitized, + languageHighlightFilename: highlighterFilename, + lineCommentStart: JSON.stringify(comment.line || "//"), + blockCommentStart: JSON.stringify(comment.start || "/*"), + blockCommentEnd: JSON.stringify(comment.end || "*/") + }); + + var languageHighlightRules = lib.fillTemplate(modeHighlightTemplate, { + language: languageNameSanitized, + languageTokens: lib.formatJS(patterns, " ").trim(), + uuid: language.uuid, + name: name, + metaData: lib.formatJS(language, "").trim() + }); + + if (devMode) { + console.log(languageMode); + console.log(languageHighlightRules); + console.log("Not writing, 'cause we're in dev mode, baby."); + } + else { + fs.writeFileSync(highlighterFile, languageHighlightRules); + fs.writeFileSync(modeFile, languageMode); + console.log("created file " + highlighterFile); + test(modeFile); + } + }); +} + +if (!module.parent) { + var args = process.argv.splice(2); + var devMode = args[0] == "--dev"; + if (devMode) + args.shift(); + if (args.length < 1) { + console.error("Usage: node tmlanguage.js [--dev] path/or/url/to/syntax.file ..."); + process.exit(1); + } + args.forEach(fetchAndConvert); +} else { + exports.fetchAndConvert = fetchAndConvert; +} diff --git a/tool/tmsnippets.js b/tool/tmsnippets.js new file mode 100644 index 00000000..febc7946 --- /dev/null +++ b/tool/tmsnippets.js @@ -0,0 +1,82 @@ +var fs = require('fs') +var plist = require('plist') + +var snippets = []; +var path = process.argv[2] || process.cwd(); +function readSnippet(path, name) { + if (name) + path += name + console.log(name) + if (!/\.(tmSnippet|sublime-snippet|plist)$/i.test(path)) + return + console.log(name) + var plistString = fs.readFileSync(path, "utf8"); + plist.parseString(plistString, function(_, plist){ + snippets.push(plist) + }) +} + +// read +function readDir(path) { + if (fs.statSync(path).isDirectory()) { + path += "/" + fs.readdirSync(path).forEach(function(name) { + if (/snippets/i.test(name)) + readSnippetsInDir(path + name) + else + readDir(path + name) + }) + } +} +function readSnippetsInDir(path) { + if (fs.statSync(path).isDirectory()) { + path += "/" + snippets.push(path) + fs.readdirSync(path).forEach(function(name) { + readSnippet(path, name) + }) + } else { + readSnippet(path) + } +} +readDir(path) +// transform +snippets = snippets.map(function(s) { + if (s.length == 1) + s = s[0] + if (s.scope) + s.scope = s.scope.replace(/source\./g, "") + delete s.uuid + return s +}) + +// stringify +var indent = "" +var text = JSON.stringify(snippets, null, 1) + // .replace(/(\n\s*)"(\w+)"\:/g, "$1$2:") + .replace(/(\n\s*)\},\n\s*{/g, "$1}, {") + .replace(/\[\n\s*\{\n/g, "[{\n").replace(/(\n\s*)\}\n\s*\]/g, "$1}]") + .replace(/\[\n\s*[^\[\{\}\]]{0,100}\]/g, function(x){return x.replace(/\n\s*/g, " ")}) + .replace(/\:\s*\{\n\s*(.*)\n\s*\}/g, ": {$1}") + .split(/\n\s*/).map(function(x){ + if (x[0] == "}" || x[0] == "]") + indent = indent.substr(1) + + if (x.slice(-1) == "{" || x.slice(-1) == "[") { + indent += "\t" + return indent.substr(1) + x + } + return indent +x + }).join("\n") + .replace(/\\[\\tnr]/g, function(a){ + if (a[1] == "\\") + return a + else if (a[1] == "t") + return "\t" + else + return "\\n"+"\\" + "\n" + }) + +fs.writeFileSync(path += "/./ace.snippets.js", text) + +console.log(path) \ No newline at end of file diff --git a/tool/tmtheme.js b/tool/tmtheme.js old mode 100644 new mode 100755 index 806d4b98..c784eec7 --- a/tool/tmtheme.js +++ b/tool/tmtheme.js @@ -1,131 +1,188 @@ -var xml = require("../support/node-o3-xml/lib/o3-xml"); var fs = require("fs"); +var path = require("path"); +var util = require("util"); +var cssParse = require("css-parse"); +var cssStringify = require("css-stringify"); -function plistToJson(el) { - if (el.tagName != "plist") - throw new Error("not a plist!"); - - return $plistParse(el.selectSingleNode("dict")); -}; - -function $plistParse(el) { - if (el.tagName == "dict") { - var dict = {}; - var key; - var childNodes = el.childNodes; - for (var i=0, l=childNodes.length; i.css rules, + // (because some exist, for collab1 and ace_indentation_guide + try { + var outThemeCss = fs.readFileSync(outputDirectory + "/" + name + ".css"); + var oldRules = cssParse(outThemeCss).stylesheet.rules; + var newRules = cssParse(css).stylesheet.rules; + + + for (var i = 0; i < newRules.length; i++) { + var newSelectors = newRules[i].selectors; + + for (var j = 0; j < oldRules.length; j++) { + var oldSelectors = oldRules[j].selectors; + newSelectors = newSelectors.filter(function(s) { + return oldSelectors.indexOf(s) == -1; + }) + if (!newSelectors.length) + break; + } + if (newSelectors.length) { + newRules[i].selectors = newSelectors; + console.log("Adding NEW rule: ", newRules[i]) + oldRules.splice(i, 0, newRules[i]); + } + } + + oldRules = normalizeStylesheet(oldRules); + + css = cssStringify({stylesheet: {rules: oldRules}}, { compress: false }); + } catch(e) { + console.log("Creating new file: " + name + ".css") + css = cssStringify(cssParse(css), { compress: false }); + } + + var js = fillTemplate(jsTemplate, { + name: name, + css: 'require("../requirejs/text!./' + name + '.css")', // quoteString(css), // + cssClass: "ace-" + hyphenate(name), + isDark: styles.isDark + }); + + fs.writeFileSync(outputDirectory + "/" + name + ".js", js); + fs.writeFileSync(outputDirectory + "/" + name + ".css", css); + }) } + +if (process.argv.length > 1) { + var args = process.argv.splice(2); + if (args.length < 3) { + console.error("Usage: node tmtheme.js [theme_name, path/to/theme.tmTheme path/to/output/directory]"); + process.exit(1); + } + var name = args[0]; + var themePath = args[1]; + var outputDirectory = args[2]; + convertTheme(name, themePath, outputDirectory); +} else { + for (var name in themes) { + convertBuiltinTheme(name); + } +} + +var sortedUnsupportedScopes = {}; +for (var u in unsupportedScopes) { + var value = unsupportedScopes[u]; + if (sortedUnsupportedScopes[value] === undefined) { + sortedUnsupportedScopes[value] = []; + } + sortedUnsupportedScopes[value].push(u); +} + +console.log("I found these unsupported scopes:"); +console.log(sortedUnsupportedScopes); +console.log("It's safe to ignore these, but they may affect your syntax highlighting if your mode depends on any of these rules."); +console.log("Refer to the docs on ace.ajax.org for information on how to add a scope to the CSS generator."); + + +/*** TODO: generate images for indent guides in node + +var indentGuideColor = "#2D2D2D" +var canvas = document.createElement("canvas") +canvas.width = 1; canvas.height = 2; +var ctx = canvas.getContext("2d") +imageData = ctx.getImageData(0,0,1,2) + +function getColor(color) { + ctx.fillStyle = color; + ctx.fillRect(0,0,1,2); + return Array.slice(ctx.getImageData(0,0,1,2).data).slice(0,4) +} +bgColor = getComputedStyle(ace.renderer.scroller).backgroundColor +var a = [].concat(getColor(bgColor), getColor(indentGuideColor)); +a.forEach(function(val,i){imageData.data[i] = val}) + +ctx.putImageData(imageData,0,0) +image = canvas.toDataURL("png") + +var rule = "."+ace.renderer.$theme +" .ace_indent-guide {\n\ + background: url(" + image +") right repeat-y;\n\ +}" +console.log(rule) +require("ace/lib/dom").importCssString(rule) + +*/ diff --git a/tool/tmthemes/Chrome DevTools.tmTheme b/tool/tmthemes/Chrome DevTools.tmTheme new file mode 100644 index 00000000..8f14e4fa --- /dev/null +++ b/tool/tmthemes/Chrome DevTools.tmTheme @@ -0,0 +1,294 @@ + + + + + author + Austin Cummings + name + Chrome DevTools + settings + + + settings + + background + #FFFFFF + caret + #000000 + foreground + #000000 + invisibles + #B3B3B3F4 + lineHighlight + #0000001A + selection + #BAD6FD + + + + name + String + scope + string + settings + + foreground + #C41A16 + + + + name + Number + scope + constant.numeric + settings + + foreground + #1C00CF + + + + name + Keyword + scope + keyword + settings + + foreground + #AA0D91 + + + + name + Operator + scope + keyword.operator + settings + + foreground + #000000 + + + + name + Identifier + scope + constant.language + settings + + foreground + #AA0D91 + + + + name + Exception + scope + support.class.exception + settings + + foreground + #990000 + + + + name + Function name + scope + entity.name.function + settings + + foreground + #000000 + + + + + name + Type name + scope + entity.name.type + settings + + fontStyle + bold underline + + + + name + Arguments + scope + variable.parameter + settings + + fontStyle + italic + + + + name + Comment + scope + comment + settings + + + foreground + #007400 + + + + name + Invalid + scope + invalid + settings + + + foreground + #FF0000 + + + + name + Trailing whitespace + scope + invalid.deprecated.trailing-whitespace + settings + + background + #E71A1100 + + + + name + Embedded source + scope + text source + settings + + background + #FAFAFAFC + foreground + #000000 + + + + name + Tag + scope + meta.tag, declaration.tag + settings + + foreground + #AA0D91 + + + + + name + Support + scope + support + settings + + fontStyle + bold + foreground + #000000 + + + + name + Storage + scope + storage + settings + + + foreground + #AA0D91 + + + + name + Section name + scope + entity.name.section + settings + + fontStyle + bold underline + + + + name + Frame title + scope + entity.name.function.frame + settings + + fontStyle + bold + foreground + #000000 + + + + + name + XML Declaration + scope + meta.tag.preprocessor.xml + settings + + foreground + #333333 + + + + name + Tag Attribute + scope + entity.other.attribute-name + settings + + fontStyle + italic + foreground + + #994500 + + + + name + Tag Name + scope + entity.name.tag + settings + + foreground + #881280 + + + + + uuid + 4FCFA210-B247-11D9-9D00-000D93347A42 + + diff --git a/tool/tmthemes/Dreamweaver.tmTheme b/tool/tmthemes/Dreamweaver.tmTheme new file mode 100644 index 00000000..466863af --- /dev/null +++ b/tool/tmthemes/Dreamweaver.tmTheme @@ -0,0 +1,521 @@ + + + + + comment + By Jim Isaacs - jimisaacs.com + name + Dreamweaver + settings + + + settings + + background + #FFFFFF + caret + #000000 + foreground + #000000 + invisibles + #BFBFBF + lineHighlight + #00000012 + selection + #5EA0FF + + + + name + text + scope + text + settings + + foreground + #000000 + + + + name + constant numeric + scope + constant.numeric - source.css + settings + + fontStyle + + foreground + #EE000B + + + + name + comment general + scope + comment + settings + + fontStyle + + foreground + #9A9A9A + + + + name + html meta + scope + text.html meta.tag + settings + + fontStyle + + foreground + #00359E + + + + name + html string + scope + text.html.basic meta.tag string.quoted - source + settings + + foreground + #001EFF + + + + name + html contstant + scope + text.html.basic constant.character.entity.html + settings + + fontStyle + bold + foreground + #000000 + + + + name + html a tag + scope + text.html meta.tag.a - string + settings + + fontStyle + + foreground + #106800 + + + + name + html img tag + scope + text.html meta.tag.img - string + settings + + foreground + #6D232E + + + + name + html form tag + scope + text.html meta.tag.form - string + settings + + foreground + #FF9700 + + + + name + html table + scope + text.html meta.tag.table - string + settings + + foreground + #009079 + + + + name + js embedded + scope + source.js.embedded.html punctuation.definition.tag - source.php, source.js.embedded.html entity.name.tag.script, source.js.embedded entity.other.attribute-name - source.js string + settings + + fontStyle + + foreground + #842B44 + + + + name + js comment + scope + source.js comment - source.php + settings + + foreground + #9A9A9A + + + + name + js meta function + scope + source.js meta.function - source.php + settings + + fontStyle + + foreground + #000000 + + + + name + js instance / support.function + scope + source.js meta.class - source.php, source.js support.function - source.php + settings + + foreground + #24C696 + + + + name + js string + scope + source.js string - source.php, source.js keyword.operator + settings + + fontStyle + + foreground + #0035FF + + + + name + js support + scope + source.js support.class + settings + + foreground + #7E00B7 + + + + name + js storage + scope + source.js storage + settings + + fontStyle + bold + foreground + #000000 + + + + name + js storage (not function) / bool / new / braces + scope + source.js storage - storage.type.function - source.php, source.js constant - source.php, source.js keyword - source.php, source.js variable.language, source.js meta.brace, source.js punctuation.definition.parameters.begin, source.js punctuation.definition.parameters.end + settings + + fontStyle + bold + foreground + #05208C + + + + name + js regexp + scope + source.js string.regexp, source.js string.regexp constant + settings + + foreground + #106800 + + + + name + css embedded + scope + source.css.embedded.html punctuation.definition.tag, source.css.embedded.html entity.name.tag.style, source.css.embedded entity.other.attribute-name - meta.selector + settings + + foreground + #8D00B7 + + + + name + css @import + scope + source.css meta.at-rule.import.css + settings + + fontStyle + bold + foreground + #009C7F + + + + name + css @important + scope + source.css keyword.other.important + settings + + fontStyle + bold + foreground + #EE000B + + + + name + css @media + scope + source.css meta.at-rule.media + settings + + fontStyle + bold + foreground + #430303 + + + + name + css string + scope + source.css string + settings + + foreground + #106800 + + + + name + css selector/prop-list + scope + source.css meta.selector, source.css meta.property-list, source.css meta.at-rule + settings + + foreground + #DA29FF + + + + name + css punctuation + scope + source.css punctuation.separator - source.php, source.css punctuation.terminator - source.php + settings + + fontStyle + bold + foreground + #DA29FF + + + + name + css property name + scope + source.css meta.property-name + settings + + foreground + #05208C + + + + name + css property value + scope + source.css meta.property-value + settings + + foreground + #0035FF + + + + name + php begin/end block + scope + source.php punctuation.section.embedded.begin, source.php punctuation.section.embedded.end + settings + + fontStyle + bold + foreground + #EE000B + + + + name + php + scope + source.php - punctuation.section + settings + + fontStyle + + foreground + #000000 + + + + name + php varaible + scope + source.php variable, source.php meta.function.arguments + settings + + foreground + #000000 + + + + name + php punctuation + scope + source.php punctuation - string - variable - meta.function + settings + + foreground + #05208C + + + + name + php storage.type + scope + source.php storage.type + settings + + foreground + #24BF96 + + + + name + php keyword general / storage misc + scope + source.php keyword - comment, source.php storage.type.class, source.php storage.type.interface, source.php storage.modifier, source.php constant.language + settings + + foreground + #009714 + + + + name + php support / storage / operator + scope + source.php support , source.php storage, source.php keyword.operator, source.php storage.type.function + settings + + foreground + #0035FF + + + + name + php varaible global + scope + source.php variable.other.global + settings + + foreground + #0092F2 + + + + name + php support constant + scope + source.php support.constant, source.php constant.language.php + settings + + foreground + #551D02 + + + + name + php string + scope + source.php string, source.php string keyword.operator + settings + + fontStyle + + foreground + #E20000 + + + + name + php string variable + scope + source.php string.quoted.double variable + settings + + foreground + #FF6200 + + + + name + php comment general + scope + source.php comment + settings + + foreground + #FF9404 + + + + name + Invalid + scope + invalid + settings + + background + #EFFF8A + fontStyle + bold + foreground + #EE000B + + + + uuid + 4C43099A-C325-4F56-BACB-F332209207B0 + + diff --git a/tool/tmthemes/GitHub.tmTheme b/tool/tmthemes/GitHub.tmTheme new file mode 100644 index 00000000..aa21abce --- /dev/null +++ b/tool/tmthemes/GitHub.tmTheme @@ -0,0 +1,573 @@ + + + + + author + Martin Kühl + comment + A theme based on the GitHub code stylesheet. + name + GitHub + settings + + + comment + +background #files .file .data background-color +caret #files .file .meta color +invisibles .syntax .w +lineHighlight #FFFEEB #files .file .private background-color + alt: #FFFFCC colour that gets added via javascript +selection #B4D5FE handmade :-) + alt: #FFFFCC colour that gets added via javascript + #EAF2F5 #header .userbox background-color + #EAEAEA #files .file background-color + #DEDEDE #files .file border-color + #F9EA86 Mac OS X system selection colour “Gold” + + settings + + background + #F8F8FF + caret + #666666 + foreground + #000000 + invisibles + #BBBBBB + lineHighlight + #FFFEEB + selection + #B4D5FE + + + + comment + .syntax .c, .syntax .c[ml] + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #999988 + + + + name + Comment.Preproc + scope + comment.block.preprocessor + settings + + comment + .syntax .cp + fontStyle + bold + foreground + #999999 + + + + name + Comment.Special + scope + comment.documentation, comment.block.documentation + settings + + comment + .syntax .cs + fontStyle + bold italic + foreground + #999999 + + + + name + Error + scope + invalid.illegal + settings + + background + #E3D2D2 + comment + .syntax .err + foreground + #A61717 + + + + comment + .syntax .k, .syntax .k[dpr] + name + Keyword + scope + keyword, storage + settings + + fontStyle + bold + + + + comment + .syntax .o, .syntax .ow + name + Operator + scope + keyword.operator + settings + + fontStyle + bold + + + + name + Keyword.Constant + scope + constant.language, support.constant + settings + + comment + .style .kc + fontStyle + bold + + + + name + Keyword.Type + scope + storage.type, support.type + settings + + comment + .style .kt + fontStyle + bold + foreground + #445588 + + + + name + Name.Attribute + scope + entity.other.attribute-name + settings + + comment + .style .na + foreground + #008080 + + + + name + Name.Builtin + scope + variable.other + settings + + comment + .style .nb + foreground + #0086B3 + + + + name + Name.Builtin.Pseudo + scope + variable.language + settings + + comment + .style .bp + foreground + #999999 + + + + comment + TODO: support.class is styled as Name.Constant on GitHub. + name + Name.Class + scope + entity.name.type, entity.other.inherited-class, support.class + settings + + comment + .style .nc + fontStyle + bold + foreground + #445588 + + + + name + Name.Constant + scope + variable.other.constant + settings + + comment + .style .no + foreground + #008080 + + + + name + Name.Entity + scope + constant.character.entity + settings + + comment + .style .ni + foreground + #800080 + + + + name + Name.Exception + scope + entity.name.exception + settings + + comment + .style .ne + foreground + #990000 + + + + name + Name.Function + scope + entity.name.function, support.function, keyword.other.name-of-parameter + settings + + comment + .style .nf + foreground + #990000 + + + + name + Name.Namespace + scope + entity.name.section + settings + + comment + .style .nn + foreground + #555555 + + + + name + Name.Tag + scope + entity.name.tag + settings + + comment + .style .nt + foreground + #000080 + + + + name + Name.Variable + scope + variable.parameter, support.variable + settings + + comment + .style .nv, .style .v[cgi] + foreground + #008080 + + + + name + Literal.Number + scope + constant.numeric, constant.other + settings + + comment + .style .m, .style .m[fhio], .style .il + foreground + #009999 + + + + name + Literal.String + scope + string - string source, constant.character + settings + + comment + .style .s[bcd2ehixl] + fontStyle + + foreground + #DD1144 + + + + name + Literal.String.Regex + scope + string.regexp + settings + + comment + .style .sr + foreground + #009926 + + + + name + Literal.String.Symbol + scope + constant.other.symbol + settings + + comment + .style .ss + foreground + #990073 + + + + name + Punctuation + scope + punctuation + settings + + fontStyle + bold + + + + name + Generic.Deleted + scope + markup.deleted + settings + + background + #FFDDDD + comment + .syntax .gd + foreground + #000000 + + + + name + Generic.Emph + scope + markup.italic + settings + + comment + .syntax .ge + fontStyle + italic + + + + name + Generic.Error + scope + markup.error + settings + + comment + .syntax .gr + foreground + #AA0000 + + + + name + Generic.Heading + scope + markup.heading.1 + settings + + comment + .syntax .gh + foreground + #999999 + + + + name + Generic.Inserted + scope + markup.inserted + settings + + background + #DDFFDD + comment + .syntax .gi + foreground + #000000 + + + + name + Generic.Output + scope + markup.output, markup.raw + settings + + comment + .syntax .go + foreground + #888888 + + + + name + Generic.Prompt + scope + markup.prompt + settings + + comment + .syntax .gp + foreground + #555555 + + + + name + Generic.Strong + scope + markup.bold + settings + + comment + .syntax .gs + fontStyle + bold + + + + name + Generic.Subheading + scope + markup.heading + settings + + comment + .syntax .gu + foreground + #AAAAAA + + + + name + Generic.Traceback + scope + markup.traceback + settings + + comment + .syntax .gt + foreground + #AA0000 + + + + name + Generic.Underline + scope + markup.underline + settings + + fontStyle + underline + + + + name + Extra: Diff Range + scope + meta.diff.range, meta.diff.index, meta.separator + settings + + background + #EAF2F5 + comment + .syntax .gc + foreground + #999999 + + + + name + Extra: Diff From + scope + meta.diff.header.from-file + settings + + background + #FFDDDD + foreground + #999999 + + + + name + Extra: Diff To + scope + meta.diff.header.to-file + settings + + background + #DDFFDD + foreground + #999999 + + + + name + Extra: Link + scope + meta.link + settings + + fontStyle + + foreground + #4183C4 + + + + uuid + FDD6F02A-74F7-4B6C-97F1-857D792EC90E + + diff --git a/tool/tmthemes/Katzenmilch.tmTheme b/tool/tmthemes/Katzenmilch.tmTheme new file mode 100644 index 00000000..3878ffe9 --- /dev/null +++ b/tool/tmthemes/Katzenmilch.tmTheme @@ -0,0 +1,399 @@ + + + + + name + Katzen-Milch + comment + Those silly germans and their cat milk! Ghee wizz! + settings + + + settings + + background + #f3f2f3 + caret + #100011 + foreground + #0f0009ff + invisibles + #000000 + lineHighlight + #ffffff + selection + #6405D044 + selectionBorder + #8425f0 + bracketContentsOptions + underline + tagsForeground + #0f0009ff + tagsOptions + underline + + + + name + Parenthesis + scope + punctuation.definition.list + settings + + fontStyle + + foreground + #940494 + background + #4444940a + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #404f50aa + background + #5f0fff02 + + + + name + String + scope + string + settings + + foreground + #5a5f9b + background + #aaafdb09 + + + + name + Number + scope + constant.numeric + settings + + foreground + #4f827bee + background + #77c2bb0f + + + + name + User-defined Constant + scope + constant.character, constant.other + settings + + foreground + #025f69ff + background + #7f229910 + + + + name + Built-in Constant + scope + constant.language + settings + + fontStyle + + foreground + #7D7e52 + background + #bDbe820f + + + + name + Storage Modifier + scope + storage.modifier + settings + + fontStyle + bold + foreground + #7B5D8f + background + #9B9FfD0a + + + + name + Storage + scope + storage + settings + + fontStyle + bold + foreground + #7B5cbfff + background + #8B5Ddf0d + + + + name + Function Name + scope + entity.name.function + settings + + fontStyle + + foreground + #025f49f7 + background + #22ff491f + + + + name + Support Function + scope + support.function + settings + + foreground + #9D7e62 + background + #bDbe820a + + + + name + Misc Function + scope + entity.name.function.misc + settings + + foreground + #939469 + background + #E3E4A90a + + + + name + Predicate Function + scope + entity.name.function.predicate + settings + + foreground + #856F63 + background + #A5DF930a + + + + name + Input/Output Function + scope + entity.name.function.io + settings + + foreground + #aF938C + background + #DFB3AC0a + + + + name + External Symbol + scope + variable.other.external-symbol + settings + + foreground + #7BaFaD + background + #BBDFDD0a + + + + name + Variable + scope + variable.language, variable.other + settings + + foreground + #316fcf + background + #3aafff0a + + + + name + Parameter Variable + scope + variable.parameter + settings + + fontStyle + italic + foreground + #33969fdd + background + #05d6f90b + + + + name + Keyword + scope + keyword + settings + + foreground + #674Aa8 + background + #A3AAD80e + + + + name + Class Name + scope + entity.name.class + settings + + fontStyle + bold + foreground + #B9986F + background + #B998DF22 + + + + name + Structure Name + scope + entity.name.structure + settings + + foreground + #22af9d + background + #B998DF0a + + + + name + Type Name + scope + entity.name.type + settings + + foreground + #af47a9 + background + #af77a90d + + + + name + Class name + scope + entity.name.class, entity.name.type.class + settings + + foreground + #cc4357 + background + #ffddff92 + + + + name + Support Class + scope + support.class + settings + + foreground + #ef6aa7ff + background + #ef6aa710 + + + + name + Invalid + scope + invalid + settings + + background + #CC1B27 + foreground + #DFDFD5 + + + + + name + ♦ String embedded-source + scope + string source + settings + + fontStyle + italic + foreground + #13499fdd + background + #0099ff0a + + + + name + Tag name + scope + entity.name.tag + settings + + foreground + #3976a2 + background + #49a6d20a + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + fontStyle + + foreground + #4946c2ee + background + #4986c209 + + + + + diff --git a/tool/tmthemes/Kuroir Theme.tmTheme b/tool/tmthemes/Kuroir Theme.tmTheme new file mode 100644 index 00000000..36acd588 --- /dev/null +++ b/tool/tmthemes/Kuroir Theme.tmTheme @@ -0,0 +1,916 @@ + + + + + author + Stanley Rost + comment + Kuroir + name + Kuroir Theme + settings + + + settings + + background + #E8E9E8 + caret + #202020 + foreground + #363636 + invisibles + #0000004A + lineHighlight + #CBDC2F38 + selection + #F5AA0091 + + bracketsForeground + #C41717 + bracketsOptions + foreground underline + + bracketContentsForeground + #C41717 + bracketContentsOptions + foreground underline background + + guide + #8F8F8F + activeGuide + #FA2828 + + tagsOptions + stippled_underline + + + + name + Comment + scope + comment + settings + + background + #DCDCDC8F + fontStyle + + foreground + #949494E8 + + + + name + Regions + scope + comment.line.region + settings + + background + #E9D6DC85 + fontStyle + + foreground + #A54776 + + + + name + Line Marker + scope + comment.line.marker.php + settings + + background + #E9E4BE + foreground + #668D68 + + + + name + Todo + scope + comment.line.todo.php + settings + + background + #D9EAB8 + fontStyle + + foreground + #456E48 + + + + name + FIXME + scope + comment.line.fixme.php + settings + + background + #E1D0CA + fontStyle + + foreground + #880006 + + + + name + Constant + scope + constant + settings + + foreground + #CD6839 + + + + name + Entity + scope + entity + settings + + background + #E8E9E8 + fontStyle + + foreground + #8B4726 + + + + name + Storage + scope + storage + settings + + fontStyle + + foreground + #A52A2A + + + + name + Keyword Control + scope + keyword.control + settings + + foreground + #CD3700 + + + + name + Library Function + scope + support.function - variable, keyword.other.special-method.ruby + settings + + foreground + #B03060 + + + + name + Comparison + scope + keyword.operator.comparison,keyword.operator.logical + settings + + foreground + #B83126 + + + + name + String + scope + string + settings + + fontStyle + + foreground + #639300 + + + + name + R Interpolation + scope + string.quoted.double.ruby source.ruby.embedded.source + settings + + foreground + #007E69 + + + + name + Support + scope + support + settings + + fontStyle + + foreground + #104E8B + + + + name + Variable + scope + variable + settings + + foreground + #009ACD + + + + name + Invalid Deprecated + scope + invalid.deprecated + settings + + background + #E8E9E8 + fontStyle + italic underline + foreground + #FD1732 + + + + name + Invalid Illegal + scope + invalid.illegal + settings + + background + #FF060026 + foreground + #FD1224 + + + + name + Embedded Source (Bright) + scope + text source + settings + + background + #77ADE900 + foreground + #7B211A + + + + name + Entity inherited-class + scope + entity.other.inherited-class + settings + + fontStyle + italic + foreground + #005273 + + + + name + String.regexp + scope + string.regexp + settings + + background + #C9D4BE + foreground + #417E00 + + + + name + Support.function + scope + support.function + settings + + fontStyle + + foreground + #005273 + + + + name + Support.constant + scope + support.constant + settings + + fontStyle + + foreground + #CF6A4C + + + + name + j Entity Name Type + scope + entity.name.type + settings + + fontStyle + underline + + + + name + j Cast + scope + meta.cast + settings + + fontStyle + italic + foreground + #676767 + + + + name + Doctype/XML Processing + scope + meta.sgml.html meta.doctype, meta.sgml.html meta.doctype entity, meta.sgml.html meta.doctype string, meta.xml-processing, meta.xml-processing entity, meta.xml-processing string + settings + + foreground + #494949 + + + + name + Meta.tag.all + scope + meta.tag, meta.tag entity + settings + + foreground + #005273 + + + + name + Meta.tag.inline + scope + source entity.name.tag, source entity.other.attribute-name, meta.tag.inline, meta.tag.inline entity + settings + + foreground + #005273 + + + + name + Namespaces + scope + entity.name.tag.namespace, entity.other.attribute-name.namespace + settings + + foreground + #B85423 + + + + name + css tag-name + scope + entity.name.tag.css + settings + + foreground + #B83126 + + + + name + css:pseudo-class + scope + meta.selector.css entity.other.attribute-name.tag.pseudo-class + settings + + foreground + #B12E25 + + + + name + css#id + scope + meta.selector.css entity.other.attribute-name.id,entity.other.attribute-name.id.css + settings + + foreground + #B8002D + + + + name + css.class + scope + meta.selector.css entity.other.attribute-name.class, entity.other.attribute-name.class.css + settings + + foreground + #B8012D + + + + name + css property-name: + scope + support.type.property-name.css, meta.property-name + settings + + foreground + #005273 + + + + name + css @at-rule + scope + meta.preprocessor.at-rule keyword.control.at-rule + settings + + foreground + #8693A5 + + + + name + css property-value; + scope + meta.property-value + settings + + foreground + #417E00 + + + + name + css property-value color + scope + constant.other.color + settings + + foreground + #B8860B + + + + name + css !important / !default + scope + keyword.other.important,keyword.other.default + settings + + foreground + #EE3A8C + + + + name + css additional-constants + scope + meta.property-value support.constant.named-color.css, meta.property-value constant + settings + + foreground + #417E00 + + + + + + name + css constructor.argument + scope + meta.constructor.argument.css + settings + + foreground + #417E00 + + + + name + css constant.numeric + scope + constant.numeric + settings + + foreground + #9A5925 + + + + name + css keyword.unit + scope + keyword.other + settings + + foreground + #9F5E3D + + + + name + css keyword.unit + scope + source.scss support.function.misc + settings + + foreground + #1B76B0 + + + + name + diff.header + scope + meta.diff, meta.diff.header + settings + + background + #82000E + fontStyle + italic + foreground + #F8BEBE + + + + name + diff.deleted + scope + markup.deleted + settings + + background + #420E09 + foreground + #F8F8F8 + + + + name + diff.changed + scope + markup.changed + settings + + background + #4A410D + foreground + #F8F8F8 + + + + name + diff.inserted + scope + markup.inserted + settings + + background + #253B22 + foreground + #F8F8F8 + + + + name + Markup: Italic + scope + markup.italic + settings + + fontStyle + italic + foreground + #CD2626 + + + + name + Markup: Bold + scope + markup.bold + settings + + fontStyle + bold + foreground + #8B1A1A + + + + name + Markup: Underline + scope + markup.underline + settings + + fontStyle + underline + foreground + #E18964 + + + + name + Markup: Quote + scope + markup.quote + settings + + background + #FEE09C12 + fontStyle + italic + foreground + #8B7765 + + + + name + Markup: Heading + scope + markup.heading, markup.heading entity + settings + + background + #BF61330D + fontStyle + + foreground + #B8012D + + + + name + Markup: List + scope + markup.list + settings + + foreground + #8F5B26 + + + + name + Markup: Raw + scope + markup.raw + settings + + background + #B1B3BA08 + fontStyle + + foreground + #578BB3 + + + + name + Markup: Comment + scope + markup comment + settings + + fontStyle + italic + foreground + #F67B37 + + + + name + Markup: Separator + scope + meta.separator + settings + + background + #242424 + foreground + #60A633 + + + + name + Markup: Other + scope + markup.other + settings + + background + #B1B3BA08 + fontStyle + + foreground + #578BB3 + + + + name + Log Entry + scope + meta.line.entry.logfile, meta.line.exit.logfile + settings + + background + #EEEEEE29 + + + + name + Log Entry Error + scope + meta.line.error.logfile + settings + + background + #751012 + + + + name + SCSS Punctuation End Comments + scope + punctuation.definition.end + settings + + background + #DCDCDC8F + fontStyle + + + + + name + -------------------------------- + settings + + + + name + HTML Attribute name + scope + entity.other.attribute-name.html + settings + + foreground + #629F9E + + + + name + JS String + scope + string.quoted.double.js, string.quoted.single.js + settings + + foreground + #79A316 + + + + name + JS Function + scope + entity.name.function.js + settings + + foreground + #488C45 + fontStyle + italic + + + + name + JS Embedded code general + scope + source.js.embedded.html + settings + + foreground + #666 + + + + name + JS Storage Type + scope + storage.type.js + settings + + foreground + #BB3182 + + + + name + JS Support Class + scope + support.class.js + settings + + foreground + #338FD5 + + + + name + JS Control Keyword + scope + keyword.control.js, keyword.operator.js + settings + + foreground + #A99904 + fontStyle + italic + + + + + name + Matching Pairs + scope + entity.name.class + settings + + background + #D7D7A7 + foreground + #616838 + fontStyle + + + + + name + Active Guide + scope + active_guide + settings + + background + #968F96 + fontStyle + + + + + name + Highlight Matching Word + scope + highlight_matching_word + settings + + background + #CBDC2F38 + fontStyle + + + + + uuid + 467560D0-6ACE-4409-82FD-4791420837AC + + diff --git a/tool/tmthemes/Merbivore Soft.tmTheme b/tool/tmthemes/Merbivore Soft.tmTheme new file mode 100644 index 00000000..60c4cc94 --- /dev/null +++ b/tool/tmthemes/Merbivore Soft.tmTheme @@ -0,0 +1,322 @@ + + + + + name + Merbivore Soft + settings + + + settings + + background + #1C1C1C + caret + #FFFFFF + foreground + #E6E1DC + invisibles + #404040 + lineHighlight + #333435 + selection + #494949 + + + + name + Source + scope + source + settings + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #AC4BB8 + + + + name + Deprecated + scope + invalid.deprecated + settings + + foreground + #FFFFFF + background + #FE3838 + + + + name + Keyword + scope + keyword, storage + settings + + fontStyle + + foreground + #FC803A + + + + name + Function (definition) + scope + entity.name.function, keyword.other.name-of-parameter.objc + settings + + fontStyle + + + + + name + Class (definition) + scope + entity.name + settings + + + + name + Class inheritence + scope + entity.other.inherited-class + settings + + foreground + #C984CD + + + + name + Number + scope + constant.numeric + settings + + fontStyle + + foreground + #7FC578 + + + + name + Variable + scope + variable.language, variable.other + settings + + fontStyle + + + + + name + Constant + scope + constant + settings + + fontStyle + + foreground + #68C1D8 + + + + name + Constant (other variable) + scope + variable.other.constant + settings + + + + name + Constant (built-in) + scope + constant.language + settings + + fontStyle + + foreground + #E1C582 + + + + name + String + scope + string + settings + + fontStyle + + foreground + #8EC65F + + + + name + Library function + scope + support.function + settings + + fontStyle + + + + + name + Library constant + scope + constant.library + settings + + foreground + #8EC65F + + + + name + Library type + scope + support.type + settings + + foreground + #68C1D8 + + + + name + Library constant + scope + support.constant + settings + + foreground + #8EC65F + + + + name + Markup tag + scope + meta.tag, declaration.tag, entity.name.tag + settings + + fontStyle + + foreground + #FC803A + + + + name + Markup tag + scope + meta + settings + + fontStyle + italic + foreground + #AC4BB8 + + + + name + Markup tag attribute + scope + entity.other.attribute-name + settings + + foreground + #EAF1A3 + + + + name + Invalid + scope + invalid + settings + + background + #FE3838 + foreground + #FFFFFF + + + + name + String interpolation + scope + constant.character.escaped, constant.character.escape, string source, string source.ruby + settings + + fontStyle + + foreground + #B3E5B4 + + + + name + Diff Add + scope + markup.inserted + settings + + background + #6FC58B + foreground + #E6E1DC + + + + name + Diff Remove + scope + markup.deleted + settings + + background + #AC3735 + foreground + #E6E1DC + + + + name + Diff Header + scope + meta.diff.header, meta.separator.diff, meta.diff.index, meta.diff.range + settings + + background + #5A9EE1 + + + + uuid + B3517E4B-5243-46CF-AB04-9AE7B41DE3F2 + + diff --git a/tool/tmthemes/Merbivore.tmTheme b/tool/tmthemes/Merbivore.tmTheme new file mode 100644 index 00000000..41afeb81 --- /dev/null +++ b/tool/tmthemes/Merbivore.tmTheme @@ -0,0 +1,296 @@ + + + + + name + Merbivore + settings + + + settings + + background + #161616 + caret + #FFFFFF + foreground + #E6E1DC + invisibles + #404040 + lineHighlight + #333435 + selection + #454545 + + + + name + Source + scope + source + settings + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #AD2EA4 + + + + name + Keyword + scope + keyword, storage + settings + + fontStyle + + foreground + #FC6F09 + + + + name + Function (definition) + scope + entity.name.function, keyword.other.name-of-parameter.objc + settings + + fontStyle + + + + + name + Class (definition) + scope + entity.name + settings + + + + name + Class inheritence + scope + entity.other.inherited-class + settings + + foreground + #FC83FF + + + + name + Number + scope + constant.numeric + settings + + fontStyle + + foreground + #58C554 + + + + name + Variable + scope + variable.language, variable.other + settings + + fontStyle + + + + + name + Constant + scope + constant + settings + + fontStyle + + foreground + #1EDAFB + + + + name + Constant (other variable) + scope + variable.other.constant + settings + + + + name + Constant lib + scope + constant.library + settings + + foreground + #8DFF0A + + + + name + support function + scope + support.function + settings + + foreground + #FC6F09 + + + + name + Constant (built-in) + scope + constant.language + settings + + fontStyle + + foreground + #FDC251 + + + + name + String + scope + string + settings + + fontStyle + + foreground + #8DFF0A + + + + name + Library type + scope + support.type + settings + + foreground + #1EDAFB + + + + name + Library constant + scope + support.constant + settings + + foreground + #8DFF0A + + + + name + Markup tag + scope + meta.tag, declaration.tag, entity.name.tag + settings + + fontStyle + + foreground + #FC6F09 + + + + name + Markup tag attribute + scope + entity.other.attribute-name + settings + + foreground + #FFFF89 + + + + name + Invalid + scope + invalid + settings + + background + #990000 + foreground + #FFFFFF + + + + name + String interpolation + scope + constant.character.escaped, constant.character.escape, string source, string source.ruby + settings + + fontStyle + + foreground + #519F50 + + + + name + Diff Add + scope + markup.inserted + settings + + background + #144212 + foreground + #E6E1DC + + + + name + Diff Remove + scope + markup.deleted + settings + + background + #660000 + foreground + #E6E1DC + + + + name + Diff Header + scope + meta.diff.header, meta.separator.diff, meta.diff.index, meta.diff.range + settings + + background + #2F33AB + + + + uuid + 2ABC646D-06F3-48A5-94E9-18EF34474C97 + + diff --git a/tool/tmthemes/Monokai.tmTheme b/tool/tmthemes/Monokai.tmTheme index fb01ff36..c179cbe2 100644 --- a/tool/tmthemes/Monokai.tmTheme +++ b/tool/tmthemes/Monokai.tmTheme @@ -1,5 +1,5 @@ - + name @@ -16,11 +16,32 @@ foreground #F8F8F2 invisibles - #49483E + #3B3A32 lineHighlight - #49483E + #3E3D32 selection #49483E + findHighlight + #FFE792 + findHighlightForeground + #000000 + selectionBorder + #222218 + activeGuide + #9D550FB0 + + bracketsForeground + #F8F8F2A5 + bracketsOptions + underline + + bracketContentsForeground + #F8F8F2A5 + bracketContentsOptions + underline + + tagsOptions + stippled_underline @@ -56,6 +77,7 @@ #AE81FF + name Built-in constant @@ -282,6 +304,82 @@ #F8F8F0 + + name + JSON String + scope + meta.structure.dictionary.json string.quoted.double.json + settings + + foreground + #CFCFC2 + + + + + name + diff.header + scope + meta.diff, meta.diff.header + settings + + foreground + #75715E + + + + name + diff.deleted + scope + markup.deleted + settings + + foreground + #F92672 + + + + name + diff.inserted + scope + markup.inserted + settings + + foreground + #A6E22E + + + + name + diff.changed + scope + markup.changed + settings + + foreground + #E6DB74 + + + + + scope + constant.numeric.line-number.find-in-files - match + settings + + foreground + #AE81FFA0 + + + + scope + entity.name.filename.find-in-files + settings + + foreground + #E6DB74 + + + uuid D8D5E82E-3D5B-46B5-B38E-8C841C21347D diff --git a/tool/tmthemes/Pastels on Dark.tmTheme b/tool/tmthemes/Pastels on Dark.tmTheme index e3928606..47b83631 100644 --- a/tool/tmthemes/Pastels on Dark.tmTheme +++ b/tool/tmthemes/Pastels on Dark.tmTheme @@ -12,17 +12,17 @@ settings background - #211E1E + #2C2828 caret - #FFFFFF + #A7A7A7 foreground - #DADADA + #8F938F invisibles - #4F4D4D + #FFFFFF40 lineHighlight - #353030 + #FFFFFF08 selection - #73597E80 + #DDF0FF33 @@ -35,7 +35,7 @@ fontStyle foreground - #555555 + #A6C6FF @@ -48,7 +48,7 @@ fontStyle foreground - #555555 + #A6C6FF @@ -59,7 +59,7 @@ settings foreground - #AD9361 + #66A968 @@ -85,7 +85,7 @@ fontStyle foreground - #A1A1FF + #757aD8 @@ -122,7 +122,7 @@ fontStyle foreground - #A1A1FF + #AEB2F8 @@ -206,15 +206,28 @@ name Invalid scope - invalid + invalid, invalid.illegal settings background - #FF0000 + #562D56BF fontStyle bold foreground - #FFF9F9 + #F8F8F8 + + + + name + Invalid + scope + invalid.deprecated + settings + + fontStyle + italic, underline + foreground + #D2A8A1 @@ -224,6 +237,8 @@ invalid.deprecated.trailing-whitespace settings + fontStyle + bold background #FFD0D0 @@ -260,7 +275,7 @@ fontStyle foreground - #666666 + #E9C062 @@ -269,6 +284,17 @@ scope variable settings + + foreground + #BEBF55 + + + + name + Variables + scope + variable.language + settings foreground #C1C144 @@ -282,7 +308,7 @@ settings foreground - #6782D3 + #4FB7C5 @@ -384,7 +410,7 @@ fontStyle foreground - #47B8D6 + #797878 @@ -419,7 +445,7 @@ settings foreground - #888888 + #494949 diff --git a/tool/tmthemes/Solarized-dark.tmTheme b/tool/tmthemes/Solarized-dark.tmTheme new file mode 100644 index 00000000..4efdabdb --- /dev/null +++ b/tool/tmthemes/Solarized-dark.tmTheme @@ -0,0 +1,312 @@ + + + + + name + Solarized (dark) + settings + + + settings + + background + #002B36 + caret + #D30102 + foreground + #93A1A1 + invisibles + #93A1A180 + lineHighlight + #073642 + selection + #073642 + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #657B83 + + + + name + String + scope + string + settings + + foreground + #2AA198 + + + + name + Regexp + scope + string.regexp + settings + + foreground + #D30102 + + + + name + Number + scope + constant.numeric + settings + + foreground + #D33682 + + + + name + Variable + scope + variable.language, variable.other + settings + + foreground + #268BD2 + + + + name + Keyword + scope + keyword + settings + + foreground + #859900 + + + + name + Storage + scope + storage + settings + + fontStyle + bold + foreground + #93A1A1 + + + + name + Class name + scope + entity.name.class, entity.name.type.class + settings + + fontStyle + + foreground + #CB4B16 + + + + name + Function name + scope + entity.name.function + settings + + foreground + #268BD2 + + + + name + Variable start + scope + punctuation.definition.variable + settings + + foreground + #859900 + + + + name + Embedded code markers + scope + punctuation.section.embedded.begin, punctuation.section.embedded.end + settings + + foreground + #D30102 + + + + name + Built-in constant + scope + constant.language, meta.preprocessor + settings + + foreground + #B58900 + + + + name + Support.construct + scope + support.function.construct, keyword.other.new + settings + + foreground + #CB4B16 + + + + name + User-defined constant + scope + constant.character, constant.other + settings + + foreground + #CB4B16 + + + + name + Inherited class + scope + entity.other.inherited-class + settings + + foreground + #6C71C4 + + + + name + Function argument + scope + variable.parameter + settings + + + + name + Tag name + scope + entity.name.tag + settings + + fontStyle + bold + foreground + #268BD2 + + + + name + Tag start/end + scope + punctuation.definition.tag + settings + + foreground + #657B83 + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + foreground + #93A1A1 + + + + name + Library function + scope + support.function + settings + + foreground + #268BD2 + + + + name + Continuation + scope + punctuation.separator.continuation + settings + + foreground + #D30102 + + + + name + Library constant + scope + support.constant + settings + + + + name + Library class/type + scope + support.type, support.class + settings + + foreground + #859900 + + + + name + Library Exception + scope + support.type.exception + settings + + foreground + #CB4B16 + + + + name + Library variable + scope + support.other.variable + settings + + + + name + Invalid + scope + invalid + settings + + + + uuid + F930B0BF-AA03-4232-A30F-CEF749FF8E72 + + diff --git a/tool/tmthemes/Solarized-light.tmTheme b/tool/tmthemes/Solarized-light.tmTheme new file mode 100644 index 00000000..9db72b86 --- /dev/null +++ b/tool/tmthemes/Solarized-light.tmTheme @@ -0,0 +1,305 @@ + + + + + name + Solarized (light) + settings + + + settings + + background + #FDF6E3 + caret + #000000 + foreground + #586E75 + invisibles + #93A1A180 + lineHighlight + #EEE8D5 + selection + #073642 + + + + name + Comment + scope + comment + settings + + foreground + #93A1A1 + + + + name + String + scope + string + settings + + foreground + #2AA198 + + + + name + Regexp + scope + string.regexp + settings + + foreground + #D30102 + + + + name + Number + scope + constant.numeric + settings + + foreground + #D33682 + + + + name + Variable + scope + variable.language, variable.other + settings + + foreground + #268BD2 + + + + name + Keyword + scope + keyword + settings + + foreground + #859900 + + + + name + Storage + scope + storage + settings + + fontStyle + bold + foreground + #073642 + + + + name + Class name + scope + entity.name.class, entity.name.type.class + settings + + foreground + #268BD2 + + + + name + Function name + scope + entity.name.function + settings + + foreground + #268BD2 + + + + name + Variable start + scope + punctuation.definition.variable + settings + + foreground + #859900 + + + + name + Embedded code markers + scope + punctuation.section.embedded.begin, punctuation.section.embedded.end + settings + + foreground + #D30102 + + + + name + Built-in constant + scope + constant.language, meta.preprocessor + settings + + foreground + #B58900 + + + + name + Support.construct + scope + support.function.construct, keyword.other.new + settings + + foreground + #D30102 + + + + name + User-defined constant + scope + constant.character, constant.other + settings + + foreground + #CB4B16 + + + + name + Inherited class + scope + entity.other.inherited-class + settings + + + + name + Function argument + scope + variable.parameter + settings + + + + name + Tag name + scope + entity.name.tag + settings + + fontStyle + bold + foreground + #268BD2 + + + + name + Tag start/end + scope + punctuation.definition.tag.begin, punctuation.definition.tag.end + settings + + foreground + #93A1A1 + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + foreground + #93A1A1 + + + + name + Library function + scope + support.function + settings + + foreground + #268BD2 + + + + name + Continuation + scope + punctuation.separator.continuation + settings + + foreground + #D30102 + + + + name + Library constant + scope + support.constant + settings + + + + name + Library class/type + scope + support.type, support.class + settings + + foreground + #859900 + + + + name + Library Exception + scope + support.type.exception + settings + + foreground + #CB4B16 + + + + name + Library variable + scope + support.other.variable + settings + + + + name + Invalid + scope + invalid + settings + + + + uuid + 38E819D9-AE02-452F-9231-ECC3B204AFD7 + + diff --git a/tool/tmthemes/Mac Classic.tmTheme b/tool/tmthemes/Textmate (Mac Classic).tmTheme similarity index 100% rename from tool/tmthemes/Mac Classic.tmTheme rename to tool/tmthemes/Textmate (Mac Classic).tmTheme diff --git a/tool/tmthemes/Tomorrow-Night-Blue.tmTheme b/tool/tmthemes/Tomorrow-Night-Blue.tmTheme new file mode 100644 index 00000000..b1669a27 --- /dev/null +++ b/tool/tmthemes/Tomorrow-Night-Blue.tmTheme @@ -0,0 +1,186 @@ + + + + + comment + http://chriskempson.com + name + Tomorrow Night - Blue + settings + + + settings + + background + #002451 + caret + #FFFFFF + foreground + #FFFFFF + invisibles + #404F7D + lineHighlight + #00346E + selection + #003F8E + + + + name + Comment + scope + comment + settings + + foreground + #7285B7 + + + + name + Foreground, Operator + scope + keyword.operator.class, keyword.operator, constant.other, source.php.embedded.line + settings + + fontStyle + + foreground + #FFFFFF + + + + name + Variable, String Link, Regular Expression, Tag Name + scope + variable, support.other.variable, string.other.link, string.regexp, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag + settings + + foreground + #FF9DA4 + + + + name + Number, Constant, Function Argument, Tag Attribute, Embedded + scope + constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit + settings + + fontStyle + + foreground + #FFC58F + + + + name + Class, Support + scope + entity.name.class, entity.name.type.class, support.type, support.class + settings + + fontStyle + + foreground + #FFEEAD + + + + name + String, Symbols, Inherited Class, Markup Heading + scope + string, constant.other.symbol, entity.other.inherited-class, markup.heading + settings + + fontStyle + + foreground + #D1F1A9 + + + + name + Operator, Misc + scope + keyword.operator, constant.other.color + settings + + foreground + #99FFFF + + + + name + Function, Special Method, Block Level + scope + entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level + settings + + fontStyle + + foreground + #BBDAFF + + + + name + Keyword, Storage + scope + keyword, storage, storage.type, entity.name.tag.css + settings + + fontStyle + + foreground + #EBBBFF + + + + name + Invalid + scope + invalid + settings + + background + #F99DA5 + fontStyle + + foreground + #FFFFFF + + + + name + Separator + scope + meta.separator + settings + + background + #BBDAFE + foreground + #FFFFFF + + + + name + Deprecated + scope + invalid.deprecated + settings + + background + #EBBBFF + fontStyle + + foreground + #FFFFFF + + + + uuid + 3F4BB232-3C3A-4396-99C0-06A9573715E9 + + diff --git a/tool/tmthemes/Tomorrow-Night-Bright.tmTheme b/tool/tmthemes/Tomorrow-Night-Bright.tmTheme new file mode 100644 index 00000000..15d40106 --- /dev/null +++ b/tool/tmthemes/Tomorrow-Night-Bright.tmTheme @@ -0,0 +1,186 @@ + + + + + comment + http://chriskempson.com + name + Tomorrow Night - Bright + settings + + + settings + + background + #000000 + caret + #9F9F9F + foreground + #DEDEDE + invisibles + #343434 + lineHighlight + #2A2A2A + selection + #424242 + + + + name + Comment + scope + comment + settings + + foreground + #969896 + + + + name + Foreground + scope + keyword.operator.class, constant.other, source.php.embedded.line + settings + + fontStyle + + foreground + #EEEEEE + + + + name + Variable, String Link, Regular Expression, Tag Name + scope + variable, support.other.variable, string.other.link, string.regexp, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag + settings + + foreground + #D54E53 + + + + name + Number, Constant, Function Argument, Tag Attribute, Embedded + scope + constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit + settings + + fontStyle + + foreground + #E78C45 + + + + name + Class, Support + scope + entity.name.class, entity.name.type.class, support.type, support.class + settings + + fontStyle + + foreground + #E7C547 + + + + name + String, Symbols, Inherited Class, Markup Heading + scope + string, constant.other.symbol, entity.other.inherited-class, markup.heading + settings + + fontStyle + + foreground + #B9CA4A + + + + name + Operator, Misc + scope + keyword.operator, constant.other.color + settings + + foreground + #70C0B1 + + + + name + Function, Special Method, Block Level + scope + entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level + settings + + fontStyle + + foreground + #7AA6DA + + + + name + Keyword, Storage + scope + keyword, storage, storage.type, entity.name.tag.css + settings + + fontStyle + + foreground + #C397D8 + + + + name + Invalid + scope + invalid + settings + + background + #DF5F5F + fontStyle + + foreground + #CED2CF + + + + name + Separator + scope + meta.separator + settings + + background + #82A3BF + foreground + #CED2CF + + + + name + Deprecated + scope + invalid.deprecated + settings + + background + #B798BF + fontStyle + + foreground + #CED2CF + + + + uuid + 33D8C715-AD3A-455B-8DF2-56F708909FFE + + diff --git a/tool/tmthemes/Tomorrow-Night-Eighties.tmTheme b/tool/tmthemes/Tomorrow-Night-Eighties.tmTheme new file mode 100644 index 00000000..33dabddf --- /dev/null +++ b/tool/tmthemes/Tomorrow-Night-Eighties.tmTheme @@ -0,0 +1,186 @@ + + + + + comment + http://chriskempson.com + name + Tomorrow Night - Eighties + settings + + + settings + + background + #2D2D2D + caret + #CCCCCC + foreground + #CCCCCC + invisibles + #6A6A6A + lineHighlight + #393939 + selection + #515151 + + + + name + Comment + scope + comment + settings + + foreground + #999999 + + + + name + Foreground + scope + keyword.operator.class, constant.other, source.php.embedded.line + settings + + fontStyle + + foreground + #CCCCCC + + + + name + Variable, String Link, Tag Name + scope + variable, support.other.variable, string.other.link, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag + settings + + foreground + #F2777A + + + + name + Number, Constant, Function Argument, Tag Attribute, Embedded + scope + constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit + settings + + fontStyle + + foreground + #F99157 + + + + name + Class, Support + scope + entity.name.class, entity.name.type.class, support.type, support.class + settings + + fontStyle + + foreground + #FFCC66 + + + + name + String, Symbols, Inherited Class, Markup Heading + scope + string, constant.other.symbol, entity.other.inherited-class, markup.heading + settings + + fontStyle + + foreground + #99CC99 + + + + name + Operator, Misc + scope + keyword.operator, constant.other.color + settings + + foreground + #66CCCC + + + + name + Function, Special Method, Block Level + scope + entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level + settings + + fontStyle + + foreground + #6699CC + + + + name + Keyword, Storage + scope + keyword, storage, storage.type, entity.name.tag.css + settings + + fontStyle + + foreground + #CC99CC + + + + name + Invalid + scope + invalid + settings + + background + #F2777A + fontStyle + + foreground + #CDCDCD + + + + name + Separator + scope + meta.separator + settings + + background + #99CCCC + foreground + #CDCDCD + + + + name + Deprecated + scope + invalid.deprecated + settings + + background + #CC99CC + fontStyle + + foreground + #CDCDCD + + + + uuid + DE477E5B-BD4D-46B0-BF80-2EA32A2814D5 + + diff --git a/tool/tmthemes/Tomorrow-Night.tmTheme b/tool/tmthemes/Tomorrow-Night.tmTheme new file mode 100644 index 00000000..bb1efaf0 --- /dev/null +++ b/tool/tmthemes/Tomorrow-Night.tmTheme @@ -0,0 +1,186 @@ + + + + + comment + http://chriskempson.com + name + Tomorrow Night + settings + + + settings + + background + #1D1F21 + caret + #AEAFAD + foreground + #C5C8C6 + invisibles + #4B4E55 + lineHighlight + #282A2E + selection + #373B41 + + + + name + Comment + scope + comment + settings + + foreground + #969896 + + + + name + Foreground + scope + keyword.operator.class, constant.other, source.php.embedded.line + settings + + fontStyle + + foreground + #CED1CF + + + + name + Variable, String Link, Regular Expression, Tag Name + scope + variable, support.other.variable, string.other.link, string.regexp, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag + settings + + foreground + #CC6666 + + + + name + Number, Constant, Function Argument, Tag Attribute, Embedded + scope + constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit + settings + + fontStyle + + foreground + #DE935F + + + + name + Class, Support + scope + entity.name.class, entity.name.type.class, support.type, support.class + settings + + fontStyle + + foreground + #F0C674 + + + + name + String, Symbols, Inherited Class, Markup Heading + scope + string, constant.other.symbol, entity.other.inherited-class, markup.heading + settings + + fontStyle + + foreground + #B5BD68 + + + + name + Operator, Misc + scope + keyword.operator, constant.other.color + settings + + foreground + #8ABEB7 + + + + name + Function, Special Method, Block Level + scope + entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level + settings + + fontStyle + + foreground + #81A2BE + + + + name + Keyword, Storage + scope + keyword, storage, storage.type, entity.name.tag.css + settings + + fontStyle + + foreground + #B294BB + + + + name + Invalid + scope + invalid + settings + + background + #DF5F5F + fontStyle + + foreground + #CED2CF + + + + name + Separator + scope + meta.separator + settings + + background + #82A3BF + foreground + #CED2CF + + + + name + Deprecated + scope + invalid.deprecated + settings + + background + #B798BF + fontStyle + + foreground + #CED2CF + + + + uuid + F96223EB-1A60-4617-92F3-D24D4F13DB09 + + diff --git a/tool/tmthemes/Tomorrow.tmTheme b/tool/tmthemes/Tomorrow.tmTheme new file mode 100644 index 00000000..8c98c226 --- /dev/null +++ b/tool/tmthemes/Tomorrow.tmTheme @@ -0,0 +1,186 @@ + + + + + comment + http://chriskempson.com + name + Tomorrow + settings + + + settings + + background + #FFFFFF + caret + #AEAFAD + foreground + #4D4D4C + invisibles + #D1D1D1 + lineHighlight + #EFEFEF + selection + #D6D6D6 + + + + name + Comment + scope + comment + settings + + foreground + #8E908C + + + + name + Foreground + scope + keyword.operator.class, constant.other, source.php.embedded.line + settings + + fontStyle + + foreground + #666969 + + + + name + Variable, String Link, Regular Expression, Tag Name + scope + variable, support.other.variable, string.other.link, string.regexp, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag + settings + + foreground + #C82829 + + + + name + Number, Constant, Function Argument, Tag Attribute, Embedded + scope + constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit + settings + + fontStyle + + foreground + #F5871F + + + + name + Class, Support + scope + entity.name.class, entity.name.type.class, support.type, support.class + settings + + fontStyle + + foreground + #C99E00 + + + + name + String, Symbols, Inherited Class, Markup Heading + scope + string, constant.other.symbol, entity.other.inherited-class, markup.heading + settings + + fontStyle + + foreground + #718C00 + + + + name + Operator, Misc + scope + keyword.operator, constant.other.color + settings + + foreground + #3E999F + + + + name + Function, Special Method, Block Level + scope + entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level + settings + + fontStyle + + foreground + #4271AE + + + + name + Keyword, Storage + scope + keyword, storage, storage.type + settings + + fontStyle + + foreground + #8959A8 + + + + name + Invalid + scope + invalid + settings + + background + #C82829 + fontStyle + + foreground + #FFFFFF + + + + name + Separator + scope + meta.separator + settings + + background + #4271AE + foreground + #FFFFFF + + + + name + Deprecated + scope + invalid.deprecated + settings + + background + #8959A8 + fontStyle + + foreground + #FFFFFF + + + + uuid + 82CCD69C-F1B1-4529-B39E-780F91F07604 + + diff --git a/tool/tmthemes/Twilight.tmTheme b/tool/tmthemes/Twilight.tmTheme index a83f7ecb..a5984e82 100644 --- a/tool/tmthemes/Twilight.tmTheme +++ b/tool/tmthemes/Twilight.tmTheme @@ -343,6 +343,19 @@ #CDA869 + + name + Function name + scope + entity.name.function, support.function.any-method + settings + + fontStyle + bold + foreground + #AC885B + + name § css:pseudo-class diff --git a/tool/tmthemes/Vibrant Ink.tmTheme b/tool/tmthemes/Vibrant Ink.tmTheme new file mode 100644 index 00000000..a1e5cf28 --- /dev/null +++ b/tool/tmthemes/Vibrant Ink.tmTheme @@ -0,0 +1,460 @@ + + + + + name + Vibrant Ink + settings + + + settings + + background + #0F0F0F + caret + #FFFFFF + foreground + #FFFFFF + invisibles + #404040 + lineHighlight + #333333 + selection + #6699CC + + + + name + Text base + scope + text + settings + + background + #0F0F0F + foreground + #FFFFFF + + + + name + Inline Ruby Html + scope + source.ruby.rails.embedded.html + settings + + background + #000000 + + + + name + Ruby Html + scope + text.html.ruby + settings + + background + #101010 + foreground + #FFFFFF + + + + name + Invalid + scope + invalid, invalid.deprecated + settings + + background + #000000 + foreground + #CCFF33 + + + + name + Number + scope + constant.numeric + settings + + foreground + #99CC99 + + + + name + Ruby source + scope + source.ruby + settings + + + + name + Source base + scope + source + settings + + background + #000000 + foreground + #FFFFFF + + + + name + Comment + scope + comment + settings + + foreground + #9933CC + + + + name + Constant + scope + constant + settings + + foreground + #339999 + + + + name + Keyword + scope + keyword + settings + + fontStyle + + foreground + #FF6600 + + + + name + Pre-processor Line + scope + keyword.preprocessor + settings + + fontStyle + + foreground + #EDF8F9 + + + + name + Pre-processor Directive + scope + keyword.preprocessor directive + settings + + fontStyle + + foreground + #FFFFFF + + + + name + Function name + scope + entity.name.function, storage.type.function.js + settings + + fontStyle + + foreground + #FFCC00 + + + + name + Function argument + scope + variable.parameter + settings + + fontStyle + italic + + + + name + Block comment + scope + source comment.block + settings + + background + #070707 + foreground + #772CB7 + + + + name + Variable + scope + variable.other + settings + + fontStyle + + foreground + #FFFFFF + + + + name + Support Function + scope + support.function + settings + + foreground + #FFCC00 + + + + name + String + scope + string + settings + + foreground + #66FF00 + + + + name + String escapes + scope + string constant.character.escape + settings + + foreground + #AAAAAA + + + + name + String (executed) + scope + string.interpolated + settings + + background + #CCCC33 + foreground + #000000 + + + + name + Regular expression + scope + string.regexp + settings + + foreground + #44B4CC + + + + name + String (literal) + scope + string.literal + settings + + foreground + #CCCC33 + + + + name + String escapes (executed) + scope + string.interpolated constant.character.escape + settings + + foreground + #555555 + + + + name + Class name + scope + entity.name.class, support.class.js + settings + + fontStyle + underline + + + + name + Class inheritance + scope + entity.other.inherited-class + settings + + fontStyle + italic underline + + + + name + Tag name + scope + entity.name.tag + settings + + fontStyle + + + + + name + Html Meta + scope + meta.tag.inline.any.html, meta.tag.block.any.html + settings + + fontStyle + + foreground + #FF6600 + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + fontStyle + italic + foreground + #99CC99 + + + + name + Other Keywords + scope + keyword.other + settings + + foreground + #DDE93D + + + + name + CSS Selector + scope + meta.selector.css, entity.other.attribute-name.pseudo-class.css, entity.name.tag.wildcard.css, entity.other.attribute-name.id.css, entity.other.attribute-name.class.css + settings + + foreground + #FF6600 + + + + name + CSS Property + scope + support.type.property-name.css + settings + + foreground + #999966 + + + + name + CSS Other + scope + keyword.other.unit.css, constant.other.rgb-value.css, constant.numeric.css + settings + + foreground + #FFFFFF + + + + name + Javascript Events + scope + support.function.event-handler.js + settings + + foreground + #FFFFFF + + + + name + Javascript Operators + scope + keyword.operator.js + settings + + foreground + #FFFFFF + + + + name + Javascript Keywords + scope + keyword.control.js + settings + + foreground + #CCCC66 + + + + name + Prototype Objects + scope + support.class.prototype.js + settings + + foreground + #FFFFFF + + + + name + Prototype Methods + scope + object.property.function.prototype.js + settings + + foreground + #FF6600 + + + + uuid + 4B7A9AA6-C472-4460-BA48-199E2624956B + + diff --git a/tool/tmthemes/Xcode_default.tmTheme b/tool/tmthemes/Xcode_default.tmTheme new file mode 100644 index 00000000..c7b5072c --- /dev/null +++ b/tool/tmthemes/Xcode_default.tmTheme @@ -0,0 +1,240 @@ + + + + + comment + Carmine Paolino + name + Xcode default + settings + + + settings + + background + #FFFFFF + caret + #000000 + foreground + #000000 + invisibles + #BFBFBF + lineHighlight + #00000012 + selection + #B5D5FF + + + + name + Comment + scope + comment + settings + + foreground + #008E00 + + + + name + Preprocessor Statements + scope + meta.preprocessor, keyword.control.import + settings + + foreground + #7D4726 + + + + name + String + scope + string + settings + + foreground + #DF0002 + + + + name + Number + scope + constant.numeric + settings + + foreground + #3A00DC + + + + name + Built-in constant + scope + constant.language + settings + + foreground + #C800A4 + + + + name + User-defined constant + scope + constant.character, constant.other + settings + + foreground + #275A5E + + + + name + Variable + scope + variable.language, variable.other + settings + + foreground + #C800A4 + + + + name + Keyword + scope + keyword + settings + + foreground + #C800A4 + + + + name + Storage + scope + storage + settings + + foreground + #C900A4 + + + + name + Class name + scope + entity.name.class + settings + + foreground + #438288 + + + + name + Inherited class + scope + entity.other.inherited-class + settings + + + + name + Function name + scope + entity.name.function + settings + + + + name + Function argument + scope + variable.parameter + settings + + + + name + Tag name + scope + entity.name.tag + settings + + foreground + #790EAD + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + foreground + #450084 + + + + name + Library function + scope + support.function + settings + + foreground + #450084 + + + + name + Library constant + scope + support.constant + settings + + foreground + #450084 + + + + name + Library class/type + scope + support.type, support.class + settings + + foreground + #790EAD + + + + name + Library variable + scope + support.other.variable + settings + + foreground + #790EAD + + + + name + Invalid + scope + invalid + settings + + + + uuid + EE3AD170-2B7F-4DE1-B724-C75F13FE0085 + + diff --git a/tool/update_deps.js b/tool/update_deps.js new file mode 100644 index 00000000..c3648d9c --- /dev/null +++ b/tool/update_deps.js @@ -0,0 +1,324 @@ +var https = require("https"); +var http = require("http"); +var url = require("url"); +var fs = require("fs"); + +var Path = require("path"); +var spawn = require("child_process").spawn; +var async = require("asyncjs"); +var rootDir = __dirname + "/../lib/ace/"; + +var deps = { + csslint: { + path: "mode/css/csslint.js", + url: "https://raw.github.com/stubbornella/csslint/master/release/csslint.js", + needsFixup: true + }, + requirejs: { + path: "../../demo/kitchen-sink/require.js", + url: "https://raw.github.com/jrburke/requirejs/master/require.js", + needsFixup: false + }, + luaparse: { + path: "mode/lua/luaparse.js", + url: "https://raw.github.com/oxyc/luaparse/master/luaparse.js", + needsFixup: true, + postProcess: function(src) { + return src.replace( + /\(function\s*\(root,\s*name,\s*factory\)\s*{[\s\S]*?}\(this,\s*'luaparse',/, + "(function (root, name, factory) {\n factory(exports)\n}(this, 'luaparse'," + ) + } + }, + html5: { + path: "mode/html/saxparser.js", + browserify: { + npmModule: "git+https://github.com/aredridel/html5.git#master", + path: "html5/lib/sax/SAXParser.js", + exports: "SAXParser" + }, + fetch: browserify, + needsFixup: true, + postProcess: function(src) { + return src; + } + }, + xquery: { + path: "mode/xquery/xquery_lexer.js", + browserify: { + npmModule: "git+https://github.com/wcandillon/xqlint.git#master", + path: "xqlint/lib/lexers/xquery_lexer.js", + exports: "XQueryLexer" + }, + fetch: browserify, + needsFixup: true, + postProcess: function(src){ + return src; + } + }, + jsoniq: { + path: "mode/xquery/jsoniq_lexer.js", + browserify: { + npmModule: "git+https://github.com/wcandillon/xqlint.git#master", + path: "xqlint/lib/lexers/jsoniq_lexer.js", + exports: "JSONiqLexer" + }, + fetch: browserify, + needsFixup: true, + postProcess: function(src){ + return src; + } + }, + xqlint: { + path: "mode/xquery/xqlint.js", + browserify: { + npmModule: "git+https://github.com/wcandillon/xqlint.git#master", + path: "xqlint/lib/xqlint.js", + exports: "XQLint" + }, + fetch: browserify, + needsFixup: true, + postProcess: function(src){ + return src; + } + }, + jshint: { + path: "mode/javascript/jshint.js", + browserify: { + npmModule: "git+https://github.com/ajaxorg/jshint.git#master", + path: "jshint/src/jshint.js", + exports: "jshint" + }, + fetch: browserify, + needsFixup: true, + postProcess: function(src) { + src = src.replace( + /"Expected a conditional expression and instead saw an assignment."/g, + '"Assignment in conditional expression"' + ); + src = src.replace(/var defaultMaxListeners = 10;/, function(a) {return a.replace("10", "200")}); + return src; + } + }, + emmet: { + path: "ext/emmet core.js", + url: [ + "https://raw.github.com/sergeche/emmet-sublime/master/emmet/emmet-app.js", + "https://raw.github.com/sergeche/emmet-sublime/master/emmet/snippets.json" + ], + postProcess: function(data) { + return data[0] + .replace("define(emmet)", "define('emmet', [], emmet)") + .replace(/(emmet.define\('bootstrap'.*)[\s\S]*$/, function(_, x) { + return x + "\n" + + "var snippets = " + data[1] + ";\n" + + "var res = require('resources');\n" + + "var userData = res.getVocabulary('user') || {};\n" + + "res.setVocabulary(require('utils').deepMerge(userData, snippets), 'user');\n" + + "});"; + }); + } + }, + vim: { + fetch: function(){ + var rootHref = "https://raw.githubusercontent.com/codemirror/CodeMirror/master/" + var fileMap = {"keymap/vim.js": "keyboard/vim.js", "test/vim_test.js": "keyboard/vim_test.js"}; + async.forEach(Object.keys(fileMap), function(x, next) { + download(rootHref + x, function(e, d) { + d = d.replace(/^\(function.*{[^{}]+^}[^{}]+{/m, "define(function(require, exports, module) {"); + d = d.replace(/^\s*return vimApi;\s*};/gm, " //};") + .replace("var Vim = function() {", "$& return vimApi; } //{") + fs.writeFile(rootDir + fileMap[x], d, next) + }) + }, function() { + console.log("done") + }); + } + }, + liveScript: { + path: "mode/livescript.js", + url: "https://raw.githubusercontent.com/gkz/LiveScript/master/lib/mode-ls.js" + }, + coffee: { + fetch: function(){ + var rootHref = "https://raw.github.com/jashkenas/coffee-script/master/"; + var path = "mode/coffee/"; + + var subDir = "lib/coffee-script/"; + var deps = [ + "helpers.js", + "lexer.js", + "nodes.js", + "parser.js", + "rewriter.js", + "scope.js" + ].map(function(x) { + return { + name: x, + href: rootHref + subDir + x, + path: rootDir + path + x + }; + }); + deps.push({name:"LICENSE", href: rootHref + "LICENSE"}); + + var downloads = {}, counter = 0; + + deps.forEach(function(x) { + download(x.href, function(err, data) { + counter++; + downloads[x.name] = data; + if (counter == deps.length) + allDone(); + }); + }); + function allDone() { + deps.pop(); + var license = downloads.LICENSE.split('\n'); + license = "/**\n * " + license.join("\n * ") + "\n */"; + + deps.forEach(function(x) { + var data = downloads[x.name]; + console.log(x.name); + console.log(!data); + if (!data) + return; + if (x.name == "parser.js") { + data = data.replace("var parser = (function(){", "") + .replace(/\nreturn (new Parser)[\s\S]*$/, "\n\nmodule.exports = $1;\n\n"); + } else { + data = data.replace("(function() {", "") + .replace(/\}\).call\(this\);\s*$/, ""); + } + data = license + + "\n\n" + + "define(function(require, exports, module) {\n" + + data + + "\n});"; + + fs.writeFile(x.path, data, "utf-8", function(err){ + if (err) throw err; + console.log("File " + x.name + " saved."); + console.warn("mode/coffee/coffee-script file needs to updated manually"); + console.warn("mode/coffee/parser.js: parseError function needs to be modified"); + }); + }); + } + } + }, + xmldom: { + fetch: function() { + var rootHref = "https://raw.githubusercontent.com/iDeBugger/xmldom/master/" + var fileMap = { + "sax.js": "mode/xml/sax.js", + "dom-parser.js": "mode/xml/dom-parser.js", + "dom.js": "mode/xml/dom.js" + }; + async.forEach(Object.keys(fileMap), function(x, next) { + download(rootHref + x, function(e, d) { + fs.writeFile(rootDir + fileMap[x], d, next) + }) + }, function() { + console.log("XmlDOM updating done") + }); + } + }, +}; + +var download = function(href, callback) { + if (Array.isArray(href)) + return async.map(href, download, callback); + + var options = url.parse(href); + var protocol = options.protocol === "https:" ? https : http; + console.log("connecting to " + options.host + " " + options.path); + protocol.get(options, function(res) { + var data = ""; + res.setEncoding("utf-8"); + + res.on("data", function(chunk){ + data += chunk; + }); + + res.on("end", function(){ + callback(null, data); + }); + }); +}; + +var getDep = function(dep) { + if (!dep.fetch) + dep.fetch = download + dep.fetch(dep.url, function(err, data) { + if (dep.postProcess) + data = dep.postProcess(data); + if (dep.needsFixup) + data = "define(function(require, exports, module) {\n" + + data + + "\n});"; + + fs.writeFile(rootDir + dep.path, data, "utf-8", function(err){ + if (err) throw err; + console.log("File " + dep.path + " saved."); + }); + }); +}; + +function run(cmd, cb) { + var proc = process.platform == "win32" + ? spawn("cmd", ["/c", cmd], {cwd: __dirname}) + : spawn("bash", ["-c", cmd], {cwd: __dirname}); + + var result = "", err = ""; + proc.stderr.setEncoding("utf8"); + proc.stderr.on('data', function (data) { + err += data; + }); + + proc.stdout.setEncoding("utf8"); + proc.stdout.on('data', function (data) { + result += data; + }); + + proc.on('exit', done); + proc.on('close', done); + function done(code) { + if (code !== 0) { + console.error(cmd + '::: process exited with code :::' + code); + console.error(err) + } + cb(err, result) + } +} + +function unquote(str) { + return str.replace(/\\(.)/g, function(x, a) { + return a == "n" ? "\n" + : a == "t" ? "\t" + : a == "r" ? "\r" + : a + }); +} + +function browserify(_, cb) { + var br = this.browserify; + var path = Path.join("node_modules", br.path) + run("npm install " + this.browserify.npmModule, function() { + run("browserify " + path + " -s " + br.exports, function(err, src) { + src = src.replace(/^.*return\s*\(function/, "module.exports = (function") + .replace(/\}\);\s*$/, ""); + src = src.replace(/(\],|\{)((?:\d+|"\w+"):\[)/g, "$1\n$2") + .replace(/^(\},)(\{[^{}\[\]]*?\}\])/gm, "$1\n$2") + cb(err, src); + }) + }) +} + +var args = process.argv.slice(2); +args = args.filter(function(x) {return x[0] != "-" }); +if (!args.length) + args = Object.keys(deps); + +args.forEach(function(key) { + getDep(deps[key]) +}); + diff --git a/tool/wrap_keyword_regexp.js b/tool/wrap_keyword_regexp.js new file mode 100644 index 00000000..d1e1508a --- /dev/null +++ b/tool/wrap_keyword_regexp.js @@ -0,0 +1,21 @@ +// a little script to turn giant keyword regexps into +// something that ace can use; for example: +// +// \b(NS(Rect(ToCGRect|FromCGRect)|MakeCollectable|S(tringFromProtocol))\b +// +// into +// +// (?:\\b)(NS(?:Rect(?:ToCGRect|FromCGRect)|MakeCollectable|S(?:tringFromProtocol))(?:\b) + +var inputString = process.argv.splice(2)[0]; + +// solve word boundaries +var outputString = inputString.replace(/\\b/g, "(?:\\\\b)"); + +// I apparently need to do this, instead of something clever, because the regexp +// lastIndex is screwing up my positional +outputString = outputString.split("b)("); + +outputString = outputString[0] + "b)(" + outputString[1].replace(/\(([^\?])/g, "(?:$1"); + +console.log("\n\n" + outputString + "\n\n"); \ No newline at end of file diff --git a/version.js b/version.js index dce117ae..eaf1e5fe 100755 --- a/version.js +++ b/version.js @@ -1,4 +1,4 @@ #!/usr/bin/env node var x; -eval("x= " + require("fs").readFileSync(__dirname + "/package.json")) -console.log(x.version) \ No newline at end of file +x = require('./package'); +console.log(x.version)