├── public ├── js │ ├── termlib │ │ ├── termlib │ │ │ ├── tests │ │ │ │ ├── test1.txt │ │ │ │ ├── whats_inside.txt │ │ │ │ └── test2.txt │ │ │ ├── sample_wrap.html │ │ │ ├── term_styles.css │ │ │ ├── samples.html │ │ │ ├── multiterm_test.html │ │ │ ├── sample_invaders.html │ │ │ ├── index.html │ │ │ ├── sample_import.html │ │ │ ├── termlib_parser.js │ │ │ ├── sample_style_settings.html │ │ │ └── sample_globbing.html │ │ └── termlib_parser_min.js │ ├── ace │ │ ├── mode-xml.js │ │ ├── theme-eclipse.js │ │ ├── theme-clouds.js │ │ ├── theme-monokai.js │ │ ├── theme-cobalt.js │ │ ├── theme-dawn.js │ │ ├── keybinding-vim.js │ │ ├── theme-kr_theme.js │ │ ├── theme-idle_fingers.js │ │ ├── theme-clouds_midnight.js │ │ ├── theme-mono_industrial.js │ │ ├── theme-twilight.js │ │ ├── theme-pastel_on_dark.js │ │ ├── keybinding-emacs.js │ │ ├── mode-ruby.js │ │ ├── mode-python.js │ │ ├── mode-coffee.js │ │ ├── mode-c_cpp.js │ │ ├── mode-css.js │ │ ├── mode-javascript.js │ │ ├── mode-java.js │ │ └── mode-html.js │ └── github.js ├── images │ ├── logo.png │ ├── qmark.png │ ├── nav-rule.png │ ├── collabocats.jpg │ ├── footer_logo.png │ ├── active-arrow.png │ ├── background-v2.png │ ├── rackspace_logo.png │ ├── background-white.png │ ├── dropdown_sprites.jpg │ └── next_step_arrow.gif └── css │ ├── term.css │ └── style.css ├── .gitignore ├── Gemfile ├── config.ru ├── TODO.txt ├── LICENSE ├── Gemfile.lock ├── app.rb ├── README.md └── views ├── index.erb └── term.erb /public/js/termlib/termlib/tests/test1.txt: -------------------------------------------------------------------------------- 1 | This is just a simple sample text. -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | coverage 2 | .bundle 3 | pkg 4 | .DS_Store 5 | Gemfile.lock 6 | tmp 7 | .powrc 8 | -------------------------------------------------------------------------------- /public/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github/ghterm/HEAD/public/images/logo.png -------------------------------------------------------------------------------- /public/images/qmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github/ghterm/HEAD/public/images/qmark.png -------------------------------------------------------------------------------- /public/images/nav-rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github/ghterm/HEAD/public/images/nav-rule.png -------------------------------------------------------------------------------- /public/images/collabocats.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github/ghterm/HEAD/public/images/collabocats.jpg -------------------------------------------------------------------------------- /public/images/footer_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github/ghterm/HEAD/public/images/footer_logo.png -------------------------------------------------------------------------------- /public/images/active-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github/ghterm/HEAD/public/images/active-arrow.png -------------------------------------------------------------------------------- /public/images/background-v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github/ghterm/HEAD/public/images/background-v2.png -------------------------------------------------------------------------------- /public/images/rackspace_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github/ghterm/HEAD/public/images/rackspace_logo.png -------------------------------------------------------------------------------- /public/images/background-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github/ghterm/HEAD/public/images/background-white.png -------------------------------------------------------------------------------- /public/images/dropdown_sprites.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github/ghterm/HEAD/public/images/dropdown_sprites.jpg -------------------------------------------------------------------------------- /public/images/next_step_arrow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github/ghterm/HEAD/public/images/next_step_arrow.gif -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | gem "sinatra" 4 | gem "sinatra_auth_github" 5 | gem "nestful" 6 | gem "i18n" 7 | 8 | -------------------------------------------------------------------------------- /public/js/termlib/termlib/sample_wrap.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github/ghterm/HEAD/public/js/termlib/termlib/sample_wrap.html -------------------------------------------------------------------------------- /public/js/termlib/termlib/tests/whats_inside.txt: -------------------------------------------------------------------------------- 1 | *** Whats's in this directory? *** 2 | 3 | This directorty contains some test files to go with "sample_socket.html", 4 | the test-page for the termlib.js-socket extension "termlib_socket.js". -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | require "rubygems" 2 | require "bundler" 3 | Bundler.setup 4 | 5 | Bundler.require(:runtime) 6 | 7 | require 'app' 8 | 9 | use Rack::Static, :urls => ["/css", "/images", "/js"], :root => "public" 10 | 11 | run TerminalApp 12 | 13 | -------------------------------------------------------------------------------- /public/js/termlib/termlib/term_styles.css: -------------------------------------------------------------------------------- 1 | .term { 2 | font-family: courier,fixed,swiss,sans-serif; 3 | font-size: 12px; 4 | color: #33d011; 5 | background: none; 6 | } 7 | 8 | .termReverse { 9 | color: #111111; 10 | background: #33d011; 11 | } 12 | -------------------------------------------------------------------------------- /public/js/termlib/termlib/tests/test2.txt: -------------------------------------------------------------------------------- 1 | __ = function() { 2 | // a simple JSON test (may fail with some windows firewalls) 3 | alert('This alert is part of the server response.\nA line of text will be written to the terminal.'); 4 | this.write('\n#### THIS LINE OF TEXT IS WRITTEN BY THE IMPORTED FUNCTION ###\n '); 5 | 6 | // delete the temp ref "__" (the temp var is a MSIE 7 work around) 7 | delete window.__; 8 | } -------------------------------------------------------------------------------- /public/css/term.css: -------------------------------------------------------------------------------- 1 | .term { 2 | font-family: "Courier New",courier,fixed,monospace; 3 | font-size: 13px; 4 | color: #6f8; 5 | background: #000; 6 | letter-spacing: 1px; 7 | } 8 | .term .termReverse { 9 | color: #fff; 10 | background: #999; 11 | } 12 | #termDiv > table { 13 | border: 1px solid #aaa; 14 | } 15 | #editor { 16 | background: #fff; 17 | display: none; 18 | } 19 | #editorDiv { 20 | position: relative; 21 | width: 700px; 22 | height: 500px; 23 | background: #fff; 24 | } 25 | -------------------------------------------------------------------------------- /TODO.txt: -------------------------------------------------------------------------------- 1 | * load data on demand, not 'ls' (branches) 2 | 3 | * can create new repos with 'mkdir' 4 | * can create new files 5 | * can delete files 6 | 7 | * search / fork projects 8 | * branch - create and switch to a branch 9 | * diff 10 | 11 | * add breadcrumbs somewheres - i'm getting lost 12 | * make "edit github/master/file" work 13 | * "cd /" goes back to the root 14 | * create and switch to another branch 15 | * poll current branch to see if it changes while editing 16 | * if current branch changes - commit to another branch 17 | 18 | * bookmarklet that opens github project in ghterm 19 | * ipad keyboard (?) 20 | * improve save and close button / exp 21 | 22 | * more sidebar context and help 23 | 24 | * list files with numbers ($ edit 2) 25 | * cd into a file then ls/cat lists out the file content 26 | * advanced log options 27 | 28 | * themes for editor / syntax highlighting for files 29 | 30 | * use cached trees when listing 31 | 32 | * pjax for getting back to a place 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 Scott Chacon 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | activesupport (3.1.0.rc4) 5 | multi_json (~> 1.0) 6 | addressable (2.2.6) 7 | faraday (0.6.1) 8 | addressable (~> 2.2.4) 9 | multipart-post (~> 1.1.0) 10 | rack (>= 1.1.0, < 2) 11 | i18n (0.6.0) 12 | json (1.5.3) 13 | mime-types (1.16) 14 | multi_json (1.0.3) 15 | multipart-post (1.1.2) 16 | nestful (0.0.6) 17 | activesupport (>= 3.0.0.beta) 18 | oauth2 (0.4.1) 19 | faraday (~> 0.6.1) 20 | multi_json (>= 0.0.5) 21 | rack (1.3.0) 22 | rest-client (1.6.3) 23 | mime-types (>= 1.16) 24 | sinatra (1.2.6) 25 | rack (~> 1.1) 26 | tilt (>= 1.2.2, < 2.0) 27 | sinatra_auth_github (0.1.2) 28 | rest-client (~> 1.6.1) 29 | sinatra (~> 1.0) 30 | warden-github (~> 0.1.1) 31 | tilt (1.3.2) 32 | warden (1.0.4) 33 | rack (>= 1.0) 34 | warden-github (0.1.1) 35 | json (~> 1.5) 36 | oauth2 (~> 0.4.1) 37 | warden (~> 1.0.4) 38 | 39 | PLATFORMS 40 | ruby 41 | 42 | DEPENDENCIES 43 | i18n 44 | nestful 45 | sinatra 46 | sinatra_auth_github 47 | -------------------------------------------------------------------------------- /public/js/ace/mode-xml.js: -------------------------------------------------------------------------------- 1 | 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}),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}) -------------------------------------------------------------------------------- /app.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra' 2 | require 'sinatra_auth_github' 3 | require 'nestful' 4 | 5 | class TerminalApp < Sinatra::Base 6 | enable :sessions 7 | 8 | set :github_options, { 9 | :secret => ENV['GITHUB_CLIENT_SECRET'], 10 | :client_id => ENV['GITHUB_CLIENT_ID'], 11 | :scopes => 'user,repo' 12 | } 13 | 14 | register Sinatra::Auth::Github 15 | 16 | HOST = 'https://api.github.com' 17 | 18 | get '/' do 19 | if github_user 20 | redirect '/term' 21 | else 22 | erb :index 23 | end 24 | end 25 | 26 | get '/term' do 27 | if github_user 28 | @user = github_user 29 | erb :term 30 | else 31 | redirect '/' 32 | end 33 | end 34 | 35 | get '/authenticate' do 36 | authenticate! 37 | redirect '/term' 38 | end 39 | 40 | post '/proxy' do 41 | url = HOST + '/' + params.delete('proxy_url') 42 | p = JSON.parse(Base64.decode64(params['datap'])) 43 | p['access_token'] = github_user.token 44 | 45 | resp = Nestful.post url, :params => p 46 | 47 | content_type :json 48 | resp 49 | end 50 | 51 | get '/logout' do 52 | logout! 53 | redirect '/' 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /public/js/ace/theme-eclipse.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/eclipse",function(a,b,c){var d=a("pilot/dom"),e=a("text!ace/theme/eclipse.css");d.importCssString(e),b.cssClass="ace-eclipse"}),define("text!ace/theme/eclipse.css",".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: 40px; background: rgb(227, 227, 227); border-right: 1px solid rgb(159, 159, 159);\t color: rgb(136, 136, 136);}.ace-eclipse .ace_gutter-layer { right: 10px; text-align: right;}.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 {\tcolor: 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);}") -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **NOTE: This repository is no longer supported or updated by GitHub. If you wish to continue to develop this code yourself, we recommend you fork it.** 2 | 3 | # GitHub Terminal 4 | 5 | This is an example application written to demonstrate what is possible with the new GitHub [Git Data API][api] and GitHub OAuth2 services. This app allows you to login as your GitHub user and edit and commit groups of files through a virtual terminal. With this you could contribute meaningfully to a project using just Javascript in the browser - no Git or editor needs to be installed locally. 6 | 7 | [api]: http://developer.github.com/v3/git/ 8 | 9 | # Features 10 | 11 | Currently, you can: 12 | 13 | * List all the projects you have read and write access to. 14 | * `cd` into any project and branch and `ls` as if it were a directory. 15 | * Edit any file in a project you have write access to. 16 | * Commit your edited files directly to your GitHub branch. 17 | * View status of changed files with `status` and unstage them with `unstage` command. 18 | * View the commit log of any branch with `log` command. 19 | 20 | # Screenshots 21 | 22 | ![list projects](https://img.skitch.com/20110615-1i4r8dub96267e7fdswhuqcerx.png) 23 | 24 | Here we can see a listing of my projects, in this case with a filter on the string 'git-'. Private repositories are listed in orange. 25 | 26 | ![list tree](https://img.skitch.com/20110615-rq4ccy7gg49nrm25rp2j1swkdg.png) 27 | 28 | You can `cd` into a project and a branch, then an `ls` will show you the project tree. 29 | 30 | # Libraries Used 31 | 32 | * Ace JS Editor (http://ace.ajax.org/) 33 | * Termlib (http://www.masswerk.at/termlib/) 34 | * GitHub-API JS Library (https://github.com/fitzgen/github-api) (hacked to death) 35 | 36 | # Contributing 37 | 38 | If you want to fix or change something, please fork on GitHub, push your change to a branch named after your change and send me a pull request. 39 | 40 | Some ideas of things to do are in the TODO file. 41 | 42 | # License 43 | 44 | MIT, see LICENCE file 45 | 46 | -------------------------------------------------------------------------------- /public/js/ace/theme-clouds.js: -------------------------------------------------------------------------------- 1 | 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"}) -------------------------------------------------------------------------------- /public/js/ace/theme-monokai.js: -------------------------------------------------------------------------------- 1 | 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"}) -------------------------------------------------------------------------------- /public/js/ace/theme-cobalt.js: -------------------------------------------------------------------------------- 1 | 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"}) -------------------------------------------------------------------------------- /public/js/ace/theme-dawn.js: -------------------------------------------------------------------------------- 1 | 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"}) -------------------------------------------------------------------------------- /public/js/ace/keybinding-vim.js: -------------------------------------------------------------------------------- 1 | define("ace/keyboard/keybinding/vim",function(a,b,c){var d=a("ace/keyboard/state_handler").StateHandler,e=a("ace/keyboard/state_handler").matchCharacterOnly,f={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:e}],insertMode:[{key:"esc",then:"start"}]};b.Vim=new d(f)}),define("ace/keyboard/state_handler",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 7 | 8 | you are free to use this parser under the "termlib.js" license: 9 | http://www.masswerk.at/termlib/ 10 | */ 11 | function Parser(){this.whiteSpace={' ':true,'\t':true};this.quoteChars={'"':true,"'":true,'`':true};this.singleEscapes={'\\':true};this.optionChars={'-':true};this.escapeExpressions={'%':Parser.prototype.plugins.hexExpression};} 12 | Parser.prototype={version:'1.1',plugins:{hexExpression:function(termref,charindex,escapechar,quotelevel){if(termref.lineBuffer.length>charindex+2){var hi=termref.lineBuffer.charAt(charindex+1);var lo=termref.lineBuffer.charAt(charindex+2);lo=lo.toUpperCase();hi=hi.toUpperCase();if((((hi>='0')&&(hi<='9'))||((hi>='A')&&((hi<='F'))))&&(((lo>='0')&&(lo<='9'))||((lo>='A')&&((lo<='F'))))){Parser.prototype.plugins._escExprStrip(termref,charindex+1,charindex+3);return String.fromCharCode(parseInt(hi+lo,16));}} 13 | return escapechar;},_escExprStrip:function(termref,from,to){termref.lineBuffer=termref.lineBuffer.substring(0,from)+ 14 | termref.lineBuffer.substring(to);}},getopt:function(termref,optsstring){var opts={'illegals':[]};while((termref.argc0)&&(this.optionChars[a.charAt(0)])){var i=1;while(i='0')&&(nc<='9'))){v+=nc;i++;} 15 | else{break;}} 16 | if(optsstring.indexOf(c)>=0){opts[c]=(v=='')?{value:-1}:(isNaN(v))?{value:0}:{value:parseFloat(v)};} 17 | else{opts.illegals[opts.illegals.length]=c;} 18 | i++;} 19 | termref.argc++;} 20 | else{break;}} 21 | return opts;},parseLine:function(termref){var argv=[''];var argQL=[''];var argc=0;var escape=false;for(var i=0;i=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\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(RubyHighlightRules,f),b.RubyHighlightRules=RubyHighlightRules}) -------------------------------------------------------------------------------- /public/js/ace/mode-python.js: -------------------------------------------------------------------------------- 1 | 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}),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;PythonHighlightRules=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(PythonHighlightRules,f),b.PythonHighlightRules=PythonHighlightRules}) -------------------------------------------------------------------------------- /public/js/ace/mode-coffee.js: -------------------------------------------------------------------------------- 1 | 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}),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}) -------------------------------------------------------------------------------- /views/index.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Terminal.GitHub 6 | 7 | 8 | 9 | 10 | 11 | 12 | 63 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /public/js/ace/mode-c_cpp.js: -------------------------------------------------------------------------------- 1 | define("ace/mode/c_cpp",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/tokenizer").Tokenizer,g=a("ace/mode/c_cpp_highlight_rules").c_cppHighlightRules,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)}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)}}.call(j.prototype),b.Mode=j}),define("ace/mode/c_cpp_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;c_cppHighlightRules=function(){var a=new f,b=e.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("|")),c=e.arrayToMap("NULL".split("|"));this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},a.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{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",regex:"<[a-zA-Z0-9.]+>"},{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(c_cppHighlightRules,g),b.c_cppHighlightRules=c_cppHighlightRules}),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}) -------------------------------------------------------------------------------- /views/term.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Terminal.GitHub 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 68 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /public/js/termlib/termlib/samples.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | mass:werk termlib samples 4 | 5 | 90 | 91 | 92 | 93 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 |
termlib.js home|multiple terminals|parser|faq|documentation|samples
111 | 112 | 113 | 116 | 147 |
114 |

mass:werk termlib.js samples

115 |
117 |

Here are some sample pages that address different issues of advanced usage of termlib.js:

118 |

 

119 | 120 |
    121 |
  • The Chrome Sample
    122 | shows how to implement a Terminal-object inside a window-like DHTML-division. (This is a quite old example.)
  • 123 |
  • The Import Sample
    124 | shows how to import/paste text into a terminal window.
  • 125 |
  • The Socket Sample
    126 | demos the termlib.js-socket extension for client-server communication (AJAX).
  • 127 |
  • The Remote Terminal Sample
    128 | shows how to implement a terminal client to a remote host using the termlib.js-socket extension. As this sample requires a backend at the server-side, it won't work out of the box.
  • 129 |
  • The Color Sample
    130 | demos the color support introduced with version 1.2.
  • 131 |
  • The Text Wrap Sample
    132 | demos the wrapping support introduced with version 1.3.
  • 133 |
  • The Style Settings Sample
    134 | demos the style configuration introduced with version 1.4 and shows, how to implement a custom style for bold.
  • 135 |
  • Text Globbing Sample
    136 | demonstrates how to set up a modal state (here a dialog), how to trap a special key, and how to acces the current input of the command line.
  • 137 |
  • ANSI-Mapping Sample
    138 | demonstrates how to make use of the new support for ANSI-SRG-codes.
  • 139 |
  • Termlib-Invaders
    140 | a sample application featuring a Space Invaders game.
  • 141 |
142 | 143 |

 

144 |

Please consult the source code of this pages for implemntation details.

These pages are only demonstrations, and provided AS IS without any warranty of any kind.
Most of these samples won't work with Netscape Navigator 4.x

145 | 146 |
148 | 149 | 150 | -------------------------------------------------------------------------------- /public/js/ace/mode-css.js: -------------------------------------------------------------------------------- 1 | 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}),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 2 | 3 | termlib Multiple Terminal Test 4 | 5 | 6 | 97 | 98 | 153 | 154 | 155 | 156 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 |
termlib.js home|multiple terminals|parser|faq|documentation|samples
174 | 175 | 176 | 179 | 182 | 185 | 190 |
177 | Multiple Terminal Test
  178 |
180 | > open terminal 1   181 |
183 | > open terminal 2   184 |
186 |  
187 | (c) mass:werk,
N. Landsteiner 2003-2005
188 | http://www.masswerk.at 189 |
191 | 192 |
193 |
194 | 195 | 196 | -------------------------------------------------------------------------------- /public/js/ace/mode-javascript.js: -------------------------------------------------------------------------------- 1 | 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(JavaScriptHighlightRules,g),b.JavaScriptHighlightRules=JavaScriptHighlightRules}),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}),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 2 | 3 | 4 | Invaders Sample 5 | 6 | 7 | 8 | 93 | 94 | 192 | 193 | 194 | 195 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 |
termlib.js home|multiple terminals|parser|faq|documentation|samples
213 | 214 | 215 | 216 | 237 | 260 | 261 |
217 | 218 | 221 | 224 | 227 | 230 | 235 |
219 | Invaders Sample
  220 |
222 | > open terminal   223 |
225 |

> play invaders 

226 |
228 |   229 |
231 |  
232 | (c) mass:werk,
N. Landsteiner 2005-2008
233 | http://www.masswerk.at 234 |
236 |
238 |

Termlib - Invaders
 

239 |

A simple text-mode invaders game.

240 |

Requires version 1.4 of "termlib.js".

241 |

Usage:

242 |

    TermlibInvaders.start(TerminalRef [, maxCols [, maxRows]])

243 |

returns status (boolean, true: success).

244 |

The optional arguments maxCols and maxRows specify the maximum dimensions to use for the game. If the terminal window is bigger, the game will be centered in the window and a frame will be drawn around.

245 | 246 |

The code is contained in a single global object and supports configurable colors using the web-colors API.

247 | 248 |

Usage example:

249 | 250 |

if ( TermlibInvaders.start(this) ) {
251 |     return;
252 | }
253 | else {
254 |     // oops, terminal doesn't meet the requirements
255 |     this.write('Sorry, invaders failed.');
256 | }

257 | 258 |

 

259 |
262 | 263 | 264 | 265 | 266 | -------------------------------------------------------------------------------- /public/js/ace/mode-java.js: -------------------------------------------------------------------------------- 1 | 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}),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(JavaScriptHighlightRules,g),b.JavaScriptHighlightRules=JavaScriptHighlightRules}),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}),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(JavaHighlightRules,g),b.JavaHighlightRules=JavaHighlightRules}) -------------------------------------------------------------------------------- /public/js/termlib/termlib/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | mass:werk termlib 4 | 5 | 90 | 91 | 92 | 93 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 |
termlib.js home|multiple terminals|parser|faq|documentation|samples
111 | 112 | 113 | 116 | 142 | 173 | 179 | 187 | 195 | 204 | 215 | 220 | 226 | 231 | 235 | 238 |
114 |

mass:werk termlib.js

115 |
117 | The JavaScript library "termlib.js" provides a `Terminal' object, which 118 | facillitates a simple and object oriented approach to generate and control a 119 | terminal-like interface for web services.

120 | 121 | "termlib.js" features direct keyboard input and powerful output methods 122 | for multiple and simultanious instances of the `Terminal' object.

123 | 124 | The library was written with the aim of simple usage and a maximum of compatibility 125 | with minimal foot print in the global namespace.


126 | 127 | 128 | A short example:
129 |
130 |   var term = new Terminal( {handler: termHandler} );
131 |   term.open();
132 | 
133 |   function termHandler() {
134 |      this.newLine();
135 |      var line = this.lineBuffer;
136 |      if (line != "") {
137 |         this.write("You typed: "+line);
138 |      }
139 |      this.prompt();
140 |   }
141 |
143 | Key Features: 144 | 145 |
    146 |
  • Object oriented: Handle multiple instances independently at the same time!
  • 147 |
  • Type styles: Ready-to-use type styles and support for custom styles and mark up.
  • Colors: Extended support for colors. 149 |
  • ANSI codes: Limited ANSI-support for SGR codes.
  • 150 |
  • Text wrapping: Automatic text wrapping (v 1.3 and higher, see faq for details)
  • 151 |
  • Remote communications: The socket extension for client-server remote communication (commonly known as AJAX) provides a tightly integrated API for a simple and object oriented approach to XMLHttpRequests.
    (Starting with version 1.5 the socket extension is included in the main library.)
  • 152 |
  • Import methods: "termlib.js" provides methods for text import via dialogs or copy'n'paste.
  • 153 |
  • Parser: Set up your own shell-like application using the included parser.
  • 154 |
  • Documentation: Extensive documentation and loads of usage examples.
  • 155 |
  • Free: Best of all: "termlib.js" is free, see the licence below.
  • 156 |
157 | 158 | Note on Backward Compatibility:

159 | 160 | 161 | 162 | 163 | 165 | 166 | 167 | 168 | 169 | 170 | 171 |
Version 1.5: Changed the license.
Also dropped support for Netscape 4 (layers) and included the socket extension in the main library.
164 | As the socket extension is now included in the library, please delete any script-tags refering to "termlib_socket.js" from older applications!
 
Version 1.52: Re-organized the Parser. The parser is now a self-contained object with a constructor.
 
172 |
174 | License

175 | 176 | This JavaScript-library is free.
177 | Include a visible backlink to <http://www.masswerk.at/termlib/> in the embedding web page or application. The library should always be accompanied by the "readme.txt" and the sample HTML-documents. 178 |
180 | Distribution

181 | 182 | This JavaScript-library may be distributed freely as long it is distributed together with the "readme.txt" and the sample HTML-documents and this document.

183 | 184 | Any changes to the library should be commented and be documented in the readme-file.
185 | Any changes must be reflected in the `Terminal.version' string as "Version.Subversion (compatibility)". 186 |
188 | Disclaimer

189 | 190 | This software is distributed AS IS and in the hope that it will be useful, but WITHOUT ANY 191 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 192 | PURPOSE. The entire risk as to the quality and performance of the product is borne by the 193 | user. No use of the product is authorized hereunder except under this disclaimer. 194 |
196 | History

197 | 198 | This library evolved from the terminal script "TermApp" ((c) N. Landsteiner 2003) and is in its 199 | current form a down scaled spinn-off of the "JS/UIX" project. (JS/UIX is not a free software by now.) 200 | c.f.: <http://www.masswerk.at/jsuix>

201 | 202 | For version history: see the readme.txt. 203 |
205 |  
206 | Download

207 | Be sure to have read the license information and the disclamer and that you are willing to respect copyrights.

208 | 209 | Download: termlib.zip (~ 140 KB, incl. docs & sample pages)

210 | Current version is "1.57 (original)".
211 | Files are provided with line breaks in format <CRLF>.
212 | The ZIP-archive includes now also a compacted version of "termlib.js". 213 |   214 |
216 | Donations

217 | 218 | Donations are welcome: You may use the PayPal-button to support and/or honor the development of "termlib.js" at: http://www.masswerk.at/termlib/donate/ 219 |
221 | Author

222 | © Norbert Landsteiner 2003-2010
223 | mass:werk – media environments
224 | http://www.masswerk.at 225 |
227 |  
228 | Author's note:
229 | Please do not contact me on questions of simple usage. There is an extensive documentation (readme.txt) including plenty of sample code that should provide all information you need. 230 |
232 |  
233 | > top of page 234 |
236 |   237 |
239 | 240 | 241 | -------------------------------------------------------------------------------- /public/js/termlib/termlib/sample_import.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | termlib Text Import Sample 4 | 5 | 6 | 107 | 108 | 201 | 202 | 203 | 204 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 |
termlib.js home|multiple terminals|parser|faq|documentation|samples
222 | 223 | 224 | 225 | 248 | 281 | 282 |
226 | 227 | 230 | 233 | 238 | 241 | 246 |
228 | Text Import Sample
  229 |
231 | > open terminal   232 |
234 |

> test insertText() 

235 |

> test importEachLine() 

236 |

> test importMultiLine() 

237 |
239 |   240 |
242 |  
243 | (c) mass:werk,
N. Landsteiner 2005-2007
244 | http://www.masswerk.at 245 |
247 |
249 |

How to import text to a termlib.js Terminal object.
 

250 |

This page demos 3 different methods of TermGlobals for text import:

251 |
    252 |
  • TermGlobals.insertText( text:String )
    253 | Auto-types a given text at the current cursor position.
    254 | this is a true input (just as it came form the keyboard).
    255 | Works only with single line input.
    256 |  
  • 257 |
  • TermGlobals.importEachLine( text:String )
    258 | Types multiline input to the current command line.
    259 | The given text exchanges any text on the current command line.
    260 | Each line is executed separately - just as if it would have
    261 | been typed with a trailing <ENTER> each.
    262 |   263 |
  • 264 |
  • TermGlobals.importMultiLine( text:String )
    265 | Imports multiple lines of text as one input, fakes terminal input.
    266 | The whole text will be imported as one string using "\n" as line
    267 | separator. (As all non-printable characters the newline will be
    268 | displayed as a caret [CARET/CIRCUMFLEX ACCENT] using type().)
    269 | As with TermGlobals.importEachLine() any text in the current
    270 | command line will be lost.
    271 |   272 |
  • 273 |
274 | 275 |

Note on forms for input:
276 | Be sure to set TermGlobals.keylock to true before waiting for any form input!

277 | 278 |

All three methods act on the currently active Terminal-object and return their
success. A negative return value indicates an inactive terminal, or a global or
279 | individual lock => ((TermGlobals.keylock) || (TermGlobals.activeTerm.lock)).

280 |
283 | 284 | 285 | 286 | 304 | 305 | 306 | -------------------------------------------------------------------------------- /public/css/style.css: -------------------------------------------------------------------------------- 1 | html { 2 | height: 100%; 3 | } 4 | 5 | .index-content { 6 | width: 500px; 7 | padding: 5px; 8 | margin: 0 auto; 9 | } 10 | 11 | .index-content ul, 12 | .index-content ol { 13 | margin-left: 1.5em; 14 | } 15 | 16 | .index-content ul { 17 | list-style-type: disc; 18 | } 19 | 20 | .index-content ul code, 21 | p code { 22 | font: 12px Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace; 23 | color: #52595d; 24 | -webkit-border-radius: 3px; 25 | -moz-border-radius: 3px; 26 | border-radius: 3px; 27 | -moz-background-clip: padding; 28 | -webkit-background-clip: padding-box; 29 | background-clip: padding-box; 30 | border: 1px solid #ccc; 31 | background-color: #f9f9f9; 32 | padding: 0px 3px; 33 | display: inline-block; 34 | } 35 | 36 | 37 | 38 | /* Remove Below */ 39 | 40 | #header .logo img { 41 | left:-25px; 42 | top:-3px; 43 | } 44 | 45 | #header { 46 | height:81px; 47 | } 48 | #main { 49 | background-position-y: -10px 50 | } 51 | .topsearch .nav { 52 | position:relative; 53 | top:9px; 54 | } 55 | 56 | .category_index { float: left; margin: 0.25em; width:19em; } 57 | .category_index h2 { background: #ddd; text-align: center; padding: 0.25em; margin-bottom: 0.5em; } 58 | .category_index dt, .category_index dd { margin-right: 0.5em; } 59 | .category_index dt { margin-left: 0.5em !important; } 60 | .category_index dd { margin-left: 1.5em !important; } 61 | 62 | 63 | /*********************/ 64 | /* Sidebar */ 65 | /*********************/ 66 | 67 | #guides .guide .sidebar h3 { 68 | padding: 4px; 69 | margin: .2em 0; 70 | } 71 | #guides .guide .sidebar h3:focus { outline: none; } 72 | 73 | .sidebar dl { padding: 0 0.5em 0.5em 0.5em; } 74 | .sidebar dt { 75 | font-weight: bold; 76 | margin-top: 0.5em; 77 | } 78 | 79 | .ui-icon { 80 | display: inline-block; 81 | width: 16px; 82 | height: 16px; 83 | background-color: white; 84 | background-position: -2px 2px; 85 | background-repeat: no-repeat; 86 | } 87 | .ui-icon-triangle-expand { background-image: url(/images/expand.png); } 88 | .ui-icon-triangle-collapse { background-image: url(/images/collapse.png); } 89 | 90 | /****************************/ 91 | /* Forking ribbon */ 92 | /****************************/ 93 | 94 | @font-face { 95 | font-family: Collegiate; 96 | src: url("/Collegiate.ttf"); 97 | } 98 | 99 | .myribbon { 100 | position: absolute; 101 | top: 0; 102 | overflow: hidden; 103 | height: 12em; 104 | right: 0; 105 | } 106 | 107 | .myribbon a, myribbon a:hover { text-decoration: none; } 108 | 109 | .myribbon a { 110 | /* Font */ 111 | font-family: Collegiate, sans-serif; 112 | letter-spacing: -.1px; 113 | opacity: 0.95; 114 | font-size: 125%; 115 | line-height: 1.35em; 116 | 117 | /* Position */ 118 | display: block; 119 | position: relative; 120 | top: 2.5em; 121 | right: -2.6em; 122 | padding: 0.25em 0; 123 | 124 | /* Sit and spin */ 125 | -moz-transform: rotate(45deg); 126 | -webkit-transform: rotate(45deg); 127 | 128 | /* Defaults friendly for white pages. */ 129 | -moz-box-shadow: 0 0 13px #888; 130 | -webkit-box-shadow: 0 0 13px #888; 131 | color: #FFF; 132 | text-shadow: 0 0 0.5em #444; 133 | 134 | /* Culla */ 135 | background-color: #9a0000; 136 | background: -webkit-gradient(linear, left bottom, left top, from(#9a0000), to(#a90000)); 137 | } 138 | 139 | .myribbon a span { 140 | padding: 0.1em 3em; 141 | border: 1px solid #bf6060; 142 | } 143 | 144 | /****************************/ 145 | /* Bootcamp tuts */ 146 | /****************************/ 147 | .short-bottom-marg { 148 | margin-bottom: 5px; 149 | } 150 | p.next-step strong, .next-steps { 151 | color: #666666; 152 | } 153 | .next-steps { 154 | font-weight: bold; 155 | } 156 | .next-steps a { 157 | background-image: url('/images/bootcamp/next_step_arrow.gif'); 158 | background-repeat: no-repeat; 159 | background-position: right 50%; 160 | padding-right: 15px; 161 | } 162 | .next-steps a:hover { 163 | padding-right: 20px; 164 | text-decoration: none; 165 | } 166 | 167 | .founders { 168 | overflow: hidden; 169 | margin: 0px; 170 | } 171 | .founder { 172 | background:#f5f5f5; 173 | filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#fcfcfc',endColorstr='#ececec'); 174 | background:-webkit-gradient(linear,0% 0,0% 100%,from(#fcfcfc),to(#e8e8e8)); 175 | background:-moz-linear-gradient(270deg,#fcfcfc,#ececec);border-color:#eee; 176 | border:1px solid #e9e9e9; 177 | border-bottom-color:#f5f5f5; 178 | -webkit-border-radius:5px; 179 | -moz-border-radius:5px; 180 | border-radius:5px; 181 | -webkit-box-shadow:0 1px 1px rgba(0,0,0,0.2); 182 | -moz-box-shadow:0 1px 1px rgba(0,0,0,0.2); 183 | box-shadow:0 1px 1px rgba(0,0,0,0.2); 184 | display: block; 185 | position: relative; 186 | width: 250px; 187 | padding: 5px; 188 | overflow: hidden; 189 | margin: 0px 5px 5px 0px; 190 | float: left; 191 | list-style-type: none; 192 | } 193 | 194 | .founder:hover { 195 | text-decoration: none; 196 | background:#e5e5e5; 197 | filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#ececec',endColorstr='#dcdcdc'); 198 | background:-webkit-gradient(linear,0% 0,0% 100%,from(#ececec),to(#d8d8d8)); 199 | background:-moz-linear-gradient(270deg,#ececec,#dcdcdc);border-color:#ddd; 200 | } 201 | 202 | .founder img { 203 | float: left; 204 | position: relative; 205 | -webkit-box-shadow: none; 206 | -moz-box-shadow: none; 207 | box-shadow: none; 208 | border:1px solid #e9e9e9; 209 | margin-right: 1em; 210 | } 211 | .founder h4 { 212 | position: relative; 213 | font-size: 1.3em; 214 | color: #000; 215 | margin: .3em 0px 0px; 216 | } 217 | .founder p { 218 | position: relative; 219 | font-weight: bold; 220 | margin:0px !important; 221 | color: #666666; 222 | margin: 0px; 223 | } 224 | 225 | .step-title { 226 | font-weight: bold; 227 | display: inline-block; 228 | margin-top: 1em; 229 | } 230 | 231 | .step-title span { 232 | font-weight: normal; 233 | font-style: oblique; 234 | color: #666666; 235 | } 236 | 237 | img.bootcamp { 238 | display: block; 239 | } 240 | 241 | img.top-margin { 242 | margin-top: 1em !important; 243 | } 244 | 245 | /****************************/ 246 | /* Bootcamp module */ 247 | /****************************/ 248 | 249 | 250 | .bootcamp-help { 251 | margin: 0 0 20px 0; 252 | } 253 | 254 | .bootcamp-help h1 { 255 | color: #fff; 256 | font-size: 16px; 257 | font-weight: bold; 258 | background-color: #405a6a; 259 | background: -moz-linear-gradient(center top , '#829AA8', '#405A6A'); 260 | filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#829aa8', endColorstr='#405a6a'); 261 | background: -webkit-gradient(linear, left top, left bottom, from(#829aa8), to(#405a6a)); 262 | background: -moz-linear-gradient(top, #829aa8, #405a6a); 263 | border: 1px solid #677c89; 264 | border-bottom-color: #6b808d; 265 | border-radius: 5px 5px 0 0; 266 | -moz-border-radius: 5px 5px 0 0; 267 | -webkit-border-radius: 5px 5px 0 0; 268 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.7); 269 | margin: 0; 270 | padding: 8px 18px; 271 | position: relative; 272 | } 273 | .bootcamp-help h1 a { 274 | color:#fff; 275 | text-decoration:none; 276 | } 277 | 278 | .bootcamp-help h1 span { 279 | color: #e9f1f4; 280 | font-size: 70%; 281 | font-weight: normal; 282 | text-shadow: none; 283 | } 284 | 285 | .bootcamp-help .bootcamp-body { 286 | padding: 10px 0px 10px 10px; 287 | background-color: #e9f1f4; 288 | overflow: hidden; 289 | border-style: solid; 290 | border-width: 1px 1px 2px; 291 | border-color: #e9f1f4 #d8dee2 #d8dee2; 292 | border-radius: 0 0 5px 5px; 293 | -moz-border-radius: 0 0 5px 5px; 294 | -webkit-border-radius: 0 0 5px 5px; 295 | } 296 | 297 | .bootcamp-help ul { 298 | list-style-type: none; 299 | position: relative; 300 | margin: 0px; 301 | overflow: hidden; 302 | } 303 | 304 | .bootcamp-help ul li { 305 | color: #666666; 306 | font-size: 13px; 307 | font-weight: normal; 308 | background-color: #fffff5; 309 | background: -moz-linear-gradient(center top , '#fffff5', '#f5f3b4'); 310 | filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#fffff5', endColorstr='#f5f3b4'); 311 | background: -webkit-gradient(linear, left top, left bottom, from(#fffff5), to(#f5f3b4)); 312 | background: -moz-linear-gradient(top, #fffff5, #f5f3b4); 313 | border: 1px solid #dfddb5; 314 | border-radius: 5px 5px 5px 5px; 315 | -moz-border-radius: 5px 5px 5px 5px; 316 | -webkit-border-radius: 5px 5px 5px 5px; 317 | display: block; 318 | width: 125px; 319 | height: 122px; 320 | float: left; 321 | position: relative; 322 | margin: 0 10px 0 0; 323 | -moz-box-shadow: 0px 1px 0px #fff; 324 | -webkit-box-shadow: 0px 1px 0px #fff; 325 | box-shadow: 0px 1px 0px #fff; 326 | } 327 | 328 | .bootcamp-help ul li:hover { 329 | background: -moz-linear-gradient(center top , '#fcfce9', '#f1eea3'); 330 | filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#fcfce9', endColorstr='#f1eea3'); 331 | background: -webkit-gradient(linear, left top, left bottom, from(#fcfce9), to(#f1eea3)); 332 | background: -moz-linear-gradient(top, #fcfce9, #f1eea3); 333 | border: 1px solid #d6d4ad; 334 | } 335 | 336 | .bootcamp-help ul li a { 337 | color: #666666; 338 | text-decoration: none; 339 | } 340 | 341 | .bootcamp-help .image { 342 | display: block; 343 | position: relative; 344 | height: 83px; 345 | border-bottom: 1px solid #f1efaf; 346 | background-repeat: no-repeat; 347 | background-position: 0 10px; 348 | background-image: url(/images/bootcamp_sprites.png); 349 | } 350 | 351 | .bootcamp-help .setup .image { 352 | background-position: 0px 10px; 353 | } 354 | .bootcamp-help .create-a-repo .image { 355 | background-position: -125px 10px; 356 | } 357 | .bootcamp-help .fork-a-repo .image { 358 | background-position: -250px 10px; 359 | } 360 | .bootcamp-help .be-social .image { 361 | background-position: -375px 10px; 362 | } 363 | 364 | .bootcamp-help ul li:hover .image { 365 | border-bottom: 1px solid #f1eea3; 366 | } 367 | 368 | .bootcamp-help .desc { 369 | padding: 8px; 370 | display: block; 371 | overflow: hidden; 372 | border-top: 1px solid #fff; 373 | background-repeat:no-repeat; 374 | position: relative; 375 | z-index: 2; 376 | text-align: center; 377 | } 378 | 379 | .bootcamp-help ul li:hover .desc { 380 | border-top: 1px solid #fcfce9; 381 | } 382 | 383 | .bootcamp-help .desc h2 { 384 | margin: 0px; 385 | padding: 0px; 386 | font-size: 15px; 387 | color: #393939; 388 | } 389 | 390 | .bootcamp-help .desc p { 391 | margin: 0px; 392 | padding: 0px; 393 | line-height: 1.2em; 394 | } 395 | 396 | /* @end */ 397 | 398 | -------------------------------------------------------------------------------- /public/js/termlib/termlib/termlib_parser.js: -------------------------------------------------------------------------------- 1 | /* 2 | termlib_parser.js v.1.1 3 | command line parser for termlib.js 4 | (c) Norbert Landsteiner 2005-2010 5 | mass:werk - media environments 6 | 7 | 8 | you are free to use this parser under the "termlib.js" license. 9 | 10 | Synopsis: 11 | 12 | var parser = new Parser(); 13 | parser.parseLine(this); 14 | var command = this.argv[this.argc++]; 15 | 16 | Usage: 17 | 18 | Call method "parseLine(this)" from inside of your Terminal-handler. 19 | This will parse the current command line to chunks separated by any amount of 20 | white space (see property whiteSpace). 21 | "parseLine" will inject the following properties into the Terminal instance: 22 | 23 | this.argv: Array of parsed chunks (words, arguments) 24 | this.argQL: Array of quoting level per argument 25 | This array will contain the according quote character or an 26 | empty string for each element of argv with the same index 27 | this.argc: A pointer to this.argv and this.argQL 28 | (initially set to 0; used by method getopt) 29 | 30 | E.g.: For the string: This is "quoted". 31 | argv will result to ['this', 'is', 'quoted', '.'] 32 | and argQL will result to ['', '', '"', ''] 33 | if '"' is defined as a quote character (default: ', ", and `) 34 | 35 | getopt(this, "") 36 | Call this method from inside of your handler to parse any options from the 37 | next chunk in this.argv that this.argc points to. 38 | Options are considered any arguments preceded by an option character in the 39 | property optionChars (default: "-"). The second argument is a string 40 | containing all characters to be considered legal option flags. 41 | The method returns an object with a property of type object for any option 42 | flag (defined as a character in the options-string) found in argv. 43 | argc will be advanced to the first element of argv that is not an option. 44 | Each of the flag-objects will contain the property `value'. 45 | In case that the option flag was immediately followed by a number 46 | (unsigned float value), this will be stored as a number in the value, 47 | otherwise the value will be set to -1. 48 | Any flags that were not defined in the options-string will be stored as 49 | an array of chars in the property `illegals' of the returned object. 50 | 51 | E.g.: 52 | 53 | this.argv: ["test", "-en7a", "-f", "next"] 54 | this.argc: set initially to 0 55 | 56 | var command = this.argv[this.argc++]; // this.argc now points to 2nd chunk 57 | var options = parser.getopt(this, "en"); 58 | 59 | getopt will return the following object: 60 | { 61 | 'e': { value: -1 }, 62 | 'n': { value: 7 }, 63 | 'illegals': ['a', 'f'] 64 | } 65 | and this.argc will be set to 3, pointing to "next". 66 | 67 | Escape expressions: 68 | The parser can handle escape sequences, e.g.: hexdecimal notations of 69 | characters that are preceded by an escape character. (default: parse any 70 | 2-byte hex expressions preceded by "%" as a character, e.g. "%41" => "A") 71 | Escape characters are defined in the property escapeExpressions with the 72 | according method as their value. (The given function or method must be present 73 | at creation and takes four arguments: terminal instance, current char-position, 74 | the escape character found, and the current quoting level. The method or function 75 | is expected to strip any escape sequence of the lineBuffer and to return a string 76 | to be inserted at the current parsing position.) 77 | The result of an escape expression will allways add to the current chunk and will 78 | never result in parsed white space. 79 | 80 | Configuration: you may want to overide the follow objects (or add properties): 81 | parser.whiteSpace: chars to be parsed as white space 82 | parser.quoteChars: chars to be parsed as quotes 83 | parser.singleEscapes: chars to escape a quote or escape expression 84 | parser.optionChars: chars that start an option 85 | parser.escapeExpressions: chars that start escape expressions 86 | 87 | v. 1.1: Parser is now a function with a constructor. 88 | Configurations can be handled at a per-instance basis. 89 | Parser is now a single, self-contained object in the global name space. 90 | Note: we are not storing the terminal instance in order to avoid memory leakage. 91 | */ 92 | 93 | function Parser() { 94 | // config: 95 | 96 | // chars to be parsed as white space 97 | this.whiteSpace = { 98 | ' ': true, 99 | '\t': true 100 | }; 101 | 102 | // chars to be parsed as quotes 103 | this.quoteChars = { 104 | '"': true, 105 | "'": true, 106 | '`': true 107 | }; 108 | 109 | // chars to be parsed as escape char 110 | this.singleEscapes = { 111 | '\\': true 112 | }; 113 | 114 | // chars that mark the start of an option-expression 115 | // for use with getopt 116 | this.optionChars = { 117 | '-': true 118 | }; 119 | 120 | // chars that start escape expressions (value = handler) 121 | // plugin handlers for ascii escapes or variable substitution 122 | this.escapeExpressions = { 123 | '%': Parser.prototype.plugins.hexExpression 124 | }; 125 | } 126 | 127 | Parser.prototype = { 128 | version: '1.1', 129 | 130 | plugins: { 131 | hexExpression: function(termref, charindex, escapechar, quotelevel) { 132 | /* example for a plugin for Parser.escapeExpressions 133 | params: 134 | termref: reference to Terminal instance 135 | charindex: position in termref.lineBuffer (escapechar) 136 | escapechar: escape character found 137 | quotelevel: current quoting level (quote char or empty) 138 | (quotelevel is not used here, but this is a general approach to plugins) 139 | the character in position charindex will be ignored 140 | the return value is added to the current argument 141 | */ 142 | // convert hex values to chars (e.g. %20 => ) 143 | if (termref.lineBuffer.length > charindex+2) { 144 | // get next 2 chars 145 | var hi = termref.lineBuffer.charAt(charindex+1); 146 | var lo = termref.lineBuffer.charAt(charindex+2); 147 | lo = lo.toUpperCase(); 148 | hi = hi.toUpperCase(); 149 | // check for valid hex digits 150 | if ((((hi>='0') && (hi<='9')) || ((hi>='A') && ((hi<='F')))) && 151 | (((lo>='0') && (lo<='9')) || ((lo>='A') && ((lo<='F'))))) { 152 | // next 2 chars are valid hex, so strip them from lineBuffer 153 | Parser.prototype.plugins._escExprStrip(termref, charindex+1, charindex+3); 154 | // and return the char 155 | return String.fromCharCode(parseInt(hi+lo, 16)); 156 | } 157 | } 158 | // if not handled return the escape character (=> no conversion) 159 | return escapechar; 160 | }, 161 | 162 | _escExprStrip: function(termref, from, to) { 163 | // strip characters from termref.lineBuffer (for use with escape expressions) 164 | termref.lineBuffer = 165 | termref.lineBuffer.substring(0, from) + 166 | termref.lineBuffer.substring(to); 167 | } 168 | }, 169 | 170 | getopt: function(termref, optsstring) { 171 | // scans argv form current position of argc for opts 172 | // arguments in argv must not be quoted 173 | // returns an object with a property for every option flag found 174 | // option values (absolute floats) are stored in Object..value (default -1) 175 | // the property "illegals" contains an array of all flags found but not in optstring 176 | // argc is set to first argument that is not an option 177 | var opts = { 'illegals':[] }; 178 | while ((termref.argc < termref.argv.length) && (termref.argQL[termref.argc]=='')) { 179 | var a = termref.argv[termref.argc]; 180 | if ((a.length>0) && (this.optionChars[a.charAt(0)])) { 181 | var i = 1; 182 | while (i='0') && (nc<='9'))) { 188 | v += nc; 189 | i++; 190 | } 191 | else { 192 | break; 193 | } 194 | } 195 | if (optsstring.indexOf(c)>=0) { 196 | opts[c] = (v == '')? {value:-1} : (isNaN(v))? {value:0} : {value:parseFloat(v)}; 197 | } 198 | else { 199 | opts.illegals[opts.illegals.length]=c; 200 | } 201 | i++; 202 | } 203 | termref.argc++; 204 | } 205 | else { 206 | break; 207 | } 208 | } 209 | return opts; 210 | }, 211 | 212 | parseLine: function(termref) { 213 | // stand-alone parser, takes a Terminal instance as argument 214 | // parses the command line and stores results as instance properties 215 | // argv: list of parsed arguments 216 | // argQL: argument's quoting level ( or quote character) 217 | // argc: cursur for argv, set initinally to zero (0) 218 | // open quote strings are not an error but automatically closed. 219 | var argv = ['']; // arguments vector 220 | var argQL = ['']; // quoting level 221 | var argc = 0; // arguments cursor 222 | var escape = false ; // escape flag 223 | for (var i=0; i 2 | 3 | 4 | termlib Style Settings Sample 5 | 6 | 7 | 142 | 143 | 241 | 242 | 243 | 244 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 |
termlib.js home|multiple terminals|parser|faq|documentation|samples
262 | 263 | 264 | 265 | 286 | 389 | 390 |
266 | 267 | 270 | 273 | 276 | 279 | 284 |
268 | Style Settings Sample
  269 |
271 | > open terminal   272 |
274 |

> show sample text 

275 |
277 |   278 |
280 |  
281 | (c) mass:werk,
N. Landsteiner 2005-2007
282 | http://www.masswerk.at 283 |
285 |
287 |

Introducing Style Settings
 

288 |

Version 1.4 of "termlib.js" introduces configurations for styles and associated markup.

289 | 290 |

The method TermGlobals.assignStyle() allows you to 291 | install a custom style and associated mark up with a single method call.

292 |

TermGlobals.assignStyle() takes four arguments:

293 | 294 | 295 | 296 | 299 | 300 | 301 | 304 | 305 | 306 | 309 | 310 | 311 | 314 | 315 |
<style-code> 297 | The code to be used in the style vector for this style.
298 | <style-code> must be a power of 2 between 0 and 256 (<style-code> = 2^n, 0 <= n <= 7)
<markup> 302 | The one letter markup to be associated with this style (case insensitive).
303 | "p" and "c" are reserved.
<HTMLopen> 307 | The opening HTML clause to be written before a range in this style.
308 | (This is used as a line of text is rendered to the terminal display.)
<HTMLclose> 312 | The closing HTML clause to be written after a range in this style.
313 | (This is used as a line of text is rendered to the terminal display.)
316 | 317 | 318 |

As an example we will install a style "b" for bold and use style #16 (2^4) for this.
319 | To have this all ready before needed, you would want to do this before opening any instance of Terminal:

320 | 321 |
322 |   TermGlobals.assignStyle( 16, 'b', '<b>', '</b>' );
323 | 
324 | 325 |

 

326 |

Now we can use our new style and markup in any write() statement like this:

327 |
328 |   myTerm.write('This is %+bBOLD%-b.');
329 | 
330 | 
331 | 332 |

Now as we have installed our new "bold" style, we see that any bold letters are running wider then any plain text using the same letters. Since we want a well behaved terminal output, we'll have definitely to fix this.

333 |

We will apply some kerning to provide the extra space required for bold letters. 334 | To do this, we'll add a "letter-spacing" definition to our CSS rule ".term" (if it's not already there):

335 | 336 |
  .term
337 |   {
338 |      font-family: "Courier New",courier,fixed,monospace;
339 |      font-size: 12px;
340 | 
341 |      /* ... any other definitions ... */
342 | 
343 |      letter-spacing: 1px;
344 |   }
345 | 346 |

 

347 |

(As we can now see, installing a bold style involves some synchronized CSS and HTML coding. This is also the reason why bold is not in the standard set of termlib.js styles.)

348 | 349 |

 

350 | 351 |

As a second example we'll install a small style "m" ("minature", "s" is already in use for strike) with style code 32 (2^5).

352 |

This should be rendered with font-size: 10px.
353 | To preserve our mono-spced appearance we'll have to adjust the kerning for the smaller character-width.
354 | So we'll use a custom HTML span with a style attribute for this:

355 | 356 |
357 |   TermGlobals.assignStyle(
358 |                            32,
359 |                            'm',
360 |                            '<span style="font-size:10px; letter-spacing:2px;">',
361 |                            '</span>'
362 |                          );
363 | 
364 | 
365 |

As above we can now use this in a write() statement like this:

366 |
367 |   myTerm.write('This is %+mSMALL%-m.');
368 | 
369 | 370 |

 

371 |

Finally you could define a style as some kind of makro using the HTMl-parts (3rd and 4th argument) for visible information:

372 | 373 |
374 |   TermGlobals.assignStyle( 64, 'e', 'ERROR: ', '!' );
375 |   
376 |   myTerm.write('%+eYou did not enter enter a valid number%-e');
377 |   
378 |   // "ERROR: You did not enter enter a valid number!"
379 | 
380 | 381 |

 

382 |

Notes:
383 | With version 1.4 TermGlobals is just a reference to Terminal.prototype.globals.
384 | Since the term "TermGlobals" is handy outside any handler, we used this as a shortcut.

385 |

Unlike any other methods TermGlobals.assignStyle() alerts any errors. (Since these alerts should only occure in development phase, this provides an easy debugging facillity without any notice to application users.)

386 |

You usually would not want to change style #1 (reverse) since this style is used by the cursor in block mode.

387 |

 

388 |
391 | 392 | 393 | 394 | 395 | -------------------------------------------------------------------------------- /public/js/ace/mode-html.js: -------------------------------------------------------------------------------- 1 | define("ace/mode/html",function(a,b,c){var d=a("pilot/oop"),e=a("ace/mode/text").Mode,f=a("ace/mode/javascript").Mode,g=a("ace/mode/css").Mode,h=a("ace/tokenizer").Tokenizer,i=a("ace/mode/html_highlight_rules").HtmlHighlightRules,j=function(){this.$tokenizer=new h((new i).getRules()),this.$js=new f,this.$css=new g};d.inherits(j,e),function(){this.toggleCommentLines=function(a,b,c,d){this.$delegate("toggleCommentLines",arguments,function(){return 0})},this.getNextLineIndent=function(a,b,c){var d=this;return this.$delegate("getNextLineIndent",arguments,function(){return d.$getIndent(b)})},this.checkOutdent=function(a,b,c){return this.$delegate("checkOutdent",arguments,function(){return!1})},this.autoOutdent=function(a,b,c){this.$delegate("autoOutdent",arguments)},this.$delegate=function(a,b,c){var d=b[0],e=d.split("js-");if(!e[0]&&e[1]){b[0]=e[1];return this.$js[a].apply(this.$js,b)}var e=d.split("css-");if(!e[0]&&e[1]){b[0]=e[1];return this.$css[a].apply(this.$css,b)}return c?c():undefined}}.call(j.prototype),b.Mode=j}),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(JavaScriptHighlightRules,g),b.JavaScriptHighlightRules=JavaScriptHighlightRules}),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}),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}) -------------------------------------------------------------------------------- /public/js/termlib/termlib/sample_globbing.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | termlib Globbing Sample 4 | 5 | 6 | 424 | 425 | 489 | 490 | 491 | 492 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 |
termlib.js home|multiple terminals|parser|faq|documentation|samples
510 | 511 | 512 | 513 | 531 | 555 | 556 |
514 | 515 | 518 | 521 | 524 | 529 |
516 | Text Globbing Sample
  517 |
519 | > open terminal   520 |
522 |   523 |
525 |  
526 | (c) mass:werk,
N. Landsteiner 2005-2009
527 | http://www.masswerk.at 528 |
530 |
532 |

A Simple Globbing Sample (with dialog)
 

533 |

This sample demonstrates how to back up and restore a terminal's state
in order to implement a special mode (here a dialog).
534 | It also shows how to trap a special key and how to process the current
input of the command line.

535 |

Open the terminal, type a some text and hit TAB or ESC for globbing.
536 | Any completions are evaluated from the last word in the line.

537 |

Possible completions are stored in an object containing lists (arrays)
per first letter:

538 |
539 | var termGlobDict = {
540 |    'a': [
541 |           // put strings beginning with "a" here
542 |         ],
543 |    'b': [
544 |           // put strings beginning with "b" here
545 |         ]
546 |    ...
547 | }
548 |

(Only the max. first 9 hits are displayed as possible options.)

549 |

Inside a dialog options may be selected by either

550 |
    551 |
  • typing the according number or
  • 552 |
  • by moving the cursor and hitting <ENTER>.
  • 553 |
554 |
557 | 558 | 559 | 560 | 561 | -------------------------------------------------------------------------------- /public/js/github.js: -------------------------------------------------------------------------------- 1 | // ## Client-side Javascript API wrapper for GitHub (mostly v3) 2 | // 3 | // Stolen, stripped and rebuilt from https://github.com/fitzgen/github-api 4 | // thanks to Nick Fitzgerald 5 | // 6 | 7 | (function (globals) { 8 | 9 | // Before we implement the API methods, we will define all of our private 10 | // variables and helper functions with one `var` statement. 11 | var 12 | 13 | // The username and authentication token of the library's user. 14 | authToken, 15 | 16 | // To save keystrokes when we make JSONP calls to the HTTP API, we will keep 17 | // track of the root from which all V2 urls extend. 18 | apiRoot = "https://github.com/api/v2/json/", 19 | api3Root = "https://api.github.com/", 20 | 21 | // Send a JSONP request to the Github API that calls `callback` with 22 | // the `context` argument as `this`. 23 | // 24 | // The `url` parameter is concatenated with the apiRoot, for the reasons 25 | // mentioned above. The way that we are supporting non-global, anonymous 26 | // functions is by sticking them in the globally exposed 27 | // `gh.__jsonp_callbacks` object with a "unique" `id` that is the current 28 | // time in milliseconds. Once the callback is called, it is deleted from the 29 | // object to prevent memory leaks. 30 | jsonp = function (url, callback, context) { 31 | var id = +new Date, 32 | script = document.createElement("script"); 33 | 34 | while (gh.__jsonp_callbacks[id] !== undefined) 35 | id += Math.random(); // Avoid slight possibility of id clashes. 36 | 37 | gh.__jsonp_callbacks[id] = function () { 38 | delete gh.__jsonp_callbacks[id]; 39 | callback.apply(context, arguments); 40 | }; 41 | 42 | var prefix = "?"; 43 | if (url.indexOf("?") >= 0) 44 | prefix = "&"; 45 | 46 | url += prefix + "callback=" + encodeURIComponent("gh.__jsonp_callbacks[" + id + "]"); 47 | if (authToken) { 48 | url += "&access_token=" + authToken; 49 | } 50 | script.setAttribute("src", apiRoot + url); 51 | 52 | document.getElementsByTagName('head')[0].appendChild(script); 53 | }, 54 | 55 | // post to sinatra proxy so this is do-able, freaking cross-site grr 56 | postp = function (url, vals, callback) { 57 | v = {} 58 | v['proxy_url'] = url 59 | v['datap'] = Base64.encode(JSON.stringify(vals)) 60 | $.post('/proxy', v, callback, 'json') 61 | }, 62 | 63 | // This helper function will throw a TypeError if the library user is not 64 | // properly authenticated. Otherwise, it silently returns. 65 | authRequired = function (username) { 66 | if (!authToken) { 67 | throw new TypeError("gh: Must be authenticated to do that."); 68 | } 69 | }, 70 | 71 | // Convert an object to a url parameter string. 72 | // 73 | // paramify({foo:1, bar:3}) -> "foo=1&bar=3". 74 | paramify = function (params) { 75 | var str = "", key; 76 | for (key in params) if (params.hasOwnProperty(key)) 77 | str += key + "=" + params[key] + "&"; 78 | return str.replace(/&$/, ""); 79 | }, 80 | 81 | // Get around how the GH team haven't migrated all the API to version 2, and 82 | // how gists use a different api root. 83 | withTempApiRoot = function (tempApiRoot, fn) { 84 | return function () { 85 | var oldRoot = apiRoot; 86 | apiRoot = tempApiRoot; 87 | fn.apply(this, arguments); 88 | apiRoot = oldRoot; 89 | }; 90 | }, 91 | 92 | withV3Api = function (fn) { 93 | return function () { 94 | var oldRoot = apiRoot; 95 | apiRoot = api3Root; 96 | fn.apply(this, arguments); 97 | apiRoot = oldRoot; 98 | }; 99 | }, 100 | 101 | // Expose the global `gh` variable, through which every API method is 102 | // accessed, but keep a local variable around so we can reference it easily. 103 | gh = globals.gh = {}; 104 | 105 | // Psuedo private home for JSONP callbacks (which are required to be global 106 | // by the nature of JSONP, as discussed earlier). 107 | gh.__jsonp_callbacks = {}; 108 | 109 | // Authenticate as a user. Does not try to validate at any point; that job 110 | // is up to each individual method, which calls `authRequired` as needed. 111 | gh.authenticate = function (token) { 112 | authToken = token; 113 | return this; 114 | }; 115 | 116 | // ### Users 117 | 118 | // The constructor for user objects. Just creating an instance of a user 119 | // doesn't fetch any data from GitHub, you need to get explicit about what 120 | // you want to do that. 121 | // 122 | // var huddlej = gh.user("huddlej"); 123 | gh.user = function (username) { 124 | if ( !(this instanceof gh.user)) { 125 | return new gh.user(username); 126 | } 127 | this.username = username; 128 | }; 129 | 130 | // Show basic user info; you can get more info if you are authenticated as 131 | // this user. 132 | // 133 | // gh.user("fitzgen").show(function (data) { 134 | // console.log(data.user); 135 | // }); 136 | gh.user.prototype.show = withV3Api(function (callback, context) { 137 | jsonp("users/" + this.username, callback, context); 138 | return this; 139 | }); 140 | 141 | gh.user.prototype.orgs = withV3Api(function (callback, context) { 142 | jsonp("user/orgs", callback, context); 143 | return this; 144 | }); 145 | 146 | gh.user.prototype.orgRepos = withV3Api(function (org, callback, context) { 147 | jsonp("orgs/" + org + "/repos", callback, context); 148 | return this; 149 | }); 150 | 151 | // Get a list of this user's repositories, 30 per page 152 | // 153 | // gh.user("fitzgen").repos(function (data) { 154 | // data.repositories.forEach(function (repo) { 155 | // ... 156 | // }); 157 | // }); 158 | gh.user.prototype.repos = function (callback, context, page) { 159 | gh.repo.forUser(this.username, callback, context, page); 160 | return this; 161 | }; 162 | 163 | // Get a list of all repos for this user. 164 | // 165 | // gh.user("fitzgen").allRepos(function (data) { 166 | // alert(data.repositories.length); 167 | // }); 168 | gh.user.prototype.allRepos = function (callback, context) { 169 | var repos = [], 170 | username = this.username, 171 | page = 1; 172 | 173 | function exitCallback () { 174 | callback.call(context, { repositories: repos }); 175 | } 176 | 177 | function pageLoop (data) { 178 | if (data.data.length == 0) { 179 | exitCallback(); 180 | } else { 181 | repos = repos.concat(data.data); 182 | page += 1; 183 | if (data.data.length < 100) { 184 | exitCallback(); 185 | } else { 186 | gh.repo.forUser(username, pageLoop, context, page); 187 | } 188 | } 189 | } 190 | 191 | gh.repo.forUser(username, pageLoop, context, page); 192 | 193 | return this; 194 | }; 195 | 196 | // Get a list of all repos that this user can push to (including ones that 197 | // they are just a collaborator on, and do not own). Must be authenticated 198 | // as this user. 199 | gh.user.prototype.pushable = function (callback, context) { 200 | authRequired(this.user); 201 | jsonp("repos/pushable", callback, context); 202 | }; 203 | 204 | 205 | // ### Repositories 206 | 207 | // This is the base constructor for creating repo objects. Note that this 208 | // won't actually hit the GitHub API until you specify what data you want, 209 | // or what action you wish to take via a prototype method. 210 | gh.repo = function (user, repo) { 211 | if ( !(this instanceof gh.repo)) { 212 | return new gh.repo(user, repo); 213 | } 214 | this.repo = repo; 215 | this.user = user; 216 | }; 217 | 218 | // Get basic information on this repo. 219 | // 220 | // gh.repo("schacon", "grit").show(function (data) { 221 | // console.log(data.repository.description); 222 | // }); 223 | gh.repo.prototype.show = function (callback, context) { 224 | jsonp("repos/show/" + this.user + "/" + this.repo, callback, context); 225 | return this; 226 | }; 227 | 228 | // Get all the repos that are owned by `user`. 229 | gh.repo.forUser = withV3Api(function (user, callback, context, page) { 230 | if (!page) 231 | page = 1; 232 | 233 | jsonp("user/repos?page=" + page + '&per_page=' + 100, callback, context); 234 | return this; 235 | }); 236 | 237 | gh.repo.prototype.commit = function (sha) { 238 | return gh.commit(this.user, this.repo, sha) 239 | }; 240 | 241 | gh.repo.prototype.tree = function (sha) { 242 | return gh.tree(this.user, this.repo, sha) 243 | }; 244 | 245 | gh.repo.prototype.blob = function (sha) { 246 | return gh.blob(this.user, this.repo, sha) 247 | }; 248 | 249 | gh.repo.prototype.ref = function (ref, sha) { 250 | return gh.ref(this.user, this.repo, ref, sha) 251 | }; 252 | 253 | 254 | gh.repo.prototype.branches = withV3Api(function (callback, context) { 255 | jsonp("repos/" + this.user + "/" + this.repo + "/git/refs/heads", callback, context); 256 | return this; 257 | }); 258 | 259 | // ### Commits 260 | 261 | gh.commit = function (user, repo, sha) { 262 | if ( !(this instanceof gh.commit) ) 263 | return new gh.commit(user, repo, sha); 264 | this.user = user; 265 | this.repo = repo; 266 | this.sha = sha; 267 | }; 268 | 269 | gh.commit.prototype.show = withV3Api(function (callback, context) { 270 | jsonp("repos/" + this.user + "/" + this.repo + "/commits/" + this.sha, 271 | callback, context); 272 | return this; 273 | }); 274 | 275 | gh.commit.prototype.list = withV3Api(function (callback, context) { 276 | jsonp("repos/" + this.user + "/" + this.repo + "/commits?sha=" + this.sha, 277 | callback, context); 278 | return this; 279 | }); 280 | 281 | gh.commit.prototype.write = function (commitHash, callback) { 282 | url = "repos/" + this.user + "/" + this.repo + "/git/commits" 283 | postp(url, commitHash, callback) 284 | return this; 285 | }; 286 | 287 | // ### Trees 288 | 289 | gh.tree = function (user, repo, sha) { 290 | if ( !(this instanceof gh.tree) ) 291 | return new gh.tree(user, repo, sha); 292 | this.user = user; 293 | this.repo = repo; 294 | this.sha = sha; 295 | }; 296 | 297 | gh.tree.prototype.show = withV3Api(function (callback, context) { 298 | jsonp("repos/" + this.user + "/" + this.repo + "/git/trees/" + this.sha, 299 | callback, context); 300 | return this; 301 | }); 302 | 303 | gh.tree.prototype.write = function (treeHash, callback) { 304 | url = "repos/" + this.user + "/" + this.repo + "/git/trees" 305 | postp(url, treeHash, callback) 306 | return this; 307 | }; 308 | 309 | // ### Blobs 310 | 311 | gh.blob = function (user, repo, sha) { 312 | if ( !(this instanceof gh.blob) ) 313 | return new gh.blob(user, repo, sha); 314 | this.user = user; 315 | this.repo = repo; 316 | this.sha = sha; 317 | }; 318 | 319 | gh.blob.prototype.show = withV3Api(function (callback, context) { 320 | jsonp("repos/" + this.user + "/" + this.repo + "/git/blobs/" + this.sha, 321 | callback, context); 322 | return this; 323 | }); 324 | 325 | gh.blob.prototype.write = function (content, callback) { 326 | var vals = {} 327 | vals['content'] = content 328 | url = "repos/" + this.user + "/" + this.repo + "/git/blobs" 329 | postp(url, vals, callback) 330 | return this; 331 | }; 332 | 333 | gh.blob.prototype.decode = function (data) { 334 | return Base64.decode(data) 335 | } 336 | 337 | // ### Refs 338 | 339 | gh.ref = function (user, repo, ref, sha) { 340 | if ( !(this instanceof gh.ref) ) 341 | return new gh.ref(user, repo, ref, sha); 342 | this.user = user; 343 | this.repo = repo; 344 | this.ref = ref; 345 | this.sha = sha; 346 | }; 347 | 348 | gh.ref.prototype.show = withV3Api(function (callback, context) { 349 | jsonp("repos/" + this.user + "/" + this.repo + "/git/" + this.ref, 350 | callback, context); 351 | return this; 352 | }); 353 | 354 | gh.ref.prototype.update = function (commitSha, callback) { 355 | var vals = {'ref': this.ref, 'type': 'commit', 'sha': commitSha} 356 | url = "repos/" + this.user + "/" + this.repo + "/git/" + this.ref 357 | postp(url, vals, callback) 358 | return this; 359 | }; 360 | 361 | }(window)); 362 | 363 | var Base64 = { 364 | // private property 365 | _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", 366 | 367 | // public method for encoding 368 | encode : function (input) { 369 | var output = ""; 370 | var chr1, chr2, chr3, enc1, enc2, enc3, enc4; 371 | var i = 0; 372 | 373 | input = Base64._utf8_encode(input); 374 | 375 | while (i < input.length) { 376 | 377 | chr1 = input.charCodeAt(i++); 378 | chr2 = input.charCodeAt(i++); 379 | chr3 = input.charCodeAt(i++); 380 | 381 | enc1 = chr1 >> 2; 382 | enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 383 | enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 384 | enc4 = chr3 & 63; 385 | 386 | if (isNaN(chr2)) { 387 | enc3 = enc4 = 64; 388 | } else if (isNaN(chr3)) { 389 | enc4 = 64; 390 | } 391 | 392 | output = output + 393 | this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + 394 | this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); 395 | 396 | } 397 | 398 | return output; 399 | }, 400 | 401 | // public method for decoding 402 | decode : function (input) { 403 | var output = ""; 404 | var chr1, chr2, chr3; 405 | var enc1, enc2, enc3, enc4; 406 | var i = 0; 407 | 408 | input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 409 | 410 | while (i < input.length) { 411 | 412 | enc1 = this._keyStr.indexOf(input.charAt(i++)); 413 | enc2 = this._keyStr.indexOf(input.charAt(i++)); 414 | enc3 = this._keyStr.indexOf(input.charAt(i++)); 415 | enc4 = this._keyStr.indexOf(input.charAt(i++)); 416 | 417 | chr1 = (enc1 << 2) | (enc2 >> 4); 418 | chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); 419 | chr3 = ((enc3 & 3) << 6) | enc4; 420 | 421 | output = output + String.fromCharCode(chr1); 422 | 423 | if (enc3 != 64) { 424 | output = output + String.fromCharCode(chr2); 425 | } 426 | if (enc4 != 64) { 427 | output = output + String.fromCharCode(chr3); 428 | } 429 | 430 | } 431 | 432 | output = Base64._utf8_decode(output); 433 | 434 | return output; 435 | 436 | }, 437 | 438 | // private method for UTF-8 encoding 439 | _utf8_encode : function (string) { 440 | string = string.replace(/\r\n/g,"\n"); 441 | var utftext = ""; 442 | 443 | for (var n = 0; n < string.length; n++) { 444 | 445 | var c = string.charCodeAt(n); 446 | 447 | if (c < 128) { 448 | utftext += String.fromCharCode(c); 449 | } 450 | else if((c > 127) && (c < 2048)) { 451 | utftext += String.fromCharCode((c >> 6) | 192); 452 | utftext += String.fromCharCode((c & 63) | 128); 453 | } 454 | else { 455 | utftext += String.fromCharCode((c >> 12) | 224); 456 | utftext += String.fromCharCode(((c >> 6) & 63) | 128); 457 | utftext += String.fromCharCode((c & 63) | 128); 458 | } 459 | 460 | } 461 | 462 | return utftext; 463 | }, 464 | 465 | // private method for UTF-8 decoding 466 | _utf8_decode : function (utftext) { 467 | var string = ""; 468 | var i = 0; 469 | var c = c1 = c2 = 0; 470 | 471 | while ( i < utftext.length ) { 472 | 473 | c = utftext.charCodeAt(i); 474 | 475 | if (c < 128) { 476 | string += String.fromCharCode(c); 477 | i++; 478 | } 479 | else if((c > 191) && (c < 224)) { 480 | c2 = utftext.charCodeAt(i+1); 481 | string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); 482 | i += 2; 483 | } 484 | else { 485 | c2 = utftext.charCodeAt(i+1); 486 | c3 = utftext.charCodeAt(i+2); 487 | string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); 488 | i += 3; 489 | } 490 | 491 | } 492 | 493 | return string; 494 | } 495 | } 496 | 497 | --------------------------------------------------------------------------------