├── .gitignore ├── js ├── sessions │ ├── state.js │ ├── readme.rst │ ├── dragdrop.js │ ├── autosave.js │ ├── addRemove.js │ └── switching.js ├── util │ ├── aceLoad.js │ ├── template.js │ ├── text.js │ ├── i18n.js │ └── readme.rst ├── ui.js ├── ace │ ├── mode-text.js │ ├── ext-error_marker.js │ ├── mode-plain_text.js │ ├── mode-gitignore.js │ ├── ext-statusbar.js │ ├── theme-son_of_obsidian.js │ ├── ext-linking.js │ ├── mode-csp.js │ ├── theme-gruvbox.js │ ├── mode-properties.js │ ├── theme-kuroir.js │ ├── theme-xcode.js │ ├── ext-spellcheck.js │ ├── ext-themelist.js │ ├── theme-kr.js │ ├── theme-clouds.js │ ├── theme-eclipse.js │ ├── theme-solarized_dark.js │ ├── theme-vibrant_ink.js │ ├── theme-merbivore.js │ ├── theme-github.js │ ├── theme-solarized_light.js │ ├── theme-idle_fingers.js │ ├── theme-dawn.js │ ├── theme-kr_theme.js │ ├── mode-gcode.js │ ├── theme-monokai.js │ ├── theme-clouds_midnight.js │ ├── theme-merbivore_soft.js │ ├── theme-cobalt.js │ ├── theme-gob.js │ ├── theme-twilight.js │ ├── theme-tomorrow.js │ ├── theme-pastel_on_dark.js │ ├── theme-dracula.js │ ├── mode-sql.js │ ├── theme-mono_industrial.js │ ├── theme-textmate.js │ ├── theme-tomorrow_night.js │ ├── theme-chrome.js │ ├── theme-crimson_editor.js │ └── mode-lisp.js ├── sequences.js ├── settings.js ├── storage │ ├── nullfile.js │ ├── syncfile.js │ ├── syncFS.js │ └── readme.rst ├── ui │ ├── cli.js │ ├── statusbar.js │ ├── window.js │ ├── readme.rst │ ├── contextMenus.js │ └── dialog.js ├── api.js ├── readme.rst ├── command.js └── sessions.js ├── icon-128.png ├── icon-128-inverted.png ├── .editorconfig ├── templates ├── paletteItem.html ├── projectDir.html ├── projectFile.html ├── dialog.html ├── theme.css ├── menuItem.html ├── about.html └── tab.html ├── config ├── api.json ├── sequences.json ├── keys.json └── user.json ├── css ├── seed.less ├── seed-dark.less ├── seed-twilight.less ├── menus.less ├── searchbar.less ├── palette.less ├── dialog.less ├── base.less ├── tabs.less └── ui.less ├── package.json ├── license.txt ├── .github └── issue_template.md ├── manifest.json ├── readme.rst ├── main.html ├── code_of_conduct.rst └── contributing.rst /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | css/*.css 3 | build/ -------------------------------------------------------------------------------- /js/sessions/state.js: -------------------------------------------------------------------------------- 1 | define({ 2 | tabs: [], 3 | stack: [] 4 | }); -------------------------------------------------------------------------------- /icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomaswilburn/Caret/HEAD/icon-128.png -------------------------------------------------------------------------------- /icon-128-inverted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomaswilburn/Caret/HEAD/icon-128-inverted.png -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /templates/paletteItem.html: -------------------------------------------------------------------------------- 1 |
  • 2 |
    {{label}}
    3 |
    {{sublabel}}
    4 |
  • -------------------------------------------------------------------------------- /templates/projectDir.html: -------------------------------------------------------------------------------- 1 | 8 | {{label}} 9 | -------------------------------------------------------------------------------- /js/util/aceLoad.js: -------------------------------------------------------------------------------- 1 | define(function() { 2 | return { 3 | load: function(name, parentRequire, onLoad, config) { 4 | ace.require("ace/lib/net").loadScript(name, () => onLoad()); 5 | } 6 | } 7 | }); -------------------------------------------------------------------------------- /config/api.json: -------------------------------------------------------------------------------- 1 | { 2 | "sampleMessage": { 3 | "id": "extension id goes here", 4 | "message": { 5 | "data": "message can be any JSON object passable to chrome.runtime.sendMessage" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /js/ui.js: -------------------------------------------------------------------------------- 1 | // all UI modules that must be loaded independently 2 | 3 | define([ 4 | "ui/cli", 5 | "ui/keys", 6 | "ui/menus", 7 | "ui/palette", 8 | "ui/projectManager", 9 | "ui/searchbar", 10 | "ui/window" 11 | ]); -------------------------------------------------------------------------------- /templates/projectFile.html: -------------------------------------------------------------------------------- 1 | 9 | {{label}} 10 | -------------------------------------------------------------------------------- /config/sequences.json: -------------------------------------------------------------------------------- 1 | { 2 | "sequence:test": [ 3 | { "ace": "gotolineend" }, 4 | { "command": "ace:command", "argument": "selecttolinestart" }, 5 | { "command": "status:set", "argument": "Selected a line via custom sequence!" }, 6 | "status:clear" 7 | ] 8 | } -------------------------------------------------------------------------------- /css/seed.less: -------------------------------------------------------------------------------- 1 | @accent: #808; 2 | @foreground: #111; 3 | @background: #F7F7F7; 4 | @faded: #AAA; 5 | 6 | @import "base"; 7 | @import "tabs"; 8 | @import "ui"; 9 | @import "menus"; 10 | @import "dialog"; 11 | @import "palette"; 12 | @import "project"; 13 | @import "searchbar"; -------------------------------------------------------------------------------- /css/seed-dark.less: -------------------------------------------------------------------------------- 1 | @accent: #FFA200; 2 | @foreground: white; 3 | @background: #222525; 4 | @faded: #333; 5 | 6 | @import "base"; 7 | @import "tabs"; 8 | @import "ui"; 9 | @import "menus"; 10 | @import "dialog"; 11 | @import "palette"; 12 | @import "project"; 13 | @import "searchbar"; -------------------------------------------------------------------------------- /css/seed-twilight.less: -------------------------------------------------------------------------------- 1 | @accent: #35467A; 2 | @foreground: #BBB; 3 | @background: #090915; 4 | @faded: lighten(@background, 4%); 5 | 6 | @import "base"; 7 | @import "tabs"; 8 | @import "ui"; 9 | @import "menus"; 10 | @import "dialog"; 11 | @import "palette"; 12 | @import "project"; 13 | @import "searchbar"; -------------------------------------------------------------------------------- /templates/dialog.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/theme.css: -------------------------------------------------------------------------------- 1 | {{#blocks}} 2 | {{selector}} { 3 | {{#styles}} 4 | {{prop}}: {{value}}; 5 | {{/styles}} 6 | } 7 | {{/blocks}} 8 | 9 | .ace-cart .ace_indent-guide { 10 | background: url("data:image/png,base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y, 11 | } -------------------------------------------------------------------------------- /js/ace/mode-text.js: -------------------------------------------------------------------------------- 1 | 2 | ; (function() { 3 | ace.require(["ace/mode/text"], function(m) { 4 | if (typeof module == "object" && typeof exports == "object" && module) { 5 | module.exports = m; 6 | } 7 | }); 8 | })(); 9 | -------------------------------------------------------------------------------- /js/ace/ext-error_marker.js: -------------------------------------------------------------------------------- 1 | 2 | ; (function() { 3 | ace.require(["ace/ext/error_marker"], function(m) { 4 | if (typeof module == "object" && typeof exports == "object" && module) { 5 | module.exports = m; 6 | } 7 | }); 8 | })(); 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Caret", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "build": "grunt" 6 | }, 7 | "dependencies": { 8 | "grunt": "*", 9 | "grunt-contrib-less": "*", 10 | "grunt-contrib-watch": "*", 11 | "jszip": "^2.6.0" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git://github.com/thomaswilburn/Caret.git" 16 | }, 17 | "license": "GPL-3.0" 18 | } 19 | -------------------------------------------------------------------------------- /templates/menuItem.html: -------------------------------------------------------------------------------- 1 |
  • {{label}} 12 | {{#shortcut}} 13 | {{shortcut}} 14 | {{/shortcut}} 15 | {{#hasChildren}} 16 | 17 | {{/hasChildren}}
  • -------------------------------------------------------------------------------- /templates/about.html: -------------------------------------------------------------------------------- 1 |
    2 |

    Caret v.{{version}}

    3 | 11 |
    12 | -------------------------------------------------------------------------------- /templates/tab.html: -------------------------------------------------------------------------------- 1 | 6 | {{fileName}} 14 | 15 | {{#modified}}○{{/modified}} 16 | {{^modified}}×{{/modified}} 17 | 18 | -------------------------------------------------------------------------------- /js/util/template.js: -------------------------------------------------------------------------------- 1 | define(["util/inflate"], function(inflate) { 2 | 3 | /* 4 | 5 | A plugin that pre-loads templates into the util/inflate cache, then passes 6 | it through (similar to how the settings! plugin works). 7 | 8 | */ 9 | 10 | return { 11 | load: function(name, parentRequire, onLoad, config) { 12 | var files = name.split(","); 13 | var pending = files.map(inflate.load); 14 | Promise.all(pending).then(function() { 15 | onLoad(inflate); 16 | }); 17 | } 18 | }; 19 | 20 | }); -------------------------------------------------------------------------------- /js/sequences.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "command", 3 | "settings!sequences" 4 | ], function(command, Settings) { 5 | 6 | command.on("*", async function(cmd, argument, callback) { 7 | var sequences = await Settings.get("sequences"); 8 | 9 | if (!(cmd in sequences)) return 10 | for (var item of sequences[cmd]) { 11 | if (typeof item == "string") { 12 | item = { command: item } 13 | } 14 | await command.fire(item.ace ? "ace:command" : item.command, item.argument || item.ace); 15 | } 16 | }); 17 | 18 | }); -------------------------------------------------------------------------------- /js/settings.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "command", 3 | "storage/settingsProvider", 4 | ], function(command, Settings) { 5 | 6 | /* A plugin that handles loading Settings "synchronously" */ 7 | 8 | return { 9 | load: async function(name, parentRequire, onLoad, config) { 10 | if (name.length == 0) { 11 | return onLoad(Settings); 12 | } 13 | 14 | var files = name.split(","); 15 | var completed = 0; 16 | 17 | var completed = files.map(f => Settings.load(f)); 18 | await Promise.all(completed); 19 | onLoad(Settings); 20 | } 21 | }; 22 | 23 | }); -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | This program is free software: you can redistribute it and/or modify 2 | it under the terms of the GNU General Public License as published by 3 | the Free Software Foundation, either version 3 of the License, or 4 | (at your option) any later version. 5 | 6 | This program is distributed in the hope that it will be useful, 7 | but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | GNU General Public License for more details. 10 | 11 | You should have received a copy of the GNU General Public License 12 | along with this program. If not, see . -------------------------------------------------------------------------------- /js/util/text.js: -------------------------------------------------------------------------------- 1 | define(function() { 2 | 3 | var cache = {}; 4 | var directory = null; 5 | 6 | return { 7 | load: function(name, parentRequire, onLoad, config) { 8 | if (name in cache) { 9 | return onLoad(cache[name]); 10 | } 11 | 12 | var getFile = function() { 13 | directory.getFile(name, {create: false}, function(entry) { 14 | entry.file(function(file) { 15 | var reader = new FileReader(); 16 | reader.onloadend = function() { 17 | cache[name] = reader.result; 18 | onLoad(reader.result); 19 | }; 20 | reader.readAsText(file); 21 | }); 22 | }); 23 | }; 24 | 25 | if (directory) return getFile(); 26 | chrome.runtime.getPackageDirectoryEntry(function(dir) { 27 | directory = dir; 28 | getFile(); 29 | }); 30 | } 31 | }; 32 | 33 | }); -------------------------------------------------------------------------------- /js/sessions/readme.rst: -------------------------------------------------------------------------------- 1 | Module description - sessions/\* 2 | ================================ 3 | 4 | The sessions folder contains functionality that was broken out to keep 5 | ``sessions.js`` from getting huge. 6 | 7 | addRemove.js 8 | ------------ 9 | 10 | Provides methods for adding, removing, and re-ordering sessions and 11 | their tabs. 12 | 13 | autosave.js 14 | ----------- 15 | 16 | Automatically triggers saving files either on a timer or when the window loses 17 | focus, depending on your config. 18 | 19 | binding.js 20 | ---------- 21 | 22 | Event bindings, such as drag/drop and middle click 23 | 24 | dragdrop.js 25 | ----------- 26 | 27 | Specifically handles the events when a file or folder is dropped on the main 28 | editor window. 29 | 30 | state.js 31 | -------- 32 | 33 | Actual tab state as a singleton, imported by other modules to do 34 | re-ordering or other tab manipulation. 35 | 36 | switching.js 37 | ------------ 38 | 39 | Provides the utility methods for between tabs, directly or in order. 40 | -------------------------------------------------------------------------------- /js/storage/nullfile.js: -------------------------------------------------------------------------------- 1 | define(function() { 2 | 3 | // The null file is the equivalent of dev/null--you can read/write, but you get nothing 4 | // It's used for things like settings files, which can't be saved. 5 | 6 | var NullFile = function(content) { 7 | this.content = content; 8 | }; 9 | NullFile.prototype = { 10 | virtual: true, 11 | open: function(mode) { 12 | return Promise.resolve(this); 13 | }, 14 | read: function(c) { 15 | return Promise.resolve(this.content || ""); 16 | }, 17 | write: async function(data) { 18 | return Promise.resolve(); 19 | }, 20 | stat: function() { 21 | return Promise.reject("Can't stat a null file"); 22 | }, 23 | retain: function() { 24 | return Promise.resolve(); 25 | }, 26 | restore: function(id) { 27 | return Promise.reject("Can't restore a null file"); 28 | }, 29 | getPath: function(c) { 30 | return Promise.resolve("/dev/null"); 31 | } 32 | }; 33 | 34 | return NullFile; 35 | 36 | }); -------------------------------------------------------------------------------- /js/sessions/dragdrop.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "command", 3 | "sessions/addRemove", 4 | "ui/projectManager", 5 | "storage/file" 6 | ], function(command, addRemove, projectManager, File) { 7 | 8 | command.on("session:open-dragdrop", function(items) { 9 | [].forEach.call(items, async function(entry){ 10 | //only process files 11 | if (entry.kind !== "file") return; 12 | entry = entry.webkitGetAsEntry(); 13 | 14 | //files get opened in a tab 15 | if (entry.isFile) { 16 | var f = new File(entry); 17 | var data = await f.read(); 18 | addRemove.add(data, f); 19 | //directories get added to project 20 | } else if (entry.isDirectory) { 21 | projectManager.insertDirectory(entry); 22 | } 23 | }); 24 | }); 25 | 26 | document.body.addEventListener("dragover", function(e) { 27 | e.preventDefault(); 28 | }); 29 | 30 | document.body.addEventListener("drop", function(e) { 31 | e.preventDefault(); 32 | if (e.dataTransfer.types.indexOf("Files") === -1) return; 33 | command.fire("session:open-dragdrop", e.dataTransfer.items); 34 | }); 35 | 36 | }); -------------------------------------------------------------------------------- /js/ace/mode-plain_text.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/plain_text",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/text_highlight_rules","ace/mode/behaviour"], function(require, exports, module) { 2 | "use strict"; 3 | 4 | var oop = require("../lib/oop"); 5 | var TextMode = require("./text").Mode; 6 | var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; 7 | var Behaviour = require("./behaviour").Behaviour; 8 | 9 | var Mode = function() { 10 | this.HighlightRules = TextHighlightRules; 11 | this.$behaviour = new Behaviour(); 12 | }; 13 | 14 | oop.inherits(Mode, TextMode); 15 | 16 | (function() { 17 | this.type = "text"; 18 | this.getNextLineIndent = function(state, line, tab) { 19 | return ''; 20 | }; 21 | this.$id = "ace/mode/plain_text"; 22 | }).call(Mode.prototype); 23 | 24 | exports.Mode = Mode; 25 | }); (function() { 26 | ace.require(["ace/mode/plain_text"], function(m) { 27 | if (typeof module == "object" && typeof exports == "object" && module) { 28 | module.exports = m; 29 | } 30 | }); 31 | })(); 32 | -------------------------------------------------------------------------------- /js/sessions/autosave.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "command", 3 | "storage/settingsProvider", 4 | "ui/statusbar", 5 | "sessions/state", 6 | "util/i18n" 7 | ], function(command, Settings, status, state, i18n) { 8 | 9 | var autosaveTimeout = null; 10 | var scheduleAutosave = function() { 11 | if (autosaveTimeout) clearTimeout(autosaveTimeout); 12 | Settings.pull("user").then(function(settings) { 13 | if(settings.user.autosaveInterval) { 14 | //schedule next save in minutes 15 | autosaveTimeout = setTimeout(autosave, settings.user.autosaveInterval * 60 * 1000); 16 | } 17 | }); 18 | }; 19 | 20 | var autosave = function() { 21 | status.toast(i18n.get("fileAutosaving")); 22 | state.tabs.forEach(function(tab) { 23 | if (tab.file && !tab.file.virtual && tab.modified) { 24 | tab.save(); 25 | } 26 | }); 27 | scheduleAutosave(); 28 | }; 29 | 30 | scheduleAutosave(); 31 | command.on("init:restart", scheduleAutosave); 32 | 33 | window.addEventListener("blur", function() { 34 | Settings.pull("user").then(function(settings) { 35 | if (settings.user.autosaveOnBlur) { 36 | autosave(); 37 | } 38 | }); 39 | }); 40 | 41 | }); -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | Thanks for filing an issue! Please feel free to delete this paragraph and adapt the template below to fit your needs. Before filing an issue, it may make sense to search through [closed issues](https://github.com/thomaswilburn/Caret/issues?q=is%3Aissue+is%3Aclosed) to see if your question has already been addressed. If you have questions, you can also check the [wiki](https://github.com/thomaswilburn/Caret/wiki) for answers. 2 | 3 | ### Type of issue (choose one): 4 | - [ ] Bug 5 | - [ ] Feature request 6 | - [ ] Question 7 | 8 | ### Test steps 9 | 10 | *What steps cause the problem to occur? Are there any particular settings or configurations that are required in order to reproduce it?* 11 | 12 | ### Description 13 | 14 | *If this is a bug, what would you expect the correct behavior to be? If it's a feature request, what do you want Caret to do? Are there other examples of this feature that I could look at? Screenshots are always helpful.* 15 | 16 | ### Additional notes 17 | 18 | *If this is a bug, is there anything else I should know? If it's a feature request, any caveats I should keep in mind?* 19 | 20 | ### System details 21 | 22 | *Please provide your Chrome version and operating system here.* 23 | -------------------------------------------------------------------------------- /js/ui/cli.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "command", 3 | "editor" 4 | ], function(command, editor) { 5 | 6 | var cli = document.querySelector(".command-line"); 7 | var input = document.querySelector(".command-line input"); 8 | 9 | input.addEventListener("keyup", function(e) { 10 | switch (e.keyCode) { 11 | case 13: 12 | //on enter, execute command 13 | var value = input.value; 14 | var split = value.split(" "); 15 | var cmd = split[0]; 16 | var arg = split[1]; 17 | if (arg) { 18 | try { 19 | arg = JSON.parse(arg); 20 | } catch (e) { 21 | //failure to parse isn't the end of the world. 22 | } 23 | } 24 | if (cmd) { 25 | command.fire(cmd, arg); 26 | } 27 | 28 | case 27: 29 | //on escape, also hide the prompt 30 | cli.classList.remove("show"); 31 | editor.focus(); 32 | } 33 | }); 34 | 35 | command.on("app:show-prompt", function() { 36 | input.value = ""; 37 | cli.classList.add("show"); 38 | input.focus(); 39 | }); 40 | 41 | command.on("app:hide-prompt", function() { 42 | cli.classList.remove("show"); 43 | editor.focus(); 44 | }) 45 | 46 | }); -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Caret", 3 | "description": "Professional text editing for Chrome and Chrome OS", 4 | "version": "1.8.25", 5 | "manifest_version": 2, 6 | "default_locale": "en", 7 | "icons": { 8 | "128": "icon-128.png" 9 | }, 10 | "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCh9A0p0K76KGXnEYMf4tVxhHUBXQTRh984XrkVSuzX6Tp4al9cj7NgXh3Sjx+0+KctLzpmvCw9bwgWueAE13LhjQ+dJONaR5xhte0KTAfaVRGV5EKCBx6KwzcaBGWBHv3V1b/8CbTENivW3/eVTg0/gmyB0tzfqzEoXy/lnRkZdQIDAQAB", 11 | "update_url": "http://thomaswilburn.net/caret/updates.xml", 12 | "app": { 13 | "background": { 14 | "scripts": [ 15 | "background.js" 16 | ] 17 | } 18 | }, 19 | "permissions": [ 20 | "clipboardRead", 21 | "clipboardWrite", 22 | "contextMenus", 23 | "storage", 24 | "notifications", 25 | "syncFileSystem", 26 | "app.window.fullscreen.overrideEsc", 27 | { 28 | "fileSystem": [ 29 | "write", 30 | "retainEntries", 31 | "directory" 32 | ] 33 | } 34 | ], 35 | "kiosk_enabled": false, 36 | "offline_enabled": true, 37 | "file_handlers": { 38 | "text": { 39 | "types": [ 40 | "application/javascript", 41 | "application/json", 42 | "application/x-shellscript", 43 | "application/xml", 44 | "message/rfc822", 45 | "text/*", 46 | "application/*" 47 | ] 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /js/util/i18n.js: -------------------------------------------------------------------------------- 1 | define(function() { 2 | 3 | var translationCache = {}; 4 | 5 | return { 6 | //process a chunk of template HTML for i18n strings 7 | process: function(html) { 8 | return html.replace(/__MSG_(\w+)__/g, (match, tag) => chrome.i18n.getMessage(tag)); 9 | }, 10 | //process the page for inline strings, marked with .i18n 11 | page: function() { 12 | document.querySelectorAll(".i18n").forEach(function(element) { 13 | var original = element.innerHTML; 14 | var translated = chrome.i18n.getMessage(original); 15 | if (translated) element.innerHTML = translated; 16 | var title = element.getAttribute("title") || ""; 17 | var translatedTitle = chrome.i18n.getMessage(title); 18 | if (translatedTitle) element.setAttribute("title", translatedTitle); 19 | }); 20 | }, 21 | //get a message, or return the untranslated text 22 | //caches results for speed 23 | get: function(message) { 24 | //rest params trigger uncached behavior for substitution 25 | if (!translationCache[message] || arguments.length > 1) { 26 | var subs = []; 27 | for (var i = 1; i < arguments.length; i++) subs.push(arguments[i]); 28 | var translated = chrome.i18n.getMessage(message, subs) || message; 29 | translationCache[message] = translated; 30 | return translated; 31 | } 32 | return translationCache[message]; 33 | } 34 | } 35 | 36 | }); -------------------------------------------------------------------------------- /readme.rst: -------------------------------------------------------------------------------- 1 | *NOTE: With Google planning to remove Chrome Apps from its browser and OS in June of 2022, Caret is no longer under active development. I'm not accepting new pull requests or issues.* 2 | 3 | Caret 4 | ===== 5 | 6 | Caret is a lightweight-but-powerful programmer's editor running as a Chrome 7 | Packaged App. Inspired by Sublime and built on top of the Ace editing 8 | component, it offers: 9 | 10 | - multiple cursors 11 | - tabbed editing and retained files 12 | - syntax highlighting and themes 13 | - command palette/smart go to 14 | - hackable, synchronized configuration files 15 | - project files and folder view 16 | - fast project-wide string search 17 | 18 | More information, links to Caret in the Chrome Web Store, and an 19 | external package file are available at http://thomaswilburn.net/caret. 20 | Documentation can be found in the 21 | `wiki `_. 22 | 23 | You can also load Caret from source code, either to hack around on or 24 | to try the absolute bleeding edge. You'll need to have Node and NPM 25 | installed first, then follow these steps: 26 | 27 | 0. Clone this repo to your local machine 28 | 1. Run ``npm install`` to get the development dependencies (Grunt, LESS, 29 | and some other packages) 30 | 2. Run ``npm run build``, which will generate the CSS files from the LESS 31 | source 32 | 3. Visit ``chrome://extensions`` and enable Developer Mode. 33 | 4. Still on the extensions page, click the button marked "Load unpacked 34 | extension..." and select the directory containing Caret's 35 | manifest.json. 36 | 37 | -------------------------------------------------------------------------------- /js/api.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "command", 3 | "settings!api" 4 | ], function(command, Settings) { 5 | 6 | var noop = function() {}; 7 | 8 | //handles sending custom messages based on Caret commands (builds, plugins, etc) 9 | var targets = Settings.get("api"); 10 | command.on("init:restart", () => targets = Settings.get("api")); 11 | 12 | command.on("api:execute", async function(id, c = noop) { 13 | if (!( id in targets )) return c(); 14 | var config = targets[id]; 15 | var message = {}; 16 | //shallow-copy config message, just in case 17 | //TODO: replace with Object.assign() 18 | for (var key in config.message) { 19 | //if we implement message variables, this would be the place to handle them. 20 | message[key] = config.message[key]; 21 | } 22 | if (config.sendEditorContext) { 23 | //add context information to the message 24 | message.context = { 25 | selection: editor.session.getTextRange(), 26 | path: "" 27 | }; 28 | 29 | if (editor.session.file && editor.session.file.getPath) { 30 | var path = await editor.session.file.getPath(); 31 | message.context.path = path; 32 | } 33 | 34 | } 35 | chrome.runtime.sendMessage(config.id, message, null, function() { 36 | if (chrome.runtime.lastError) { 37 | console.error(chrome.runtime.lastError); 38 | } 39 | c(chrome.runtime.lastError); 40 | }); 41 | }); 42 | 43 | //External apps can send messages by matching Caret's command/argument config objects 44 | chrome.runtime.onMessageExternal.addListener(async function(message, sender, c = noop) { 45 | var result = await command.fire(message.command, message.argument); 46 | c(null, result); 47 | }); 48 | }); -------------------------------------------------------------------------------- /css/menus.less: -------------------------------------------------------------------------------- 1 | /* Like dialogs, menus always are black-on-white */ 2 | 3 | .toolbar { 4 | padding: 0; 5 | margin: 0; 6 | color: @foreground; 7 | line-height: 30px; 8 | list-style-type: none; 9 | z-index: 99; 10 | 11 | hr { 12 | border: none; 13 | border-top: 1px solid rgba(128, 128, 128, .2); 14 | margin: 4px 8px; 15 | } 16 | 17 | .shortcut { 18 | color: #444; 19 | margin-left: 1em; 20 | } 21 | 22 | //nested menus (default) 23 | li { 24 | transition: opacity .2s; 25 | display: flex; 26 | padding: 4px 8px; 27 | justify-content: space-between; 28 | position: relative; 29 | 30 | &:hover:not(.top), &.active { 31 | color: black; 32 | background: #EEE; 33 | } 34 | 35 | &.parent:hover, &.active { 36 | 37 | & > .menu { 38 | display: block; 39 | } 40 | 41 | } 42 | 43 | .menu { 44 | display: none; 45 | min-width: 250px; 46 | position: absolute; 47 | margin-left: 90%; 48 | margin-top: -2em; 49 | z-index: 999; 50 | color: black; 51 | background: white; 52 | padding: 4px 0; 53 | line-height: 1.4; 54 | white-space: nowrap; 55 | box-shadow: 0px 8px 16px rgba(0, 0, 0, .2); 56 | // border-left: 2px solid @accent; 57 | } 58 | 59 | &.parent::after { 60 | content: "..."; 61 | font-weight: bold; 62 | position: absolute; 63 | right: 4px; 64 | top: 0; 65 | color: #444; 66 | } 67 | 68 | } 69 | 70 | //base-level menus 71 | & > li { 72 | display: inline-block; 73 | padding: 4px 8px; 74 | line-height: initial; 75 | 76 | & > .menu { 77 | margin-left: -8px; 78 | margin-top: 4px; 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /js/storage/syncfile.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "storage/syncFS", 3 | "command" 4 | ], function(sync, command) { 5 | 6 | /* 7 | 8 | SyncFile is a wrapper around Chrome's synchronized storage use the same 9 | interface as the File module. This means you can assign a SyncFile 10 | containing Caret's settings JSON to a tab just as you would a regular file, 11 | and the tab can read/write from it without any customization. The one 12 | difference is the virtual flag, which is used to prevent some file-only 13 | behaviors (such as retainEntry calls). 14 | 15 | As soon as chrome.syncFileSystem allows us to create a filesystem even if 16 | the device is offline for the first request, we'll swap these over to a 17 | wrapper around file entries from that storage. The change should remain 18 | entirely transparent as far as other modules are concerned, although there 19 | are some abstraction leaks in settings.js that we'll need to handle. 20 | 21 | */ 22 | 23 | var SyncFile = function(name) { 24 | this.entry = {}; 25 | if (name) { 26 | this.open(name); 27 | } 28 | this.virtual = true; 29 | }; 30 | SyncFile.prototype = { 31 | name: "", 32 | open: function(name) { 33 | this.name = name; 34 | this.entry.name = name; 35 | return this; 36 | }, 37 | read: async function() { 38 | var name = this.name; 39 | return await sync.get(this.name) 40 | }, 41 | write: async function(content) { 42 | await sync.set(this.name, content); 43 | command.fire("settings:change-local"); 44 | }, 45 | retain: function() { return false; }, 46 | restore: function() { return Promise.reject("Cannot restore sync storage files") } 47 | }; 48 | 49 | return SyncFile; 50 | 51 | }); -------------------------------------------------------------------------------- /js/ui/statusbar.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "editor", 3 | "command" 4 | ], function(editor, command) { 5 | 6 | /* 7 | A module for changing the status text at the bottom of the window. 8 | */ 9 | 10 | var external = ""; 11 | var element = document.querySelector(".status-text"); 12 | var update = function() { 13 | var selection = editor.getSelection(); 14 | var displayText = ""; 15 | var cursor = selection.getCursor(); 16 | displayText = (cursor.row + 1) + ":" + (cursor.column + 1); 17 | if (external) { 18 | displayText += " - " + external; 19 | } 20 | element.innerHTML = displayText; 21 | }; 22 | editor.on("changeSelection", update); 23 | 24 | var toastTimeout = null; 25 | 26 | var interface = { 27 | setMessage: function(msg) { 28 | external = msg; 29 | if (toastTimeout !== null) { 30 | clearTimeout(toastTimeout); 31 | toastTimeout = null; 32 | } 33 | update(); 34 | return true; 35 | }, 36 | clearMessage: function() { 37 | external = ""; 38 | update(); 39 | return true; 40 | }, 41 | toast: function(msg, seconds) { 42 | external = msg; 43 | update(); 44 | if (toastTimeout !== null) { 45 | clearTimeout(toastTimeout); 46 | } 47 | toastTimeout = setTimeout(function() { 48 | external = ""; 49 | update(); 50 | toastTimeout = null; 51 | }, seconds ? seconds * 1000 : 5000); 52 | return true; 53 | } 54 | }; 55 | 56 | command.on("status:set", interface.setMessage); 57 | command.on("status:clear", interface.clearMessage); 58 | command.on("status:toast", interface.toast); 59 | 60 | return interface; 61 | 62 | }); -------------------------------------------------------------------------------- /css/searchbar.less: -------------------------------------------------------------------------------- 1 | .searchbar { 2 | display: none; 3 | color: darken(@foreground, 30%); 4 | background-color: darken(@background, 10%); 5 | z-index: 999; 6 | padding: 8px; 7 | box-sizing: content-box; 8 | align-items: stretch; 9 | flex: 0 0 20px; 10 | 11 | .vertical-center() { 12 | display: flex; 13 | flex-direction: column; 14 | justify-content: center; 15 | } 16 | 17 | &.active { 18 | display: flex; 19 | } 20 | 21 | input[type=checkbox] { 22 | display:none; 23 | 24 | & + label { 25 | flex: 0 0 22px; 26 | .vertical-center(); 27 | color: darken(@foreground, 30%); 28 | font-size: 16px; 29 | margin: 0 4px; 30 | cursor: pointer; 31 | } 32 | 33 | &:checked + label { 34 | font-weight: bold; 35 | color: @accent; 36 | } 37 | } 38 | 39 | .search-box { 40 | flex: 1; 41 | border: none; 42 | padding: 4px; 43 | background: transparent; 44 | background-color: @background; 45 | color: @foreground; 46 | font-size: 12px; 47 | 48 | &::selection { 49 | background: mix(@accent, #ccc, 15%); 50 | } 51 | } 52 | 53 | button { 54 | border: none; 55 | outline: none; 56 | background: transparent; 57 | color: darken(@foreground, 30%); 58 | cursor: pointer; 59 | padding: 0 10px; 60 | .vertical-center(); 61 | 62 | &:hover { 63 | color: @accent; 64 | background: rgba(128, 128, 128, .2); 65 | } 66 | } 67 | } 68 | 69 | //search result markers 70 | .caret-search-marker { 71 | pointer-events: auto; 72 | position: absolute; 73 | cursor: pointer; 74 | 75 | &:hover { 76 | &:extend(.caret-search-term); 77 | } 78 | } 79 | 80 | .caret-search-term { 81 | position: absolute; 82 | outline: 1px solid @accent; 83 | background: rgba(128, 128, 128, .3); 84 | } 85 | -------------------------------------------------------------------------------- /js/util/readme.rst: -------------------------------------------------------------------------------- 1 | Module descriptions - util 2 | ========================== 3 | 4 | aceLoad.js 5 | ---------- 6 | 7 | Shims Ace's loadScript() async loader so that AMD modules can simply 8 | declare Ace dependencies the same way they declare AMD dependencies. 9 | 10 | chromePromise.js 11 | ---------------- 12 | 13 | Wraps the ``chrome.*`` APIs up using Promises for easy interop with ``async`` 14 | and ``await``. Doesn't shim everything, only the async functions currently 15 | used by Caret. 16 | 17 | i18n.js 18 | ------- 19 | 20 | Gets translated strings from Chrome's localization system. Language files are 21 | located in _locales. 22 | 23 | inflate.js 24 | ---------- 25 | 26 | Chrome OS disallows using ``eval()`` or ``new Function()``, which means 27 | many template libraries simply won't work without pre-compiling the 28 | templates. Instead of going that route, recognizing that template speed 29 | is almost never a bottleneck for Caret, inflate.js provides 30 | Mustache-compatible templating that can load from the filesystem or the 31 | DOM (loaded automatically by ID). Exposes the following methods: 32 | 33 | - ``load``- Pulls a template from the given filesystem path. Returns a 34 | promise that resolves when the template is ready. 35 | - ``loadHTML`` - Directly insert HTML into the template cache for use. 36 | - ``get`` - Fills a template with data and returns a DOM element. 37 | - ``getHTML`` - Fills a template with data and returns the string 38 | representation 39 | - ``getAsync`` - Used to simultaneously load and fill a template. 40 | Returns a promise that resolves with the filled template as a DOM 41 | element. 42 | 43 | template.js 44 | ----------- 45 | 46 | A plugin that loads a template from disk, then returns the ``inflate`` 47 | templating object. Useful for modules that need a template as part of 48 | their dependencies. 49 | 50 | text.js 51 | ------- 52 | 53 | A RequireJS plugin that loads files from Caret's app directory using 54 | XHR. Used to get the default settings JSON through a standard interface. 55 | -------------------------------------------------------------------------------- /js/ace/mode-gitignore.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/gitignore_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { 2 | "use strict"; 3 | 4 | var oop = require("../lib/oop"); 5 | var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; 6 | 7 | var GitignoreHighlightRules = function() { 8 | this.$rules = { 9 | "start" : [ 10 | { 11 | token : "comment", 12 | regex : /^\s*#.*$/ 13 | }, { 14 | token : "keyword", // negated patterns 15 | regex : /^\s*!.*$/ 16 | } 17 | ] 18 | }; 19 | 20 | this.normalizeRules(); 21 | }; 22 | 23 | GitignoreHighlightRules.metaData = { 24 | fileTypes: ['gitignore'], 25 | name: 'Gitignore' 26 | }; 27 | 28 | oop.inherits(GitignoreHighlightRules, TextHighlightRules); 29 | 30 | exports.GitignoreHighlightRules = GitignoreHighlightRules; 31 | }); 32 | 33 | ace.define("ace/mode/gitignore",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/gitignore_highlight_rules"], function(require, exports, module) { 34 | "use strict"; 35 | 36 | var oop = require("../lib/oop"); 37 | var TextMode = require("./text").Mode; 38 | var GitignoreHighlightRules = require("./gitignore_highlight_rules").GitignoreHighlightRules; 39 | 40 | var Mode = function() { 41 | this.HighlightRules = GitignoreHighlightRules; 42 | this.$behaviour = this.$defaultBehaviour; 43 | }; 44 | oop.inherits(Mode, TextMode); 45 | 46 | (function() { 47 | this.lineCommentStart = "#"; 48 | this.$id = "ace/mode/gitignore"; 49 | }).call(Mode.prototype); 50 | 51 | exports.Mode = Mode; 52 | }); (function() { 53 | ace.require(["ace/mode/gitignore"], function(m) { 54 | if (typeof module == "object" && typeof exports == "object" && module) { 55 | module.exports = m; 56 | } 57 | }); 58 | })(); 59 | -------------------------------------------------------------------------------- /js/ace/ext-statusbar.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/ext/statusbar",["require","exports","module","ace/lib/dom","ace/lib/lang"], function(require, exports, module) { 2 | "use strict"; 3 | var dom = require("../lib/dom"); 4 | var lang = require("../lib/lang"); 5 | 6 | var StatusBar = function(editor, parentNode) { 7 | this.element = dom.createElement("div"); 8 | this.element.className = "ace_status-indicator"; 9 | this.element.style.cssText = "display: inline-block;"; 10 | parentNode.appendChild(this.element); 11 | 12 | var statusUpdate = lang.delayedCall(function(){ 13 | this.updateStatus(editor); 14 | }.bind(this)).schedule.bind(null, 100); 15 | 16 | editor.on("changeStatus", statusUpdate); 17 | editor.on("changeSelection", statusUpdate); 18 | editor.on("keyboardActivity", statusUpdate); 19 | }; 20 | 21 | (function(){ 22 | this.updateStatus = function(editor) { 23 | var status = []; 24 | function add(str, separator) { 25 | str && status.push(str, separator || "|"); 26 | } 27 | 28 | add(editor.keyBinding.getStatusText(editor)); 29 | if (editor.commands.recording) 30 | add("REC"); 31 | 32 | var sel = editor.selection; 33 | var c = sel.lead; 34 | 35 | if (!sel.isEmpty()) { 36 | var r = editor.getSelectionRange(); 37 | add("(" + (r.end.row - r.start.row) + ":" +(r.end.column - r.start.column) + ")", " "); 38 | } 39 | add(c.row + ":" + c.column, " "); 40 | if (sel.rangeCount) 41 | add("[" + sel.rangeCount + "]", " "); 42 | status.pop(); 43 | this.element.textContent = status.join(""); 44 | }; 45 | }).call(StatusBar.prototype); 46 | 47 | exports.StatusBar = StatusBar; 48 | 49 | }); (function() { 50 | ace.require(["ace/ext/statusbar"], function(m) { 51 | if (typeof module == "object" && typeof exports == "object" && module) { 52 | module.exports = m; 53 | } 54 | }); 55 | })(); 56 | -------------------------------------------------------------------------------- /js/storage/syncFS.js: -------------------------------------------------------------------------------- 1 | define(["util/chromePromise"], function(chromeP) { 2 | 3 | /* 4 | SyncFS is a crappy way to use chrome.storage.sync for entries larger than 4KB. 5 | This will work until chrome.syncFileSystem is more offline-friendly. 6 | Entries are set with a string if they're less than 3KB, otherwise the keyed entry 7 | stores the number of 3KB chunks used, and those are stored at key + chunkNumber. 8 | */ 9 | 10 | var cache = null; 11 | var requests = []; 12 | var pending = false; 13 | 14 | var decode = function(key) { 15 | //extracts multiple entries from a single key 16 | //presumes cache is set first 17 | var seed = cache[key]; 18 | if (!seed) return null; 19 | if (typeof seed == "string") return seed; 20 | var pieces = []; 21 | for (var i = 0; i < seed; i++) { 22 | pieces.push(cache[key + i]); 23 | } 24 | var whole = pieces.join(""); 25 | return whole; 26 | }; 27 | 28 | return { 29 | get: async function(key) { 30 | if (cache) { 31 | return decode(key); 32 | } 33 | 34 | if (!pending) pending = new Promise(async function(ok, fail) { 35 | var all = await chromeP.storage.sync.get(); 36 | cache = all; 37 | pending = null; 38 | ok(); 39 | }); 40 | 41 | return pending.then(_ => decode(key)); 42 | }, 43 | set: async function(key, data) { 44 | cache = null; 45 | var hash = {}; 46 | if (data.length < 3000) { 47 | hash[key] = data; 48 | } else { 49 | var chunks = []; 50 | for (var i = 0; i < data.length; i += 3000) { 51 | chunks.push(data.substr(i, 3000)); 52 | } 53 | hash[key] = chunks.length; 54 | chunks.forEach((chunk, i) => hash[key + i] = chunk); 55 | } 56 | await chromeP.storage.sync.set(hash); 57 | }, 58 | remove: async function(key) { 59 | var seed = cache[key]; 60 | if (typeof seed == "number") { 61 | var all = new Array(seed).map(i => chromeP.storage.sync.remove(key + i)); 62 | return Promise.all(all); 63 | } 64 | cache = null; 65 | await chromeP.storage.sync.remove(key); 66 | } 67 | } 68 | 69 | 70 | }); -------------------------------------------------------------------------------- /js/ace/theme-son_of_obsidian.js: -------------------------------------------------------------------------------- 1 | /*Son of Obsidian theme ported to Ace by Luciano Paciornick*/ 2 | ace.define( 3 | "ace/theme/son_of_obsidian", 4 | ["require", "exports", "module", "ace/lib/dom"], 5 | function(require, exports, module) { 6 | exports.isDark = true; 7 | exports.cssClass = "ace-son-of-obsidian"; 8 | exports.cssText = ".ace-son-of-obsidian .ace_gutter {background: #e8e8e8; color: #333 } .ace-son-of-obsidian .ace_print-margin {width: 1px; background: #e8e8e8 } .ace-son-of-obsidian {background-color: #22272a; color: #F8F8F8 } .ace-son-of-obsidian .ace_cursor {color: rgba(255, 255, 255, 0.65) } .ace-son-of-obsidian .ace_marker-layer .ace_selection {background: #808080 } .ace-son-of-obsidian.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #22272a; border-radius: 2px } .ace-son-of-obsidian .ace_marker-layer .ace_step {background: rgb(198, 219, 174) } .ace-son-of-obsidian .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px; border: 1px solid rgba(255, 255, 255, 0.25) } .ace-son-of-obsidian .ace_marker-layer .ace_active-line {background: rgba(103, 140, 177, 0.27) } .ace-son-of-obsidian .ace_gutter-active-line {background-color: rgba(103, 140, 177, 0.27) } .ace-son-of-obsidian .ace_marker-layer .ace_selected-word {border: 1px solid #808080 } .ace-son-of-obsidian .ace_fold {background-color: #93C763; border-color: #F8F8F8 } .ace-son-of-obsidian .ace_constant, .ace-son-of-obsidian .ace_entity.ace_name.ace_tag, .ace-son-of-obsidian .ace_keyword, .ace-son-of-obsidian .ace_storage {color: #93C763 } .ace-son-of-obsidian .ace_constant.ace_numeric, .ace-son-of-obsidian .ace_keyword.ace_other.ace_unit {color: #FFCD22 } .ace-son-of-obsidian .ace_meta.ace_tag, .ace-son-of-obsidian .ace_support {color: #FFFFFF } .ace-son-of-obsidian .ace_invalid.ace_illegal {color: #F8F8F8; background-color: #9D1E15 } .ace-son-of-obsidian .ace_invalid.ace_deprecated {font-style: italic; color: #AB2A1D } .ace-son-of-obsidian .ace_string {color: #FF8000 } .ace-son-of-obsidian .ace_comment {color: #66747B } .ace-son-of-obsidian .ace_entity.ace_other.ace_attribute-name {color: #678CB1 }"; 9 | var dom = require("../lib/dom"); 10 | dom.importCssString(exports.cssText, exports.cssClass); 11 | }); 12 | -------------------------------------------------------------------------------- /js/ace/ext-linking.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/ext/linking",["require","exports","module","ace/editor","ace/config"], function(require, exports, module) { 2 | 3 | var Editor = require("../editor").Editor; 4 | 5 | require("../config").defineOptions(Editor.prototype, "editor", { 6 | enableLinking: { 7 | set: function(val) { 8 | if (val) { 9 | this.on("click", onClick); 10 | this.on("mousemove", onMouseMove); 11 | } else { 12 | this.off("click", onClick); 13 | this.off("mousemove", onMouseMove); 14 | } 15 | }, 16 | value: false 17 | } 18 | }); 19 | 20 | exports.previousLinkingHover = false; 21 | 22 | function onMouseMove(e) { 23 | var editor = e.editor; 24 | var ctrl = e.getAccelKey(); 25 | 26 | if (ctrl) { 27 | var editor = e.editor; 28 | var docPos = e.getDocumentPosition(); 29 | var session = editor.session; 30 | var token = session.getTokenAt(docPos.row, docPos.column); 31 | 32 | if (exports.previousLinkingHover && exports.previousLinkingHover != token) { 33 | editor._emit("linkHoverOut"); 34 | } 35 | editor._emit("linkHover", {position: docPos, token: token}); 36 | exports.previousLinkingHover = token; 37 | } else if (exports.previousLinkingHover) { 38 | editor._emit("linkHoverOut"); 39 | exports.previousLinkingHover = false; 40 | } 41 | } 42 | 43 | function onClick(e) { 44 | var ctrl = e.getAccelKey(); 45 | var button = e.getButton(); 46 | 47 | if (button == 0 && ctrl) { 48 | var editor = e.editor; 49 | var docPos = e.getDocumentPosition(); 50 | var session = editor.session; 51 | var token = session.getTokenAt(docPos.row, docPos.column); 52 | 53 | editor._emit("linkClick", {position: docPos, token: token}); 54 | } 55 | } 56 | 57 | }); (function() { 58 | ace.require(["ace/ext/linking"], function(m) { 59 | if (typeof module == "object" && typeof exports == "object" && module) { 60 | module.exports = m; 61 | } 62 | }); 63 | })(); 64 | -------------------------------------------------------------------------------- /js/ui/window.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "command", 3 | "storage/settingsProvider" 4 | ], function(command, Settings) { 5 | 6 | var frame = chrome.app.window.current(); 7 | 8 | var setTheme = async function() { 9 | var data = await Settings.pull("user"); 10 | var themes = { 11 | "dark": "css/caret-dark.css", 12 | "twilight": "css/caret-twilight.css", 13 | "light": "css/caret.css" 14 | }; 15 | var theme = data.user.uiTheme || "light"; 16 | var url = themes[theme] || themes.dark; 17 | document.querySelector("#theme").setAttribute("href", url); 18 | }; 19 | setTheme(); 20 | command.on("init:restart", setTheme); 21 | 22 | command.on("app:minimize", function() { 23 | frame.minimize(); 24 | editor.focus(); 25 | }); 26 | 27 | command.on("app:maximize", function() { 28 | frame.isMaximized() || frame.isFullscreen() ? frame.restore() : frame.maximize(); 29 | document.body.classList.toggle("fullscreened", !frame.isMaximized()); 30 | editor.focus(); 31 | }); 32 | 33 | if (frame.isMaximized() || frame.isFullscreen()) { 34 | document.body.classList.add("fullscreened"); 35 | } 36 | 37 | command.on("app:restart", function() { 38 | chrome.runtime.reload(); 39 | }); 40 | 41 | //developer command for reloading CSS 42 | command.on("app:reload-css", function() { 43 | var link = document.querySelector("link#theme"); 44 | link.href = link.href; 45 | }); 46 | 47 | //handle immersive fullscreen 48 | var onFullscreen = function() { 49 | document.body.classList.add("fullscreened"); 50 | Settings.pull("user").then(function(data) { 51 | if (data.user.immersiveFullscreen) { 52 | document.body.classList.add("immersive"); 53 | editor.resize(); 54 | } 55 | }); 56 | } 57 | 58 | frame.onFullscreened.addListener(onFullscreen); 59 | if (frame.isFullscreen()) { 60 | onFullscreen(); 61 | } 62 | 63 | frame.onRestored.addListener(function() { 64 | document.body.classList.remove("fullscreen"); 65 | document.body.classList.remove("immersive"); 66 | }); 67 | 68 | //kill middle clicks if not handled 69 | document.body.addEventListener("click", function(e) { 70 | if (e.button == 1) { 71 | e.preventDefault(); 72 | } 73 | }); 74 | 75 | }); -------------------------------------------------------------------------------- /css/palette.less: -------------------------------------------------------------------------------- 1 | .palette { 2 | display: none; 3 | width: 320px; 4 | position: fixed; 5 | top: 20px; 6 | left: ~"calc(50% - 150px)"; 7 | background: transparent; 8 | color: darken(@foreground, 30%); 9 | z-index: 999; 10 | font-size: 16px; 11 | box-shadow: 0px 8px 16px rgba(0, 0, 0, .2); 12 | 13 | @paletteBackground: lighten(@background, 10%); 14 | 15 | transition-property: opacity, -webkit-transform; 16 | transition-duration: .1s, .2s; 17 | transition-timing-function: linear, ease-in-out; 18 | 19 | -webkit-transform: perspective(1000px) translateY(0px) rotateX(0deg) translateZ(0); 20 | opacity: 1; 21 | 22 | &.enter { 23 | opacity: .2; 24 | transition-duration: 0s, 0s; 25 | -webkit-transform: perspective(1000px) translateY(10px) rotateX(-45deg) translateZ(-20px); 26 | } 27 | 28 | &.active { 29 | display: block; 30 | } 31 | 32 | .main { 33 | background: @paletteBackground; 34 | padding: 8px 12px; 35 | } 36 | 37 | h1 { 38 | font-size: 16px; 39 | padding: 0; 40 | margin-top: 0px; 41 | font-weight: normal; 42 | } 43 | 44 | input { 45 | width: 100%; 46 | display: block; 47 | border: none; 48 | border-bottom: 2px solid @background; 49 | padding: 8px; 50 | margin-top: 8px; 51 | background: transparent; 52 | color: @foreground; 53 | font-weight: bold; 54 | font-size: 18px; 55 | 56 | &:focus { 57 | outline: none; 58 | border-bottom: 2px solid @accent; 59 | } 60 | } 61 | 62 | .results { 63 | background: fade(@paletteBackground, 90%); 64 | padding: 0; 65 | margin: 0; 66 | list-style-type: none; 67 | z-index: 999; 68 | border-top: 1px solid @faded; 69 | 70 | li { 71 | border-left: 2px solid @faded; 72 | display: block; 73 | padding: 8px; 74 | 75 | &.current { 76 | border-left: 2px solid @accent; 77 | font-weight: bold; 78 | background: @paletteBackground; 79 | } 80 | 81 | .label { 82 | font-size: 18px; 83 | } 84 | 85 | .sublabel { 86 | font-size: 14px; 87 | // font-weight: normal; 88 | white-space: nowrap; 89 | overflow: hidden; 90 | max-height: 1.5em; 91 | margin-top: 4px; 92 | } 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /css/dialog.less: -------------------------------------------------------------------------------- 1 | //dialog always uses the white coloring, regardless of ui theme 2 | .dialog { 3 | min-width: 250px; 4 | max-width: 400px; 5 | margin-top: 50px; 6 | background: white; 7 | color: black; 8 | box-shadow: 0px 4px 8px rgba(0, 0, 0, .2); 9 | z-index: 999; 10 | padding: 10px; 11 | line-height: 170%; 12 | transition-property: -webkit-transform; 13 | transition-duration: .3s; 14 | transition-timing-function: ease-in-out; 15 | -webkit-transform: translateY(0px) rotateX(0); 16 | 17 | .enter & { 18 | -webkit-transform: translateY(-10px) rotateX(-20deg); 19 | } 20 | 21 | .text { 22 | white-space: pre-wrap; 23 | text-align: center; 24 | display: block; 25 | } 26 | 27 | .button-row { 28 | display: flex; 29 | justify-content: space-around; 30 | margin-top: 10px; 31 | font-size: 16px; 32 | 33 | button { 34 | padding: 10px; 35 | border: none; 36 | text-align: center; 37 | background: white; 38 | color: black; 39 | min-width: 75px; 40 | margin: 0 8px; 41 | text-transform: uppercase; 42 | color: #455A64; 43 | 44 | &:hover { 45 | background: #EEE; 46 | } 47 | 48 | &:focus { 49 | outline: none; 50 | font-weight: bold; 51 | } 52 | } 53 | } 54 | } 55 | 56 | .modal-overlay { 57 | position: fixed; 58 | display: flex; 59 | justify-content: center; 60 | align-items: flex-start; 61 | content: ""; 62 | top: 0; 63 | bottom: 0; 64 | left: 0; 65 | right: 0; 66 | background: rgba(0, 0, 0, .1); 67 | z-index: 99; 68 | transition-duration: .2s; 69 | transition-timing-function: linear; 70 | transition-property: opacity; 71 | opacity: 1; 72 | -webkit-transform: translateZ(0); 73 | z-index: 999; 74 | 75 | &.enter { 76 | opacity: .2; 77 | } 78 | } 79 | 80 | .credits { 81 | white-space: initial; 82 | 83 | h2 { 84 | font-size: 18px; 85 | font-weight: normal; 86 | } 87 | 88 | h3 { 89 | font-size: 14px; 90 | } 91 | 92 | a, a:visited { 93 | color: #455A64; 94 | } 95 | 96 | ul { 97 | padding: 0; 98 | margin: 0; 99 | list-style: none; 100 | 101 | li { 102 | padding: 0; 103 | margin: 0; 104 | margin-bottom: 1em; 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /css/base.less: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | text-rendering: optimizeLegibility; 4 | } 5 | 6 | html, body { 7 | height: 100%; 8 | background: @background; 9 | color: @foreground; 10 | } 11 | 12 | body { 13 | margin: 0; 14 | padding: 0; 15 | font-family: 16 | "Segoe UI", 17 | "Roboto", 18 | "Helvetica Neue", 19 | "San Francisco", 20 | "Droid Sans", 21 | "Liberation Sans", 22 | sans-serif; 23 | display: flex; 24 | flex-direction: column; 25 | align-items: stretch; 26 | align-content: stretch; 27 | max-width: 100%; 28 | border-right: 1px solid #AAA; 29 | } 30 | 31 | a[target] { 32 | color: @foreground; 33 | } 34 | 35 | :focus { 36 | outline: @accent auto 5px; 37 | } 38 | 39 | //MACRO-LEVEL POSITIONING 40 | 41 | .titlebar { 42 | flex: 0 0 30px; 43 | z-index: 999; 44 | } 45 | 46 | .tabs { 47 | flex: 0 0 36px; 48 | } 49 | 50 | .central { 51 | display: flex; 52 | flex-grow: 1; 53 | align-items: stretch; 54 | align-content: stretch; 55 | min-height: 0; 56 | } 57 | 58 | .editing { 59 | min-width: 0px; 60 | display: flex; 61 | flex-grow: 1; 62 | align-items: stretch; 63 | align-content: stretch; 64 | flex-direction: column; 65 | } 66 | 67 | #editor { 68 | flex-grow: 1; 69 | padding-top: 2px; 70 | z-index: 9; 71 | } 72 | 73 | .bottom-bar { 74 | flex: 0 0 auto; 75 | align-self: flex-end; 76 | width: 100%; 77 | display: flex; 78 | justify-content: space-between; 79 | align-content: stretch; 80 | box-shadow: 0 -4px 4px rgba(0, 0, 0, .1); 81 | z-index: 99; 82 | -webkit-transform: translateZ(0); 83 | transform: translateZ(0); 84 | } 85 | 86 | //fullscreen changes 87 | .fullscreened { 88 | border-right: none; 89 | } 90 | 91 | //immersive mode 92 | 93 | .immersive { 94 | .titlebar, .bottom-bar { 95 | display: none; 96 | } 97 | 98 | .central { 99 | margin-top: 5px; 100 | } 101 | 102 | .tabs { 103 | height: 6px; 104 | position: fixed; 105 | top: 0; 106 | right: 0; 107 | left: 0; 108 | overflow: hidden; 109 | transition: height .3s ease; 110 | align-items: stretch; 111 | align-content: stretch; 112 | z-index: 999; 113 | 114 | .tab { 115 | overflow: hidden; 116 | } 117 | 118 | &:hover { 119 | height: 34px; 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /js/ui/readme.rst: -------------------------------------------------------------------------------- 1 | Module description - ui/\* 2 | ========================== 3 | 4 | cli.js 5 | ------ 6 | 7 | Creates the UI and bindings for a "command line" that can run Caret 8 | commands directly. Useful when testing a new command, since you don't 9 | need to change keys.json or menu.json in order to run it. 10 | 11 | contextMenus.js 12 | --------------- 13 | 14 | Simplifies the process of adding Chrome context menus to page links, 15 | including adding a basic REST-style router for getting parameters out of 16 | the link URL. Exposes a ``register`` method for setting up the actual 17 | menu and its callback, and a ``makeURL`` method to help with making 18 | route URLs that correctly start with the app's extension ID. 19 | 20 | dialog.js 21 | --------- 22 | 23 | Exposes a function that will pop up a dialog box, since Chrome apps are 24 | not allowed to use ``alert()``, ``confirm()``, or ``prompt()``. 25 | Reasonably customizable. 26 | 27 | keys.js 28 | ------- 29 | 30 | Reads the local keyboard settings and registers on the document body to 31 | convert them into commands. Also handles unbinding any Ace commands that 32 | would otherwise collide. Exposes no external methods or data. 33 | 34 | menus.js 35 | -------- 36 | 37 | Generates the menu bar from the local menu settings file. Exposes no 38 | external methods or data at this time. 39 | 40 | palette.js 41 | ---------- 42 | 43 | Sets up the command palette and returns it as a singleton for any other 44 | modules that might want to trigger it or alter its data, although it is 45 | recommended that other modules simply send ``palette:*`` commands 46 | instead. 47 | 48 | projectManager.js 49 | ----------------- 50 | 51 | Tracks any current project settings, files, and navigable directories. 52 | Exposes the manager object to dependent modules, primarily so that the 53 | palette can get the list of files for Go To File. 54 | 55 | searchbar.js 56 | ------------ 57 | 58 | Allows the user to search all files in the project. Exposes only the 59 | ``searchbar:show-project-search`` command. 60 | 61 | statusbar.js 62 | ------------ 63 | 64 | Sets the status text, and returns an interface with ``setMessage()``, 65 | ``clearMessage()``, and ``toast()`` methods. It's recommended to use the 66 | ``status:*`` commands instead of requiring this module directly. 67 | 68 | window.js 69 | --------- 70 | 71 | Handles various app lifecycle events, such as restarting and closing tabs. -------------------------------------------------------------------------------- /config/keys.json: -------------------------------------------------------------------------------- 1 | { 2 | // To disable Caret's key-capture behavior, set a value to null or false 3 | // for example: "Ctrl-Space": null will defer that combo to the ChromeOS language switcher 4 | 5 | //basic navigation/application keys 6 | "Ctrl-O": "session:open-file", 7 | "Ctrl-W": "session:close-tab", 8 | "Ctrl-S": "session:save-file", 9 | "Ctrl-Shift-S": "session:save-file-as", 10 | "Ctrl-Alt-S": "session:save-all", 11 | "Ctrl-N": "session:new-file", 12 | "Ctrl-Tab": "session:change-tab", 13 | "Ctrl-Shift-Tab": { "command": "session:change-tab", "argument": -1 }, 14 | 15 | //Chromebook fixes 16 | "Ctrl-Up": { "ace": "addCursorAbove" }, 17 | "Ctrl-Down": { "ace": "addCursorBelow" }, 18 | "Ctrl-Home": { "ace": "gotostart" }, 19 | "Ctrl-End": { "ace": "gotoend" }, 20 | "Ctrl-PageUp": { "ace": "gotostart" }, 21 | "Ctrl-PageDown": { "ace": "gotoend" }, 22 | "Alt-PageDown": { "ace": "gotopagedown" }, 23 | "PageDown": { "ace": "gotopagedown" }, 24 | "Alt-PageUp": { "ace": "gotopageup" }, 25 | "PageUp": {"ace": "gotopageup" }, 26 | "Alt-Home": { "ace": "gotolinestart" }, 27 | "Home": { "ace": "gotolinestart" }, 28 | "Alt-End": { "ace": "gotolineend" }, 29 | "End": { "ace": "gotolineend" }, 30 | "Ctrl-Space": { "ace": "startAutocomplete" }, 31 | 32 | //Sublime compatibility 33 | "Ctrl-L": { "ace": "expandtoline" }, 34 | "Alt-Q": "sublime:wrap", 35 | "Ctrl-D": "sublime:select-or-more-after", 36 | "Ctrl-P": { "command": "palette:open" }, 37 | "Ctrl-Shift-P": { "command": "palette:open", "argument": "command" }, 38 | "Ctrl-R": { "command": "palette:open", "argument": "reference" }, 39 | "Ctrl-G": { "command": "palette:open", "argument": "line" }, 40 | "Ctrl-Shift-F": { "command": "searchbar:show-project-search" }, 41 | "Ctrl-M": { "ace": "jumptomatching" }, 42 | "Ctrl-Shift-M": { "command": "sublime:expand-to-matching" }, 43 | "Ctrl-Q": { "command": "ace:togglemacro" }, 44 | "Ctrl-Shift-Q": { "ace": "replaymacro" }, 45 | "Ctrl--": { "command": "editor:adjust-zoom", "argument": -1 }, 46 | "Ctrl-=": { "command": "editor:adjust-zoom", "argument": 1 }, 47 | "Ctrl-0": { "command": "editor:default-zoom" }, 48 | "Ctrl-J": { "ace": "joinlines" }, 49 | "Ctrl-Shift-K": { "ace": "removeline" }, 50 | "Ctrl-Shift-Up": { "ace": "movelinesup" }, 51 | "Ctrl-Shift-Down": { "ace": "movelinesdown" }, 52 | 53 | //dev mode 54 | "Ctrl-Shift-M": "sequence:test", 55 | "Ctrl-.": { "command": "app:show-prompt" } 56 | } 57 | -------------------------------------------------------------------------------- /js/ace/mode-csp.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/csp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { 2 | "use strict"; 3 | 4 | var oop = require("../lib/oop"); 5 | var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; 6 | 7 | var CspHighlightRules = function() { 8 | var keywordMapper = this.createKeywordMapper({ 9 | "constant.language": "child-src|connect-src|default-src|font-src|frame-src|img-src|manifest-src|media-src|object-src" 10 | + "|script-src|style-src|worker-src|base-uri|plugin-types|sandbox|disown-opener|form-action|frame-ancestors|report-uri" 11 | + "|report-to|upgrade-insecure-requests|block-all-mixed-content|require-sri-for|reflected-xss|referrer|policy-uri", 12 | "variable": "'none'|'self'|'unsafe-inline'|'unsafe-eval'|'strict-dynamic'|'unsafe-hashed-attributes'" 13 | }, "identifier", true); 14 | 15 | this.$rules = { 16 | start: [{ 17 | token: "string.link", 18 | regex: /https?:[^;\s]*/ 19 | }, { 20 | token: "operator.punctuation", 21 | regex: /;/ 22 | }, { 23 | token: keywordMapper, 24 | regex: /[^\s;]+/ 25 | }] 26 | }; 27 | }; 28 | 29 | oop.inherits(CspHighlightRules, TextHighlightRules); 30 | 31 | exports.CspHighlightRules = CspHighlightRules; 32 | }); 33 | 34 | ace.define("ace/mode/csp",["require","exports","module","ace/mode/text","ace/mode/csp_highlight_rules","ace/lib/oop"], function(require, exports, module) { 35 | "use strict"; 36 | 37 | var TextMode = require("./text").Mode; 38 | var CspHighlightRules = require("./csp_highlight_rules").CspHighlightRules; 39 | var oop = require("../lib/oop"); 40 | 41 | var Mode = function() { 42 | this.HighlightRules = CspHighlightRules; 43 | }; 44 | 45 | oop.inherits(Mode, TextMode); 46 | 47 | (function() { 48 | this.$id = "ace/mode/csp"; 49 | }).call(Mode.prototype); 50 | 51 | exports.Mode = Mode; 52 | }); (function() { 53 | ace.require(["ace/mode/csp"], function(m) { 54 | if (typeof module == "object" && typeof exports == "object" && module) { 55 | module.exports = m; 56 | } 57 | }); 58 | })(); 59 | -------------------------------------------------------------------------------- /js/ui/contextMenus.js: -------------------------------------------------------------------------------- 1 | define(function() { 2 | 3 | //track all assigned context menus in order to respond 4 | var registry = {}; 5 | var appID = chrome.runtime.id; 6 | 7 | //all context menus created here are handled via onClick 8 | var onClick = function(info) { 9 | var id = info.menuItemId; 10 | var handler = registry[id]; 11 | if (handler) { 12 | var params = handler.parse(info.linkUrl); 13 | handler.callback(params); 14 | } 15 | }; 16 | 17 | //provides a chrome-extension:// URL for menus based on a filter string 18 | var makeURL = function(filter, id) { 19 | var url = `chrome-extension://${appID}/${filter}`; 20 | if (typeof id != "undefined") { 21 | url += "/" + id; 22 | } 23 | return url; 24 | }; 25 | 26 | var createRoute = function(route, handler) { 27 | var parts = route.split("/"); 28 | var positionMap = {}; 29 | var position = 1; 30 | parts = parts.map(function(s) { 31 | if (s[0] == ":") { 32 | //set the key to be used on parsing 33 | positionMap[position++] = s.replace(/^:/, ""); 34 | return "*"; 35 | } 36 | return s.replace(/[\^()\[\]]/, function(match) { return "\\" + match }); 37 | }); 38 | var re = new RegExp(parts.map(function(s) { return s == "*" ? "([^\/]+)" : s }).join("\\/")); 39 | var parser = function(url) { 40 | var result = re.exec(url); 41 | if (!result) return result; 42 | var params = {}; 43 | for (var place in positionMap) { 44 | var key = positionMap[place]; 45 | params[key] = result[place]; 46 | } 47 | params.url = url; 48 | return params; 49 | }; 50 | return { 51 | parse: parser, 52 | regex: re, 53 | url: makeURL(parts.join("/")), 54 | callback: handler 55 | }; 56 | }; 57 | 58 | chrome.contextMenus.onClicked.addListener(onClick); 59 | 60 | return { 61 | register: function(label, id, route, handler) { 62 | var compiled = createRoute(route, handler); 63 | id = id + ":" + appID; 64 | registry[id] = compiled; 65 | chrome.contextMenus.create({ 66 | title: label, 67 | targetUrlPatterns: [ compiled.url ], 68 | contexts: ["link"], 69 | id: id 70 | }, function() { 71 | if (chrome.runtime.lastError) { 72 | //It'll complain about re-registration, but there's no harm in it. 73 | //console.log(chrome.runtime.lastError); 74 | } 75 | }); 76 | }, 77 | makeURL: makeURL 78 | }; 79 | 80 | }); -------------------------------------------------------------------------------- /js/storage/readme.rst: -------------------------------------------------------------------------------- 1 | Module descriptions - storage/\* 2 | ================================ 3 | 4 | file.js 5 | ------- 6 | 7 | Wraps the chrome.fileSystem APIs in a friendly File constructor. File objects 8 | have the following methods or properties, most of which should be self 9 | explanatory. All methods return promises, and can be used with the ``await`` 10 | keyword. 11 | 12 | - ``open`` 13 | - ``read`` 14 | - ``write`` 15 | - ``stat`` 16 | - ``retain`` 17 | - ``restore`` 18 | - ``getPath`` 19 | - ``entry`` - contains the actual entry object. 20 | 21 | All storage in Caret, regardless of its actual backing structure, goes 22 | through objects adhering to the File interface, which makes it much 23 | easier to open many types of data through the same tab/editor UI. It 24 | also makes persistence much more consistent and less verbose throughout 25 | Caret. 26 | 27 | nullfile.js 28 | ----------- 29 | 30 | It's a file stub that does nothing when you try to interact with it--useful 31 | for read-only tabs, like search results or config defaults. 32 | 33 | settingsProvider.js 34 | ------------------- 35 | 36 | The actual singleton returned when modules load configs via the 37 | ``settings`` plugin. Provides the following API: 38 | 39 | - ``get`` Retrieves the current settings object by name, with all 40 | layers \`(project, local, and default) merged over top each other. 41 | - ``getAsString`` Retrieves the local settings as a string, mostly used 42 | when opening settings for editing. 43 | - ``getAsFile`` 44 | - ``load`` Requests a fresh copy of the local settings from sync 45 | storage, usually called after either writing to settings or when the 46 | dependent module does not have a settings cache. 47 | - ``setProject`` Sets the top-most JSON object to be merged when 48 | calling ``Settings.get()``, used for the project-specific settings 49 | overrides. 50 | - ``clearProject`` Removes the top-most JSON object, so that only local 51 | and default settings are merged. 52 | - ``pull`` Calls load/get for you on the list of arguments, and returns 53 | a promise that's fullfilled with a hash of the requested settings. 54 | 55 | syncfile.js 56 | ----------- 57 | 58 | A constructor matching the File interface, but backed by 59 | chrome.storage.sync. Used to open settings "files." 60 | 61 | syncFS.js 62 | --------- 63 | 64 | An abstraction over top of chrome.storage.sync, capable of storing data 65 | larger than the sync storage limit by splitting it into multiple entries 66 | behind the scenes. Returns promises for all methods. 67 | -------------------------------------------------------------------------------- /main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Caret 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
    13 | Caret 14 |
      15 |
      16 | - 17 | + 18 | ~ 19 |
      20 |
      21 | 22 |
      23 | 24 |
      25 |
      26 |
      27 | loading 28 |
      29 |
      30 |
      31 |
      32 | 33 |
      34 |
      35 |
      36 |
      37 | 38 |
      39 | 40 | 46 | 47 |
      48 |
      49 |
      50 | 51 | 52 |
      53 |
      54 | 55 |
      56 | 57 | × 58 |
      59 | 60 |
      61 |
      62 |

      63 | 64 |
      65 |
        66 |
        67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /js/sessions/addRemove.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "sessions/state", 3 | "sessions/switching", 4 | "tab", 5 | "editor", 6 | "ui/statusbar", 7 | "ui/dialog", 8 | "command", 9 | "util/i18n" 10 | ], function(state, switching, Tab, editor, status, dialog, command, i18n) { 11 | 12 | var noop = function() {}; 13 | 14 | var addTab = function(contents, file) { 15 | var current = editor.getSession(); 16 | var tab; 17 | //reuse tab if opening a file into an empty tab 18 | if (file && !current.file && !current.modified) { 19 | tab = current; 20 | tab.setValue(contents); 21 | tab.setFile(file); 22 | tab.modified = false; 23 | } else { 24 | tab = new Tab(contents, file); 25 | state.stack.unshift(tab); 26 | state.tabs.push(tab); 27 | } 28 | if (file && !file.virtual) { 29 | file.entry.file(function(f) { 30 | var loaded = i18n.get("fileLoaded", f.name, f.size); 31 | status.toast(loaded, 2); 32 | }); 33 | } 34 | switching.raise(tab); 35 | tab.detectSyntax(); 36 | return tab; 37 | }; 38 | 39 | //removeTab looks long, but it handles the async save/don't/cancel flow 40 | var removeTab = async function(index, c = noop) { 41 | if (!index) { 42 | index = state.tabs.indexOf(editor.getSession()); 43 | } 44 | var tab = state.tabs[index]; 45 | state.stack = state.stack.filter(t => t !== tab); 46 | 47 | if (tab.modified) { 48 | var confirm = await dialog( 49 | i18n.get("dialogModifiedUnsaved", tab.fileName), 50 | [ 51 | {label: i18n.get("dialogSave"), value: true, shortcut: "y" }, 52 | {label: i18n.get("dialogDiscard"), value: false, shortcut: "n" }, 53 | { label: i18n.get("dialogCancel"), shortcut: "c" } 54 | ] 55 | ); 56 | if (typeof confirm !== "boolean") { 57 | return; 58 | } 59 | if (confirm) { 60 | await tab.save(); 61 | } 62 | } 63 | tab.drop(); 64 | state.tabs = state.tabs.filter((tab, i) => !(i == index)); 65 | if (state.tabs.length == 0) { 66 | return addTab(); 67 | } 68 | var next = index - 1; 69 | if (next < 0) { 70 | next = 0; 71 | } 72 | var current = editor.getSession(); 73 | if (tab !== current) { 74 | command.fire("session:render"); 75 | } else { 76 | switching.raise(state.tabs[next]); 77 | } 78 | c(); 79 | }; 80 | 81 | command.on("session:close-tab", removeTab); 82 | 83 | return { 84 | add: addTab, 85 | remove: removeTab 86 | } 87 | 88 | }); -------------------------------------------------------------------------------- /js/ace/theme-gruvbox.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/gruvbox",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-gruvbox"; 5 | exports.cssText = ".ace-gruvbox .ace_gutter-active-line {\ 6 | background-color: #3C3836;\ 7 | }\ 8 | .ace-gruvbox {\ 9 | color: #EBDAB4;\ 10 | background-color: #1D2021;\ 11 | }\ 12 | .ace-gruvbox .ace_invisible {\ 13 | color: #504945;\ 14 | }\ 15 | .ace-gruvbox .ace_marker-layer .ace_selection {\ 16 | background: rgba(179, 101, 57, 0.75)\ 17 | }\ 18 | .ace-gruvbox.ace_multiselect .ace_selection.ace_start {\ 19 | box-shadow: 0 0 3px 0px #002240;\ 20 | }\ 21 | .ace-gruvbox .ace_keyword {\ 22 | color: #8ec07c;\ 23 | }\ 24 | .ace-gruvbox .ace_comment {\ 25 | font-style: italic;\ 26 | color: #928375;\ 27 | }\ 28 | .ace-gruvbox .ace-statement {\ 29 | color: red;\ 30 | }\ 31 | .ace-gruvbox .ace_variable {\ 32 | color: #84A598;\ 33 | }\ 34 | .ace-gruvbox .ace_variable.ace_language {\ 35 | color: #D2879B;\ 36 | }\ 37 | .ace-gruvbox .ace_constant {\ 38 | color: #C2859A;\ 39 | }\ 40 | .ace-gruvbox .ace_constant.ace_language {\ 41 | color: #C2859A;\ 42 | }\ 43 | .ace-gruvbox .ace_constant.ace_numeric {\ 44 | color: #C2859A;\ 45 | }\ 46 | .ace-gruvbox .ace_string {\ 47 | color: #B8BA37;\ 48 | }\ 49 | .ace-gruvbox .ace_support {\ 50 | color: #F9BC41;\ 51 | }\ 52 | .ace-gruvbox .ace_support.ace_function {\ 53 | color: #F84B3C;\ 54 | }\ 55 | .ace-gruvbox .ace_storage {\ 56 | color: #8FBF7F;\ 57 | }\ 58 | .ace-gruvbox .ace_keyword.ace_operator {\ 59 | color: #EBDAB4;\ 60 | }\ 61 | .ace-gruvbox .ace_punctuation.ace_operator {\ 62 | color: yellow;\ 63 | }\ 64 | .ace-gruvbox .ace_marker-layer .ace_active-line {\ 65 | background: #3C3836;\ 66 | }\ 67 | .ace-gruvbox .ace_marker-layer .ace_selected-word {\ 68 | border-radius: 4px;\ 69 | border: 8px solid #3f475d;\ 70 | }\ 71 | .ace-gruvbox .ace_print-margin {\ 72 | width: 5px;\ 73 | background: #3C3836;\ 74 | }\ 75 | .ace-gruvbox .ace_indent-guide {\ 76 | background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQUFD4z6Crq/sfAAuYAuYl+7lfAAAAAElFTkSuQmCC\") right repeat-y;\ 77 | }"; 78 | 79 | var dom = require("../lib/dom"); 80 | dom.importCssString(exports.cssText, exports.cssClass); 81 | 82 | }); (function() { 83 | ace.require(["ace/theme/gruvbox"], function(m) { 84 | if (typeof module == "object" && typeof exports == "object" && module) { 85 | module.exports = m; 86 | } 87 | }); 88 | })(); 89 | -------------------------------------------------------------------------------- /js/sessions/switching.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "sessions/state", 3 | "editor", 4 | "command" 5 | ], function(state, editor, command) { 6 | 7 | /* 8 | Various functions for swapping between tags, either from clicks or keyboard. 9 | */ 10 | 11 | var stackOffset = 0; 12 | 13 | var raiseTab = function(tab) { 14 | editor.setSession(tab); 15 | editor.setReadOnly(tab.readOnly); 16 | command.fire("session:syntax"); 17 | command.fire("session:render"); 18 | editor.focus(); 19 | command.fire("session:check-file"); 20 | }; 21 | 22 | var raiseBlurred = function(tab) { 23 | editor.setSession(tab); 24 | command.fire("session:syntax", tab.syntaxMode || "plain_text"); 25 | command.fire("session:render"); 26 | command.fire("session:check-file"); 27 | }; 28 | 29 | var resetStack = function(tab) { 30 | var raised = tab || state.stack[stackOffset]; 31 | state.stack = state.stack.filter(t => t != raised); 32 | state.stack.unshift(raised); 33 | } 34 | 35 | var watchCtrl = function(e) { 36 | if (e.keyCode == 17) { 37 | resetStack(); 38 | document.body.removeEventListener("keyup", watchCtrl); 39 | ctrl = false; 40 | } 41 | }; 42 | 43 | var ctrl = false; 44 | 45 | // most-recent order 46 | var switchTab = function(arg, c = function() {}) { 47 | arg = arg || 1; 48 | if (!ctrl) { 49 | ctrl = true; 50 | stackOffset = 0; 51 | document.body.addEventListener("keyup", watchCtrl); 52 | } 53 | stackOffset = (stackOffset + arg) % state.stack.length; 54 | if (stackOffset < 0) stackOffset = state.stack.length + stackOffset; 55 | raiseTab(state.stack[stackOffset]); 56 | c(); 57 | }; 58 | 59 | //left-to-right order 60 | var switchTabLinear = function(shift, c = function() {}) { 61 | shift = shift || 1; 62 | var current = editor.getSession(); 63 | var currentIndex = state.tabs.indexOf(current); 64 | var shifted = (currentIndex + shift) % state.tabs.length; 65 | if (shifted < 0) { 66 | shifted = state.tabs.length + shifted; 67 | } 68 | var tab = state.tabs[shifted]; 69 | raiseTab(tab); 70 | resetStack(tab); 71 | c(); 72 | }; 73 | 74 | command.on("session:raise-tab", function(index) { 75 | var tab = state.tabs[index]; 76 | raiseTab(tab); 77 | resetStack(tab); 78 | }); 79 | command.on("session:change-tab", switchTab); 80 | command.on("session:change-tab-linear", switchTabLinear); 81 | 82 | return { 83 | raise: raiseTab, 84 | raiseBlurred: raiseBlurred, 85 | switchTab: switchTab, 86 | switchLinear: switchTabLinear 87 | }; 88 | 89 | }); -------------------------------------------------------------------------------- /js/ace/mode-properties.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/properties_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { 2 | "use strict"; 3 | 4 | var oop = require("../lib/oop"); 5 | var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; 6 | 7 | var PropertiesHighlightRules = function() { 8 | 9 | var escapeRe = /\\u[0-9a-fA-F]{4}|\\/; 10 | 11 | this.$rules = { 12 | "start" : [ 13 | { 14 | token : "comment", 15 | regex : /[!#].*$/ 16 | }, { 17 | token : "keyword", 18 | regex : /[=:]$/ 19 | }, { 20 | token : "keyword", 21 | regex : /[=:]/, 22 | next : "value" 23 | }, { 24 | token : "constant.language.escape", 25 | regex : escapeRe 26 | }, { 27 | defaultToken: "variable" 28 | } 29 | ], 30 | "value" : [ 31 | { 32 | regex : /\\$/, 33 | token : "string", 34 | next : "value" 35 | }, { 36 | regex : /$/, 37 | token : "string", 38 | next : "start" 39 | }, { 40 | token : "constant.language.escape", 41 | regex : escapeRe 42 | }, { 43 | defaultToken: "string" 44 | } 45 | ] 46 | }; 47 | 48 | }; 49 | 50 | oop.inherits(PropertiesHighlightRules, TextHighlightRules); 51 | 52 | exports.PropertiesHighlightRules = PropertiesHighlightRules; 53 | }); 54 | 55 | ace.define("ace/mode/properties",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/properties_highlight_rules"], function(require, exports, module) { 56 | "use strict"; 57 | 58 | var oop = require("../lib/oop"); 59 | var TextMode = require("./text").Mode; 60 | var PropertiesHighlightRules = require("./properties_highlight_rules").PropertiesHighlightRules; 61 | 62 | var Mode = function() { 63 | this.HighlightRules = PropertiesHighlightRules; 64 | this.$behaviour = this.$defaultBehaviour; 65 | }; 66 | oop.inherits(Mode, TextMode); 67 | 68 | (function() { 69 | this.$id = "ace/mode/properties"; 70 | }).call(Mode.prototype); 71 | 72 | exports.Mode = Mode; 73 | }); (function() { 74 | ace.require(["ace/mode/properties"], function(m) { 75 | if (typeof module == "object" && typeof exports == "object" && module) { 76 | module.exports = m; 77 | } 78 | }); 79 | })(); 80 | -------------------------------------------------------------------------------- /js/ace/theme-kuroir.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/kuroir",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = false; 4 | exports.cssClass = "ace-kuroir"; 5 | exports.cssText = "\ 6 | .ace-kuroir .ace_gutter {\ 7 | background: #e8e8e8;\ 8 | color: #333;\ 9 | }\ 10 | .ace-kuroir .ace_print-margin {\ 11 | width: 1px;\ 12 | background: #e8e8e8;\ 13 | }\ 14 | .ace-kuroir {\ 15 | background-color: #E8E9E8;\ 16 | color: #363636;\ 17 | }\ 18 | .ace-kuroir .ace_cursor {\ 19 | color: #202020;\ 20 | }\ 21 | .ace-kuroir .ace_marker-layer .ace_selection {\ 22 | background: rgba(245, 170, 0, 0.57);\ 23 | }\ 24 | .ace-kuroir.ace_multiselect .ace_selection.ace_start {\ 25 | box-shadow: 0 0 3px 0px #E8E9E8;\ 26 | }\ 27 | .ace-kuroir .ace_marker-layer .ace_step {\ 28 | background: rgb(198, 219, 174);\ 29 | }\ 30 | .ace-kuroir .ace_marker-layer .ace_bracket {\ 31 | margin: -1px 0 0 -1px;\ 32 | border: 1px solid rgba(0, 0, 0, 0.29);\ 33 | }\ 34 | .ace-kuroir .ace_marker-layer .ace_active-line {\ 35 | background: rgba(203, 220, 47, 0.22);\ 36 | }\ 37 | .ace-kuroir .ace_gutter-active-line {\ 38 | background-color: rgba(203, 220, 47, 0.22);\ 39 | }\ 40 | .ace-kuroir .ace_marker-layer .ace_selected-word {\ 41 | border: 1px solid rgba(245, 170, 0, 0.57);\ 42 | }\ 43 | .ace-kuroir .ace_invisible {\ 44 | color: #BFBFBF\ 45 | }\ 46 | .ace-kuroir .ace_fold {\ 47 | border-color: #363636;\ 48 | }\ 49 | .ace-kuroir .ace_constant{color:#CD6839;}.ace-kuroir .ace_constant.ace_numeric{color:#9A5925;}.ace-kuroir .ace_support{color:#104E8B;}.ace-kuroir .ace_support.ace_function{color:#005273;}.ace-kuroir .ace_support.ace_constant{color:#CF6A4C;}.ace-kuroir .ace_storage{color:#A52A2A;}.ace-kuroir .ace_invalid.ace_illegal{color:#FD1224;\ 50 | background-color:rgba(255, 6, 0, 0.15);}.ace-kuroir .ace_invalid.ace_deprecated{text-decoration:underline;\ 51 | font-style:italic;\ 52 | color:#FD1732;\ 53 | background-color:#E8E9E8;}.ace-kuroir .ace_string{color:#639300;}.ace-kuroir .ace_string.ace_regexp{color:#417E00;\ 54 | background-color:#C9D4BE;}.ace-kuroir .ace_comment{color:rgba(148, 148, 148, 0.91);\ 55 | background-color:rgba(220, 220, 220, 0.56);}.ace-kuroir .ace_variable{color:#009ACD;}.ace-kuroir .ace_meta.ace_tag{color:#005273;}.ace-kuroir .ace_markup.ace_heading{color:#B8012D;\ 56 | background-color:rgba(191, 97, 51, 0.051);}.ace-kuroir .ace_markup.ace_list{color:#8F5B26;}\ 57 | "; 58 | 59 | var dom = require("../lib/dom"); 60 | dom.importCssString(exports.cssText, exports.cssClass); 61 | }); (function() { 62 | ace.require(["ace/theme/kuroir"], function(m) { 63 | if (typeof module == "object" && typeof exports == "object" && module) { 64 | module.exports = m; 65 | } 66 | }); 67 | })(); 68 | -------------------------------------------------------------------------------- /js/readme.rst: -------------------------------------------------------------------------------- 1 | Module descriptions - core 2 | ========================== 3 | 4 | This document serves as basic documentation for Caret's AMD modules. 5 | It's not exhaustive, but it will serve as a starting place for anyone 6 | wanting to dive in a little deeper. 7 | 8 | Caret's execution starts in main.js, which mostly serves as bootstrap 9 | for the other modules. It also registers command listeners for the UI 10 | themes, various window events, and app-level commands like 11 | ``app:check-for-updates``. After that, we really get down to business. 12 | 13 | In addition to the module folders, which contain their own readme files, 14 | there are also folders for the current Ace build (ace) and any external 15 | libraries used by Caret, such as the ES6 Promises shim (lib). 16 | 17 | aceBindings.js 18 | -------------- 19 | 20 | Takes care of any messiness between Caret and Ace APIs. Registers the 21 | ``ace:command`` listener, as well as a bunch of Sublime emulation 22 | commands. Exposes no external methods or data. 23 | 24 | api.js 25 | ------ 26 | 27 | Registers for chrome.runtime.onMessageExternal events, patching them 28 | into the command module, and dispatches messages from ``api:execute`` 29 | commands. Exposes no external methods or data. 30 | 31 | command.js 32 | ---------- 33 | 34 | Serves as a messaging buffer between modules, and from declarative DOM 35 | attributes to modules. Exposes three properties: ``fire()`` for sending 36 | commands, ``on()`` for subscribing to them, and an array called ``list`` 37 | that can be used to add palette-only items at runtime. 38 | 39 | editor.js 40 | --------- 41 | 42 | Sets up the Ace editor and registers for events in the ``editor:*`` 43 | namespace. Returns the Ace object. 44 | 45 | fileManager.js 46 | -------------- 47 | 48 | Handles opening files from launch data, retained handles, and user 49 | commands. Exposes no external methods or data. 50 | 51 | main.js 52 | ------- 53 | 54 | All execution starts here. This module is in charge of program initialization, 55 | lifecycle, and random ``app:*`` commands. 56 | 57 | sessions.js 58 | ----------- 59 | 60 | Manages Caret's tabs, including all UI interaction with the tab bar and 61 | the process of adding or removing tabs. Exposes a number of methods and 62 | manipulating the tab structure. Most of the actual session code is 63 | loaded from the ``/sessions`` folder, to make the file more manageable. 64 | 65 | settings.js 66 | ----------- 67 | 68 | Runs as a RequireJS plugin, so that dependent modules can rely on having 69 | settings available on startup, but actually just returns the same 70 | singleton as ``storage/settingsProvider``. 71 | 72 | tab.js 73 | ------ 74 | 75 | Exposes a Tab constructor to dependents, which is an augmented Ace 76 | EditorSession. Tabs do additional setup work to support Caret, as well 77 | as adding methods for saving files and dropping retained file handles. 78 | -------------------------------------------------------------------------------- /js/ace/theme-xcode.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/xcode",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = false; 4 | exports.cssClass = "ace-xcode"; 5 | exports.cssText = "\ 6 | .ace-xcode .ace_gutter {\ 7 | background: #e8e8e8;\ 8 | color: #333\ 9 | }\ 10 | .ace-xcode .ace_print-margin {\ 11 | width: 1px;\ 12 | background: #e8e8e8\ 13 | }\ 14 | .ace-xcode {\ 15 | background-color: #FFFFFF;\ 16 | color: #000000\ 17 | }\ 18 | .ace-xcode .ace_cursor {\ 19 | color: #000000\ 20 | }\ 21 | .ace-xcode .ace_marker-layer .ace_selection {\ 22 | background: #B5D5FF\ 23 | }\ 24 | .ace-xcode.ace_multiselect .ace_selection.ace_start {\ 25 | box-shadow: 0 0 3px 0px #FFFFFF;\ 26 | }\ 27 | .ace-xcode .ace_marker-layer .ace_step {\ 28 | background: rgb(198, 219, 174)\ 29 | }\ 30 | .ace-xcode .ace_marker-layer .ace_bracket {\ 31 | margin: -1px 0 0 -1px;\ 32 | border: 1px solid #BFBFBF\ 33 | }\ 34 | .ace-xcode .ace_marker-layer .ace_active-line {\ 35 | background: rgba(0, 0, 0, 0.071)\ 36 | }\ 37 | .ace-xcode .ace_gutter-active-line {\ 38 | background-color: rgba(0, 0, 0, 0.071)\ 39 | }\ 40 | .ace-xcode .ace_marker-layer .ace_selected-word {\ 41 | border: 1px solid #B5D5FF\ 42 | }\ 43 | .ace-xcode .ace_constant.ace_language,\ 44 | .ace-xcode .ace_keyword,\ 45 | .ace-xcode .ace_meta,\ 46 | .ace-xcode .ace_variable.ace_language {\ 47 | color: #C800A4\ 48 | }\ 49 | .ace-xcode .ace_invisible {\ 50 | color: #BFBFBF\ 51 | }\ 52 | .ace-xcode .ace_constant.ace_character,\ 53 | .ace-xcode .ace_constant.ace_other {\ 54 | color: #275A5E\ 55 | }\ 56 | .ace-xcode .ace_constant.ace_numeric {\ 57 | color: #3A00DC\ 58 | }\ 59 | .ace-xcode .ace_entity.ace_other.ace_attribute-name,\ 60 | .ace-xcode .ace_support.ace_constant,\ 61 | .ace-xcode .ace_support.ace_function {\ 62 | color: #450084\ 63 | }\ 64 | .ace-xcode .ace_fold {\ 65 | background-color: #C800A4;\ 66 | border-color: #000000\ 67 | }\ 68 | .ace-xcode .ace_entity.ace_name.ace_tag,\ 69 | .ace-xcode .ace_support.ace_class,\ 70 | .ace-xcode .ace_support.ace_type {\ 71 | color: #790EAD\ 72 | }\ 73 | .ace-xcode .ace_storage {\ 74 | color: #C900A4\ 75 | }\ 76 | .ace-xcode .ace_string {\ 77 | color: #DF0002\ 78 | }\ 79 | .ace-xcode .ace_comment {\ 80 | color: #008E00\ 81 | }\ 82 | .ace-xcode .ace_indent-guide {\ 83 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==) right repeat-y\ 84 | }"; 85 | 86 | var dom = require("../lib/dom"); 87 | dom.importCssString(exports.cssText, exports.cssClass); 88 | }); (function() { 89 | ace.require(["ace/theme/xcode"], function(m) { 90 | if (typeof module == "object" && typeof exports == "object" && module) { 91 | module.exports = m; 92 | } 93 | }); 94 | })(); 95 | -------------------------------------------------------------------------------- /js/ace/ext-spellcheck.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/ext/spellcheck",["require","exports","module","ace/lib/event","ace/editor","ace/config"], function(require, exports, module) { 2 | "use strict"; 3 | var event = require("../lib/event"); 4 | 5 | exports.contextMenuHandler = function(e){ 6 | var host = e.target; 7 | var text = host.textInput.getElement(); 8 | if (!host.selection.isEmpty()) 9 | return; 10 | var c = host.getCursorPosition(); 11 | var r = host.session.getWordRange(c.row, c.column); 12 | var w = host.session.getTextRange(r); 13 | 14 | host.session.tokenRe.lastIndex = 0; 15 | if (!host.session.tokenRe.test(w)) 16 | return; 17 | var PLACEHOLDER = "\x01\x01"; 18 | var value = w + " " + PLACEHOLDER; 19 | text.value = value; 20 | text.setSelectionRange(w.length, w.length + 1); 21 | text.setSelectionRange(0, 0); 22 | text.setSelectionRange(0, w.length); 23 | 24 | var afterKeydown = false; 25 | event.addListener(text, "keydown", function onKeydown() { 26 | event.removeListener(text, "keydown", onKeydown); 27 | afterKeydown = true; 28 | }); 29 | 30 | host.textInput.setInputHandler(function(newVal) { 31 | console.log(newVal , value, text.selectionStart, text.selectionEnd); 32 | if (newVal == value) 33 | return ''; 34 | if (newVal.lastIndexOf(value, 0) === 0) 35 | return newVal.slice(value.length); 36 | if (newVal.substr(text.selectionEnd) == value) 37 | return newVal.slice(0, -value.length); 38 | if (newVal.slice(-2) == PLACEHOLDER) { 39 | var val = newVal.slice(0, -2); 40 | if (val.slice(-1) == " ") { 41 | if (afterKeydown) 42 | return val.substring(0, text.selectionEnd); 43 | val = val.slice(0, -1); 44 | host.session.replace(r, val); 45 | return ""; 46 | } 47 | } 48 | 49 | return newVal; 50 | }); 51 | }; 52 | var Editor = require("../editor").Editor; 53 | require("../config").defineOptions(Editor.prototype, "editor", { 54 | spellcheck: { 55 | set: function(val) { 56 | var text = this.textInput.getElement(); 57 | text.spellcheck = !!val; 58 | if (!val) 59 | this.removeListener("nativecontextmenu", exports.contextMenuHandler); 60 | else 61 | this.on("nativecontextmenu", exports.contextMenuHandler); 62 | }, 63 | value: true 64 | } 65 | }); 66 | 67 | }); (function() { 68 | ace.require(["ace/ext/spellcheck"], function(m) { 69 | if (typeof module == "object" && typeof exports == "object" && module) { 70 | module.exports = m; 71 | } 72 | }); 73 | })(); 74 | -------------------------------------------------------------------------------- /css/tabs.less: -------------------------------------------------------------------------------- 1 | .tabs { 2 | background: @faded; 3 | padding: 2px 2px 0 0; 4 | display: flex; 5 | justify-content: flex-start; 6 | //box-shadow: inset 4px 4px 16px rgba(0, 0, 0, .3); 7 | 8 | .tab { 9 | display: flex; 10 | justify-content: space-between; 11 | align-items: center; 12 | max-width: 200px; 13 | min-width: 0px; 14 | // margin-right: 3px; 15 | opacity: .5; 16 | background: @background; 17 | border-bottom: 4px solid darken(@background, 10%); 18 | color: @foreground; 19 | padding: 0 12px; 20 | flex: 1 1 0px; 21 | position: relative; 22 | 23 | a { 24 | text-decoration: none; 25 | color: @foreground; 26 | padding: 6px 0; 27 | width: 100%; 28 | flex: 1; 29 | 30 | &:focus { 31 | outline: none; 32 | border: none; 33 | } 34 | } 35 | 36 | transition: max-width .5s linear, -webkit-transform .2s ease, border-width .2s ease, opacity .2s ease; 37 | transition: max-width .5s linear, transform .2s ease, border-width .2s ease, opacity .2s ease; 38 | 39 | &.active { 40 | padding-bottom: 0px; 41 | border-bottom: 4px solid @accent; 42 | color: @foreground; 43 | opacity: 1; 44 | z-index: 9; 45 | font-weight: bold; 46 | 47 | .close { 48 | color: @accent; 49 | } 50 | } 51 | 52 | &:hover:not(.active) { 53 | opacity: .8; 54 | } 55 | 56 | &.dragging { 57 | width: 0; 58 | padding: 0; 59 | flex-grow: 0; 60 | } 61 | 62 | &.hovering { 63 | border-left-color: @faded; 64 | border-left-width: 25px; 65 | border-left-style: solid; 66 | } 67 | 68 | &.enter { 69 | //max-width: 0px; 70 | -webkit-transform: translateY(24px); 71 | transform: translateY(24px); 72 | } 73 | 74 | .label { 75 | cursor: default; 76 | white-space: nowrap; 77 | text-overflow: ellipsis; 78 | overflow: hidden; 79 | } 80 | 81 | .close { 82 | font-size: 19px; 83 | text-align: center; 84 | width: 18px; 85 | cursor: pointer; 86 | flex: 0 0 18px; 87 | align-self: center; 88 | font-family: monospace; 89 | 90 | &:hover { 91 | color: @foreground; 92 | } 93 | } 94 | 95 | &.newtab { 96 | opacity: .25; 97 | min-width: 30px; 98 | max-width: 30px; 99 | margin: 2px 0 4px 0; 100 | border-radius: 2px; 101 | display: flex; 102 | align-items: center; 103 | justify-content: center; 104 | align-content: center; 105 | 106 | .big-label { 107 | font-size: 24px; 108 | color: lighten(@foreground, 60%); 109 | font-weight: bold; 110 | text-align: center; 111 | } 112 | } 113 | } 114 | } -------------------------------------------------------------------------------- /js/ace/ext-themelist.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/ext/themelist",["require","exports","module"], function(require, exports, module) { 2 | "use strict"; 3 | 4 | var themeData = [ 5 | ["Chrome" ], 6 | ["Clouds" ], 7 | ["Crimson Editor" ], 8 | ["Dawn" ], 9 | ["Dreamweaver" ], 10 | ["Eclipse" ], 11 | ["GitHub" ], 12 | ["IPlastic" ], 13 | ["Solarized Light"], 14 | ["TextMate" ], 15 | ["Tomorrow" ], 16 | ["XCode" ], 17 | ["Kuroir"], 18 | ["KatzenMilch"], 19 | ["SQL Server" ,"sqlserver" , "light"], 20 | ["Ambiance" ,"ambiance" , "dark"], 21 | ["Chaos" ,"chaos" , "dark"], 22 | ["Clouds Midnight" ,"clouds_midnight" , "dark"], 23 | ["Dracula" ,"" , "dark"], 24 | ["Cobalt" ,"cobalt" , "dark"], 25 | ["Gruvbox" ,"gruvbox" , "dark"], 26 | ["Green on Black" ,"gob" , "dark"], 27 | ["idle Fingers" ,"idle_fingers" , "dark"], 28 | ["krTheme" ,"kr_theme" , "dark"], 29 | ["Merbivore" ,"merbivore" , "dark"], 30 | ["Merbivore Soft" ,"merbivore_soft" , "dark"], 31 | ["Mono Industrial" ,"mono_industrial" , "dark"], 32 | ["Monokai" ,"monokai" , "dark"], 33 | ["Pastel on dark" ,"pastel_on_dark" , "dark"], 34 | ["Solarized Dark" ,"solarized_dark" , "dark"], 35 | ["Terminal" ,"terminal" , "dark"], 36 | ["Tomorrow Night" ,"tomorrow_night" , "dark"], 37 | ["Tomorrow Night Blue" ,"tomorrow_night_blue" , "dark"], 38 | ["Tomorrow Night Bright","tomorrow_night_bright" , "dark"], 39 | ["Tomorrow Night 80s" ,"tomorrow_night_eighties" , "dark"], 40 | ["Twilight" ,"twilight" , "dark"], 41 | ["Vibrant Ink" ,"vibrant_ink" , "dark"] 42 | ]; 43 | 44 | 45 | exports.themesByName = {}; 46 | exports.themes = themeData.map(function(data) { 47 | var name = data[1] || data[0].replace(/ /g, "_").toLowerCase(); 48 | var theme = { 49 | caption: data[0], 50 | theme: "ace/theme/" + name, 51 | isDark: data[2] == "dark", 52 | name: name 53 | }; 54 | exports.themesByName[name] = theme; 55 | return theme; 56 | }); 57 | 58 | }); (function() { 59 | ace.require(["ace/ext/themelist"], function(m) { 60 | if (typeof module == "object" && typeof exports == "object" && module) { 61 | module.exports = m; 62 | } 63 | }); 64 | })(); 65 | -------------------------------------------------------------------------------- /js/ace/theme-kr.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/kr_theme",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-kr-theme"; 5 | exports.cssText = ".ace-kr-theme .ace_gutter {\ 6 | background: #1c1917;\ 7 | color: #FCFFE0\ 8 | }\ 9 | .ace-kr-theme .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #1c1917\ 12 | }\ 13 | .ace-kr-theme {\ 14 | background-color: #0B0A09;\ 15 | color: #FCFFE0\ 16 | }\ 17 | .ace-kr-theme .ace_cursor {\ 18 | color: #FF9900\ 19 | }\ 20 | .ace-kr-theme .ace_marker-layer .ace_selection {\ 21 | background: rgba(170, 0, 255, 0.45)\ 22 | }\ 23 | .ace-kr-theme.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #0B0A09;\ 25 | border-radius: 2px\ 26 | }\ 27 | .ace-kr-theme .ace_marker-layer .ace_step {\ 28 | background: rgb(102, 82, 0)\ 29 | }\ 30 | .ace-kr-theme .ace_marker-layer .ace_bracket {\ 31 | margin: -1px 0 0 -1px;\ 32 | border: 1px solid rgba(255, 177, 111, 0.32)\ 33 | }\ 34 | .ace-kr-theme .ace_marker-layer .ace_active-line {\ 35 | background: #38403D\ 36 | }\ 37 | .ace-kr-theme .ace_gutter-active-line {\ 38 | background-color : #38403D\ 39 | }\ 40 | .ace-kr-theme .ace_marker-layer .ace_selected-word {\ 41 | border: 1px solid rgba(170, 0, 255, 0.45)\ 42 | }\ 43 | .ace-kr-theme .ace_invisible {\ 44 | color: rgba(255, 177, 111, 0.32)\ 45 | }\ 46 | .ace-kr-theme .ace_keyword,\ 47 | .ace-kr-theme .ace_meta {\ 48 | color: #949C8B\ 49 | }\ 50 | .ace-kr-theme .ace_constant,\ 51 | .ace-kr-theme .ace_constant.ace_character,\ 52 | .ace-kr-theme .ace_constant.ace_character.ace_escape,\ 53 | .ace-kr-theme .ace_constant.ace_other {\ 54 | color: rgba(210, 117, 24, 0.76)\ 55 | }\ 56 | .ace-kr-theme .ace_invalid {\ 57 | color: #F8F8F8;\ 58 | background-color: #A41300\ 59 | }\ 60 | .ace-kr-theme .ace_support {\ 61 | color: #9FC28A\ 62 | }\ 63 | .ace-kr-theme .ace_support.ace_constant {\ 64 | color: #C27E66\ 65 | }\ 66 | .ace-kr-theme .ace_fold {\ 67 | background-color: #949C8B;\ 68 | border-color: #FCFFE0\ 69 | }\ 70 | .ace-kr-theme .ace_support.ace_function {\ 71 | color: #85873A\ 72 | }\ 73 | .ace-kr-theme .ace_storage {\ 74 | color: #FFEE80\ 75 | }\ 76 | .ace-kr-theme .ace_string {\ 77 | color: rgba(164, 161, 181, 0.8)\ 78 | }\ 79 | .ace-kr-theme .ace_string.ace_regexp {\ 80 | color: rgba(125, 255, 192, 0.65)\ 81 | }\ 82 | .ace-kr-theme .ace_comment {\ 83 | font-style: italic;\ 84 | color: #706D5B\ 85 | }\ 86 | .ace-kr-theme .ace_variable {\ 87 | color: #D1A796\ 88 | }\ 89 | .ace-kr-theme .ace_list,\ 90 | .ace-kr-theme .ace_markup.ace_list {\ 91 | background-color: #0F0040\ 92 | }\ 93 | .ace-kr-theme .ace_variable.ace_language {\ 94 | color: #FF80E1\ 95 | }\ 96 | .ace-kr-theme .ace_meta.ace_tag {\ 97 | color: #BABD9C\ 98 | }\ 99 | .ace-kr-theme .ace_indent-guide {\ 100 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYFBXV/8PAAJoAXX4kT2EAAAAAElFTkSuQmCC) right repeat-y\ 101 | }"; 102 | 103 | var dom = require("../lib/dom"); 104 | dom.importCssString(exports.cssText, exports.cssClass); 105 | }); 106 | -------------------------------------------------------------------------------- /js/ace/theme-clouds.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/clouds",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = false; 4 | exports.cssClass = "ace-clouds"; 5 | exports.cssText = ".ace-clouds .ace_gutter {\ 6 | background: #ebebeb;\ 7 | color: #333\ 8 | }\ 9 | .ace-clouds .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #e8e8e8\ 12 | }\ 13 | .ace-clouds {\ 14 | background-color: #FFFFFF;\ 15 | color: #000000\ 16 | }\ 17 | .ace-clouds .ace_cursor {\ 18 | color: #000000\ 19 | }\ 20 | .ace-clouds .ace_marker-layer .ace_selection {\ 21 | background: #BDD5FC\ 22 | }\ 23 | .ace-clouds.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #FFFFFF;\ 25 | }\ 26 | .ace-clouds .ace_marker-layer .ace_step {\ 27 | background: rgb(255, 255, 0)\ 28 | }\ 29 | .ace-clouds .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid #BFBFBF\ 32 | }\ 33 | .ace-clouds .ace_marker-layer .ace_active-line {\ 34 | background: #FFFBD1\ 35 | }\ 36 | .ace-clouds .ace_gutter-active-line {\ 37 | background-color : #dcdcdc\ 38 | }\ 39 | .ace-clouds .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid #BDD5FC\ 41 | }\ 42 | .ace-clouds .ace_invisible {\ 43 | color: #BFBFBF\ 44 | }\ 45 | .ace-clouds .ace_keyword,\ 46 | .ace-clouds .ace_meta,\ 47 | .ace-clouds .ace_support.ace_constant.ace_property-value {\ 48 | color: #AF956F\ 49 | }\ 50 | .ace-clouds .ace_keyword.ace_operator {\ 51 | color: #484848\ 52 | }\ 53 | .ace-clouds .ace_keyword.ace_other.ace_unit {\ 54 | color: #96DC5F\ 55 | }\ 56 | .ace-clouds .ace_constant.ace_language {\ 57 | color: #39946A\ 58 | }\ 59 | .ace-clouds .ace_constant.ace_numeric {\ 60 | color: #46A609\ 61 | }\ 62 | .ace-clouds .ace_constant.ace_character.ace_entity {\ 63 | color: #BF78CC\ 64 | }\ 65 | .ace-clouds .ace_invalid {\ 66 | background-color: #FF002A\ 67 | }\ 68 | .ace-clouds .ace_fold {\ 69 | background-color: #AF956F;\ 70 | border-color: #000000\ 71 | }\ 72 | .ace-clouds .ace_storage,\ 73 | .ace-clouds .ace_support.ace_class,\ 74 | .ace-clouds .ace_support.ace_function,\ 75 | .ace-clouds .ace_support.ace_other,\ 76 | .ace-clouds .ace_support.ace_type {\ 77 | color: #C52727\ 78 | }\ 79 | .ace-clouds .ace_string {\ 80 | color: #5D90CD\ 81 | }\ 82 | .ace-clouds .ace_comment {\ 83 | color: #BCC8BA\ 84 | }\ 85 | .ace-clouds .ace_entity.ace_name.ace_tag,\ 86 | .ace-clouds .ace_entity.ace_other.ace_attribute-name {\ 87 | color: #606060\ 88 | }\ 89 | .ace-clouds .ace_indent-guide {\ 90 | background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y\ 91 | }"; 92 | 93 | var dom = require("../lib/dom"); 94 | dom.importCssString(exports.cssText, exports.cssClass); 95 | }); (function() { 96 | ace.require(["ace/theme/clouds"], function(m) { 97 | if (typeof module == "object" && typeof exports == "object" && module) { 98 | module.exports = m; 99 | } 100 | }); 101 | })(); 102 | -------------------------------------------------------------------------------- /css/ui.less: -------------------------------------------------------------------------------- 1 | //window frame 2 | .titlebar { 3 | -webkit-app-region: drag; 4 | -webkit-transform: translateZ(0); 5 | transform: translateZ(0); 6 | z-index: 999; 7 | display: flex; 8 | align-items: center; 9 | justify-content: flex-start; 10 | padding: 4px 16px; 11 | background: linear-gradient(to left, @background, mix(@background, #888, 90%)); 12 | 13 | .toolbar, .window-controls { 14 | -webkit-app-region: no-drag; 15 | } 16 | 17 | .app-name { 18 | margin-right: 10px; 19 | padding-right: 10px; 20 | border-right: 1px solid @foreground; 21 | } 22 | 23 | .window-controls { 24 | position: absolute; 25 | top: 0; 26 | right: 0; 27 | bottom: 0; 28 | display: flex; 29 | align-content: stretch; 30 | align-items: baseline; 31 | padding: 0 4px; 32 | 33 | a { 34 | width: 40px; 35 | display: block; 36 | margin-left: 1px; 37 | font-family: monospace; 38 | font-size: 18px; 39 | font-weight: bold; 40 | text-align: center; 41 | background: mix(@background, #888, 65%); 42 | color: mix(@foreground, #888, 50%); 43 | transition: opacity .3s ease; 44 | opacity: .8; 45 | color: @foreground; 46 | 47 | &:hover { 48 | opacity: 1; 49 | color: @foreground; 50 | } 51 | 52 | &.close { 53 | background: @accent; 54 | color: white; 55 | } 56 | } 57 | } 58 | } 59 | 60 | //status bar 61 | .bottom-bar { 62 | margin: 0; 63 | padding: 2px 5px; 64 | font-size: 14px; 65 | 66 | .status-text { 67 | display: flex; 68 | flex-flow: column; 69 | justify-content: center; 70 | } 71 | 72 | select { 73 | font-size: inherit; 74 | margin: 0; 75 | border: none; 76 | width: 150px; 77 | background: @background; 78 | color: @foreground; 79 | -webkit-appearance: none; 80 | } 81 | } 82 | 83 | //command line 84 | .command-line { 85 | display: none; 86 | height: 30px; 87 | padding: 4px; 88 | 89 | &.show { 90 | display: flex; 91 | align-content: stretch; 92 | align-items: center; 93 | } 94 | 95 | input { 96 | width: 100%; 97 | padding: 4px; 98 | font-family: monospace; 99 | border: none; 100 | } 101 | 102 | .close { 103 | font-weight: bold; 104 | font-size: 15px; 105 | padding: 0 8px; 106 | } 107 | 108 | } 109 | 110 | //app-wide scrollbar 111 | ::-webkit-scrollbar { 112 | width: 15px; 113 | height: 15px; 114 | } 115 | 116 | ::-webkit-scrollbar-button { 117 | height: 0px; 118 | width: 0px; 119 | } 120 | 121 | ::-webkit-scrollbar-track { 122 | background-color: transparent; 123 | } 124 | 125 | ::-webkit-scrollbar-thumb { 126 | background-color: mix(@foreground, @background, 30%); 127 | border: 3px solid transparent; 128 | border-radius: 6px; 129 | background-clip: content-box; 130 | } 131 | 132 | ::-webkit-scrollbar-thumb:hover { 133 | background-color: mix(@foreground, @background, 35%); 134 | } 135 | 136 | ::-webkit-scrollbar-corner { 137 | background-color: mix(@foreground, @background, 15%); 138 | } 139 | -------------------------------------------------------------------------------- /js/ace/theme-eclipse.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/eclipse",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | "use strict"; 3 | 4 | exports.isDark = false; 5 | exports.cssText = ".ace-eclipse .ace_gutter {\ 6 | background: #ebebeb;\ 7 | border-right: 1px solid rgb(159, 159, 159);\ 8 | color: rgb(136, 136, 136);\ 9 | }\ 10 | .ace-eclipse .ace_print-margin {\ 11 | width: 1px;\ 12 | background: #ebebeb;\ 13 | }\ 14 | .ace-eclipse {\ 15 | background-color: #FFFFFF;\ 16 | color: black;\ 17 | }\ 18 | .ace-eclipse .ace_fold {\ 19 | background-color: rgb(60, 76, 114);\ 20 | }\ 21 | .ace-eclipse .ace_cursor {\ 22 | color: black;\ 23 | }\ 24 | .ace-eclipse .ace_storage,\ 25 | .ace-eclipse .ace_keyword,\ 26 | .ace-eclipse .ace_variable {\ 27 | color: rgb(127, 0, 85);\ 28 | }\ 29 | .ace-eclipse .ace_constant.ace_buildin {\ 30 | color: rgb(88, 72, 246);\ 31 | }\ 32 | .ace-eclipse .ace_constant.ace_library {\ 33 | color: rgb(6, 150, 14);\ 34 | }\ 35 | .ace-eclipse .ace_function {\ 36 | color: rgb(60, 76, 114);\ 37 | }\ 38 | .ace-eclipse .ace_string {\ 39 | color: rgb(42, 0, 255);\ 40 | }\ 41 | .ace-eclipse .ace_comment {\ 42 | color: rgb(113, 150, 130);\ 43 | }\ 44 | .ace-eclipse .ace_comment.ace_doc {\ 45 | color: rgb(63, 95, 191);\ 46 | }\ 47 | .ace-eclipse .ace_comment.ace_doc.ace_tag {\ 48 | color: rgb(127, 159, 191);\ 49 | }\ 50 | .ace-eclipse .ace_constant.ace_numeric {\ 51 | color: darkblue;\ 52 | }\ 53 | .ace-eclipse .ace_tag {\ 54 | color: rgb(25, 118, 116);\ 55 | }\ 56 | .ace-eclipse .ace_type {\ 57 | color: rgb(127, 0, 127);\ 58 | }\ 59 | .ace-eclipse .ace_xml-pe {\ 60 | color: rgb(104, 104, 91);\ 61 | }\ 62 | .ace-eclipse .ace_marker-layer .ace_selection {\ 63 | background: rgb(181, 213, 255);\ 64 | }\ 65 | .ace-eclipse .ace_marker-layer .ace_bracket {\ 66 | margin: -1px 0 0 -1px;\ 67 | border: 1px solid rgb(192, 192, 192);\ 68 | }\ 69 | .ace-eclipse .ace_meta.ace_tag {\ 70 | color:rgb(25, 118, 116);\ 71 | }\ 72 | .ace-eclipse .ace_invisible {\ 73 | color: #ddd;\ 74 | }\ 75 | .ace-eclipse .ace_entity.ace_other.ace_attribute-name {\ 76 | color:rgb(127, 0, 127);\ 77 | }\ 78 | .ace-eclipse .ace_marker-layer .ace_step {\ 79 | background: rgb(255, 255, 0);\ 80 | }\ 81 | .ace-eclipse .ace_active-line {\ 82 | background: rgb(232, 242, 254);\ 83 | }\ 84 | .ace-eclipse .ace_gutter-active-line {\ 85 | background-color : #DADADA;\ 86 | }\ 87 | .ace-eclipse .ace_marker-layer .ace_selected-word {\ 88 | border: 1px solid rgb(181, 213, 255);\ 89 | }\ 90 | .ace-eclipse .ace_indent-guide {\ 91 | background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\ 92 | }"; 93 | 94 | exports.cssClass = "ace-eclipse"; 95 | 96 | var dom = require("../lib/dom"); 97 | dom.importCssString(exports.cssText, exports.cssClass); 98 | }); (function() { 99 | ace.require(["ace/theme/eclipse"], function(m) { 100 | if (typeof module == "object" && typeof exports == "object" && module) { 101 | module.exports = m; 102 | } 103 | }); 104 | })(); 105 | -------------------------------------------------------------------------------- /js/ace/theme-solarized_dark.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/solarized_dark",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-solarized-dark"; 5 | exports.cssText = ".ace-solarized-dark .ace_gutter {\ 6 | background: #01313f;\ 7 | color: #d0edf7\ 8 | }\ 9 | .ace-solarized-dark .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #33555E\ 12 | }\ 13 | .ace-solarized-dark {\ 14 | background-color: #002B36;\ 15 | color: #93A1A1\ 16 | }\ 17 | .ace-solarized-dark .ace_entity.ace_other.ace_attribute-name,\ 18 | .ace-solarized-dark .ace_storage {\ 19 | color: #93A1A1\ 20 | }\ 21 | .ace-solarized-dark .ace_cursor,\ 22 | .ace-solarized-dark .ace_string.ace_regexp {\ 23 | color: #D30102\ 24 | }\ 25 | .ace-solarized-dark .ace_marker-layer .ace_active-line,\ 26 | .ace-solarized-dark .ace_marker-layer .ace_selection {\ 27 | background: rgba(255, 255, 255, 0.1)\ 28 | }\ 29 | .ace-solarized-dark.ace_multiselect .ace_selection.ace_start {\ 30 | box-shadow: 0 0 3px 0px #002B36;\ 31 | }\ 32 | .ace-solarized-dark .ace_marker-layer .ace_step {\ 33 | background: rgb(102, 82, 0)\ 34 | }\ 35 | .ace-solarized-dark .ace_marker-layer .ace_bracket {\ 36 | margin: -1px 0 0 -1px;\ 37 | border: 1px solid rgba(147, 161, 161, 0.50)\ 38 | }\ 39 | .ace-solarized-dark .ace_gutter-active-line {\ 40 | background-color: #0d3440\ 41 | }\ 42 | .ace-solarized-dark .ace_marker-layer .ace_selected-word {\ 43 | border: 1px solid #073642\ 44 | }\ 45 | .ace-solarized-dark .ace_invisible {\ 46 | color: rgba(147, 161, 161, 0.50)\ 47 | }\ 48 | .ace-solarized-dark .ace_keyword,\ 49 | .ace-solarized-dark .ace_meta,\ 50 | .ace-solarized-dark .ace_support.ace_class,\ 51 | .ace-solarized-dark .ace_support.ace_type {\ 52 | color: #859900\ 53 | }\ 54 | .ace-solarized-dark .ace_constant.ace_character,\ 55 | .ace-solarized-dark .ace_constant.ace_other {\ 56 | color: #CB4B16\ 57 | }\ 58 | .ace-solarized-dark .ace_constant.ace_language {\ 59 | color: #B58900\ 60 | }\ 61 | .ace-solarized-dark .ace_constant.ace_numeric {\ 62 | color: #D33682\ 63 | }\ 64 | .ace-solarized-dark .ace_fold {\ 65 | background-color: #268BD2;\ 66 | border-color: #93A1A1\ 67 | }\ 68 | .ace-solarized-dark .ace_entity.ace_name.ace_function,\ 69 | .ace-solarized-dark .ace_entity.ace_name.ace_tag,\ 70 | .ace-solarized-dark .ace_support.ace_function,\ 71 | .ace-solarized-dark .ace_variable,\ 72 | .ace-solarized-dark .ace_variable.ace_language {\ 73 | color: #268BD2\ 74 | }\ 75 | .ace-solarized-dark .ace_string {\ 76 | color: #2AA198\ 77 | }\ 78 | .ace-solarized-dark .ace_comment {\ 79 | font-style: italic;\ 80 | color: #657B83\ 81 | }\ 82 | .ace-solarized-dark .ace_indent-guide {\ 83 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNg0Db1ZVCxc/sPAAd4AlUHlLenAAAAAElFTkSuQmCC) right repeat-y\ 84 | }"; 85 | 86 | var dom = require("../lib/dom"); 87 | dom.importCssString(exports.cssText, exports.cssClass); 88 | }); (function() { 89 | ace.require(["ace/theme/solarized_dark"], function(m) { 90 | if (typeof module == "object" && typeof exports == "object" && module) { 91 | module.exports = m; 92 | } 93 | }); 94 | })(); 95 | -------------------------------------------------------------------------------- /js/ace/theme-vibrant_ink.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/vibrant_ink",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-vibrant-ink"; 5 | exports.cssText = ".ace-vibrant-ink .ace_gutter {\ 6 | background: #1a1a1a;\ 7 | color: #BEBEBE\ 8 | }\ 9 | .ace-vibrant-ink .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #1a1a1a\ 12 | }\ 13 | .ace-vibrant-ink {\ 14 | background-color: #0F0F0F;\ 15 | color: #FFFFFF\ 16 | }\ 17 | .ace-vibrant-ink .ace_cursor {\ 18 | color: #FFFFFF\ 19 | }\ 20 | .ace-vibrant-ink .ace_marker-layer .ace_selection {\ 21 | background: #6699CC\ 22 | }\ 23 | .ace-vibrant-ink.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #0F0F0F;\ 25 | }\ 26 | .ace-vibrant-ink .ace_marker-layer .ace_step {\ 27 | background: rgb(102, 82, 0)\ 28 | }\ 29 | .ace-vibrant-ink .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid #404040\ 32 | }\ 33 | .ace-vibrant-ink .ace_marker-layer .ace_active-line {\ 34 | background: #333333\ 35 | }\ 36 | .ace-vibrant-ink .ace_gutter-active-line {\ 37 | background-color: #333333\ 38 | }\ 39 | .ace-vibrant-ink .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid #6699CC\ 41 | }\ 42 | .ace-vibrant-ink .ace_invisible {\ 43 | color: #404040\ 44 | }\ 45 | .ace-vibrant-ink .ace_keyword,\ 46 | .ace-vibrant-ink .ace_meta {\ 47 | color: #FF6600\ 48 | }\ 49 | .ace-vibrant-ink .ace_constant,\ 50 | .ace-vibrant-ink .ace_constant.ace_character,\ 51 | .ace-vibrant-ink .ace_constant.ace_character.ace_escape,\ 52 | .ace-vibrant-ink .ace_constant.ace_other {\ 53 | color: #339999\ 54 | }\ 55 | .ace-vibrant-ink .ace_constant.ace_numeric {\ 56 | color: #99CC99\ 57 | }\ 58 | .ace-vibrant-ink .ace_invalid,\ 59 | .ace-vibrant-ink .ace_invalid.ace_deprecated {\ 60 | color: #CCFF33;\ 61 | background-color: #000000\ 62 | }\ 63 | .ace-vibrant-ink .ace_fold {\ 64 | background-color: #FFCC00;\ 65 | border-color: #FFFFFF\ 66 | }\ 67 | .ace-vibrant-ink .ace_entity.ace_name.ace_function,\ 68 | .ace-vibrant-ink .ace_support.ace_function,\ 69 | .ace-vibrant-ink .ace_variable {\ 70 | color: #FFCC00\ 71 | }\ 72 | .ace-vibrant-ink .ace_variable.ace_parameter {\ 73 | font-style: italic\ 74 | }\ 75 | .ace-vibrant-ink .ace_string {\ 76 | color: #66FF00\ 77 | }\ 78 | .ace-vibrant-ink .ace_string.ace_regexp {\ 79 | color: #44B4CC\ 80 | }\ 81 | .ace-vibrant-ink .ace_comment {\ 82 | color: #9933CC\ 83 | }\ 84 | .ace-vibrant-ink .ace_entity.ace_other.ace_attribute-name {\ 85 | font-style: italic;\ 86 | color: #99CC99\ 87 | }\ 88 | .ace-vibrant-ink .ace_indent-guide {\ 89 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYNDTc/oPAALPAZ7hxlbYAAAAAElFTkSuQmCC) right repeat-y\ 90 | }"; 91 | 92 | var dom = require("../lib/dom"); 93 | dom.importCssString(exports.cssText, exports.cssClass); 94 | }); (function() { 95 | ace.require(["ace/theme/vibrant_ink"], function(m) { 96 | if (typeof module == "object" && typeof exports == "object" && module) { 97 | module.exports = m; 98 | } 99 | }); 100 | })(); 101 | -------------------------------------------------------------------------------- /config/user.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultTheme": "chrome", //This should be any of the supported Ace themes 3 | // look for theme-*.js here: https://github.com/ajaxorg/ace-builds/tree/master/src-noconflict 4 | 5 | "uiTheme": "light", //dark, twilight, or light 6 | "autoHideProject": false, //collapse the project view until you hover 7 | "immersiveFullscreen": false, //hides menus/tabs in Chrome OS fullscreen mode 8 | "highlightLine": false, 9 | "hideGutter": false, //set to true to hide the line numbering 10 | 11 | // editor options 12 | "showWhitespace": false, //show whitespace characters (spaces, tabs, returns) 13 | "showMargin": false, 14 | "scrollPastEnd": true, //allow the editor to scroll past the end of the document 15 | "trimTrailingWhitespace": true, //run "Trim Trailing Whitespace" on save 16 | "trimEmptyLines": false, //should the trim whitespace command also truncate empty lines? 17 | 18 | // syntax options 19 | "indentation": 2, //indentation size 20 | "useTabs": false, //will turn off Ace's setUseSoftTabs() option and use tab characters instead 21 | "wordWrap": true, 22 | "wrapLimit": false, //Set to the number of characters you want or false for full window 23 | "lineEndings": "auto", //newline format - "windows", "unix", or "auto" 24 | 25 | //only fixed-width fonts supported, for now 26 | "fontFamily": "", 27 | "fontSize": 13, 28 | "lineHeight": 1, 29 | 30 | //Web workers are used for code hinting in PHP, JavaScript, and JSON. 31 | //We don't yet have a way to set the worker options, but you can disable it. 32 | "useWorker": true, 33 | //autocomplete triggers on Ctrl-Space 34 | "autocomplete": true, 35 | //autocomplete triggers automatically 36 | "autocompleteLive": false, 37 | //"Behaviors" are the auto-paired quotes and HTML tags in the editor 38 | "disableBehaviors": false, 39 | 40 | //By default, the palette searches the current file's text only unless you widen the scope. 41 | //If you'd like it to search all open files by default, set this option to true. 42 | "searchAllFiles": false, 43 | //set the max search results that project wide search will return. 44 | "maxSearchMatches": 500, 45 | 46 | //set a regex to ignore in project view/search 47 | "ignoreFiles": "node_modules", 48 | //by default, Caret doesn't show hidden folders (i.e., .git) in its project view 49 | "showHiddenDirectories": false, 50 | //set this to enable autosave every X minutes 51 | "autosaveInterval": 0, 52 | "autosaveOnBlur": false, 53 | //If the editor jumps to the top on focus change, set this: 54 | "disableReload": false, 55 | //Set this to stop the editor from restoring the last set of tabs it had open 56 | "disableTabRestore": false, 57 | 58 | //If you want to disable update checks at startup, change this 59 | "promptForUpdates": true, 60 | // options are "background", "launch", and "silent" 61 | "updateNotifications": "background", 62 | 63 | 64 | //Wildly eccentric? You might like Vim keybindings. 65 | "emulateVim": false, 66 | 67 | //jsHint settings are applied on opening a JS file. You may need to restart Caret for changes to take effect. 68 | "jsHint": {}, 69 | 70 | // You can set syntax options here. Not all options supported yet. 71 | "syntaxSpecific": { 72 | "python": { 73 | "indentation": 4 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /js/ace/theme-merbivore.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/merbivore",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-merbivore"; 5 | exports.cssText = ".ace-merbivore .ace_gutter {\ 6 | background: #202020;\ 7 | color: #E6E1DC\ 8 | }\ 9 | .ace-merbivore .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #555651\ 12 | }\ 13 | .ace-merbivore {\ 14 | background-color: #161616;\ 15 | color: #E6E1DC\ 16 | }\ 17 | .ace-merbivore .ace_cursor {\ 18 | color: #FFFFFF\ 19 | }\ 20 | .ace-merbivore .ace_marker-layer .ace_selection {\ 21 | background: #454545\ 22 | }\ 23 | .ace-merbivore.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #161616;\ 25 | }\ 26 | .ace-merbivore .ace_marker-layer .ace_step {\ 27 | background: rgb(102, 82, 0)\ 28 | }\ 29 | .ace-merbivore .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid #404040\ 32 | }\ 33 | .ace-merbivore .ace_marker-layer .ace_active-line {\ 34 | background: #333435\ 35 | }\ 36 | .ace-merbivore .ace_gutter-active-line {\ 37 | background-color: #333435\ 38 | }\ 39 | .ace-merbivore .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid #454545\ 41 | }\ 42 | .ace-merbivore .ace_invisible {\ 43 | color: #404040\ 44 | }\ 45 | .ace-merbivore .ace_entity.ace_name.ace_tag,\ 46 | .ace-merbivore .ace_keyword,\ 47 | .ace-merbivore .ace_meta,\ 48 | .ace-merbivore .ace_meta.ace_tag,\ 49 | .ace-merbivore .ace_storage,\ 50 | .ace-merbivore .ace_support.ace_function {\ 51 | color: #FC6F09\ 52 | }\ 53 | .ace-merbivore .ace_constant,\ 54 | .ace-merbivore .ace_constant.ace_character,\ 55 | .ace-merbivore .ace_constant.ace_character.ace_escape,\ 56 | .ace-merbivore .ace_constant.ace_other,\ 57 | .ace-merbivore .ace_support.ace_type {\ 58 | color: #1EDAFB\ 59 | }\ 60 | .ace-merbivore .ace_constant.ace_character.ace_escape {\ 61 | color: #519F50\ 62 | }\ 63 | .ace-merbivore .ace_constant.ace_language {\ 64 | color: #FDC251\ 65 | }\ 66 | .ace-merbivore .ace_constant.ace_library,\ 67 | .ace-merbivore .ace_string,\ 68 | .ace-merbivore .ace_support.ace_constant {\ 69 | color: #8DFF0A\ 70 | }\ 71 | .ace-merbivore .ace_constant.ace_numeric {\ 72 | color: #58C554\ 73 | }\ 74 | .ace-merbivore .ace_invalid {\ 75 | color: #FFFFFF;\ 76 | background-color: #990000\ 77 | }\ 78 | .ace-merbivore .ace_fold {\ 79 | background-color: #FC6F09;\ 80 | border-color: #E6E1DC\ 81 | }\ 82 | .ace-merbivore .ace_comment {\ 83 | font-style: italic;\ 84 | color: #AD2EA4\ 85 | }\ 86 | .ace-merbivore .ace_entity.ace_other.ace_attribute-name {\ 87 | color: #FFFF89\ 88 | }\ 89 | .ace-merbivore .ace_indent-guide {\ 90 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQFxf3ZXB1df0PAAdsAmERTkEHAAAAAElFTkSuQmCC) right repeat-y\ 91 | }"; 92 | 93 | var dom = require("../lib/dom"); 94 | dom.importCssString(exports.cssText, exports.cssClass); 95 | }); (function() { 96 | ace.require(["ace/theme/merbivore"], function(m) { 97 | if (typeof module == "object" && typeof exports == "object" && module) { 98 | module.exports = m; 99 | } 100 | }); 101 | })(); 102 | -------------------------------------------------------------------------------- /js/ace/theme-github.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/github",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = false; 4 | exports.cssClass = "ace-github"; 5 | exports.cssText = "\ 6 | .ace-github .ace_gutter {\ 7 | background: #e8e8e8;\ 8 | color: #AAA;\ 9 | }\ 10 | .ace-github {\ 11 | background: #fff;\ 12 | color: #000;\ 13 | }\ 14 | .ace-github .ace_keyword {\ 15 | font-weight: bold;\ 16 | }\ 17 | .ace-github .ace_string {\ 18 | color: #D14;\ 19 | }\ 20 | .ace-github .ace_variable.ace_class {\ 21 | color: teal;\ 22 | }\ 23 | .ace-github .ace_constant.ace_numeric {\ 24 | color: #099;\ 25 | }\ 26 | .ace-github .ace_constant.ace_buildin {\ 27 | color: #0086B3;\ 28 | }\ 29 | .ace-github .ace_support.ace_function {\ 30 | color: #0086B3;\ 31 | }\ 32 | .ace-github .ace_comment {\ 33 | color: #998;\ 34 | font-style: italic;\ 35 | }\ 36 | .ace-github .ace_variable.ace_language {\ 37 | color: #0086B3;\ 38 | }\ 39 | .ace-github .ace_paren {\ 40 | font-weight: bold;\ 41 | }\ 42 | .ace-github .ace_boolean {\ 43 | font-weight: bold;\ 44 | }\ 45 | .ace-github .ace_string.ace_regexp {\ 46 | color: #009926;\ 47 | font-weight: normal;\ 48 | }\ 49 | .ace-github .ace_variable.ace_instance {\ 50 | color: teal;\ 51 | }\ 52 | .ace-github .ace_constant.ace_language {\ 53 | font-weight: bold;\ 54 | }\ 55 | .ace-github .ace_cursor {\ 56 | color: black;\ 57 | }\ 58 | .ace-github.ace_focus .ace_marker-layer .ace_active-line {\ 59 | background: rgb(255, 255, 204);\ 60 | }\ 61 | .ace-github .ace_marker-layer .ace_active-line {\ 62 | background: rgb(245, 245, 245);\ 63 | }\ 64 | .ace-github .ace_marker-layer .ace_selection {\ 65 | background: rgb(181, 213, 255);\ 66 | }\ 67 | .ace-github.ace_multiselect .ace_selection.ace_start {\ 68 | box-shadow: 0 0 3px 0px white;\ 69 | }\ 70 | .ace-github.ace_nobold .ace_line > span {\ 71 | font-weight: normal !important;\ 72 | }\ 73 | .ace-github .ace_marker-layer .ace_step {\ 74 | background: rgb(252, 255, 0);\ 75 | }\ 76 | .ace-github .ace_marker-layer .ace_stack {\ 77 | background: rgb(164, 229, 101);\ 78 | }\ 79 | .ace-github .ace_marker-layer .ace_bracket {\ 80 | margin: -1px 0 0 -1px;\ 81 | border: 1px solid rgb(192, 192, 192);\ 82 | }\ 83 | .ace-github .ace_gutter-active-line {\ 84 | background-color : rgba(0, 0, 0, 0.07);\ 85 | }\ 86 | .ace-github .ace_marker-layer .ace_selected-word {\ 87 | background: rgb(250, 250, 255);\ 88 | border: 1px solid rgb(200, 200, 250);\ 89 | }\ 90 | .ace-github .ace_invisible {\ 91 | color: #BFBFBF\ 92 | }\ 93 | .ace-github .ace_print-margin {\ 94 | width: 1px;\ 95 | background: #e8e8e8;\ 96 | }\ 97 | .ace-github .ace_indent-guide {\ 98 | background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\ 99 | }"; 100 | 101 | var dom = require("../lib/dom"); 102 | dom.importCssString(exports.cssText, exports.cssClass); 103 | }); (function() { 104 | ace.require(["ace/theme/github"], function(m) { 105 | if (typeof module == "object" && typeof exports == "object" && module) { 106 | module.exports = m; 107 | } 108 | }); 109 | })(); 110 | -------------------------------------------------------------------------------- /js/ace/theme-solarized_light.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/solarized_light",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = false; 4 | exports.cssClass = "ace-solarized-light"; 5 | exports.cssText = ".ace-solarized-light .ace_gutter {\ 6 | background: #fbf1d3;\ 7 | color: #333\ 8 | }\ 9 | .ace-solarized-light .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #e8e8e8\ 12 | }\ 13 | .ace-solarized-light {\ 14 | background-color: #FDF6E3;\ 15 | color: #586E75\ 16 | }\ 17 | .ace-solarized-light .ace_cursor {\ 18 | color: #000000\ 19 | }\ 20 | .ace-solarized-light .ace_marker-layer .ace_selection {\ 21 | background: rgba(7, 54, 67, 0.09)\ 22 | }\ 23 | .ace-solarized-light.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #FDF6E3;\ 25 | }\ 26 | .ace-solarized-light .ace_marker-layer .ace_step {\ 27 | background: rgb(255, 255, 0)\ 28 | }\ 29 | .ace-solarized-light .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid rgba(147, 161, 161, 0.50)\ 32 | }\ 33 | .ace-solarized-light .ace_marker-layer .ace_active-line {\ 34 | background: #EEE8D5\ 35 | }\ 36 | .ace-solarized-light .ace_gutter-active-line {\ 37 | background-color : #EDE5C1\ 38 | }\ 39 | .ace-solarized-light .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid #7f9390\ 41 | }\ 42 | .ace-solarized-light .ace_invisible {\ 43 | color: rgba(147, 161, 161, 0.50)\ 44 | }\ 45 | .ace-solarized-light .ace_keyword,\ 46 | .ace-solarized-light .ace_meta,\ 47 | .ace-solarized-light .ace_support.ace_class,\ 48 | .ace-solarized-light .ace_support.ace_type {\ 49 | color: #859900\ 50 | }\ 51 | .ace-solarized-light .ace_constant.ace_character,\ 52 | .ace-solarized-light .ace_constant.ace_other {\ 53 | color: #CB4B16\ 54 | }\ 55 | .ace-solarized-light .ace_constant.ace_language {\ 56 | color: #B58900\ 57 | }\ 58 | .ace-solarized-light .ace_constant.ace_numeric {\ 59 | color: #D33682\ 60 | }\ 61 | .ace-solarized-light .ace_fold {\ 62 | background-color: #268BD2;\ 63 | border-color: #586E75\ 64 | }\ 65 | .ace-solarized-light .ace_entity.ace_name.ace_function,\ 66 | .ace-solarized-light .ace_entity.ace_name.ace_tag,\ 67 | .ace-solarized-light .ace_support.ace_function,\ 68 | .ace-solarized-light .ace_variable,\ 69 | .ace-solarized-light .ace_variable.ace_language {\ 70 | color: #268BD2\ 71 | }\ 72 | .ace-solarized-light .ace_storage {\ 73 | color: #073642\ 74 | }\ 75 | .ace-solarized-light .ace_string {\ 76 | color: #2AA198\ 77 | }\ 78 | .ace-solarized-light .ace_string.ace_regexp {\ 79 | color: #D30102\ 80 | }\ 81 | .ace-solarized-light .ace_comment,\ 82 | .ace-solarized-light .ace_entity.ace_other.ace_attribute-name {\ 83 | color: #93A1A1\ 84 | }\ 85 | .ace-solarized-light .ace_indent-guide {\ 86 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHjy8NJ/AAjgA5fzQUmBAAAAAElFTkSuQmCC) right repeat-y\ 87 | }"; 88 | 89 | var dom = require("../lib/dom"); 90 | dom.importCssString(exports.cssText, exports.cssClass); 91 | }); (function() { 92 | ace.require(["ace/theme/solarized_light"], function(m) { 93 | if (typeof module == "object" && typeof exports == "object" && module) { 94 | module.exports = m; 95 | } 96 | }); 97 | })(); 98 | -------------------------------------------------------------------------------- /js/ace/theme-idle_fingers.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/idle_fingers",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-idle-fingers"; 5 | exports.cssText = ".ace-idle-fingers .ace_gutter {\ 6 | background: #3b3b3b;\ 7 | color: rgb(153,153,153)\ 8 | }\ 9 | .ace-idle-fingers .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #3b3b3b\ 12 | }\ 13 | .ace-idle-fingers {\ 14 | background-color: #323232;\ 15 | color: #FFFFFF\ 16 | }\ 17 | .ace-idle-fingers .ace_cursor {\ 18 | color: #91FF00\ 19 | }\ 20 | .ace-idle-fingers .ace_marker-layer .ace_selection {\ 21 | background: rgba(90, 100, 126, 0.88)\ 22 | }\ 23 | .ace-idle-fingers.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #323232;\ 25 | }\ 26 | .ace-idle-fingers .ace_marker-layer .ace_step {\ 27 | background: rgb(102, 82, 0)\ 28 | }\ 29 | .ace-idle-fingers .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid #404040\ 32 | }\ 33 | .ace-idle-fingers .ace_marker-layer .ace_active-line {\ 34 | background: #353637\ 35 | }\ 36 | .ace-idle-fingers .ace_gutter-active-line {\ 37 | background-color: #353637\ 38 | }\ 39 | .ace-idle-fingers .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid rgba(90, 100, 126, 0.88)\ 41 | }\ 42 | .ace-idle-fingers .ace_invisible {\ 43 | color: #404040\ 44 | }\ 45 | .ace-idle-fingers .ace_keyword,\ 46 | .ace-idle-fingers .ace_meta {\ 47 | color: #CC7833\ 48 | }\ 49 | .ace-idle-fingers .ace_constant,\ 50 | .ace-idle-fingers .ace_constant.ace_character,\ 51 | .ace-idle-fingers .ace_constant.ace_character.ace_escape,\ 52 | .ace-idle-fingers .ace_constant.ace_other,\ 53 | .ace-idle-fingers .ace_support.ace_constant {\ 54 | color: #6C99BB\ 55 | }\ 56 | .ace-idle-fingers .ace_invalid {\ 57 | color: #FFFFFF;\ 58 | background-color: #FF0000\ 59 | }\ 60 | .ace-idle-fingers .ace_fold {\ 61 | background-color: #CC7833;\ 62 | border-color: #FFFFFF\ 63 | }\ 64 | .ace-idle-fingers .ace_support.ace_function {\ 65 | color: #B83426\ 66 | }\ 67 | .ace-idle-fingers .ace_variable.ace_parameter {\ 68 | font-style: italic\ 69 | }\ 70 | .ace-idle-fingers .ace_string {\ 71 | color: #A5C261\ 72 | }\ 73 | .ace-idle-fingers .ace_string.ace_regexp {\ 74 | color: #CCCC33\ 75 | }\ 76 | .ace-idle-fingers .ace_comment {\ 77 | font-style: italic;\ 78 | color: #BC9458\ 79 | }\ 80 | .ace-idle-fingers .ace_meta.ace_tag {\ 81 | color: #FFE5BB\ 82 | }\ 83 | .ace-idle-fingers .ace_entity.ace_name {\ 84 | color: #FFC66D\ 85 | }\ 86 | .ace-idle-fingers .ace_collab.ace_user1 {\ 87 | color: #323232;\ 88 | background-color: #FFF980\ 89 | }\ 90 | .ace-idle-fingers .ace_indent-guide {\ 91 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMwMjLyZYiPj/8PAAreAwAI1+g0AAAAAElFTkSuQmCC) right repeat-y\ 92 | }"; 93 | 94 | var dom = require("../lib/dom"); 95 | dom.importCssString(exports.cssText, exports.cssClass); 96 | }); (function() { 97 | ace.require(["ace/theme/idle_fingers"], function(m) { 98 | if (typeof module == "object" && typeof exports == "object" && module) { 99 | module.exports = m; 100 | } 101 | }); 102 | })(); 103 | -------------------------------------------------------------------------------- /code_of_conduct.rst: -------------------------------------------------------------------------------- 1 | Contributor Covenant Code of Conduct 2 | ==================================== 3 | 4 | Our Pledge 5 | ---------- 6 | 7 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 8 | 9 | Our Standards 10 | ------------- 11 | 12 | Examples of behavior that contributes to creating a positive environment include: 13 | 14 | * Using welcoming and inclusive language 15 | * Being respectful of differing viewpoints and experiences 16 | * Gracefully accepting constructive criticism 17 | * Focusing on what is best for the community 18 | * Showing empathy towards other community members 19 | 20 | Examples of unacceptable behavior by participants include: 21 | 22 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 23 | * Trolling, insulting/derogatory comments, and personal or political attacks 24 | * Public or private harassment 25 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 26 | * Other conduct which could reasonably be considered inappropriate in a professional setting 27 | 28 | Our Responsibilities 29 | -------------------- 30 | 31 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 32 | 33 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 34 | 35 | Scope 36 | ----- 37 | 38 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 39 | 40 | Enforcement 41 | ----------- 42 | 43 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at news@thomaswilburn.net. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 44 | 45 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 46 | 47 | Attribution 48 | ----------- 49 | 50 | This Code of Conduct is adapted from the `Contributor Covenant `_, version 1.4, available at http://contributor-covenant.org/version/1/4 51 | -------------------------------------------------------------------------------- /js/ui/dialog.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "editor", 3 | "util/template!templates/dialog.html" 4 | ], function(editor, inflate) { 5 | 6 | /* 7 | You can call dialog() to present a modal, since alert() isn't allowed. 8 | 9 | Currently, your callback will be passed the value set for the button pressed. Form support is coming. 10 | */ 11 | 12 | return function(text, buttons, callback) { 13 | return new Promise(function(ok, fail) { 14 | if (typeof buttons == "function" || typeof buttons == "undefined") { 15 | callback = buttons; 16 | buttons = ["ok"]; 17 | } 18 | 19 | buttons = buttons.map(function(options) { 20 | if (typeof options == "string") { 21 | return { 22 | label: options, 23 | value: options 24 | }; 25 | } 26 | return options; 27 | }); 28 | 29 | var modal = inflate.get("templates/dialog.html", { 30 | text: text, 31 | buttons: buttons 32 | }); 33 | 34 | document.body.appendChild(modal); 35 | setTimeout(function() { 36 | //trigger enter animations 37 | modal.classList.remove("enter"); 38 | }); 39 | 40 | var defaultButton = modal.querySelector("button.default"); 41 | if (!defaultButton) defaultButton = modal.querySelector("button"); 42 | defaultButton.focus(); 43 | 44 | modal.addEventListener("click", function(e) { 45 | if (e.target != modal) return; 46 | e.preventDefault(); 47 | e.stopImmediatePropagation(); 48 | defaultButton.focus(); 49 | }); 50 | 51 | var onKeyDown = function(e) { 52 | e.stopPropagation(); 53 | e.stopImmediatePropagation(); 54 | if (e.ctrlKey || e.metaKey || e.shiftKey) { 55 | e.preventDefault(); 56 | } 57 | //check escape 58 | if (e.keyCode == 27) { 59 | modal.remove(); 60 | editor.focus(); 61 | if (callback) callback(); 62 | ok(); 63 | } 64 | }; 65 | 66 | var onKeyPress = function(e) { 67 | e.stopPropagation(); 68 | e.stopImmediatePropagation(); 69 | //allow Enter to trigger clicks 70 | if (e.keyCode != 13) { 71 | e.preventDefault(); 72 | } 73 | buttons.forEach(function(options) { 74 | if (typeof options == "string") return; 75 | if (options.shortcut && options.shortcut == String.fromCharCode(e.charCode)) { 76 | modal.remove(); 77 | editor.focus(); 78 | if (callback) callback(options.value); 79 | ok(options.value); 80 | } 81 | }); 82 | } 83 | 84 | var clickButton = function(e) { 85 | var target = e.target; 86 | if (!target.matches("button")) return; 87 | modal.remove(); 88 | var value; 89 | try { 90 | value = JSON.parse(target.value); 91 | } catch (err) { 92 | //do nothing 93 | value = target.value; 94 | } 95 | if (callback) callback(value); 96 | ok(value); 97 | editor.focus(); 98 | }; 99 | 100 | modal.onkeydown = onKeyDown; 101 | modal.onkeypress = onKeyPress; 102 | modal.onclick = clickButton; 103 | 104 | }); 105 | }; 106 | }); -------------------------------------------------------------------------------- /js/ace/theme-dawn.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/dawn",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = false; 4 | exports.cssClass = "ace-dawn"; 5 | exports.cssText = ".ace-dawn .ace_gutter {\ 6 | background: #ebebeb;\ 7 | color: #333\ 8 | }\ 9 | .ace-dawn .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #e8e8e8\ 12 | }\ 13 | .ace-dawn {\ 14 | background-color: #F9F9F9;\ 15 | color: #080808\ 16 | }\ 17 | .ace-dawn .ace_cursor {\ 18 | color: #000000\ 19 | }\ 20 | .ace-dawn .ace_marker-layer .ace_selection {\ 21 | background: rgba(39, 95, 255, 0.30)\ 22 | }\ 23 | .ace-dawn.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #F9F9F9;\ 25 | }\ 26 | .ace-dawn .ace_marker-layer .ace_step {\ 27 | background: rgb(255, 255, 0)\ 28 | }\ 29 | .ace-dawn .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid rgba(75, 75, 126, 0.50)\ 32 | }\ 33 | .ace-dawn .ace_marker-layer .ace_active-line {\ 34 | background: rgba(36, 99, 180, 0.12)\ 35 | }\ 36 | .ace-dawn .ace_gutter-active-line {\ 37 | background-color : #dcdcdc\ 38 | }\ 39 | .ace-dawn .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid rgba(39, 95, 255, 0.30)\ 41 | }\ 42 | .ace-dawn .ace_invisible {\ 43 | color: rgba(75, 75, 126, 0.50)\ 44 | }\ 45 | .ace-dawn .ace_keyword,\ 46 | .ace-dawn .ace_meta {\ 47 | color: #794938\ 48 | }\ 49 | .ace-dawn .ace_constant,\ 50 | .ace-dawn .ace_constant.ace_character,\ 51 | .ace-dawn .ace_constant.ace_character.ace_escape,\ 52 | .ace-dawn .ace_constant.ace_other {\ 53 | color: #811F24\ 54 | }\ 55 | .ace-dawn .ace_invalid.ace_illegal {\ 56 | text-decoration: underline;\ 57 | font-style: italic;\ 58 | color: #F8F8F8;\ 59 | background-color: #B52A1D\ 60 | }\ 61 | .ace-dawn .ace_invalid.ace_deprecated {\ 62 | text-decoration: underline;\ 63 | font-style: italic;\ 64 | color: #B52A1D\ 65 | }\ 66 | .ace-dawn .ace_support {\ 67 | color: #691C97\ 68 | }\ 69 | .ace-dawn .ace_support.ace_constant {\ 70 | color: #B4371F\ 71 | }\ 72 | .ace-dawn .ace_fold {\ 73 | background-color: #794938;\ 74 | border-color: #080808\ 75 | }\ 76 | .ace-dawn .ace_list,\ 77 | .ace-dawn .ace_markup.ace_list,\ 78 | .ace-dawn .ace_support.ace_function {\ 79 | color: #693A17\ 80 | }\ 81 | .ace-dawn .ace_storage {\ 82 | font-style: italic;\ 83 | color: #A71D5D\ 84 | }\ 85 | .ace-dawn .ace_string {\ 86 | color: #0B6125\ 87 | }\ 88 | .ace-dawn .ace_string.ace_regexp {\ 89 | color: #CF5628\ 90 | }\ 91 | .ace-dawn .ace_comment {\ 92 | font-style: italic;\ 93 | color: #5A525F\ 94 | }\ 95 | .ace-dawn .ace_heading,\ 96 | .ace-dawn .ace_markup.ace_heading {\ 97 | color: #19356D\ 98 | }\ 99 | .ace-dawn .ace_variable {\ 100 | color: #234A97\ 101 | }\ 102 | .ace-dawn .ace_indent-guide {\ 103 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYLh/5+x/AAizA4hxNNsZAAAAAElFTkSuQmCC) right repeat-y\ 104 | }"; 105 | 106 | var dom = require("../lib/dom"); 107 | dom.importCssString(exports.cssText, exports.cssClass); 108 | }); (function() { 109 | ace.require(["ace/theme/dawn"], function(m) { 110 | if (typeof module == "object" && typeof exports == "object" && module) { 111 | module.exports = m; 112 | } 113 | }); 114 | })(); 115 | -------------------------------------------------------------------------------- /contributing.rst: -------------------------------------------------------------------------------- 1 | Contributing to Caret 2 | ===================== 3 | 4 | Help is always welcome when it comes to making Caret the best editor it can be. This is not just limited to code, but also to documentation, bug reports, and feature requests. To contribute, visit our GitHub repo: 5 | 6 | https://github.com/thomaswilburn/Caret 7 | 8 | We use GitHub's issue system to track bugs and feature requests, so feel free to start there. You can also grab a copy of the source code from the repo. Feel free to file a pull request, but do note that all contributions must go through a thorough code review before being accepted, and you may be asked to revise your code to match Caret's style and structure. Below are a few notes to help reduce surprises in that department: 9 | 10 | - In general, use the Google JS style guide, with a few exceptions due to orneriness. 11 | - Caret style prefers double quotes to single quotes when writing strings. We also ignore the style guide when it comes to AMD module declarations, but other function declarations should follow the Google style. 12 | - JSDoc is not used in Caret, but would probably be a good idea. Comment heavily, but name your variables and write your code so that comments shouldn't be necessary. You should prefer clarity to cleverness. 13 | - For the most part, we use relatively few outside libraries besides Ace and the ES6 Promise shim. Before including other external libraries, consider whether this is truly necessary. For example, there are libraries for providing async and DOM manipulation in /util that should be used, rather than including caolan's async library or jQuery. This micro-library approach has served Caret well--consider deeply whether you need to include a large external library for your contribution. 14 | - Once AMD modules start to exceed 200 lines, it's a good idea to try breaking them up into primary packages with imported sub-modules. See the "session" module for an example. 15 | - Caret uses Grunt as its build system, and you will need it installed for development. If your contribution generates files, such as templates or CSS, do not check in the generated files, but do make sure that they will be generated as a part of the Grunt "package" task. 16 | 17 | You don't have to be a coder to help with Caret — we're always looking for designers, writers, testers, and other non-code tasks. If you'd like suggestions on where to start, send an e-mail. Contact information is available from the main project marketing page at http://thomaswilburn.net/caret 18 | 19 | If you want to help with translations 20 | ------------------------------------- 21 | 22 | - Create a new folder under ``_locales``. Name the folder after one of the supported languages (see https://developer.chrome.com/webstore/i18n?csw=1#localeTable). 23 | - Copy the ``messages.json`` file from the english (en) folder into this new folder. 24 | - Translate the messages. 25 | 26 | Instructions on how to change Chrome language for testing can be found here: 27 | https://developer.chrome.com/extensions/i18n#locales-testing 28 | 29 | **Note:** If changing the whole Mac OS language settings just to test an app, as described in the instructions, sounds like overkill, you can follow these steps: 30 | 31 | - Open a Terminal window. 32 | - Type ``defaults write com.google.Chrome AppleLanguages '(en-US)'`` and press "enter". (set the language you want in the parenthesis). 33 | - Restart Chrome. 34 | 35 | (from https://productforums.google.com/forum/#!msg/chrome/KlwkLCRln9g/7vGcFpN7ZRwJ) 36 | -------------------------------------------------------------------------------- /js/ace/theme-kr_theme.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/kr_theme",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-kr-theme"; 5 | exports.cssText = ".ace-kr-theme .ace_gutter {\ 6 | background: #1c1917;\ 7 | color: #FCFFE0\ 8 | }\ 9 | .ace-kr-theme .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #1c1917\ 12 | }\ 13 | .ace-kr-theme {\ 14 | background-color: #0B0A09;\ 15 | color: #FCFFE0\ 16 | }\ 17 | .ace-kr-theme .ace_cursor {\ 18 | color: #FF9900\ 19 | }\ 20 | .ace-kr-theme .ace_marker-layer .ace_selection {\ 21 | background: rgba(170, 0, 255, 0.45)\ 22 | }\ 23 | .ace-kr-theme.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #0B0A09;\ 25 | }\ 26 | .ace-kr-theme .ace_marker-layer .ace_step {\ 27 | background: rgb(102, 82, 0)\ 28 | }\ 29 | .ace-kr-theme .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid rgba(255, 177, 111, 0.32)\ 32 | }\ 33 | .ace-kr-theme .ace_marker-layer .ace_active-line {\ 34 | background: #38403D\ 35 | }\ 36 | .ace-kr-theme .ace_gutter-active-line {\ 37 | background-color : #38403D\ 38 | }\ 39 | .ace-kr-theme .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid rgba(170, 0, 255, 0.45)\ 41 | }\ 42 | .ace-kr-theme .ace_invisible {\ 43 | color: rgba(255, 177, 111, 0.32)\ 44 | }\ 45 | .ace-kr-theme .ace_keyword,\ 46 | .ace-kr-theme .ace_meta {\ 47 | color: #949C8B\ 48 | }\ 49 | .ace-kr-theme .ace_constant,\ 50 | .ace-kr-theme .ace_constant.ace_character,\ 51 | .ace-kr-theme .ace_constant.ace_character.ace_escape,\ 52 | .ace-kr-theme .ace_constant.ace_other {\ 53 | color: rgba(210, 117, 24, 0.76)\ 54 | }\ 55 | .ace-kr-theme .ace_invalid {\ 56 | color: #F8F8F8;\ 57 | background-color: #A41300\ 58 | }\ 59 | .ace-kr-theme .ace_support {\ 60 | color: #9FC28A\ 61 | }\ 62 | .ace-kr-theme .ace_support.ace_constant {\ 63 | color: #C27E66\ 64 | }\ 65 | .ace-kr-theme .ace_fold {\ 66 | background-color: #949C8B;\ 67 | border-color: #FCFFE0\ 68 | }\ 69 | .ace-kr-theme .ace_support.ace_function {\ 70 | color: #85873A\ 71 | }\ 72 | .ace-kr-theme .ace_storage {\ 73 | color: #FFEE80\ 74 | }\ 75 | .ace-kr-theme .ace_string {\ 76 | color: rgba(164, 161, 181, 0.8)\ 77 | }\ 78 | .ace-kr-theme .ace_string.ace_regexp {\ 79 | color: rgba(125, 255, 192, 0.65)\ 80 | }\ 81 | .ace-kr-theme .ace_comment {\ 82 | font-style: italic;\ 83 | color: #706D5B\ 84 | }\ 85 | .ace-kr-theme .ace_variable {\ 86 | color: #D1A796\ 87 | }\ 88 | .ace-kr-theme .ace_list,\ 89 | .ace-kr-theme .ace_markup.ace_list {\ 90 | background-color: #0F0040\ 91 | }\ 92 | .ace-kr-theme .ace_variable.ace_language {\ 93 | color: #FF80E1\ 94 | }\ 95 | .ace-kr-theme .ace_meta.ace_tag {\ 96 | color: #BABD9C\ 97 | }\ 98 | .ace-kr-theme .ace_indent-guide {\ 99 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYFBXV/8PAAJoAXX4kT2EAAAAAElFTkSuQmCC) right repeat-y\ 100 | }"; 101 | 102 | var dom = require("../lib/dom"); 103 | dom.importCssString(exports.cssText, exports.cssClass); 104 | }); (function() { 105 | ace.require(["ace/theme/kr_theme"], function(m) { 106 | if (typeof module == "object" && typeof exports == "object" && module) { 107 | module.exports = m; 108 | } 109 | }); 110 | })(); 111 | -------------------------------------------------------------------------------- /js/ace/mode-gcode.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/gcode_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { 2 | "use strict"; 3 | 4 | var oop = require("../lib/oop"); 5 | var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; 6 | 7 | var GcodeHighlightRules = function() { 8 | 9 | var keywords = ( 10 | "IF|DO|WHILE|ENDWHILE|CALL|ENDIF|SUB|ENDSUB|GOTO|REPEAT|ENDREPEAT|CALL" 11 | ); 12 | 13 | var builtinConstants = ( 14 | "PI" 15 | ); 16 | 17 | var builtinFunctions = ( 18 | "ATAN|ABS|ACOS|ASIN|SIN|COS|EXP|FIX|FUP|ROUND|LN|TAN" 19 | ); 20 | var keywordMapper = this.createKeywordMapper({ 21 | "support.function": builtinFunctions, 22 | "keyword": keywords, 23 | "constant.language": builtinConstants 24 | }, "identifier", true); 25 | 26 | this.$rules = { 27 | "start" : [ { 28 | token : "comment", 29 | regex : "\\(.*\\)" 30 | }, { 31 | token : "comment", // block number 32 | regex : "([N])([0-9]+)" 33 | }, { 34 | token : "string", // " string 35 | regex : "([G])([0-9]+\\.?[0-9]?)" 36 | }, { 37 | token : "string", // ' string 38 | regex : "([M])([0-9]+\\.?[0-9]?)" 39 | }, { 40 | token : "constant.numeric", // float 41 | regex : "([-+]?([0-9]*\\.?[0-9]+\\.?))|(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)" 42 | }, { 43 | token : keywordMapper, 44 | regex : "[A-Z]" 45 | }, { 46 | token : "keyword.operator", 47 | regex : "EQ|LT|GT|NE|GE|LE|OR|XOR" 48 | }, { 49 | token : "paren.lparen", 50 | regex : "[\\[]" 51 | }, { 52 | token : "paren.rparen", 53 | regex : "[\\]]" 54 | }, { 55 | token : "text", 56 | regex : "\\s+" 57 | } ] 58 | }; 59 | }; 60 | 61 | oop.inherits(GcodeHighlightRules, TextHighlightRules); 62 | 63 | exports.GcodeHighlightRules = GcodeHighlightRules; 64 | }); 65 | 66 | ace.define("ace/mode/gcode",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/gcode_highlight_rules","ace/range"], function(require, exports, module) { 67 | "use strict"; 68 | 69 | var oop = require("../lib/oop"); 70 | var TextMode = require("./text").Mode; 71 | var GcodeHighlightRules = require("./gcode_highlight_rules").GcodeHighlightRules; 72 | var Range = require("../range").Range; 73 | 74 | var Mode = function() { 75 | this.HighlightRules = GcodeHighlightRules; 76 | this.$behaviour = this.$defaultBehaviour; 77 | }; 78 | oop.inherits(Mode, TextMode); 79 | 80 | (function() { 81 | this.$id = "ace/mode/gcode"; 82 | }).call(Mode.prototype); 83 | 84 | exports.Mode = Mode; 85 | 86 | }); (function() { 87 | ace.require(["ace/mode/gcode"], function(m) { 88 | if (typeof module == "object" && typeof exports == "object" && module) { 89 | module.exports = m; 90 | } 91 | }); 92 | })(); 93 | -------------------------------------------------------------------------------- /js/ace/theme-monokai.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/monokai",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-monokai"; 5 | exports.cssText = ".ace-monokai .ace_gutter {\ 6 | background: #2F3129;\ 7 | color: #8F908A\ 8 | }\ 9 | .ace-monokai .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #555651\ 12 | }\ 13 | .ace-monokai {\ 14 | background-color: #272822;\ 15 | color: #F8F8F2\ 16 | }\ 17 | .ace-monokai .ace_cursor {\ 18 | color: #F8F8F0\ 19 | }\ 20 | .ace-monokai .ace_marker-layer .ace_selection {\ 21 | background: #49483E\ 22 | }\ 23 | .ace-monokai.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #272822;\ 25 | }\ 26 | .ace-monokai .ace_marker-layer .ace_step {\ 27 | background: rgb(102, 82, 0)\ 28 | }\ 29 | .ace-monokai .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid #49483E\ 32 | }\ 33 | .ace-monokai .ace_marker-layer .ace_active-line {\ 34 | background: #202020\ 35 | }\ 36 | .ace-monokai .ace_gutter-active-line {\ 37 | background-color: #272727\ 38 | }\ 39 | .ace-monokai .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid #49483E\ 41 | }\ 42 | .ace-monokai .ace_invisible {\ 43 | color: #52524d\ 44 | }\ 45 | .ace-monokai .ace_entity.ace_name.ace_tag,\ 46 | .ace-monokai .ace_keyword,\ 47 | .ace-monokai .ace_meta.ace_tag,\ 48 | .ace-monokai .ace_storage {\ 49 | color: #F92672\ 50 | }\ 51 | .ace-monokai .ace_punctuation,\ 52 | .ace-monokai .ace_punctuation.ace_tag {\ 53 | color: #fff\ 54 | }\ 55 | .ace-monokai .ace_constant.ace_character,\ 56 | .ace-monokai .ace_constant.ace_language,\ 57 | .ace-monokai .ace_constant.ace_numeric,\ 58 | .ace-monokai .ace_constant.ace_other {\ 59 | color: #AE81FF\ 60 | }\ 61 | .ace-monokai .ace_invalid {\ 62 | color: #F8F8F0;\ 63 | background-color: #F92672\ 64 | }\ 65 | .ace-monokai .ace_invalid.ace_deprecated {\ 66 | color: #F8F8F0;\ 67 | background-color: #AE81FF\ 68 | }\ 69 | .ace-monokai .ace_support.ace_constant,\ 70 | .ace-monokai .ace_support.ace_function {\ 71 | color: #66D9EF\ 72 | }\ 73 | .ace-monokai .ace_fold {\ 74 | background-color: #A6E22E;\ 75 | border-color: #F8F8F2\ 76 | }\ 77 | .ace-monokai .ace_storage.ace_type,\ 78 | .ace-monokai .ace_support.ace_class,\ 79 | .ace-monokai .ace_support.ace_type {\ 80 | font-style: italic;\ 81 | color: #66D9EF\ 82 | }\ 83 | .ace-monokai .ace_entity.ace_name.ace_function,\ 84 | .ace-monokai .ace_entity.ace_other,\ 85 | .ace-monokai .ace_entity.ace_other.ace_attribute-name,\ 86 | .ace-monokai .ace_variable {\ 87 | color: #A6E22E\ 88 | }\ 89 | .ace-monokai .ace_variable.ace_parameter {\ 90 | font-style: italic;\ 91 | color: #FD971F\ 92 | }\ 93 | .ace-monokai .ace_string {\ 94 | color: #E6DB74\ 95 | }\ 96 | .ace-monokai .ace_comment {\ 97 | color: #75715E\ 98 | }\ 99 | .ace-monokai .ace_indent-guide {\ 100 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ0FD0ZXBzd/wPAAjVAoxeSgNeAAAAAElFTkSuQmCC) right repeat-y\ 101 | }"; 102 | 103 | var dom = require("../lib/dom"); 104 | dom.importCssString(exports.cssText, exports.cssClass); 105 | }); (function() { 106 | ace.require(["ace/theme/monokai"], function(m) { 107 | if (typeof module == "object" && typeof exports == "object" && module) { 108 | module.exports = m; 109 | } 110 | }); 111 | })(); 112 | -------------------------------------------------------------------------------- /js/ace/theme-clouds_midnight.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/clouds_midnight",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-clouds-midnight"; 5 | exports.cssText = ".ace-clouds-midnight .ace_gutter {\ 6 | background: #232323;\ 7 | color: #929292\ 8 | }\ 9 | .ace-clouds-midnight .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #232323\ 12 | }\ 13 | .ace-clouds-midnight {\ 14 | background-color: #191919;\ 15 | color: #929292\ 16 | }\ 17 | .ace-clouds-midnight .ace_cursor {\ 18 | color: #7DA5DC\ 19 | }\ 20 | .ace-clouds-midnight .ace_marker-layer .ace_selection {\ 21 | background: #000000\ 22 | }\ 23 | .ace-clouds-midnight.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #191919;\ 25 | }\ 26 | .ace-clouds-midnight .ace_marker-layer .ace_step {\ 27 | background: rgb(102, 82, 0)\ 28 | }\ 29 | .ace-clouds-midnight .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid #BFBFBF\ 32 | }\ 33 | .ace-clouds-midnight .ace_marker-layer .ace_active-line {\ 34 | background: rgba(215, 215, 215, 0.031)\ 35 | }\ 36 | .ace-clouds-midnight .ace_gutter-active-line {\ 37 | background-color: rgba(215, 215, 215, 0.031)\ 38 | }\ 39 | .ace-clouds-midnight .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid #000000\ 41 | }\ 42 | .ace-clouds-midnight .ace_invisible {\ 43 | color: #666\ 44 | }\ 45 | .ace-clouds-midnight .ace_keyword,\ 46 | .ace-clouds-midnight .ace_meta,\ 47 | .ace-clouds-midnight .ace_support.ace_constant.ace_property-value {\ 48 | color: #927C5D\ 49 | }\ 50 | .ace-clouds-midnight .ace_keyword.ace_operator {\ 51 | color: #4B4B4B\ 52 | }\ 53 | .ace-clouds-midnight .ace_keyword.ace_other.ace_unit {\ 54 | color: #366F1A\ 55 | }\ 56 | .ace-clouds-midnight .ace_constant.ace_language {\ 57 | color: #39946A\ 58 | }\ 59 | .ace-clouds-midnight .ace_constant.ace_numeric {\ 60 | color: #46A609\ 61 | }\ 62 | .ace-clouds-midnight .ace_constant.ace_character.ace_entity {\ 63 | color: #A165AC\ 64 | }\ 65 | .ace-clouds-midnight .ace_invalid {\ 66 | color: #FFFFFF;\ 67 | background-color: #E92E2E\ 68 | }\ 69 | .ace-clouds-midnight .ace_fold {\ 70 | background-color: #927C5D;\ 71 | border-color: #929292\ 72 | }\ 73 | .ace-clouds-midnight .ace_storage,\ 74 | .ace-clouds-midnight .ace_support.ace_class,\ 75 | .ace-clouds-midnight .ace_support.ace_function,\ 76 | .ace-clouds-midnight .ace_support.ace_other,\ 77 | .ace-clouds-midnight .ace_support.ace_type {\ 78 | color: #E92E2E\ 79 | }\ 80 | .ace-clouds-midnight .ace_string {\ 81 | color: #5D90CD\ 82 | }\ 83 | .ace-clouds-midnight .ace_comment {\ 84 | color: #3C403B\ 85 | }\ 86 | .ace-clouds-midnight .ace_entity.ace_name.ace_tag,\ 87 | .ace-clouds-midnight .ace_entity.ace_other.ace_attribute-name {\ 88 | color: #606060\ 89 | }\ 90 | .ace-clouds-midnight .ace_indent-guide {\ 91 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y\ 92 | }"; 93 | 94 | var dom = require("../lib/dom"); 95 | dom.importCssString(exports.cssText, exports.cssClass); 96 | }); (function() { 97 | ace.require(["ace/theme/clouds_midnight"], function(m) { 98 | if (typeof module == "object" && typeof exports == "object" && module) { 99 | module.exports = m; 100 | } 101 | }); 102 | })(); 103 | -------------------------------------------------------------------------------- /js/ace/theme-merbivore_soft.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/merbivore_soft",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-merbivore-soft"; 5 | exports.cssText = ".ace-merbivore-soft .ace_gutter {\ 6 | background: #262424;\ 7 | color: #E6E1DC\ 8 | }\ 9 | .ace-merbivore-soft .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #262424\ 12 | }\ 13 | .ace-merbivore-soft {\ 14 | background-color: #1C1C1C;\ 15 | color: #E6E1DC\ 16 | }\ 17 | .ace-merbivore-soft .ace_cursor {\ 18 | color: #FFFFFF\ 19 | }\ 20 | .ace-merbivore-soft .ace_marker-layer .ace_selection {\ 21 | background: #494949\ 22 | }\ 23 | .ace-merbivore-soft.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #1C1C1C;\ 25 | }\ 26 | .ace-merbivore-soft .ace_marker-layer .ace_step {\ 27 | background: rgb(102, 82, 0)\ 28 | }\ 29 | .ace-merbivore-soft .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid #404040\ 32 | }\ 33 | .ace-merbivore-soft .ace_marker-layer .ace_active-line {\ 34 | background: #333435\ 35 | }\ 36 | .ace-merbivore-soft .ace_gutter-active-line {\ 37 | background-color: #333435\ 38 | }\ 39 | .ace-merbivore-soft .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid #494949\ 41 | }\ 42 | .ace-merbivore-soft .ace_invisible {\ 43 | color: #404040\ 44 | }\ 45 | .ace-merbivore-soft .ace_entity.ace_name.ace_tag,\ 46 | .ace-merbivore-soft .ace_keyword,\ 47 | .ace-merbivore-soft .ace_meta,\ 48 | .ace-merbivore-soft .ace_meta.ace_tag,\ 49 | .ace-merbivore-soft .ace_storage {\ 50 | color: #FC803A\ 51 | }\ 52 | .ace-merbivore-soft .ace_constant,\ 53 | .ace-merbivore-soft .ace_constant.ace_character,\ 54 | .ace-merbivore-soft .ace_constant.ace_character.ace_escape,\ 55 | .ace-merbivore-soft .ace_constant.ace_other,\ 56 | .ace-merbivore-soft .ace_support.ace_type {\ 57 | color: #68C1D8\ 58 | }\ 59 | .ace-merbivore-soft .ace_constant.ace_character.ace_escape {\ 60 | color: #B3E5B4\ 61 | }\ 62 | .ace-merbivore-soft .ace_constant.ace_language {\ 63 | color: #E1C582\ 64 | }\ 65 | .ace-merbivore-soft .ace_constant.ace_library,\ 66 | .ace-merbivore-soft .ace_string,\ 67 | .ace-merbivore-soft .ace_support.ace_constant {\ 68 | color: #8EC65F\ 69 | }\ 70 | .ace-merbivore-soft .ace_constant.ace_numeric {\ 71 | color: #7FC578\ 72 | }\ 73 | .ace-merbivore-soft .ace_invalid,\ 74 | .ace-merbivore-soft .ace_invalid.ace_deprecated {\ 75 | color: #FFFFFF;\ 76 | background-color: #FE3838\ 77 | }\ 78 | .ace-merbivore-soft .ace_fold {\ 79 | background-color: #FC803A;\ 80 | border-color: #E6E1DC\ 81 | }\ 82 | .ace-merbivore-soft .ace_comment,\ 83 | .ace-merbivore-soft .ace_meta {\ 84 | font-style: italic;\ 85 | color: #AC4BB8\ 86 | }\ 87 | .ace-merbivore-soft .ace_entity.ace_other.ace_attribute-name {\ 88 | color: #EAF1A3\ 89 | }\ 90 | .ace-merbivore-soft .ace_indent-guide {\ 91 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWOQkpLyZfD09PwPAAfYAnaStpHRAAAAAElFTkSuQmCC) right repeat-y\ 92 | }"; 93 | 94 | var dom = require("../lib/dom"); 95 | dom.importCssString(exports.cssText, exports.cssClass); 96 | }); (function() { 97 | ace.require(["ace/theme/merbivore_soft"], function(m) { 98 | if (typeof module == "object" && typeof exports == "object" && module) { 99 | module.exports = m; 100 | } 101 | }); 102 | })(); 103 | -------------------------------------------------------------------------------- /js/command.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "util/text!config/commands.json" 3 | ], function(list) { 4 | 5 | try { 6 | list = JSON.parse(list); 7 | } catch (e) { 8 | console.error(e); 9 | list = []; 10 | } 11 | 12 | /* 13 | 14 | The command module is the heart of Caret's loosely-coupled modules. It 15 | serves as an event bus for inter-module communication, but it also listens 16 | to the DOM for click/change events and makes it easy to bind page interactions 17 | to command callbacks. 18 | 19 | Command is usually called as if synchronous, but it does support asynchronous 20 | operation--it will pass a callback in to any subscribers, but will also 21 | immediately pass back the return value (if any) from the those subscribers. 22 | 23 | */ 24 | 25 | var commands = {}; 26 | var broadcast = []; 27 | 28 | //commands can pass a callback, although most don't respond that way 29 | var fire = async function(command, argument, callback = function() {}) { 30 | if (!commands[command]) return broadcast.forEach(f => f.apply(null, arguments)); 31 | var registry = commands[command].slice(); 32 | for (var entry of registry) { 33 | var result = await entry.callback(argument); 34 | //immediately call back if sync-style return value was provided 35 | if (typeof result !== "undefined" || entry.sync) { 36 | //console.info("Immediate return from " + name, result); 37 | callback.call(null, result); 38 | } 39 | }; 40 | }; 41 | 42 | var register = function(command, listener, sync) { 43 | if (command == "*") { 44 | return broadcast.push(listener); 45 | } 46 | if (!commands[command]) { 47 | commands[command] = []; 48 | } 49 | //we allow a sync flag to be set for operations that will definitely return 50 | commands[command].push({ 51 | callback: listener, 52 | sync: sync 53 | }); 54 | }; 55 | 56 | //delegate for all elements that have a command attribute 57 | document.body.addEventListener("click", function(e) { 58 | //cancel on inputs, selectboxes 59 | if (["input", "select"].indexOf(e.target.tagName.toLowerCase()) >= 0) return; 60 | if (e.button != 0) return; 61 | //delegate all items with a command attribute 62 | if (e.target.hasAttribute("command")) { 63 | var command = e.target.getAttribute("command"); 64 | var arg = e.target.getAttribute("argument"); 65 | fire(command, arg); 66 | e.preventDefault(); 67 | } 68 | }); 69 | 70 | document.body.addEventListener("change", function(e) { 71 | if (e.target.hasAttribute("command")) { 72 | var command = e.target.getAttribute("command"); 73 | var arg = e.target.value; 74 | fire(command, arg); 75 | } 76 | }); 77 | 78 | //handle command events directly dispatched via DOM 79 | document.body.addEventListener("caret-command", function(e) { 80 | if (!e.detail || !e.detail.command) return; 81 | fire(e.detail.command, e.detail.argument); 82 | }); 83 | 84 | //register for post-startup and fire any commands that are pending 85 | register("init:complete", function() { 86 | if (window.launchCommands) { 87 | window.launchCommands.forEach(bundle => fire(bundle.message.command, bundle.message.argument, bundle.sendResponse)); 88 | delete window.launchCommands; 89 | } 90 | }); 91 | 92 | var facade = { 93 | fire, 94 | list, 95 | on: register 96 | }; 97 | 98 | return facade; 99 | 100 | }); -------------------------------------------------------------------------------- /js/ace/theme-cobalt.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/cobalt",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-cobalt"; 5 | exports.cssText = ".ace-cobalt .ace_gutter {\ 6 | background: #011e3a;\ 7 | color: rgb(128,145,160)\ 8 | }\ 9 | .ace-cobalt .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #555555\ 12 | }\ 13 | .ace-cobalt {\ 14 | background-color: #002240;\ 15 | color: #FFFFFF\ 16 | }\ 17 | .ace-cobalt .ace_cursor {\ 18 | color: #FFFFFF\ 19 | }\ 20 | .ace-cobalt .ace_marker-layer .ace_selection {\ 21 | background: rgba(179, 101, 57, 0.75)\ 22 | }\ 23 | .ace-cobalt.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #002240;\ 25 | }\ 26 | .ace-cobalt .ace_marker-layer .ace_step {\ 27 | background: rgb(127, 111, 19)\ 28 | }\ 29 | .ace-cobalt .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid rgba(255, 255, 255, 0.15)\ 32 | }\ 33 | .ace-cobalt .ace_marker-layer .ace_active-line {\ 34 | background: rgba(0, 0, 0, 0.35)\ 35 | }\ 36 | .ace-cobalt .ace_gutter-active-line {\ 37 | background-color: rgba(0, 0, 0, 0.35)\ 38 | }\ 39 | .ace-cobalt .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid rgba(179, 101, 57, 0.75)\ 41 | }\ 42 | .ace-cobalt .ace_invisible {\ 43 | color: rgba(255, 255, 255, 0.15)\ 44 | }\ 45 | .ace-cobalt .ace_keyword,\ 46 | .ace-cobalt .ace_meta {\ 47 | color: #FF9D00\ 48 | }\ 49 | .ace-cobalt .ace_constant,\ 50 | .ace-cobalt .ace_constant.ace_character,\ 51 | .ace-cobalt .ace_constant.ace_character.ace_escape,\ 52 | .ace-cobalt .ace_constant.ace_other {\ 53 | color: #FF628C\ 54 | }\ 55 | .ace-cobalt .ace_invalid {\ 56 | color: #F8F8F8;\ 57 | background-color: #800F00\ 58 | }\ 59 | .ace-cobalt .ace_support {\ 60 | color: #80FFBB\ 61 | }\ 62 | .ace-cobalt .ace_support.ace_constant {\ 63 | color: #EB939A\ 64 | }\ 65 | .ace-cobalt .ace_fold {\ 66 | background-color: #FF9D00;\ 67 | border-color: #FFFFFF\ 68 | }\ 69 | .ace-cobalt .ace_support.ace_function {\ 70 | color: #FFB054\ 71 | }\ 72 | .ace-cobalt .ace_storage {\ 73 | color: #FFEE80\ 74 | }\ 75 | .ace-cobalt .ace_entity {\ 76 | color: #FFDD00\ 77 | }\ 78 | .ace-cobalt .ace_string {\ 79 | color: #3AD900\ 80 | }\ 81 | .ace-cobalt .ace_string.ace_regexp {\ 82 | color: #80FFC2\ 83 | }\ 84 | .ace-cobalt .ace_comment {\ 85 | font-style: italic;\ 86 | color: #0088FF\ 87 | }\ 88 | .ace-cobalt .ace_heading,\ 89 | .ace-cobalt .ace_markup.ace_heading {\ 90 | color: #C8E4FD;\ 91 | background-color: #001221\ 92 | }\ 93 | .ace-cobalt .ace_list,\ 94 | .ace-cobalt .ace_markup.ace_list {\ 95 | background-color: #130D26\ 96 | }\ 97 | .ace-cobalt .ace_variable {\ 98 | color: #CCCCCC\ 99 | }\ 100 | .ace-cobalt .ace_variable.ace_language {\ 101 | color: #FF80E1\ 102 | }\ 103 | .ace-cobalt .ace_meta.ace_tag {\ 104 | color: #9EFFFF\ 105 | }\ 106 | .ace-cobalt .ace_indent-guide {\ 107 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHCLSvkPAAP3AgSDTRd4AAAAAElFTkSuQmCC) right repeat-y\ 108 | }\ 109 | "; 110 | 111 | var dom = require("../lib/dom"); 112 | dom.importCssString(exports.cssText, exports.cssClass); 113 | }); (function() { 114 | ace.require(["ace/theme/cobalt"], function(m) { 115 | if (typeof module == "object" && typeof exports == "object" && module) { 116 | module.exports = m; 117 | } 118 | }); 119 | })(); 120 | -------------------------------------------------------------------------------- /js/ace/theme-gob.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/gob",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-gob"; 5 | exports.cssText = ".ace-gob .ace_gutter {\ 6 | background: #0B1818;\ 7 | color: #03EE03\ 8 | }\ 9 | .ace-gob .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #131313\ 12 | }\ 13 | .ace-gob {\ 14 | background-color: #0B0B0B;\ 15 | color: #00FF00\ 16 | }\ 17 | .ace-gob .ace_cursor {\ 18 | border-color: rgba(16, 248, 255, 0.90);\ 19 | background-color: rgba(16, 240, 248, 0.70);\ 20 | opacity: 0.4;\ 21 | }\ 22 | .ace-gob .ace_marker-layer .ace_selection {\ 23 | background: rgba(221, 240, 255, 0.20)\ 24 | }\ 25 | .ace-gob.ace_multiselect .ace_selection.ace_start {\ 26 | box-shadow: 0 0 3px 0px #141414;\ 27 | }\ 28 | .ace-gob .ace_marker-layer .ace_step {\ 29 | background: rgb(16, 128, 0)\ 30 | }\ 31 | .ace-gob .ace_marker-layer .ace_bracket {\ 32 | margin: -1px 0 0 -1px;\ 33 | border: 1px solid rgba(64, 255, 255, 0.25)\ 34 | }\ 35 | .ace-gob .ace_marker-layer .ace_active-line {\ 36 | background: rgba(255, 255, 255, 0.04)\ 37 | }\ 38 | .ace-gob .ace_gutter-active-line {\ 39 | background-color: rgba(255, 255, 255, 0.04)\ 40 | }\ 41 | .ace-gob .ace_marker-layer .ace_selected-word {\ 42 | border: 1px solid rgba(192, 240, 255, 0.20)\ 43 | }\ 44 | .ace-gob .ace_invisible {\ 45 | color: rgba(255, 255, 255, 0.25)\ 46 | }\ 47 | .ace-gob .ace_keyword,\ 48 | .ace-gob .ace_meta {\ 49 | color: #10D8E8\ 50 | }\ 51 | .ace-gob .ace_constant,\ 52 | .ace-gob .ace_constant.ace_character,\ 53 | .ace-gob .ace_constant.ace_character.ace_escape,\ 54 | .ace-gob .ace_constant.ace_other,\ 55 | .ace-gob .ace_heading,\ 56 | .ace-gob .ace_markup.ace_heading,\ 57 | .ace-gob .ace_support.ace_constant {\ 58 | color: #10F0A0\ 59 | }\ 60 | .ace-gob .ace_invalid.ace_illegal {\ 61 | color: #F8F8F8;\ 62 | background-color: rgba(86, 45, 86, 0.75)\ 63 | }\ 64 | .ace-gob .ace_invalid.ace_deprecated {\ 65 | text-decoration: underline;\ 66 | font-style: italic;\ 67 | color: #20F8C0\ 68 | }\ 69 | .ace-gob .ace_support {\ 70 | color: #20E8B0\ 71 | }\ 72 | .ace-gob .ace_fold {\ 73 | background-color: #50B8B8;\ 74 | border-color: #70F8F8\ 75 | }\ 76 | .ace-gob .ace_support.ace_function {\ 77 | color: #00F800\ 78 | }\ 79 | .ace-gob .ace_list,\ 80 | .ace-gob .ace_markup.ace_list,\ 81 | .ace-gob .ace_storage {\ 82 | color: #10FF98\ 83 | }\ 84 | .ace-gob .ace_entity.ace_name.ace_function,\ 85 | .ace-gob .ace_meta.ace_tag,\ 86 | .ace-gob .ace_variable {\ 87 | color: #00F868\ 88 | }\ 89 | .ace-gob .ace_string {\ 90 | color: #10F060\ 91 | }\ 92 | .ace-gob .ace_string.ace_regexp {\ 93 | color: #20F090;\ 94 | }\ 95 | .ace-gob .ace_comment {\ 96 | font-style: italic;\ 97 | color: #00E060;\ 98 | }\ 99 | .ace-gob .ace_variable {\ 100 | color: #00F888;\ 101 | }\ 102 | .ace-gob .ace_xml-pe {\ 103 | color: #488858;\ 104 | }\ 105 | .ace-gob .ace_indent-guide {\ 106 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQERFpYLC1tf0PAAgOAnPnhxyiAAAAAElFTkSuQmCC) right repeat-y\ 107 | }\ 108 | "; 109 | 110 | var dom = require("../lib/dom"); 111 | dom.importCssString(exports.cssText, exports.cssClass); 112 | }); (function() { 113 | ace.require(["ace/theme/gob"], function(m) { 114 | if (typeof module == "object" && typeof exports == "object" && module) { 115 | module.exports = m; 116 | } 117 | }); 118 | })(); 119 | -------------------------------------------------------------------------------- /js/ace/theme-twilight.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/twilight",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-twilight"; 5 | exports.cssText = ".ace-twilight .ace_gutter {\ 6 | background: #232323;\ 7 | color: #E2E2E2\ 8 | }\ 9 | .ace-twilight .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #232323\ 12 | }\ 13 | .ace-twilight {\ 14 | background-color: #141414;\ 15 | color: #F8F8F8\ 16 | }\ 17 | .ace-twilight .ace_cursor {\ 18 | color: #A7A7A7\ 19 | }\ 20 | .ace-twilight .ace_marker-layer .ace_selection {\ 21 | background: rgba(221, 240, 255, 0.20)\ 22 | }\ 23 | .ace-twilight.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #141414;\ 25 | }\ 26 | .ace-twilight .ace_marker-layer .ace_step {\ 27 | background: rgb(102, 82, 0)\ 28 | }\ 29 | .ace-twilight .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid rgba(255, 255, 255, 0.25)\ 32 | }\ 33 | .ace-twilight .ace_marker-layer .ace_active-line {\ 34 | background: rgba(255, 255, 255, 0.031)\ 35 | }\ 36 | .ace-twilight .ace_gutter-active-line {\ 37 | background-color: rgba(255, 255, 255, 0.031)\ 38 | }\ 39 | .ace-twilight .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid rgba(221, 240, 255, 0.20)\ 41 | }\ 42 | .ace-twilight .ace_invisible {\ 43 | color: rgba(255, 255, 255, 0.25)\ 44 | }\ 45 | .ace-twilight .ace_keyword,\ 46 | .ace-twilight .ace_meta {\ 47 | color: #CDA869\ 48 | }\ 49 | .ace-twilight .ace_constant,\ 50 | .ace-twilight .ace_constant.ace_character,\ 51 | .ace-twilight .ace_constant.ace_character.ace_escape,\ 52 | .ace-twilight .ace_constant.ace_other,\ 53 | .ace-twilight .ace_heading,\ 54 | .ace-twilight .ace_markup.ace_heading,\ 55 | .ace-twilight .ace_support.ace_constant {\ 56 | color: #CF6A4C\ 57 | }\ 58 | .ace-twilight .ace_invalid.ace_illegal {\ 59 | color: #F8F8F8;\ 60 | background-color: rgba(86, 45, 86, 0.75)\ 61 | }\ 62 | .ace-twilight .ace_invalid.ace_deprecated {\ 63 | text-decoration: underline;\ 64 | font-style: italic;\ 65 | color: #D2A8A1\ 66 | }\ 67 | .ace-twilight .ace_support {\ 68 | color: #9B859D\ 69 | }\ 70 | .ace-twilight .ace_fold {\ 71 | background-color: #AC885B;\ 72 | border-color: #F8F8F8\ 73 | }\ 74 | .ace-twilight .ace_support.ace_function {\ 75 | color: #DAD085\ 76 | }\ 77 | .ace-twilight .ace_list,\ 78 | .ace-twilight .ace_markup.ace_list,\ 79 | .ace-twilight .ace_storage {\ 80 | color: #F9EE98\ 81 | }\ 82 | .ace-twilight .ace_entity.ace_name.ace_function,\ 83 | .ace-twilight .ace_meta.ace_tag,\ 84 | .ace-twilight .ace_variable {\ 85 | color: #AC885B\ 86 | }\ 87 | .ace-twilight .ace_string {\ 88 | color: #8F9D6A\ 89 | }\ 90 | .ace-twilight .ace_string.ace_regexp {\ 91 | color: #E9C062\ 92 | }\ 93 | .ace-twilight .ace_comment {\ 94 | font-style: italic;\ 95 | color: #5F5A60\ 96 | }\ 97 | .ace-twilight .ace_variable {\ 98 | color: #7587A6\ 99 | }\ 100 | .ace-twilight .ace_xml-pe {\ 101 | color: #494949\ 102 | }\ 103 | .ace-twilight .ace_indent-guide {\ 104 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQERFpYLC1tf0PAAgOAnPnhxyiAAAAAElFTkSuQmCC) right repeat-y\ 105 | }"; 106 | 107 | var dom = require("../lib/dom"); 108 | dom.importCssString(exports.cssText, exports.cssClass); 109 | }); (function() { 110 | ace.require(["ace/theme/twilight"], function(m) { 111 | if (typeof module == "object" && typeof exports == "object" && module) { 112 | module.exports = m; 113 | } 114 | }); 115 | })(); 116 | -------------------------------------------------------------------------------- /js/ace/theme-tomorrow.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/tomorrow",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = false; 4 | exports.cssClass = "ace-tomorrow"; 5 | exports.cssText = ".ace-tomorrow .ace_gutter {\ 6 | background: #f6f6f6;\ 7 | color: #4D4D4C\ 8 | }\ 9 | .ace-tomorrow .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #f6f6f6\ 12 | }\ 13 | .ace-tomorrow {\ 14 | background-color: #FFFFFF;\ 15 | color: #4D4D4C\ 16 | }\ 17 | .ace-tomorrow .ace_cursor {\ 18 | color: #AEAFAD\ 19 | }\ 20 | .ace-tomorrow .ace_marker-layer .ace_selection {\ 21 | background: #D6D6D6\ 22 | }\ 23 | .ace-tomorrow.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #FFFFFF;\ 25 | }\ 26 | .ace-tomorrow .ace_marker-layer .ace_step {\ 27 | background: rgb(255, 255, 0)\ 28 | }\ 29 | .ace-tomorrow .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid #D1D1D1\ 32 | }\ 33 | .ace-tomorrow .ace_marker-layer .ace_active-line {\ 34 | background: #EFEFEF\ 35 | }\ 36 | .ace-tomorrow .ace_gutter-active-line {\ 37 | background-color : #dcdcdc\ 38 | }\ 39 | .ace-tomorrow .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid #D6D6D6\ 41 | }\ 42 | .ace-tomorrow .ace_invisible {\ 43 | color: #D1D1D1\ 44 | }\ 45 | .ace-tomorrow .ace_keyword,\ 46 | .ace-tomorrow .ace_meta,\ 47 | .ace-tomorrow .ace_storage,\ 48 | .ace-tomorrow .ace_storage.ace_type,\ 49 | .ace-tomorrow .ace_support.ace_type {\ 50 | color: #8959A8\ 51 | }\ 52 | .ace-tomorrow .ace_keyword.ace_operator {\ 53 | color: #3E999F\ 54 | }\ 55 | .ace-tomorrow .ace_constant.ace_character,\ 56 | .ace-tomorrow .ace_constant.ace_language,\ 57 | .ace-tomorrow .ace_constant.ace_numeric,\ 58 | .ace-tomorrow .ace_keyword.ace_other.ace_unit,\ 59 | .ace-tomorrow .ace_support.ace_constant,\ 60 | .ace-tomorrow .ace_variable.ace_parameter {\ 61 | color: #F5871F\ 62 | }\ 63 | .ace-tomorrow .ace_constant.ace_other {\ 64 | color: #666969\ 65 | }\ 66 | .ace-tomorrow .ace_invalid {\ 67 | color: #FFFFFF;\ 68 | background-color: #C82829\ 69 | }\ 70 | .ace-tomorrow .ace_invalid.ace_deprecated {\ 71 | color: #FFFFFF;\ 72 | background-color: #8959A8\ 73 | }\ 74 | .ace-tomorrow .ace_fold {\ 75 | background-color: #4271AE;\ 76 | border-color: #4D4D4C\ 77 | }\ 78 | .ace-tomorrow .ace_entity.ace_name.ace_function,\ 79 | .ace-tomorrow .ace_support.ace_function,\ 80 | .ace-tomorrow .ace_variable {\ 81 | color: #4271AE\ 82 | }\ 83 | .ace-tomorrow .ace_support.ace_class,\ 84 | .ace-tomorrow .ace_support.ace_type {\ 85 | color: #C99E00\ 86 | }\ 87 | .ace-tomorrow .ace_heading,\ 88 | .ace-tomorrow .ace_markup.ace_heading,\ 89 | .ace-tomorrow .ace_string {\ 90 | color: #718C00\ 91 | }\ 92 | .ace-tomorrow .ace_entity.ace_name.ace_tag,\ 93 | .ace-tomorrow .ace_entity.ace_other.ace_attribute-name,\ 94 | .ace-tomorrow .ace_meta.ace_tag,\ 95 | .ace-tomorrow .ace_string.ace_regexp,\ 96 | .ace-tomorrow .ace_variable {\ 97 | color: #C82829\ 98 | }\ 99 | .ace-tomorrow .ace_comment {\ 100 | color: #8E908C\ 101 | }\ 102 | .ace-tomorrow .ace_indent-guide {\ 103 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bdu3f/BwAlfgctduB85QAAAABJRU5ErkJggg==) right repeat-y\ 104 | }"; 105 | 106 | var dom = require("../lib/dom"); 107 | dom.importCssString(exports.cssText, exports.cssClass); 108 | }); (function() { 109 | ace.require(["ace/theme/tomorrow"], function(m) { 110 | if (typeof module == "object" && typeof exports == "object" && module) { 111 | module.exports = m; 112 | } 113 | }); 114 | })(); 115 | -------------------------------------------------------------------------------- /js/ace/theme-pastel_on_dark.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/pastel_on_dark",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-pastel-on-dark"; 5 | exports.cssText = ".ace-pastel-on-dark .ace_gutter {\ 6 | background: #353030;\ 7 | color: #8F938F\ 8 | }\ 9 | .ace-pastel-on-dark .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #353030\ 12 | }\ 13 | .ace-pastel-on-dark {\ 14 | background-color: #2C2828;\ 15 | color: #8F938F\ 16 | }\ 17 | .ace-pastel-on-dark .ace_cursor {\ 18 | color: #A7A7A7\ 19 | }\ 20 | .ace-pastel-on-dark .ace_marker-layer .ace_selection {\ 21 | background: rgba(221, 240, 255, 0.20)\ 22 | }\ 23 | .ace-pastel-on-dark.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #2C2828;\ 25 | }\ 26 | .ace-pastel-on-dark .ace_marker-layer .ace_step {\ 27 | background: rgb(102, 82, 0)\ 28 | }\ 29 | .ace-pastel-on-dark .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid rgba(255, 255, 255, 0.25)\ 32 | }\ 33 | .ace-pastel-on-dark .ace_marker-layer .ace_active-line {\ 34 | background: rgba(255, 255, 255, 0.031)\ 35 | }\ 36 | .ace-pastel-on-dark .ace_gutter-active-line {\ 37 | background-color: rgba(255, 255, 255, 0.031)\ 38 | }\ 39 | .ace-pastel-on-dark .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid rgba(221, 240, 255, 0.20)\ 41 | }\ 42 | .ace-pastel-on-dark .ace_invisible {\ 43 | color: rgba(255, 255, 255, 0.25)\ 44 | }\ 45 | .ace-pastel-on-dark .ace_keyword,\ 46 | .ace-pastel-on-dark .ace_meta {\ 47 | color: #757aD8\ 48 | }\ 49 | .ace-pastel-on-dark .ace_constant,\ 50 | .ace-pastel-on-dark .ace_constant.ace_character,\ 51 | .ace-pastel-on-dark .ace_constant.ace_character.ace_escape,\ 52 | .ace-pastel-on-dark .ace_constant.ace_other {\ 53 | color: #4FB7C5\ 54 | }\ 55 | .ace-pastel-on-dark .ace_keyword.ace_operator {\ 56 | color: #797878\ 57 | }\ 58 | .ace-pastel-on-dark .ace_constant.ace_character {\ 59 | color: #AFA472\ 60 | }\ 61 | .ace-pastel-on-dark .ace_constant.ace_language {\ 62 | color: #DE8E30\ 63 | }\ 64 | .ace-pastel-on-dark .ace_constant.ace_numeric {\ 65 | color: #CCCCCC\ 66 | }\ 67 | .ace-pastel-on-dark .ace_invalid,\ 68 | .ace-pastel-on-dark .ace_invalid.ace_illegal {\ 69 | color: #F8F8F8;\ 70 | background-color: rgba(86, 45, 86, 0.75)\ 71 | }\ 72 | .ace-pastel-on-dark .ace_invalid.ace_deprecated {\ 73 | text-decoration: underline;\ 74 | font-style: italic;\ 75 | color: #D2A8A1\ 76 | }\ 77 | .ace-pastel-on-dark .ace_fold {\ 78 | background-color: #757aD8;\ 79 | border-color: #8F938F\ 80 | }\ 81 | .ace-pastel-on-dark .ace_support.ace_function {\ 82 | color: #AEB2F8\ 83 | }\ 84 | .ace-pastel-on-dark .ace_string {\ 85 | color: #66A968\ 86 | }\ 87 | .ace-pastel-on-dark .ace_string.ace_regexp {\ 88 | color: #E9C062\ 89 | }\ 90 | .ace-pastel-on-dark .ace_comment {\ 91 | color: #A6C6FF\ 92 | }\ 93 | .ace-pastel-on-dark .ace_variable {\ 94 | color: #BEBF55\ 95 | }\ 96 | .ace-pastel-on-dark .ace_variable.ace_language {\ 97 | color: #C1C144\ 98 | }\ 99 | .ace-pastel-on-dark .ace_xml-pe {\ 100 | color: #494949\ 101 | }\ 102 | .ace-pastel-on-dark .ace_indent-guide {\ 103 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYIiPj/8PAARgAh2NTMh8AAAAAElFTkSuQmCC) right repeat-y\ 104 | }"; 105 | 106 | var dom = require("../lib/dom"); 107 | dom.importCssString(exports.cssText, exports.cssClass); 108 | }); (function() { 109 | ace.require(["ace/theme/pastel_on_dark"], function(m) { 110 | if (typeof module == "object" && typeof exports == "object" && module) { 111 | module.exports = m; 112 | } 113 | }); 114 | })(); 115 | -------------------------------------------------------------------------------- /js/ace/theme-dracula.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/dracula",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-dracula"; 5 | exports.cssText = "\ 6 | .ace-dracula .ace_gutter {\ 7 | background: #282a36;\ 8 | color: rgb(144,145,148)\ 9 | }\ 10 | .ace-dracula .ace_print-margin {\ 11 | width: 1px;\ 12 | background: #44475a\ 13 | }\ 14 | .ace-dracula {\ 15 | background-color: #282a36;\ 16 | color: #f8f8f2\ 17 | }\ 18 | .ace-dracula .ace_cursor {\ 19 | color: #f8f8f0\ 20 | }\ 21 | .ace-dracula .ace_marker-layer .ace_selection {\ 22 | background: #44475a\ 23 | }\ 24 | .ace-dracula.ace_multiselect .ace_selection.ace_start {\ 25 | box-shadow: 0 0 3px 0px #282a36;\ 26 | border-radius: 2px\ 27 | }\ 28 | .ace-dracula .ace_marker-layer .ace_step {\ 29 | background: rgb(198, 219, 174)\ 30 | }\ 31 | .ace-dracula .ace_marker-layer .ace_bracket {\ 32 | margin: -1px 0 0 -1px;\ 33 | border: 1px solid #a29709\ 34 | }\ 35 | .ace-dracula .ace_marker-layer .ace_active-line {\ 36 | background: #44475a\ 37 | }\ 38 | .ace-dracula .ace_gutter-active-line {\ 39 | background-color: #44475a\ 40 | }\ 41 | .ace-dracula .ace_marker-layer .ace_selected-word {\ 42 | box-shadow: 0px 0px 0px 1px #a29709;\ 43 | border-radius: 3px;\ 44 | }\ 45 | .ace-dracula .ace_fold {\ 46 | background-color: #50fa7b;\ 47 | border-color: #f8f8f2\ 48 | }\ 49 | .ace-dracula .ace_keyword {\ 50 | color: #ff79c6\ 51 | }\ 52 | .ace-dracula .ace_constant.ace_language {\ 53 | color: #bd93f9\ 54 | }\ 55 | .ace-dracula .ace_constant.ace_numeric {\ 56 | color: #bd93f9\ 57 | }\ 58 | .ace-dracula .ace_constant.ace_character {\ 59 | color: #bd93f9\ 60 | }\ 61 | .ace-dracula .ace_constant.ace_character.ace_escape {\ 62 | color: #ff79c6\ 63 | }\ 64 | .ace-dracula .ace_constant.ace_other {\ 65 | color: #bd93f9\ 66 | }\ 67 | .ace-dracula .ace_support.ace_function {\ 68 | color: #8be9fd\ 69 | }\ 70 | .ace-dracula .ace_support.ace_constant {\ 71 | color: #6be5fd\ 72 | }\ 73 | .ace-dracula .ace_support.ace_class {\ 74 | font-style: italic;\ 75 | color: #66d9ef\ 76 | }\ 77 | .ace-dracula .ace_support.ace_type {\ 78 | font-style: italic;\ 79 | color: #66d9ef\ 80 | }\ 81 | .ace-dracula .ace_storage {\ 82 | color: #ff79c6\ 83 | }\ 84 | .ace-dracula .ace_storage.ace_type {\ 85 | font-style: italic;\ 86 | color: #8be9fd\ 87 | }\ 88 | .ace-dracula .ace_invalid {\ 89 | color: #F8F8F0;\ 90 | background-color: #ff79c6\ 91 | }\ 92 | .ace-dracula .ace_invalid.ace_deprecated {\ 93 | color: #F8F8F0;\ 94 | background-color: #bd93f9\ 95 | }\ 96 | .ace-dracula .ace_string {\ 97 | color: #f1fa8c\ 98 | }\ 99 | .ace-dracula .ace_comment {\ 100 | color: #6272a4\ 101 | }\ 102 | .ace-dracula .ace_variable {\ 103 | color: #50fa7b\ 104 | }\ 105 | .ace-dracula .ace_variable.ace_parameter {\ 106 | font-style: italic;\ 107 | color: #ffb86c\ 108 | }\ 109 | .ace-dracula .ace_entity.ace_other.ace_attribute-name {\ 110 | color: #50fa7b\ 111 | }\ 112 | .ace-dracula .ace_entity.ace_name.ace_function {\ 113 | color: #50fa7b\ 114 | }\ 115 | .ace-dracula .ace_entity.ace_name.ace_tag {\ 116 | color: #ff79c6\ 117 | }\ 118 | .ace-dracula .ace_invisible {\ 119 | color: #626680;\ 120 | }\ 121 | .ace-dracula .ace_indent-guide {\ 122 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y\ 123 | }"; 124 | exports.$selectionColorConflict = true; 125 | 126 | var dom = require("../lib/dom"); 127 | dom.importCssString(exports.cssText, exports.cssClass); 128 | }); (function() { 129 | ace.require(["ace/theme/dracula"], function(m) { 130 | if (typeof module == "object" && typeof exports == "object" && module) { 131 | module.exports = m; 132 | } 133 | }); 134 | })(); 135 | -------------------------------------------------------------------------------- /js/ace/mode-sql.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/sql_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { 2 | "use strict"; 3 | 4 | var oop = require("../lib/oop"); 5 | var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; 6 | 7 | var SqlHighlightRules = function() { 8 | 9 | var keywords = ( 10 | "select|insert|update|delete|from|where|and|or|group|by|order|limit|offset|having|as|case|" + 11 | "when|then|else|end|type|left|right|join|on|outer|desc|asc|union|create|table|primary|key|if|" + 12 | "foreign|not|references|default|null|inner|cross|natural|database|drop|grant" 13 | ); 14 | 15 | var builtinConstants = ( 16 | "true|false" 17 | ); 18 | 19 | var builtinFunctions = ( 20 | "avg|count|first|last|max|min|sum|ucase|lcase|mid|len|round|rank|now|format|" + 21 | "coalesce|ifnull|isnull|nvl" 22 | ); 23 | 24 | var dataTypes = ( 25 | "int|numeric|decimal|date|varchar|char|bigint|float|double|bit|binary|text|set|timestamp|" + 26 | "money|real|number|integer" 27 | ); 28 | 29 | var keywordMapper = this.createKeywordMapper({ 30 | "support.function": builtinFunctions, 31 | "keyword": keywords, 32 | "constant.language": builtinConstants, 33 | "storage.type": dataTypes 34 | }, "identifier", true); 35 | 36 | this.$rules = { 37 | "start" : [ { 38 | token : "comment", 39 | regex : "--.*$" 40 | }, { 41 | token : "comment", 42 | start : "/\\*", 43 | end : "\\*/" 44 | }, { 45 | token : "string", // " string 46 | regex : '".*?"' 47 | }, { 48 | token : "string", // ' string 49 | regex : "'.*?'" 50 | }, { 51 | token : "string", // ` string (apache drill) 52 | regex : "`.*?`" 53 | }, { 54 | token : "constant.numeric", // float 55 | regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" 56 | }, { 57 | token : keywordMapper, 58 | regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" 59 | }, { 60 | token : "keyword.operator", 61 | regex : "\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|=" 62 | }, { 63 | token : "paren.lparen", 64 | regex : "[\\(]" 65 | }, { 66 | token : "paren.rparen", 67 | regex : "[\\)]" 68 | }, { 69 | token : "text", 70 | regex : "\\s+" 71 | } ] 72 | }; 73 | this.normalizeRules(); 74 | }; 75 | 76 | oop.inherits(SqlHighlightRules, TextHighlightRules); 77 | 78 | exports.SqlHighlightRules = SqlHighlightRules; 79 | }); 80 | 81 | ace.define("ace/mode/sql",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/sql_highlight_rules"], function(require, exports, module) { 82 | "use strict"; 83 | 84 | var oop = require("../lib/oop"); 85 | var TextMode = require("./text").Mode; 86 | var SqlHighlightRules = require("./sql_highlight_rules").SqlHighlightRules; 87 | 88 | var Mode = function() { 89 | this.HighlightRules = SqlHighlightRules; 90 | this.$behaviour = this.$defaultBehaviour; 91 | }; 92 | oop.inherits(Mode, TextMode); 93 | 94 | (function() { 95 | 96 | this.lineCommentStart = "--"; 97 | 98 | this.$id = "ace/mode/sql"; 99 | }).call(Mode.prototype); 100 | 101 | exports.Mode = Mode; 102 | 103 | }); (function() { 104 | ace.require(["ace/mode/sql"], function(m) { 105 | if (typeof module == "object" && typeof exports == "object" && module) { 106 | module.exports = m; 107 | } 108 | }); 109 | })(); 110 | -------------------------------------------------------------------------------- /js/ace/theme-mono_industrial.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/mono_industrial",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-mono-industrial"; 5 | exports.cssText = ".ace-mono-industrial .ace_gutter {\ 6 | background: #1d2521;\ 7 | color: #C5C9C9\ 8 | }\ 9 | .ace-mono-industrial .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #555651\ 12 | }\ 13 | .ace-mono-industrial {\ 14 | background-color: #222C28;\ 15 | color: #FFFFFF\ 16 | }\ 17 | .ace-mono-industrial .ace_cursor {\ 18 | color: #FFFFFF\ 19 | }\ 20 | .ace-mono-industrial .ace_marker-layer .ace_selection {\ 21 | background: rgba(145, 153, 148, 0.40)\ 22 | }\ 23 | .ace-mono-industrial.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #222C28;\ 25 | }\ 26 | .ace-mono-industrial .ace_marker-layer .ace_step {\ 27 | background: rgb(102, 82, 0)\ 28 | }\ 29 | .ace-mono-industrial .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid rgba(102, 108, 104, 0.50)\ 32 | }\ 33 | .ace-mono-industrial .ace_marker-layer .ace_active-line {\ 34 | background: rgba(12, 13, 12, 0.25)\ 35 | }\ 36 | .ace-mono-industrial .ace_gutter-active-line {\ 37 | background-color: rgba(12, 13, 12, 0.25)\ 38 | }\ 39 | .ace-mono-industrial .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid rgba(145, 153, 148, 0.40)\ 41 | }\ 42 | .ace-mono-industrial .ace_invisible {\ 43 | color: rgba(102, 108, 104, 0.50)\ 44 | }\ 45 | .ace-mono-industrial .ace_string {\ 46 | background-color: #151C19;\ 47 | color: #FFFFFF\ 48 | }\ 49 | .ace-mono-industrial .ace_keyword,\ 50 | .ace-mono-industrial .ace_meta {\ 51 | color: #A39E64\ 52 | }\ 53 | .ace-mono-industrial .ace_constant,\ 54 | .ace-mono-industrial .ace_constant.ace_character,\ 55 | .ace-mono-industrial .ace_constant.ace_character.ace_escape,\ 56 | .ace-mono-industrial .ace_constant.ace_numeric,\ 57 | .ace-mono-industrial .ace_constant.ace_other {\ 58 | color: #E98800\ 59 | }\ 60 | .ace-mono-industrial .ace_entity.ace_name.ace_function,\ 61 | .ace-mono-industrial .ace_keyword.ace_operator,\ 62 | .ace-mono-industrial .ace_variable {\ 63 | color: #A8B3AB\ 64 | }\ 65 | .ace-mono-industrial .ace_invalid {\ 66 | color: #FFFFFF;\ 67 | background-color: rgba(153, 0, 0, 0.68)\ 68 | }\ 69 | .ace-mono-industrial .ace_support.ace_constant {\ 70 | color: #C87500\ 71 | }\ 72 | .ace-mono-industrial .ace_fold {\ 73 | background-color: #A8B3AB;\ 74 | border-color: #FFFFFF\ 75 | }\ 76 | .ace-mono-industrial .ace_support.ace_function {\ 77 | color: #588E60\ 78 | }\ 79 | .ace-mono-industrial .ace_entity.ace_name,\ 80 | .ace-mono-industrial .ace_support.ace_class,\ 81 | .ace-mono-industrial .ace_support.ace_type {\ 82 | color: #5778B6\ 83 | }\ 84 | .ace-mono-industrial .ace_storage {\ 85 | color: #C23B00\ 86 | }\ 87 | .ace-mono-industrial .ace_variable.ace_language,\ 88 | .ace-mono-industrial .ace_variable.ace_parameter {\ 89 | color: #648BD2\ 90 | }\ 91 | .ace-mono-industrial .ace_comment {\ 92 | color: #666C68;\ 93 | background-color: #151C19\ 94 | }\ 95 | .ace-mono-industrial .ace_entity.ace_other.ace_attribute-name {\ 96 | color: #909993\ 97 | }\ 98 | .ace-mono-industrial .ace_entity.ace_name.ace_tag {\ 99 | color: #A65EFF\ 100 | }\ 101 | .ace-mono-industrial .ace_indent-guide {\ 102 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQ1NbwZfALD/4PAAlTArlEC4r/AAAAAElFTkSuQmCC) right repeat-y\ 103 | }"; 104 | 105 | var dom = require("../lib/dom"); 106 | dom.importCssString(exports.cssText, exports.cssClass); 107 | }); (function() { 108 | ace.require(["ace/theme/mono_industrial"], function(m) { 109 | if (typeof module == "object" && typeof exports == "object" && module) { 110 | module.exports = m; 111 | } 112 | }); 113 | })(); 114 | -------------------------------------------------------------------------------- /js/ace/theme-textmate.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/textmate",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | "use strict"; 3 | 4 | exports.isDark = false; 5 | exports.cssClass = "ace-tm"; 6 | exports.cssText = ".ace-tm .ace_gutter {\ 7 | background: #f0f0f0;\ 8 | color: #333;\ 9 | }\ 10 | .ace-tm .ace_print-margin {\ 11 | width: 1px;\ 12 | background: #e8e8e8;\ 13 | }\ 14 | .ace-tm .ace_fold {\ 15 | background-color: #6B72E6;\ 16 | }\ 17 | .ace-tm {\ 18 | background-color: #FFFFFF;\ 19 | color: black;\ 20 | }\ 21 | .ace-tm .ace_cursor {\ 22 | color: black;\ 23 | }\ 24 | .ace-tm .ace_invisible {\ 25 | color: rgb(191, 191, 191);\ 26 | }\ 27 | .ace-tm .ace_storage,\ 28 | .ace-tm .ace_keyword {\ 29 | color: blue;\ 30 | }\ 31 | .ace-tm .ace_constant {\ 32 | color: rgb(197, 6, 11);\ 33 | }\ 34 | .ace-tm .ace_constant.ace_buildin {\ 35 | color: rgb(88, 72, 246);\ 36 | }\ 37 | .ace-tm .ace_constant.ace_language {\ 38 | color: rgb(88, 92, 246);\ 39 | }\ 40 | .ace-tm .ace_constant.ace_library {\ 41 | color: rgb(6, 150, 14);\ 42 | }\ 43 | .ace-tm .ace_invalid {\ 44 | background-color: rgba(255, 0, 0, 0.1);\ 45 | color: red;\ 46 | }\ 47 | .ace-tm .ace_support.ace_function {\ 48 | color: rgb(60, 76, 114);\ 49 | }\ 50 | .ace-tm .ace_support.ace_constant {\ 51 | color: rgb(6, 150, 14);\ 52 | }\ 53 | .ace-tm .ace_support.ace_type,\ 54 | .ace-tm .ace_support.ace_class {\ 55 | color: rgb(109, 121, 222);\ 56 | }\ 57 | .ace-tm .ace_keyword.ace_operator {\ 58 | color: rgb(104, 118, 135);\ 59 | }\ 60 | .ace-tm .ace_string {\ 61 | color: rgb(3, 106, 7);\ 62 | }\ 63 | .ace-tm .ace_comment {\ 64 | color: rgb(76, 136, 107);\ 65 | }\ 66 | .ace-tm .ace_comment.ace_doc {\ 67 | color: rgb(0, 102, 255);\ 68 | }\ 69 | .ace-tm .ace_comment.ace_doc.ace_tag {\ 70 | color: rgb(128, 159, 191);\ 71 | }\ 72 | .ace-tm .ace_constant.ace_numeric {\ 73 | color: rgb(0, 0, 205);\ 74 | }\ 75 | .ace-tm .ace_variable {\ 76 | color: rgb(49, 132, 149);\ 77 | }\ 78 | .ace-tm .ace_xml-pe {\ 79 | color: rgb(104, 104, 91);\ 80 | }\ 81 | .ace-tm .ace_entity.ace_name.ace_function {\ 82 | color: #0000A2;\ 83 | }\ 84 | .ace-tm .ace_heading {\ 85 | color: rgb(12, 7, 255);\ 86 | }\ 87 | .ace-tm .ace_list {\ 88 | color:rgb(185, 6, 144);\ 89 | }\ 90 | .ace-tm .ace_meta.ace_tag {\ 91 | color:rgb(0, 22, 142);\ 92 | }\ 93 | .ace-tm .ace_string.ace_regex {\ 94 | color: rgb(255, 0, 0)\ 95 | }\ 96 | .ace-tm .ace_marker-layer .ace_selection {\ 97 | background: rgb(181, 213, 255);\ 98 | }\ 99 | .ace-tm.ace_multiselect .ace_selection.ace_start {\ 100 | box-shadow: 0 0 3px 0px white;\ 101 | }\ 102 | .ace-tm .ace_marker-layer .ace_step {\ 103 | background: rgb(252, 255, 0);\ 104 | }\ 105 | .ace-tm .ace_marker-layer .ace_stack {\ 106 | background: rgb(164, 229, 101);\ 107 | }\ 108 | .ace-tm .ace_marker-layer .ace_bracket {\ 109 | margin: -1px 0 0 -1px;\ 110 | border: 1px solid rgb(192, 192, 192);\ 111 | }\ 112 | .ace-tm .ace_marker-layer .ace_active-line {\ 113 | background: rgba(0, 0, 0, 0.07);\ 114 | }\ 115 | .ace-tm .ace_gutter-active-line {\ 116 | background-color : #dcdcdc;\ 117 | }\ 118 | .ace-tm .ace_marker-layer .ace_selected-word {\ 119 | background: rgb(250, 250, 255);\ 120 | border: 1px solid rgb(200, 200, 250);\ 121 | }\ 122 | .ace-tm .ace_indent-guide {\ 123 | background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\ 124 | }\ 125 | "; 126 | exports.$id = "ace/theme/textmate"; 127 | 128 | var dom = require("../lib/dom"); 129 | dom.importCssString(exports.cssText, exports.cssClass); 130 | }); (function() { 131 | ace.require(["ace/theme/textmate"], function(m) { 132 | if (typeof module == "object" && typeof exports == "object" && module) { 133 | module.exports = m; 134 | } 135 | }); 136 | })(); 137 | -------------------------------------------------------------------------------- /js/ace/theme-tomorrow_night.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/tomorrow_night",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-tomorrow-night"; 5 | exports.cssText = ".ace-tomorrow-night .ace_gutter {\ 6 | background: #25282c;\ 7 | color: #C5C8C6\ 8 | }\ 9 | .ace-tomorrow-night .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #25282c\ 12 | }\ 13 | .ace-tomorrow-night {\ 14 | background-color: #1D1F21;\ 15 | color: #C5C8C6\ 16 | }\ 17 | .ace-tomorrow-night .ace_cursor {\ 18 | color: #AEAFAD\ 19 | }\ 20 | .ace-tomorrow-night .ace_marker-layer .ace_selection {\ 21 | background: #373B41\ 22 | }\ 23 | .ace-tomorrow-night.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #1D1F21;\ 25 | }\ 26 | .ace-tomorrow-night .ace_marker-layer .ace_step {\ 27 | background: rgb(102, 82, 0)\ 28 | }\ 29 | .ace-tomorrow-night .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid #4B4E55\ 32 | }\ 33 | .ace-tomorrow-night .ace_marker-layer .ace_active-line {\ 34 | background: #282A2E\ 35 | }\ 36 | .ace-tomorrow-night .ace_gutter-active-line {\ 37 | background-color: #282A2E\ 38 | }\ 39 | .ace-tomorrow-night .ace_marker-layer .ace_selected-word {\ 40 | border: 1px solid #373B41\ 41 | }\ 42 | .ace-tomorrow-night .ace_invisible {\ 43 | color: #4B4E55\ 44 | }\ 45 | .ace-tomorrow-night .ace_keyword,\ 46 | .ace-tomorrow-night .ace_meta,\ 47 | .ace-tomorrow-night .ace_storage,\ 48 | .ace-tomorrow-night .ace_storage.ace_type,\ 49 | .ace-tomorrow-night .ace_support.ace_type {\ 50 | color: #B294BB\ 51 | }\ 52 | .ace-tomorrow-night .ace_keyword.ace_operator {\ 53 | color: #8ABEB7\ 54 | }\ 55 | .ace-tomorrow-night .ace_constant.ace_character,\ 56 | .ace-tomorrow-night .ace_constant.ace_language,\ 57 | .ace-tomorrow-night .ace_constant.ace_numeric,\ 58 | .ace-tomorrow-night .ace_keyword.ace_other.ace_unit,\ 59 | .ace-tomorrow-night .ace_support.ace_constant,\ 60 | .ace-tomorrow-night .ace_variable.ace_parameter {\ 61 | color: #DE935F\ 62 | }\ 63 | .ace-tomorrow-night .ace_constant.ace_other {\ 64 | color: #CED1CF\ 65 | }\ 66 | .ace-tomorrow-night .ace_invalid {\ 67 | color: #CED2CF;\ 68 | background-color: #DF5F5F\ 69 | }\ 70 | .ace-tomorrow-night .ace_invalid.ace_deprecated {\ 71 | color: #CED2CF;\ 72 | background-color: #B798BF\ 73 | }\ 74 | .ace-tomorrow-night .ace_fold {\ 75 | background-color: #81A2BE;\ 76 | border-color: #C5C8C6\ 77 | }\ 78 | .ace-tomorrow-night .ace_entity.ace_name.ace_function,\ 79 | .ace-tomorrow-night .ace_support.ace_function,\ 80 | .ace-tomorrow-night .ace_variable {\ 81 | color: #81A2BE\ 82 | }\ 83 | .ace-tomorrow-night .ace_support.ace_class,\ 84 | .ace-tomorrow-night .ace_support.ace_type {\ 85 | color: #F0C674\ 86 | }\ 87 | .ace-tomorrow-night .ace_heading,\ 88 | .ace-tomorrow-night .ace_markup.ace_heading,\ 89 | .ace-tomorrow-night .ace_string {\ 90 | color: #B5BD68\ 91 | }\ 92 | .ace-tomorrow-night .ace_entity.ace_name.ace_tag,\ 93 | .ace-tomorrow-night .ace_entity.ace_other.ace_attribute-name,\ 94 | .ace-tomorrow-night .ace_meta.ace_tag,\ 95 | .ace-tomorrow-night .ace_string.ace_regexp,\ 96 | .ace-tomorrow-night .ace_variable {\ 97 | color: #CC6666\ 98 | }\ 99 | .ace-tomorrow-night .ace_comment {\ 100 | color: #969896\ 101 | }\ 102 | .ace-tomorrow-night .ace_indent-guide {\ 103 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y\ 104 | }"; 105 | 106 | var dom = require("../lib/dom"); 107 | dom.importCssString(exports.cssText, exports.cssClass); 108 | }); (function() { 109 | ace.require(["ace/theme/tomorrow_night"], function(m) { 110 | if (typeof module == "object" && typeof exports == "object" && module) { 111 | module.exports = m; 112 | } 113 | }); 114 | })(); 115 | -------------------------------------------------------------------------------- /js/ace/theme-chrome.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/chrome",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | 3 | exports.isDark = false; 4 | exports.cssClass = "ace-chrome"; 5 | exports.cssText = ".ace-chrome .ace_gutter {\ 6 | background: #ebebeb;\ 7 | color: #333;\ 8 | overflow : hidden;\ 9 | }\ 10 | .ace-chrome .ace_print-margin {\ 11 | width: 1px;\ 12 | background: #e8e8e8;\ 13 | }\ 14 | .ace-chrome {\ 15 | background-color: #FFFFFF;\ 16 | color: black;\ 17 | }\ 18 | .ace-chrome .ace_cursor {\ 19 | color: black;\ 20 | }\ 21 | .ace-chrome .ace_invisible {\ 22 | color: rgb(191, 191, 191);\ 23 | }\ 24 | .ace-chrome .ace_constant.ace_buildin {\ 25 | color: rgb(88, 72, 246);\ 26 | }\ 27 | .ace-chrome .ace_constant.ace_language {\ 28 | color: rgb(88, 92, 246);\ 29 | }\ 30 | .ace-chrome .ace_constant.ace_library {\ 31 | color: rgb(6, 150, 14);\ 32 | }\ 33 | .ace-chrome .ace_invalid {\ 34 | background-color: rgb(153, 0, 0);\ 35 | color: white;\ 36 | }\ 37 | .ace-chrome .ace_fold {\ 38 | }\ 39 | .ace-chrome .ace_support.ace_function {\ 40 | color: rgb(60, 76, 114);\ 41 | }\ 42 | .ace-chrome .ace_support.ace_constant {\ 43 | color: rgb(6, 150, 14);\ 44 | }\ 45 | .ace-chrome .ace_support.ace_type,\ 46 | .ace-chrome .ace_support.ace_class\ 47 | .ace-chrome .ace_support.ace_other {\ 48 | color: rgb(109, 121, 222);\ 49 | }\ 50 | .ace-chrome .ace_variable.ace_parameter {\ 51 | font-style:italic;\ 52 | color:#FD971F;\ 53 | }\ 54 | .ace-chrome .ace_keyword.ace_operator {\ 55 | color: rgb(104, 118, 135);\ 56 | }\ 57 | .ace-chrome .ace_comment {\ 58 | color: #236e24;\ 59 | }\ 60 | .ace-chrome .ace_comment.ace_doc {\ 61 | color: #236e24;\ 62 | }\ 63 | .ace-chrome .ace_comment.ace_doc.ace_tag {\ 64 | color: #236e24;\ 65 | }\ 66 | .ace-chrome .ace_constant.ace_numeric {\ 67 | color: rgb(0, 0, 205);\ 68 | }\ 69 | .ace-chrome .ace_variable {\ 70 | color: rgb(49, 132, 149);\ 71 | }\ 72 | .ace-chrome .ace_xml-pe {\ 73 | color: rgb(104, 104, 91);\ 74 | }\ 75 | .ace-chrome .ace_entity.ace_name.ace_function {\ 76 | color: #0000A2;\ 77 | }\ 78 | .ace-chrome .ace_heading {\ 79 | color: rgb(12, 7, 255);\ 80 | }\ 81 | .ace-chrome .ace_list {\ 82 | color:rgb(185, 6, 144);\ 83 | }\ 84 | .ace-chrome .ace_marker-layer .ace_selection {\ 85 | background: rgb(181, 213, 255);\ 86 | }\ 87 | .ace-chrome .ace_marker-layer .ace_step {\ 88 | background: rgb(252, 255, 0);\ 89 | }\ 90 | .ace-chrome .ace_marker-layer .ace_stack {\ 91 | background: rgb(164, 229, 101);\ 92 | }\ 93 | .ace-chrome .ace_marker-layer .ace_bracket {\ 94 | margin: -1px 0 0 -1px;\ 95 | border: 1px solid rgb(192, 192, 192);\ 96 | }\ 97 | .ace-chrome .ace_marker-layer .ace_active-line {\ 98 | background: rgba(0, 0, 0, 0.07);\ 99 | }\ 100 | .ace-chrome .ace_gutter-active-line {\ 101 | background-color : #dcdcdc;\ 102 | }\ 103 | .ace-chrome .ace_marker-layer .ace_selected-word {\ 104 | background: rgb(250, 250, 255);\ 105 | border: 1px solid rgb(200, 200, 250);\ 106 | }\ 107 | .ace-chrome .ace_storage,\ 108 | .ace-chrome .ace_keyword,\ 109 | .ace-chrome .ace_meta.ace_tag {\ 110 | color: rgb(147, 15, 128);\ 111 | }\ 112 | .ace-chrome .ace_string.ace_regex {\ 113 | color: rgb(255, 0, 0)\ 114 | }\ 115 | .ace-chrome .ace_string {\ 116 | color: #1A1AA6;\ 117 | }\ 118 | .ace-chrome .ace_entity.ace_other.ace_attribute-name {\ 119 | color: #994409;\ 120 | }\ 121 | .ace-chrome .ace_indent-guide {\ 122 | background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\ 123 | }\ 124 | "; 125 | 126 | var dom = require("../lib/dom"); 127 | dom.importCssString(exports.cssText, exports.cssClass); 128 | }); (function() { 129 | ace.require(["ace/theme/chrome"], function(m) { 130 | if (typeof module == "object" && typeof exports == "object" && module) { 131 | module.exports = m; 132 | } 133 | }); 134 | })(); 135 | -------------------------------------------------------------------------------- /js/sessions.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "sessions/state", 3 | "sessions/addRemove", 4 | "sessions/switching", 5 | "sessions/binding", 6 | "editor", 7 | "command", 8 | "settings!ace", 9 | "aceBindings" 10 | ], 11 | function(state, addRemove, switching, bindEvents, editor, command, Settings) { 12 | 13 | /* 14 | 15 | The sessions module handles tracking tabs, their contents, and their bindings. 16 | It shares the sessions:* command namespace with the fileManager module. 17 | 18 | */ 19 | 20 | var syntax = document.querySelector(".syntax"); 21 | 22 | command.on("session:syntax", function(mode) { 23 | var session = editor.getSession(); 24 | if (mode) { 25 | session.setMode("ace/mode/" + mode); 26 | session.syntaxMode = mode; 27 | } else { 28 | mode = session.syntaxMode; 29 | } 30 | syntax.value = mode; 31 | session.applySettings(mode); 32 | }); 33 | 34 | var previousTab = null; 35 | var renderTabs = function() { 36 | var tabContainer = document.querySelector(".tabs"); 37 | var contents = ""; 38 | var current = editor.getSession(); 39 | if (previousTab !== current) { 40 | previousTab = current.path ? current : null; 41 | command.fire("session:active-tab", current); 42 | } 43 | tabContainer.innerHTML = ""; 44 | state.tabs.forEach(function(tab, i) { 45 | var element = tab.render(i); 46 | if (tab === current) { 47 | element.classList.add("active"); 48 | } 49 | tabContainer.appendChild(element); 50 | }); 51 | setTimeout(function() { 52 | //wait for render before triggering the enter animation 53 | tabContainer.querySelectorAll(".enter").forEach(element => element.classList.remove("enter")); 54 | }); 55 | }; 56 | 57 | var renderPending = false; 58 | command.on("session:render", function(c) { 59 | if (renderPending) return; 60 | renderPending = setTimeout(function() { 61 | renderTabs(); 62 | renderPending = false; 63 | if (c) c(); 64 | }) 65 | }, 100); 66 | 67 | var init = function() { 68 | var ace = Settings.get("ace"); 69 | ace.modes.forEach(function(mode) { 70 | var option = document.createElement("option"); 71 | option.innerHTML = mode.label; 72 | option.value = mode.name; 73 | syntax.appendChild(option); 74 | }); 75 | if (!state.tabs.length) addRemove.add(""); 76 | renderTabs(); 77 | bindEvents(); 78 | reset(); 79 | return "sessions"; 80 | }; 81 | 82 | var reset = function() { 83 | state.tabs.forEach(function(tab) { 84 | tab.detectSyntax(); 85 | }); 86 | }; 87 | 88 | command.on("init:startup", init); 89 | command.on("init:restart", reset); 90 | 91 | var locationMemory = null; 92 | 93 | return { 94 | addFile: addRemove.add, 95 | getAllTabs: function() { 96 | return state.tabs; 97 | }, 98 | getCurrent: function() { 99 | return editor.getSession(); 100 | }, 101 | getTabByIndex: function(index) { 102 | return state.tabs[index]; 103 | }, 104 | getTabByName: function(name) { 105 | for (var i = 0; i < state.tabs.length; i++) { 106 | if (state.tabs[i].fileName == name) { 107 | return state.tabs[i]; 108 | } 109 | } 110 | return null; 111 | }, 112 | getFilenames: function() { 113 | return state.tabs.map(t => t.fileName); 114 | }, 115 | setCurrent: switching.raise, 116 | raiseBlurred: switching.raiseBlurred, 117 | saveLocation: function() { 118 | var session = editor.getSession(); 119 | var position = editor.getCursorPosition(); 120 | locationMemory = { 121 | tab: session, 122 | cursor: position 123 | }; 124 | }, 125 | restoreLocation: function() { 126 | if (!locationMemory) return; 127 | switching.raise(locationMemory.tab); 128 | editor.moveCursorToPosition(locationMemory.cursor); 129 | }, 130 | renderTabs 131 | } 132 | 133 | }); -------------------------------------------------------------------------------- /js/ace/theme-crimson_editor.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/crimson_editor",["require","exports","module","ace/lib/dom"], function(require, exports, module) { 2 | exports.isDark = false; 3 | exports.cssText = ".ace-crimson-editor .ace_gutter {\ 4 | background: #ebebeb;\ 5 | color: #333;\ 6 | overflow : hidden;\ 7 | }\ 8 | .ace-crimson-editor .ace_gutter-layer {\ 9 | width: 100%;\ 10 | text-align: right;\ 11 | }\ 12 | .ace-crimson-editor .ace_print-margin {\ 13 | width: 1px;\ 14 | background: #e8e8e8;\ 15 | }\ 16 | .ace-crimson-editor {\ 17 | background-color: #FFFFFF;\ 18 | color: rgb(64, 64, 64);\ 19 | }\ 20 | .ace-crimson-editor .ace_cursor {\ 21 | color: black;\ 22 | }\ 23 | .ace-crimson-editor .ace_invisible {\ 24 | color: rgb(191, 191, 191);\ 25 | }\ 26 | .ace-crimson-editor .ace_identifier {\ 27 | color: black;\ 28 | }\ 29 | .ace-crimson-editor .ace_keyword {\ 30 | color: blue;\ 31 | }\ 32 | .ace-crimson-editor .ace_constant.ace_buildin {\ 33 | color: rgb(88, 72, 246);\ 34 | }\ 35 | .ace-crimson-editor .ace_constant.ace_language {\ 36 | color: rgb(255, 156, 0);\ 37 | }\ 38 | .ace-crimson-editor .ace_constant.ace_library {\ 39 | color: rgb(6, 150, 14);\ 40 | }\ 41 | .ace-crimson-editor .ace_invalid {\ 42 | text-decoration: line-through;\ 43 | color: rgb(224, 0, 0);\ 44 | }\ 45 | .ace-crimson-editor .ace_fold {\ 46 | }\ 47 | .ace-crimson-editor .ace_support.ace_function {\ 48 | color: rgb(192, 0, 0);\ 49 | }\ 50 | .ace-crimson-editor .ace_support.ace_constant {\ 51 | color: rgb(6, 150, 14);\ 52 | }\ 53 | .ace-crimson-editor .ace_support.ace_type,\ 54 | .ace-crimson-editor .ace_support.ace_class {\ 55 | color: rgb(109, 121, 222);\ 56 | }\ 57 | .ace-crimson-editor .ace_keyword.ace_operator {\ 58 | color: rgb(49, 132, 149);\ 59 | }\ 60 | .ace-crimson-editor .ace_string {\ 61 | color: rgb(128, 0, 128);\ 62 | }\ 63 | .ace-crimson-editor .ace_comment {\ 64 | color: rgb(76, 136, 107);\ 65 | }\ 66 | .ace-crimson-editor .ace_comment.ace_doc {\ 67 | color: rgb(0, 102, 255);\ 68 | }\ 69 | .ace-crimson-editor .ace_comment.ace_doc.ace_tag {\ 70 | color: rgb(128, 159, 191);\ 71 | }\ 72 | .ace-crimson-editor .ace_constant.ace_numeric {\ 73 | color: rgb(0, 0, 64);\ 74 | }\ 75 | .ace-crimson-editor .ace_variable {\ 76 | color: rgb(0, 64, 128);\ 77 | }\ 78 | .ace-crimson-editor .ace_xml-pe {\ 79 | color: rgb(104, 104, 91);\ 80 | }\ 81 | .ace-crimson-editor .ace_marker-layer .ace_selection {\ 82 | background: rgb(181, 213, 255);\ 83 | }\ 84 | .ace-crimson-editor .ace_marker-layer .ace_step {\ 85 | background: rgb(252, 255, 0);\ 86 | }\ 87 | .ace-crimson-editor .ace_marker-layer .ace_stack {\ 88 | background: rgb(164, 229, 101);\ 89 | }\ 90 | .ace-crimson-editor .ace_marker-layer .ace_bracket {\ 91 | margin: -1px 0 0 -1px;\ 92 | border: 1px solid rgb(192, 192, 192);\ 93 | }\ 94 | .ace-crimson-editor .ace_marker-layer .ace_active-line {\ 95 | background: rgb(232, 242, 254);\ 96 | }\ 97 | .ace-crimson-editor .ace_gutter-active-line {\ 98 | background-color : #dcdcdc;\ 99 | }\ 100 | .ace-crimson-editor .ace_meta.ace_tag {\ 101 | color:rgb(28, 2, 255);\ 102 | }\ 103 | .ace-crimson-editor .ace_marker-layer .ace_selected-word {\ 104 | background: rgb(250, 250, 255);\ 105 | border: 1px solid rgb(200, 200, 250);\ 106 | }\ 107 | .ace-crimson-editor .ace_string.ace_regex {\ 108 | color: rgb(192, 0, 192);\ 109 | }\ 110 | .ace-crimson-editor .ace_indent-guide {\ 111 | background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\ 112 | }"; 113 | 114 | exports.cssClass = "ace-crimson-editor"; 115 | 116 | var dom = require("../lib/dom"); 117 | dom.importCssString(exports.cssText, exports.cssClass); 118 | }); (function() { 119 | ace.require(["ace/theme/crimson_editor"], function(m) { 120 | if (typeof module == "object" && typeof exports == "object" && module) { 121 | module.exports = m; 122 | } 123 | }); 124 | })(); 125 | -------------------------------------------------------------------------------- /js/ace/mode-lisp.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/mode/lisp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { 2 | "use strict"; 3 | 4 | var oop = require("../lib/oop"); 5 | var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; 6 | 7 | var LispHighlightRules = function() { 8 | var keywordControl = "case|do|let|loop|if|else|when"; 9 | var keywordOperator = "eq|neq|and|or"; 10 | var constantLanguage = "null|nil"; 11 | var supportFunctions = "cons|car|cdr|cond|lambda|format|setq|setf|quote|eval|append|list|listp|memberp|t|load|progn"; 12 | 13 | var keywordMapper = this.createKeywordMapper({ 14 | "keyword.control": keywordControl, 15 | "keyword.operator": keywordOperator, 16 | "constant.language": constantLanguage, 17 | "support.function": supportFunctions 18 | }, "identifier", true); 19 | 20 | this.$rules = 21 | { 22 | "start": [ 23 | { 24 | token : "comment", 25 | regex : ";.*$" 26 | }, 27 | { 28 | token: ["storage.type.function-type.lisp", "text", "entity.name.function.lisp"], 29 | regex: "(?:\\b(?:(defun|defmethod|defmacro))\\b)(\\s+)((?:\\w|\\-|\\!|\\?)*)" 30 | }, 31 | { 32 | token: ["punctuation.definition.constant.character.lisp", "constant.character.lisp"], 33 | regex: "(#)((?:\\w|[\\\\+-=<>'\"&#])+)" 34 | }, 35 | { 36 | token: ["punctuation.definition.variable.lisp", "variable.other.global.lisp", "punctuation.definition.variable.lisp"], 37 | regex: "(\\*)(\\S*)(\\*)" 38 | }, 39 | { 40 | token : "constant.numeric", // hex 41 | regex : "0[xX][0-9a-fA-F]+(?:L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b" 42 | }, 43 | { 44 | token : "constant.numeric", // float 45 | regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(?:L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b" 46 | }, 47 | { 48 | token : keywordMapper, 49 | regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" 50 | }, 51 | { 52 | token : "string", 53 | regex : '"(?=.)', 54 | next : "qqstring" 55 | } 56 | ], 57 | "qqstring": [ 58 | { 59 | token: "constant.character.escape.lisp", 60 | regex: "\\\\." 61 | }, 62 | { 63 | token : "string", 64 | regex : '[^"\\\\]+' 65 | }, { 66 | token : "string", 67 | regex : "\\\\$", 68 | next : "qqstring" 69 | }, { 70 | token : "string", 71 | regex : '"|$', 72 | next : "start" 73 | } 74 | ] 75 | }; 76 | 77 | }; 78 | 79 | oop.inherits(LispHighlightRules, TextHighlightRules); 80 | 81 | exports.LispHighlightRules = LispHighlightRules; 82 | }); 83 | 84 | ace.define("ace/mode/lisp",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/lisp_highlight_rules"], function(require, exports, module) { 85 | "use strict"; 86 | 87 | var oop = require("../lib/oop"); 88 | var TextMode = require("./text").Mode; 89 | var LispHighlightRules = require("./lisp_highlight_rules").LispHighlightRules; 90 | 91 | var Mode = function() { 92 | this.HighlightRules = LispHighlightRules; 93 | this.$behaviour = this.$defaultBehaviour; 94 | }; 95 | oop.inherits(Mode, TextMode); 96 | 97 | (function() { 98 | 99 | this.lineCommentStart = ";"; 100 | 101 | this.$id = "ace/mode/lisp"; 102 | }).call(Mode.prototype); 103 | 104 | exports.Mode = Mode; 105 | }); (function() { 106 | ace.require(["ace/mode/lisp"], function(m) { 107 | if (typeof module == "object" && typeof exports == "object" && module) { 108 | module.exports = m; 109 | } 110 | }); 111 | })(); 112 | --------------------------------------------------------------------------------