From 09266196ab88702c3c4e9c5c7bc784330956bb65 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Fri, 29 Mar 2013 20:01:34 -0400 Subject: [PATCH 01/39] adds settings menu to ace I'm not stuck on the keybinding or aesthetics of this, please change them at will. All I really want is the ability to display a menu where I can change the editor's settings from and I want the menu to be smart enough to automatically know about new settings. This pretty much works except there isn't a registry for themes and modes so every new theme or mode has to be added to the internal list by hand... --- lib/ace/commands/default_commands.js | 9 + lib/ace/ext/showSettingsMenu.js | 643 +++++++++++++++++++++++++++ 2 files changed, 652 insertions(+) create mode 100644 lib/ace/ext/showSettingsMenu.js diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index 88621eaf..dfb79ecb 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -42,6 +42,15 @@ function bindKey(win, mac) { } exports.commands = [{ + name: "showSettingsMenu", + bindKey: bindKey("Ctrl-q", "Command-q"), + exec: function (editor) { + config.loadModule("ace/ext/showSettingsMenu", function (e) { + e(editor); + }); + }, + readOnly: true +}, { name: "selectall", bindKey: bindKey("Ctrl-A", "Command-A"), exec: function(editor) { editor.selectAll(); }, diff --git a/lib/ace/ext/showSettingsMenu.js b/lib/ace/ext/showSettingsMenu.js new file mode 100644 index 00000000..724fb735 --- /dev/null +++ b/lib/ace/ext/showSettingsMenu.js @@ -0,0 +1,643 @@ +/*jslint + indent: 4, + maxerr: 50, + white: true, + browser: true, + vars: true +*/ +/*global + define, + getComputedStyle +*/ +define(function(require, exports, module) { + "use strict"; + /** + * These functions are necessary for the settings menu + * to provide a couple really useful settings. + */ + function addFunctionsForSettingsMenu (editor) { + // when building the settings menu matching get and set functions + // must be found or the function will be ignored + + editor.getFontSize = function () { + return getComputedStyle( + editor.container).getPropertyValue('font-size'); + }; + + // this allows the settings menu to supply a wrap limit + // using a text input field easily + editor.session.setWrapLimit = function (limit) { + editor.session.setWrapLimitRange(limit, limit); + }; + } + /** + * Generates a list of set functions for the settings menu + * @param {object} editor The editor instance + * @return {array} Returns an array of objects. Each object contains the + * following properties: functionName, parentObj, and parentName. + */ + function getSetFunctions (editor) { + var out = []; + var my = { + 'editor' : editor, + 'session' : editor.session, + 'renderer' : editor.renderer + }; + var opts = []; + + var skip = [ + 'setOption', + 'setUndoManager', + 'setDocument', + 'setValue', + 'setBreakpoints', + 'setScrollTop', + 'setScrollLeft', + 'setSelectionStyle', + 'setWrapLimitRange', + 'setKeyboardHandler' + ]; + + [ + 'renderer', + 'session', + 'editor' + ].forEach(function (esra) { + var fn; + var esr = my[esra]; + var clss = esra; + for(fn in esr) { + if(skip.indexOf(fn) === -1) { + if(/^set/.test(fn) && opts.indexOf(fn) === -1) { + // found set function + opts.push(fn); + out.push({ + 'functionName' : fn, + 'parentObj' : esr, + 'parentName' : clss + }); + } + } + } + }); + return out; + } + /** + * The menu options property needs to be added to the editor + * so that the settings menu can know about options for + * selection elements and track which option is selected. + */ + function addEditorMenuOptions (editor) { + editor.menuOptions = { + "setNewLineMode" : [{ + "textContent" : "unix", + "value" : "unix" + }, { + "textContent" : "windows", + "value" : "windows" + }, { + "textContent" : "auto", + "value" : "auto" + } + ], + "setTheme" : [{ + "textContent" : "ambiance", + "value" : "ace/theme/ambiance" + }, { + "textContent" : "chaos", + "value" : "ace/theme/chaos" + }, { + "textContent" : "chrome", + "value" : "ace/theme/chrome" + }, { + "textContent" : "clouds", + "value" : "ace/theme/clouds" + }, { + "textContent" : "clouds_midnight", + "value" : "ace/theme/clouds_midnight" + }, { + "textContent" : "cobalt", + "value" : "ace/theme/cobalt" + }, { + "textContent" : "crimson_editor", + "value" : "ace/theme/crimson_editor" + }, { + "textContent" : "dawn", + "value" : "ace/theme/dawn" + }, { + "textContent" : "dreamweaver", + "value" : "ace/theme/dreamweaver" + }, { + "textContent" : "eclipse", + "value" : "ace/theme/eclipse" + }, { + "textContent" : "github", + "value" : "ace/theme/github" + }, { + "textContent" : "idle_fingers", + "value" : "ace/theme/idle_fingers" + }, { + "textContent" : "kr", + "value" : "ace/theme/kr" + }, { + "textContent" : "merbivore", + "value" : "ace/theme/merbivore" + }, { + "textContent" : "merbivore_soft", + "value" : "ace/theme/merbivore_soft" + }, { + "textContent" : "monokai", + "value" : "ace/theme/monokai" + }, { + "textContent" : "mono_industrial", + "value" : "ace/theme/mono_industrial" + }, { + "textContent" : "pastel_on_dark", + "value" : "ace/theme/pastel_on_dark" + }, { + "textContent" : "solarized_dark", + "value" : "ace/theme/solarized_dark" + }, { + "textContent" : "solarized_light", + "value" : "ace/theme/solarized_light" + }, { + "textContent" : "textmate", + "value" : "ace/theme/textmate" + }, { + "textContent" : "tomorrow", + "value" : "ace/theme/tomorrow" + }, { + "textContent" : "tomorrow_night", + "value" : "ace/theme/tomorrow_night" + }, { + "textContent" : "tomorrow_night_blue", + "value" : "ace/theme/tomorrow_night_blue" + }, { + "textContent" : "tomorrow_night_bright", + "value" : "ace/theme/tomorrow_night_bright" + }, { + "textContent" : "tomorrow_night_eighties", + "value" : "ace/theme/tomorrow_night_eighties" + }, { + "textContent" : "twilight", + "value" : "ace/theme/twilight" + }, { + "textContent" : "vibrant_ink", + "value" : "ace/theme/vibrant_ink" + }, { + "textContent" : "xcode", + "value" : "ace/theme/xcode" + } + ], + "setMode" : [{ + "textContent" : "abap", + "value" : "ace/mode/abap" + }, { + "textContent" : "asciidoc", + "value" : "ace/mode/asciidoc" + }, { + "textContent" : "c9search", + "value" : "ace/mode/c9search" + }, { + "textContent" : "clojure", + "value" : "ace/mode/clojure" + }, { + "textContent" : "coffee", + "value" : "ace/mode/coffee" + }, { + "textContent" : "coldfusion", + "value" : "ace/mode/coldfusion" + }, { + "textContent" : "csharp", + "value" : "ace/mode/csharp" + }, { + "textContent" : "css", + "value" : "ace/mode/css" + }, { + "textContent" : "curly", + "value" : "ace/mode/curly" + }, { + "textContent" : "c_cpp", + "value" : "ace/mode/c_cpp" + }, { + "textContent" : "dart", + "value" : "ace/mode/dart" + }, { + "textContent" : "diff", + "value" : "ace/mode/diff" + }, { + "textContent" : "django", + "value" : "ace/mode/django" + }, { + "textContent" : "dot", + "value" : "ace/mode/dot" + }, { + "textContent" : "ftl", + "value" : "ace/mode/ftl" + }, { + "textContent" : "glsl", + "value" : "ace/mode/glsl" + }, { + "textContent" : "golang", + "value" : "ace/mode/golang" + }, { + "textContent" : "groovy", + "value" : "ace/mode/groovy" + }, { + "textContent" : "haml", + "value" : "ace/mode/haml" + }, { + "textContent" : "haxe", + "value" : "ace/mode/haxe" + }, { + "textContent" : "html", + "value" : "ace/mode/html" + }, { + "textContent" : "jade", + "value" : "ace/mode/jade" + }, { + "textContent" : "java", + "value" : "ace/mode/java" + }, { + "textContent" : "javascript", + "value" : "ace/mode/javascript" + }, { + "textContent" : "json", + "value" : "ace/mode/json" + }, { + "textContent" : "jsp", + "value" : "ace/mode/jsp" + }, { + "textContent" : "jsx", + "value" : "ace/mode/jsx" + }, { + "textContent" : "latex", + "value" : "ace/mode/latex" + }, { + "textContent" : "less", + "value" : "ace/mode/less" + }, { + "textContent" : "liquid", + "value" : "ace/mode/liquid" + }, { + "textContent" : "lisp", + "value" : "ace/mode/lisp" + }, { + "textContent" : "livescript", + "value" : "ace/mode/livescript" + }, { + "textContent" : "logiql", + "value" : "ace/mode/logiql" + }, { + "textContent" : "lsl", + "value" : "ace/mode/lsl" + }, { + "textContent" : "lua", + "value" : "ace/mode/lua" + }, { + "textContent" : "luapage", + "value" : "ace/mode/luapage" + }, { + "textContent" : "lucene", + "value" : "ace/mode/lucene" + }, { + "textContent" : "makefile", + "value" : "ace/mode/makefile" + }, { + "textContent" : "markdown", + "value" : "ace/mode/markdown" + }, { + "textContent" : "objectivec", + "value" : "ace/mode/objectivec" + }, { + "textContent" : "ocaml", + "value" : "ace/mode/ocaml" + }, { + "textContent" : "pascal", + "value" : "ace/mode/pascal" + }, { + "textContent" : "perl", + "value" : "ace/mode/perl" + }, { + "textContent" : "pgsql", + "value" : "ace/mode/pgsql" + }, { + "textContent" : "php", + "value" : "ace/mode/php" + }, { + "textContent" : "powershell", + "value" : "ace/mode/powershell" + }, { + "textContent" : "python", + "value" : "ace/mode/python" + }, { + "textContent" : "r", + "value" : "ace/mode/r" + }, { + "textContent" : "rdoc", + "value" : "ace/mode/rdoc" + }, { + "textContent" : "rhtml", + "value" : "ace/mode/rhtml" + }, { + "textContent" : "ruby", + "value" : "ace/mode/ruby" + }, { + "textContent" : "sass", + "value" : "ace/mode/sass" + }, { + "textContent" : "scad", + "value" : "ace/mode/scad" + }, { + "textContent" : "scala", + "value" : "ace/mode/scala" + }, { + "textContent" : "scheme", + "value" : "ace/mode/scheme" + }, { + "textContent" : "scss", + "value" : "ace/mode/scss" + }, { + "textContent" : "sh", + "value" : "ace/mode/sh" + }, { + "textContent" : "sql", + "value" : "ace/mode/sql" + }, { + "textContent" : "stylus", + "value" : "ace/mode/stylus" + }, { + "textContent" : "svg", + "value" : "ace/mode/svg" + }, { + "textContent" : "tcl", + "value" : "ace/mode/tcl" + }, { + "textContent" : "tex", + "value" : "ace/mode/tex" + }, { + "textContent" : "text", + "value" : "ace/mode/text" + }, { + "textContent" : "textile", + "value" : "ace/mode/textile" + }, { + "textContent" : "tmsnippet", + "value" : "ace/mode/tmsnippet" + }, { + "textContent" : "tm_snippet", + "value" : "ace/mode/tm_snippet" + }, { + "textContent" : "toml", + "value" : "ace/mode/toml" + }, { + "textContent" : "typescript", + "value" : "ace/mode/typescript" + }, { + "textContent" : "vbscript", + "value" : "ace/mode/vbscript" + }, { + "textContent" : "xml", + "value" : "ace/mode/xml" + }, { + "textContent" : "xquery", + "value" : "ace/mode/xquery" + }, { + "textContent" : "yaml", + "value" : "ace/mode/yaml" + } + ] + }; + } + /** + * This massive thing is comprised mostly of element generation functions + * filtering out the + */ + function generateMenu (editor) { + var elements = []; + + function createCheckbox (id, checked, clss) { + var el = document.createElement('input'); + el.setAttribute('type', 'checkbox'); + el.setAttribute('id', id); + el.setAttribute('name', id); + el.setAttribute('value', checked); + el.setAttribute('class', clss); + if(checked) { + el.setAttribute('checked', 'checked'); + } + return el; + } + function createInput (id, value, clss) { + var el = document.createElement('input'); + el.setAttribute('type', 'text'); + el.setAttribute('id', id); + el.setAttribute('name', id); + el.setAttribute('value', value); + el.setAttribute('class', clss); + return el; + } + function createOption (obj) { + var attribute; + var el = document.createElement('option'); + for(attribute in obj) { + if(el.hasOwnProperty(attribute)) { + if(attribute === 'selected') { + el.setAttribute(attribute, obj[attribute]); + } + el[attribute] = obj[attribute]; + } + } + return el; + } + function createSelection (id, values, clss) { + var el = document.createElement('select'); + el.setAttribute('id', id); + el.setAttribute('name', id); + el.setAttribute('class', clss); + values.forEach(function (item) { + el.appendChild(createOption(item)); + }); + return el; + } + function createLabel (text, labelFor) { + var el = document.createElement('label'); + el.setAttribute('for', labelFor); + el.textContent = text; + return el; + } + // require editor + function createNewEntry(obj, clss, item, val) { + var el; + var div = document.createElement('div'); + div.setAttribute('contains', item); + div.setAttribute('class', 'menuEntry'); + + div.appendChild(createLabel(item, item)); + + if(Array.isArray(val)) { + el = createSelection(item, val, clss); + el.addEventListener('change', function (e) { + try{ + editor.menuOptions[e.target.id].forEach(function (x) { + if(x.textContent !== e.target.textContent) { + delete x.selected; + } + }); + obj[e.target.id](e.target.value); + } catch (err) { + throw new Error(err); + } + }); + } else if(typeof val === 'boolean') { + el = createCheckbox(item, val, clss); + el.addEventListener('change', function (e) { + try{ + obj[e.target.id](!!e.target.checked); + } catch (err) { + throw new Error(err); + } + }); + } else { + el = createInput(item, val, clss); + el.addEventListener('blur', function (e) { + try{ + if(e.target.value === 'true') { + obj[e.target.id](true); + } else if(e.target.value === 'false') { + obj[e.target.id](false); + } else { + obj[e.target.id](e.target.value); + } + } catch (err) { + throw new Error(err); + } + }); + } + div.appendChild(el); + return div; + } + function makeDropdown(item, esr, clss, fn) { + var val = editor.menuOptions[item]; + val = val.map(function (valuex) { + if(valuex.value === esr[fn]()) { + valuex.selected = 'selected'; + } else if(valuex.value === esr.$modeId) { + // is mode + valuex.selected = 'selected'; + } + return valuex; + }); + return createNewEntry(esr, clss, item, val); + } + + // require editor, elements + function handleSet (setObj) { + var item = setObj.functionName; + var esr = setObj.parentObj; + var clss = setObj.parentName; + var val; + var fn = item.replace(/^set/, 'get'); + if(editor.menuOptions[item] !== undefined) { + // has options for select element + elements.push(makeDropdown(item, esr, clss, fn)); + } else if(typeof esr[fn] === 'function') { + // has get function + try { + val = esr[fn](); + if(typeof val === 'object') { + // setMode takes a string, getMode returns an object + // the $id property of that object is the string + // which may be given to setMode... + val = val.$id; + } + // the rest of the get functions return strings, + // booleans, or numbers. + elements.push( + createNewEntry(esr, clss, item, val) + ); + } catch (e) { + // if there are errors it is because the element + // does not belong in the settings menu + } + } + } + function cleanupElementsList() { + elements.sort(function (a, b) { + var x = a.getAttribute('contains'); + var y = b.getAttribute('contains'); + return x.localeCompare(y); + }); + } + function showMenu() { + var topmenu = document.createElement('div'); + elements.forEach(function (element) { + topmenu.appendChild(element); + }); + return topmenu; + } + getSetFunctions(editor).forEach(function (setObj) { + handleSet(setObj); + }); + cleanupElementsList(); + overlayPage(showMenu(), '0', '0', '0', null); + } + /** + * and here is the ugly overlay code again... + */ + function overlayPage (contentElement, top, right, bottom, left) { + var div = document.createElement('div'); + var contentContainer = document.createElement('div'); + contentContainer.style.cssText = 'margin: 0px; padding: 0px; border: 0px;' + + 'overflow: auto;'; + contentElement.style.cssText = contentElement.style.cssText + 'overflow: auto;'; + contentContainer.appendChild(contentElement); + + var cl = document.createElement('img'); + if(top) { + top = 'top: ' + top + ';'; + } else { + top = ''; + } + if(right) { + right = 'right: ' + right + ';'; + } else { + right = ''; + } + if(bottom) { + bottom = 'bottom: ' + bottom + ';'; + } else { + bottom = ''; + } + if(left) { + left = 'left: ' + left + ';'; + } else { + left = ''; + } + + cl.src = '/famfamfam_silk_icons_v013/icons/cross.png'; + cl.style.cssText = 'margin: 5px 5px 0 0; padding: 0; ' + + 'float: right; width: 25px;'; + div.style.cssText = 'margin:0; padding:0; position: absolute;' + + top + right + bottom + left + + 'z-index:9999; background-color:white; color:black; overflow: auto;'; + + div.appendChild(cl); + div.appendChild(contentContainer); + document.body.appendChild(div); + + cl.addEventListener('click', function (e) { + div.parentNode.removeChild(div); + div = null; + }); + } + /** + * This builds the settings menu and selects + * all the options currently in effect. + */ + module.exports = function (editor) { + addFunctionsForSettingsMenu(editor); + addEditorMenuOptions(editor); + generateMenu(editor); + }; +}); \ No newline at end of file From 1d631b5ca16332e84fa46a2b080692df18935236 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Sun, 31 Mar 2013 00:18:09 -0400 Subject: [PATCH 02/39] Separated logic & presentation, lowercased file names I lowercased the file names. I've separated the code to generate an overlay menu out into a module called overlay_page, it is the same code as is in my other pull request for the keyboard shortcuts menu. It should be easy enough to change the way it looks and behaves without worrying about breaking anything. I've pulled code out into a module called element_generator because it is pretty generic and isn't concerned with gathering data for the settings menu. The element generator can be reused and augmented but there is the possibility that modules depending on it could break. show_settings_menu depends on the element_generator. As it collects data it generates generic elements and attaches event listeners to them. The massive list of options has been moved into its own module for two reasons (1) it makes maintaining show_settings_menu much easier and (2) this is the only part of the menu which has to be updated manually. We may be able to add something to the build system to automatically generate this module based on which modes and themes are found to alleviate us from having to remember to add said options in when new themes and modes are added. --- lib/ace/commands/default_commands.js | 2 +- lib/ace/ext/add_editor_menu_options.js | 360 ++++++++++++++ lib/ace/ext/element_generator.js | 125 +++++ lib/ace/ext/overlay_page.js | 86 ++++ lib/ace/ext/showSettingsMenu.js | 643 ------------------------- lib/ace/ext/show_settings_menu.js | 371 ++++++++++++++ 6 files changed, 943 insertions(+), 644 deletions(-) create mode 100644 lib/ace/ext/add_editor_menu_options.js create mode 100644 lib/ace/ext/element_generator.js create mode 100644 lib/ace/ext/overlay_page.js delete mode 100644 lib/ace/ext/showSettingsMenu.js create mode 100644 lib/ace/ext/show_settings_menu.js diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index dfb79ecb..3134fb6b 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -45,7 +45,7 @@ exports.commands = [{ name: "showSettingsMenu", bindKey: bindKey("Ctrl-q", "Command-q"), exec: function (editor) { - config.loadModule("ace/ext/showSettingsMenu", function (e) { + config.loadModule("ace/ext/show_settings_menu", function (e) { e(editor); }); }, diff --git a/lib/ace/ext/add_editor_menu_options.js b/lib/ace/ext/add_editor_menu_options.js new file mode 100644 index 00000000..520ead72 --- /dev/null +++ b/lib/ace/ext/add_editor_menu_options.js @@ -0,0 +1,360 @@ +/*jslint + indent: 4, + maxerr: 50, + white: true, + browser: true, + vars: true +*/ +/*global + define, + require +*/ + +/** + * Add Editor Menu Options + * @fileOverview Add Editor Menu Options
+ * The menu options property needs to be added to the editor + * so that the settings menu can know about options for + * selection elements and track which option is selected. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +'use strict'; + +/** + * The menu options property needs to be added to the editor + * so that the settings menu can know about options for + * selection elements and track which option is selected. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {ace.Editor} editor An instance of the ace editor. + */ +module.exports.addEditorMenuOptions = function addEditorMenuOptions (editor) { + editor.menuOptions = { + "setNewLineMode" : [{ + "textContent" : "unix", + "value" : "unix" + }, { + "textContent" : "windows", + "value" : "windows" + }, { + "textContent" : "auto", + "value" : "auto" + } + ], + "setTheme" : [{ + "textContent" : "ambiance", + "value" : "ace/theme/ambiance" + }, { + "textContent" : "chaos", + "value" : "ace/theme/chaos" + }, { + "textContent" : "chrome", + "value" : "ace/theme/chrome" + }, { + "textContent" : "clouds", + "value" : "ace/theme/clouds" + }, { + "textContent" : "clouds_midnight", + "value" : "ace/theme/clouds_midnight" + }, { + "textContent" : "cobalt", + "value" : "ace/theme/cobalt" + }, { + "textContent" : "crimson_editor", + "value" : "ace/theme/crimson_editor" + }, { + "textContent" : "dawn", + "value" : "ace/theme/dawn" + }, { + "textContent" : "dreamweaver", + "value" : "ace/theme/dreamweaver" + }, { + "textContent" : "eclipse", + "value" : "ace/theme/eclipse" + }, { + "textContent" : "github", + "value" : "ace/theme/github" + }, { + "textContent" : "idle_fingers", + "value" : "ace/theme/idle_fingers" + }, { + "textContent" : "kr", + "value" : "ace/theme/kr" + }, { + "textContent" : "merbivore", + "value" : "ace/theme/merbivore" + }, { + "textContent" : "merbivore_soft", + "value" : "ace/theme/merbivore_soft" + }, { + "textContent" : "monokai", + "value" : "ace/theme/monokai" + }, { + "textContent" : "mono_industrial", + "value" : "ace/theme/mono_industrial" + }, { + "textContent" : "pastel_on_dark", + "value" : "ace/theme/pastel_on_dark" + }, { + "textContent" : "solarized_dark", + "value" : "ace/theme/solarized_dark" + }, { + "textContent" : "solarized_light", + "value" : "ace/theme/solarized_light" + }, { + "textContent" : "textmate", + "value" : "ace/theme/textmate" + }, { + "textContent" : "tomorrow", + "value" : "ace/theme/tomorrow" + }, { + "textContent" : "tomorrow_night", + "value" : "ace/theme/tomorrow_night" + }, { + "textContent" : "tomorrow_night_blue", + "value" : "ace/theme/tomorrow_night_blue" + }, { + "textContent" : "tomorrow_night_bright", + "value" : "ace/theme/tomorrow_night_bright" + }, { + "textContent" : "tomorrow_night_eighties", + "value" : "ace/theme/tomorrow_night_eighties" + }, { + "textContent" : "twilight", + "value" : "ace/theme/twilight" + }, { + "textContent" : "vibrant_ink", + "value" : "ace/theme/vibrant_ink" + }, { + "textContent" : "xcode", + "value" : "ace/theme/xcode" + } + ], + "setMode" : [{ + "textContent" : "abap", + "value" : "ace/mode/abap" + }, { + "textContent" : "asciidoc", + "value" : "ace/mode/asciidoc" + }, { + "textContent" : "c9search", + "value" : "ace/mode/c9search" + }, { + "textContent" : "clojure", + "value" : "ace/mode/clojure" + }, { + "textContent" : "coffee", + "value" : "ace/mode/coffee" + }, { + "textContent" : "coldfusion", + "value" : "ace/mode/coldfusion" + }, { + "textContent" : "csharp", + "value" : "ace/mode/csharp" + }, { + "textContent" : "css", + "value" : "ace/mode/css" + }, { + "textContent" : "curly", + "value" : "ace/mode/curly" + }, { + "textContent" : "c_cpp", + "value" : "ace/mode/c_cpp" + }, { + "textContent" : "dart", + "value" : "ace/mode/dart" + }, { + "textContent" : "diff", + "value" : "ace/mode/diff" + }, { + "textContent" : "django", + "value" : "ace/mode/django" + }, { + "textContent" : "dot", + "value" : "ace/mode/dot" + }, { + "textContent" : "ftl", + "value" : "ace/mode/ftl" + }, { + "textContent" : "glsl", + "value" : "ace/mode/glsl" + }, { + "textContent" : "golang", + "value" : "ace/mode/golang" + }, { + "textContent" : "groovy", + "value" : "ace/mode/groovy" + }, { + "textContent" : "haml", + "value" : "ace/mode/haml" + }, { + "textContent" : "haxe", + "value" : "ace/mode/haxe" + }, { + "textContent" : "html", + "value" : "ace/mode/html" + }, { + "textContent" : "jade", + "value" : "ace/mode/jade" + }, { + "textContent" : "java", + "value" : "ace/mode/java" + }, { + "textContent" : "javascript", + "value" : "ace/mode/javascript" + }, { + "textContent" : "json", + "value" : "ace/mode/json" + }, { + "textContent" : "jsp", + "value" : "ace/mode/jsp" + }, { + "textContent" : "jsx", + "value" : "ace/mode/jsx" + }, { + "textContent" : "latex", + "value" : "ace/mode/latex" + }, { + "textContent" : "less", + "value" : "ace/mode/less" + }, { + "textContent" : "liquid", + "value" : "ace/mode/liquid" + }, { + "textContent" : "lisp", + "value" : "ace/mode/lisp" + }, { + "textContent" : "livescript", + "value" : "ace/mode/livescript" + }, { + "textContent" : "logiql", + "value" : "ace/mode/logiql" + }, { + "textContent" : "lsl", + "value" : "ace/mode/lsl" + }, { + "textContent" : "lua", + "value" : "ace/mode/lua" + }, { + "textContent" : "luapage", + "value" : "ace/mode/luapage" + }, { + "textContent" : "lucene", + "value" : "ace/mode/lucene" + }, { + "textContent" : "makefile", + "value" : "ace/mode/makefile" + }, { + "textContent" : "markdown", + "value" : "ace/mode/markdown" + }, { + "textContent" : "objectivec", + "value" : "ace/mode/objectivec" + }, { + "textContent" : "ocaml", + "value" : "ace/mode/ocaml" + }, { + "textContent" : "pascal", + "value" : "ace/mode/pascal" + }, { + "textContent" : "perl", + "value" : "ace/mode/perl" + }, { + "textContent" : "pgsql", + "value" : "ace/mode/pgsql" + }, { + "textContent" : "php", + "value" : "ace/mode/php" + }, { + "textContent" : "powershell", + "value" : "ace/mode/powershell" + }, { + "textContent" : "python", + "value" : "ace/mode/python" + }, { + "textContent" : "r", + "value" : "ace/mode/r" + }, { + "textContent" : "rdoc", + "value" : "ace/mode/rdoc" + }, { + "textContent" : "rhtml", + "value" : "ace/mode/rhtml" + }, { + "textContent" : "ruby", + "value" : "ace/mode/ruby" + }, { + "textContent" : "sass", + "value" : "ace/mode/sass" + }, { + "textContent" : "scad", + "value" : "ace/mode/scad" + }, { + "textContent" : "scala", + "value" : "ace/mode/scala" + }, { + "textContent" : "scheme", + "value" : "ace/mode/scheme" + }, { + "textContent" : "scss", + "value" : "ace/mode/scss" + }, { + "textContent" : "sh", + "value" : "ace/mode/sh" + }, { + "textContent" : "sql", + "value" : "ace/mode/sql" + }, { + "textContent" : "stylus", + "value" : "ace/mode/stylus" + }, { + "textContent" : "svg", + "value" : "ace/mode/svg" + }, { + "textContent" : "tcl", + "value" : "ace/mode/tcl" + }, { + "textContent" : "tex", + "value" : "ace/mode/tex" + }, { + "textContent" : "text", + "value" : "ace/mode/text" + }, { + "textContent" : "textile", + "value" : "ace/mode/textile" + }, { + "textContent" : "tmsnippet", + "value" : "ace/mode/tmsnippet" + }, { + "textContent" : "tm_snippet", + "value" : "ace/mode/tm_snippet" + }, { + "textContent" : "toml", + "value" : "ace/mode/toml" + }, { + "textContent" : "typescript", + "value" : "ace/mode/typescript" + }, { + "textContent" : "vbscript", + "value" : "ace/mode/vbscript" + }, { + "textContent" : "xml", + "value" : "ace/mode/xml" + }, { + "textContent" : "xquery", + "value" : "ace/mode/xquery" + }, { + "textContent" : "yaml", + "value" : "ace/mode/yaml" + } + ] + }; +}; + + +}); \ No newline at end of file diff --git a/lib/ace/ext/element_generator.js b/lib/ace/ext/element_generator.js new file mode 100644 index 00000000..1348c5d6 --- /dev/null +++ b/lib/ace/ext/element_generator.js @@ -0,0 +1,125 @@ +/*jslint + indent: 4, + maxerr: 50, + white: true, + browser: true, + vars: true +*/ +/*global + define, + require +*/ + +/** + * Element Generator + * @fileOverview Element Generator
+ * Contains methods for generating elements. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +'use strict'; +/** + * Creates a DOM option element + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {object} obj An object containing properties to add to the dom + * element. If one of those properties is named `selected` then it will be + * added as an attribute on the element instead. + */ +module.exports.createOption = function createOption (obj) { + var attribute; + var el = document.createElement('option'); + for(attribute in obj) { + if(obj.hasOwnProperty(attribute)) { + if(attribute === 'selected') { + el.setAttribute(attribute, obj[attribute]); + } else { + el[attribute] = obj[attribute]; + } + } + } + return el; +}; +/** + * Creates a DOM checkbox element. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {string} id The id of the element. + * @param {boolean} checked Whether or not the element is checked. + * @param {string} clss The class of the element. + * @returns {DOMElement} Returns a checkbox element reference. + */ +module.exports.createCheckbox = function createCheckbox (id, checked, clss) { + var el = document.createElement('input'); + el.setAttribute('type', 'checkbox'); + el.setAttribute('id', id); + el.setAttribute('name', id); + el.setAttribute('value', checked); + el.setAttribute('class', clss); + if(checked) { + el.setAttribute('checked', 'checked'); + } + return el; +}; +/** + * Creates a DOM text input element. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {string} id The id of the element. + * @param {string} value The default value of the input element. + * @param {string} clss The class of the element. + * @returns {DOMElement} Returns an input element reference. + */ +module.exports.createInput = function createInput (id, value, clss) { + var el = document.createElement('input'); + el.setAttribute('type', 'text'); + el.setAttribute('id', id); + el.setAttribute('name', id); + el.setAttribute('value', value); + el.setAttribute('class', clss); + return el; +}; +/** + * Creates a DOM label element. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {string} text The label text. + * @param {string} labelFor The id of the element being labeled. + * @returns {DOMElement} Returns a label element reference. + */ +module.exports.createLabel = function createLabel (text, labelFor) { + var el = document.createElement('label'); + el.setAttribute('for', labelFor); + el.textContent = text; + return el; +}; +/** + * Creates a DOM text input element. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {string} id The id of the element. + * @param {string} values An array of objects suitable for `createOption` + * @param {string} clss The class of the element. + * @returns {DOMElement} Returns a selection element reference. + * @see ace/ext/element_generator.createOption + */ +module.exports.createSelection = function createSelection (id, values, clss) { + var el = document.createElement('select'); + el.setAttribute('id', id); + el.setAttribute('name', id); + el.setAttribute('class', clss); + values.forEach(function (item) { + el.appendChild(module.exports.createOption(item)); + }); + return el; +}; + +}); \ No newline at end of file diff --git a/lib/ace/ext/overlay_page.js b/lib/ace/ext/overlay_page.js new file mode 100644 index 00000000..25dcbbd7 --- /dev/null +++ b/lib/ace/ext/overlay_page.js @@ -0,0 +1,86 @@ +/*jslint + indent: 4, + maxerr: 50, + white: true, + browser: true, + vars: true +*/ +/*global + define, + require +*/ + +/** + * Overlay Page + * @fileOverview Overlay Page
+ * Generates an overlay for displaying menus. The overlay is an absolutely + * positioned div. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +'use strict'; + +/** + * Generates an overlay for displaying menus. The overlay is an absolutely + * positioned div. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {DOMElement} contentElement Any element which may be presented inside + * a div. + * @param {string|number} top absolute position value. + * @param {string|number} right absolute position value. + * @param {string|number} bottom absolute position value. + * @param {string|number} left absolute position value. + */ +module.exports.overlayPage = function overlayPage (contentElement, top, right, bottom, left) { + var div = document.createElement('div'); + var contentContainer = document.createElement('div'); + contentContainer.style.cssText = 'margin: 0px; padding: 0px; border: 0px;' + + 'overflow: auto;'; + contentElement.style.cssText = contentElement.style.cssText + 'overflow: auto;'; + contentContainer.appendChild(contentElement); + + var cl = document.createElement('img'); + if (top) { + top = 'top: ' + top + ';'; + } else { + top = ''; + } + if (right) { + right = 'right: ' + right + ';'; + } else { + right = ''; + } + if (bottom) { + bottom = 'bottom: ' + bottom + ';'; + } else { + bottom = ''; + } + if (left) { + left = 'left: ' + left + ';'; + } else { + left = ''; + } + + cl.src = '/BigRedX.png'; + cl.style.cssText = 'margin: 5px 5px 0 0; padding: 0; ' + + 'float: right; width: 25px; height: 25px; border: 1px solid black;'; + div.style.cssText = 'margin:0; padding:0; position: absolute;' + + top + right + bottom + left + + 'z-index:9999; background-color:white; color:black; overflow: auto;'; + + div.appendChild(cl); + div.appendChild(contentContainer); + document.body.appendChild(div); + + cl.addEventListener('click', function () { + div.parentNode.removeChild(div); + div = null; + }); +}; + +}); \ No newline at end of file diff --git a/lib/ace/ext/showSettingsMenu.js b/lib/ace/ext/showSettingsMenu.js deleted file mode 100644 index 724fb735..00000000 --- a/lib/ace/ext/showSettingsMenu.js +++ /dev/null @@ -1,643 +0,0 @@ -/*jslint - indent: 4, - maxerr: 50, - white: true, - browser: true, - vars: true -*/ -/*global - define, - getComputedStyle -*/ -define(function(require, exports, module) { - "use strict"; - /** - * These functions are necessary for the settings menu - * to provide a couple really useful settings. - */ - function addFunctionsForSettingsMenu (editor) { - // when building the settings menu matching get and set functions - // must be found or the function will be ignored - - editor.getFontSize = function () { - return getComputedStyle( - editor.container).getPropertyValue('font-size'); - }; - - // this allows the settings menu to supply a wrap limit - // using a text input field easily - editor.session.setWrapLimit = function (limit) { - editor.session.setWrapLimitRange(limit, limit); - }; - } - /** - * Generates a list of set functions for the settings menu - * @param {object} editor The editor instance - * @return {array} Returns an array of objects. Each object contains the - * following properties: functionName, parentObj, and parentName. - */ - function getSetFunctions (editor) { - var out = []; - var my = { - 'editor' : editor, - 'session' : editor.session, - 'renderer' : editor.renderer - }; - var opts = []; - - var skip = [ - 'setOption', - 'setUndoManager', - 'setDocument', - 'setValue', - 'setBreakpoints', - 'setScrollTop', - 'setScrollLeft', - 'setSelectionStyle', - 'setWrapLimitRange', - 'setKeyboardHandler' - ]; - - [ - 'renderer', - 'session', - 'editor' - ].forEach(function (esra) { - var fn; - var esr = my[esra]; - var clss = esra; - for(fn in esr) { - if(skip.indexOf(fn) === -1) { - if(/^set/.test(fn) && opts.indexOf(fn) === -1) { - // found set function - opts.push(fn); - out.push({ - 'functionName' : fn, - 'parentObj' : esr, - 'parentName' : clss - }); - } - } - } - }); - return out; - } - /** - * The menu options property needs to be added to the editor - * so that the settings menu can know about options for - * selection elements and track which option is selected. - */ - function addEditorMenuOptions (editor) { - editor.menuOptions = { - "setNewLineMode" : [{ - "textContent" : "unix", - "value" : "unix" - }, { - "textContent" : "windows", - "value" : "windows" - }, { - "textContent" : "auto", - "value" : "auto" - } - ], - "setTheme" : [{ - "textContent" : "ambiance", - "value" : "ace/theme/ambiance" - }, { - "textContent" : "chaos", - "value" : "ace/theme/chaos" - }, { - "textContent" : "chrome", - "value" : "ace/theme/chrome" - }, { - "textContent" : "clouds", - "value" : "ace/theme/clouds" - }, { - "textContent" : "clouds_midnight", - "value" : "ace/theme/clouds_midnight" - }, { - "textContent" : "cobalt", - "value" : "ace/theme/cobalt" - }, { - "textContent" : "crimson_editor", - "value" : "ace/theme/crimson_editor" - }, { - "textContent" : "dawn", - "value" : "ace/theme/dawn" - }, { - "textContent" : "dreamweaver", - "value" : "ace/theme/dreamweaver" - }, { - "textContent" : "eclipse", - "value" : "ace/theme/eclipse" - }, { - "textContent" : "github", - "value" : "ace/theme/github" - }, { - "textContent" : "idle_fingers", - "value" : "ace/theme/idle_fingers" - }, { - "textContent" : "kr", - "value" : "ace/theme/kr" - }, { - "textContent" : "merbivore", - "value" : "ace/theme/merbivore" - }, { - "textContent" : "merbivore_soft", - "value" : "ace/theme/merbivore_soft" - }, { - "textContent" : "monokai", - "value" : "ace/theme/monokai" - }, { - "textContent" : "mono_industrial", - "value" : "ace/theme/mono_industrial" - }, { - "textContent" : "pastel_on_dark", - "value" : "ace/theme/pastel_on_dark" - }, { - "textContent" : "solarized_dark", - "value" : "ace/theme/solarized_dark" - }, { - "textContent" : "solarized_light", - "value" : "ace/theme/solarized_light" - }, { - "textContent" : "textmate", - "value" : "ace/theme/textmate" - }, { - "textContent" : "tomorrow", - "value" : "ace/theme/tomorrow" - }, { - "textContent" : "tomorrow_night", - "value" : "ace/theme/tomorrow_night" - }, { - "textContent" : "tomorrow_night_blue", - "value" : "ace/theme/tomorrow_night_blue" - }, { - "textContent" : "tomorrow_night_bright", - "value" : "ace/theme/tomorrow_night_bright" - }, { - "textContent" : "tomorrow_night_eighties", - "value" : "ace/theme/tomorrow_night_eighties" - }, { - "textContent" : "twilight", - "value" : "ace/theme/twilight" - }, { - "textContent" : "vibrant_ink", - "value" : "ace/theme/vibrant_ink" - }, { - "textContent" : "xcode", - "value" : "ace/theme/xcode" - } - ], - "setMode" : [{ - "textContent" : "abap", - "value" : "ace/mode/abap" - }, { - "textContent" : "asciidoc", - "value" : "ace/mode/asciidoc" - }, { - "textContent" : "c9search", - "value" : "ace/mode/c9search" - }, { - "textContent" : "clojure", - "value" : "ace/mode/clojure" - }, { - "textContent" : "coffee", - "value" : "ace/mode/coffee" - }, { - "textContent" : "coldfusion", - "value" : "ace/mode/coldfusion" - }, { - "textContent" : "csharp", - "value" : "ace/mode/csharp" - }, { - "textContent" : "css", - "value" : "ace/mode/css" - }, { - "textContent" : "curly", - "value" : "ace/mode/curly" - }, { - "textContent" : "c_cpp", - "value" : "ace/mode/c_cpp" - }, { - "textContent" : "dart", - "value" : "ace/mode/dart" - }, { - "textContent" : "diff", - "value" : "ace/mode/diff" - }, { - "textContent" : "django", - "value" : "ace/mode/django" - }, { - "textContent" : "dot", - "value" : "ace/mode/dot" - }, { - "textContent" : "ftl", - "value" : "ace/mode/ftl" - }, { - "textContent" : "glsl", - "value" : "ace/mode/glsl" - }, { - "textContent" : "golang", - "value" : "ace/mode/golang" - }, { - "textContent" : "groovy", - "value" : "ace/mode/groovy" - }, { - "textContent" : "haml", - "value" : "ace/mode/haml" - }, { - "textContent" : "haxe", - "value" : "ace/mode/haxe" - }, { - "textContent" : "html", - "value" : "ace/mode/html" - }, { - "textContent" : "jade", - "value" : "ace/mode/jade" - }, { - "textContent" : "java", - "value" : "ace/mode/java" - }, { - "textContent" : "javascript", - "value" : "ace/mode/javascript" - }, { - "textContent" : "json", - "value" : "ace/mode/json" - }, { - "textContent" : "jsp", - "value" : "ace/mode/jsp" - }, { - "textContent" : "jsx", - "value" : "ace/mode/jsx" - }, { - "textContent" : "latex", - "value" : "ace/mode/latex" - }, { - "textContent" : "less", - "value" : "ace/mode/less" - }, { - "textContent" : "liquid", - "value" : "ace/mode/liquid" - }, { - "textContent" : "lisp", - "value" : "ace/mode/lisp" - }, { - "textContent" : "livescript", - "value" : "ace/mode/livescript" - }, { - "textContent" : "logiql", - "value" : "ace/mode/logiql" - }, { - "textContent" : "lsl", - "value" : "ace/mode/lsl" - }, { - "textContent" : "lua", - "value" : "ace/mode/lua" - }, { - "textContent" : "luapage", - "value" : "ace/mode/luapage" - }, { - "textContent" : "lucene", - "value" : "ace/mode/lucene" - }, { - "textContent" : "makefile", - "value" : "ace/mode/makefile" - }, { - "textContent" : "markdown", - "value" : "ace/mode/markdown" - }, { - "textContent" : "objectivec", - "value" : "ace/mode/objectivec" - }, { - "textContent" : "ocaml", - "value" : "ace/mode/ocaml" - }, { - "textContent" : "pascal", - "value" : "ace/mode/pascal" - }, { - "textContent" : "perl", - "value" : "ace/mode/perl" - }, { - "textContent" : "pgsql", - "value" : "ace/mode/pgsql" - }, { - "textContent" : "php", - "value" : "ace/mode/php" - }, { - "textContent" : "powershell", - "value" : "ace/mode/powershell" - }, { - "textContent" : "python", - "value" : "ace/mode/python" - }, { - "textContent" : "r", - "value" : "ace/mode/r" - }, { - "textContent" : "rdoc", - "value" : "ace/mode/rdoc" - }, { - "textContent" : "rhtml", - "value" : "ace/mode/rhtml" - }, { - "textContent" : "ruby", - "value" : "ace/mode/ruby" - }, { - "textContent" : "sass", - "value" : "ace/mode/sass" - }, { - "textContent" : "scad", - "value" : "ace/mode/scad" - }, { - "textContent" : "scala", - "value" : "ace/mode/scala" - }, { - "textContent" : "scheme", - "value" : "ace/mode/scheme" - }, { - "textContent" : "scss", - "value" : "ace/mode/scss" - }, { - "textContent" : "sh", - "value" : "ace/mode/sh" - }, { - "textContent" : "sql", - "value" : "ace/mode/sql" - }, { - "textContent" : "stylus", - "value" : "ace/mode/stylus" - }, { - "textContent" : "svg", - "value" : "ace/mode/svg" - }, { - "textContent" : "tcl", - "value" : "ace/mode/tcl" - }, { - "textContent" : "tex", - "value" : "ace/mode/tex" - }, { - "textContent" : "text", - "value" : "ace/mode/text" - }, { - "textContent" : "textile", - "value" : "ace/mode/textile" - }, { - "textContent" : "tmsnippet", - "value" : "ace/mode/tmsnippet" - }, { - "textContent" : "tm_snippet", - "value" : "ace/mode/tm_snippet" - }, { - "textContent" : "toml", - "value" : "ace/mode/toml" - }, { - "textContent" : "typescript", - "value" : "ace/mode/typescript" - }, { - "textContent" : "vbscript", - "value" : "ace/mode/vbscript" - }, { - "textContent" : "xml", - "value" : "ace/mode/xml" - }, { - "textContent" : "xquery", - "value" : "ace/mode/xquery" - }, { - "textContent" : "yaml", - "value" : "ace/mode/yaml" - } - ] - }; - } - /** - * This massive thing is comprised mostly of element generation functions - * filtering out the - */ - function generateMenu (editor) { - var elements = []; - - function createCheckbox (id, checked, clss) { - var el = document.createElement('input'); - el.setAttribute('type', 'checkbox'); - el.setAttribute('id', id); - el.setAttribute('name', id); - el.setAttribute('value', checked); - el.setAttribute('class', clss); - if(checked) { - el.setAttribute('checked', 'checked'); - } - return el; - } - function createInput (id, value, clss) { - var el = document.createElement('input'); - el.setAttribute('type', 'text'); - el.setAttribute('id', id); - el.setAttribute('name', id); - el.setAttribute('value', value); - el.setAttribute('class', clss); - return el; - } - function createOption (obj) { - var attribute; - var el = document.createElement('option'); - for(attribute in obj) { - if(el.hasOwnProperty(attribute)) { - if(attribute === 'selected') { - el.setAttribute(attribute, obj[attribute]); - } - el[attribute] = obj[attribute]; - } - } - return el; - } - function createSelection (id, values, clss) { - var el = document.createElement('select'); - el.setAttribute('id', id); - el.setAttribute('name', id); - el.setAttribute('class', clss); - values.forEach(function (item) { - el.appendChild(createOption(item)); - }); - return el; - } - function createLabel (text, labelFor) { - var el = document.createElement('label'); - el.setAttribute('for', labelFor); - el.textContent = text; - return el; - } - // require editor - function createNewEntry(obj, clss, item, val) { - var el; - var div = document.createElement('div'); - div.setAttribute('contains', item); - div.setAttribute('class', 'menuEntry'); - - div.appendChild(createLabel(item, item)); - - if(Array.isArray(val)) { - el = createSelection(item, val, clss); - el.addEventListener('change', function (e) { - try{ - editor.menuOptions[e.target.id].forEach(function (x) { - if(x.textContent !== e.target.textContent) { - delete x.selected; - } - }); - obj[e.target.id](e.target.value); - } catch (err) { - throw new Error(err); - } - }); - } else if(typeof val === 'boolean') { - el = createCheckbox(item, val, clss); - el.addEventListener('change', function (e) { - try{ - obj[e.target.id](!!e.target.checked); - } catch (err) { - throw new Error(err); - } - }); - } else { - el = createInput(item, val, clss); - el.addEventListener('blur', function (e) { - try{ - if(e.target.value === 'true') { - obj[e.target.id](true); - } else if(e.target.value === 'false') { - obj[e.target.id](false); - } else { - obj[e.target.id](e.target.value); - } - } catch (err) { - throw new Error(err); - } - }); - } - div.appendChild(el); - return div; - } - function makeDropdown(item, esr, clss, fn) { - var val = editor.menuOptions[item]; - val = val.map(function (valuex) { - if(valuex.value === esr[fn]()) { - valuex.selected = 'selected'; - } else if(valuex.value === esr.$modeId) { - // is mode - valuex.selected = 'selected'; - } - return valuex; - }); - return createNewEntry(esr, clss, item, val); - } - - // require editor, elements - function handleSet (setObj) { - var item = setObj.functionName; - var esr = setObj.parentObj; - var clss = setObj.parentName; - var val; - var fn = item.replace(/^set/, 'get'); - if(editor.menuOptions[item] !== undefined) { - // has options for select element - elements.push(makeDropdown(item, esr, clss, fn)); - } else if(typeof esr[fn] === 'function') { - // has get function - try { - val = esr[fn](); - if(typeof val === 'object') { - // setMode takes a string, getMode returns an object - // the $id property of that object is the string - // which may be given to setMode... - val = val.$id; - } - // the rest of the get functions return strings, - // booleans, or numbers. - elements.push( - createNewEntry(esr, clss, item, val) - ); - } catch (e) { - // if there are errors it is because the element - // does not belong in the settings menu - } - } - } - function cleanupElementsList() { - elements.sort(function (a, b) { - var x = a.getAttribute('contains'); - var y = b.getAttribute('contains'); - return x.localeCompare(y); - }); - } - function showMenu() { - var topmenu = document.createElement('div'); - elements.forEach(function (element) { - topmenu.appendChild(element); - }); - return topmenu; - } - getSetFunctions(editor).forEach(function (setObj) { - handleSet(setObj); - }); - cleanupElementsList(); - overlayPage(showMenu(), '0', '0', '0', null); - } - /** - * and here is the ugly overlay code again... - */ - function overlayPage (contentElement, top, right, bottom, left) { - var div = document.createElement('div'); - var contentContainer = document.createElement('div'); - contentContainer.style.cssText = 'margin: 0px; padding: 0px; border: 0px;' + - 'overflow: auto;'; - contentElement.style.cssText = contentElement.style.cssText + 'overflow: auto;'; - contentContainer.appendChild(contentElement); - - var cl = document.createElement('img'); - if(top) { - top = 'top: ' + top + ';'; - } else { - top = ''; - } - if(right) { - right = 'right: ' + right + ';'; - } else { - right = ''; - } - if(bottom) { - bottom = 'bottom: ' + bottom + ';'; - } else { - bottom = ''; - } - if(left) { - left = 'left: ' + left + ';'; - } else { - left = ''; - } - - cl.src = '/famfamfam_silk_icons_v013/icons/cross.png'; - cl.style.cssText = 'margin: 5px 5px 0 0; padding: 0; ' + - 'float: right; width: 25px;'; - div.style.cssText = 'margin:0; padding:0; position: absolute;' + - top + right + bottom + left + - 'z-index:9999; background-color:white; color:black; overflow: auto;'; - - div.appendChild(cl); - div.appendChild(contentContainer); - document.body.appendChild(div); - - cl.addEventListener('click', function (e) { - div.parentNode.removeChild(div); - div = null; - }); - } - /** - * This builds the settings menu and selects - * all the options currently in effect. - */ - module.exports = function (editor) { - addFunctionsForSettingsMenu(editor); - addEditorMenuOptions(editor); - generateMenu(editor); - }; -}); \ No newline at end of file diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js new file mode 100644 index 00000000..a65630ad --- /dev/null +++ b/lib/ace/ext/show_settings_menu.js @@ -0,0 +1,371 @@ +/*jslint + indent: 4, + maxerr: 50, + white: true, + browser: true, + vars: true +*/ +/*global + define, + require, + getComputedStyle +*/ + +/** + * Show Settings Menu + * @fileOverview Show Settings Menu
+ * Displays an interactive settings menu mostly generated on the fly based on + * the current state of the editor. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { + "use strict"; + var overlayPage = require('./overlay_page').overlayPage; + var addEditorMenuOptions = require('./add_editor_menu_options').addEditorMenuOptions; + + /** + * These functions are necessary for the settings menu + * to provide a couple really useful settings. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {ace.Editor} editor An instance of the ace editor. + */ + function addFunctionsForSettingsMenu (editor) { + // when building the settings menu matching get and set functions + // must be found or the function will be ignored + + editor.getFontSize = function () { + return getComputedStyle( + editor.container).getPropertyValue('font-size'); + }; + + // this allows the settings menu to supply a wrap limit + // using a text input field easily + editor.session.setWrapLimit = function (limit) { + editor.session.setWrapLimitRange(limit, limit); + }; + } + /** + * Generates a list of set functions for the settings menu. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {object} editor The editor instance + * @return {array} Returns an array of objects. Each object contains the + * following properties: functionName, parentObj, and parentName. The + * function name will be the name of a method beginning with the string + * `set` which was found. The parent object will be a reference to the + * object having the method matching the function name. The parent name + * will be a string representing the identifier of the parent object e.g. + * `editor`, `session`, or `renderer`. + */ + function getSetFunctions (editor) { + /** + * Output array. Will hold the objects described above. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + var out = []; + /** + * This object provides a map between the objects which will be + * traversed and the parent name which will appear in the output. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + var my = { + 'editor' : editor, + 'session' : editor.session, + 'renderer' : editor.renderer + }; + /** + * This array will hold the set function names which have already been + * found so that they are not added to the output multiple times. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + var opts = []; + /** + * This is a list of set functions which will not appear in the settings + * menu. I don't know what to do with setKeyboardHandler. When I tried + * to use it, it didn't appear to be working. Someone who knows better + * could remove it from this list and add it's options to + * add_editor_menu_options.js + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + var skip = [ + 'setOption', + 'setUndoManager', + 'setDocument', + 'setValue', + 'setBreakpoints', + 'setScrollTop', + 'setScrollLeft', + 'setSelectionStyle', + 'setWrapLimitRange', + 'setKeyboardHandler' + ]; + + + /** + * This will search the objects mapped to the `my` variable above. When + * it finds a set function in the object that is not listed in the + * `skip` list or the `opts` list it will push a new object to the + * output array. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + [ + 'renderer', + 'session', + 'editor' + ].forEach(function (esra) { + var fn; + var esr = my[esra]; + var clss = esra; + for(fn in esr) { + if(skip.indexOf(fn) === -1) { + if(/^set/.test(fn) && opts.indexOf(fn) === -1) { + // found set function + opts.push(fn); + out.push({ + 'functionName' : fn, + 'parentObj' : esr, + 'parentName' : clss + }); + } + } + } + }); + return out; + } + /** + * Generates an interactive menu with settings useful to end users. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {ace.Editor} editor An instance of the ace editor. + */ + function generateMenu (editor) { + /** + * container for dom elements that will go in the menu. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + var elements = []; + /** + * Sorts the menu entries (elements var) so they'll appear in alphabetical order + * the sort is performed based on the value of the contains property + * of each element. Since this is an `array.sort` the array is sorted + * in place. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + function cleanupElementsList() { + elements.sort(function (a, b) { + var x = a.getAttribute('contains'); + var y = b.getAttribute('contains'); + return x.localeCompare(y); + }); + } + /** + * Wraps all dom elements contained in the elements var with a single + * div. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + function wrapElements() { + var topmenu = document.createElement('div'); + elements.forEach(function (element) { + topmenu.appendChild(element); + }); + return topmenu; + } + + /** + * Creates a new menu entry. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {object} obj This is a reference to the object containing the + * set function. It is used to set up event listeners for when the + * menu options change. + * @param {string} clss Maps to the class of the dom element. This is + * the name of the object containing the set function e.g. `editor`, + * `session`, `renderer`. + * @param {string} item Maps to the id of the dom element. This is the + * set function name. + * @param {mixed} val This is the value of the setting. It is mapped to + * the dom element's value, checked, or selected option accordingly. + */ + function createNewEntry(obj, clss, item, val) { + var egen = require('./element_generator'); + var el; + var div = document.createElement('div'); + div.setAttribute('contains', item); + div.setAttribute('class', 'menuEntry'); + + div.appendChild(egen.createLabel(item, item)); + + if(Array.isArray(val)) { + el = egen.createSelection(item, val, clss); + el.addEventListener('change', function (e) { + try{ + editor.menuOptions[e.target.id].forEach(function (x) { + if(x.textContent !== e.target.textContent) { + delete x.selected; + } + }); + // editor.session['setMode']('ace/mode/javascript') + obj[e.target.id](e.target.value); + } catch (err) { + throw new Error(err); + } + }); + } else if(typeof val === 'boolean') { + el = egen.createCheckbox(item, val, clss); + el.addEventListener('change', function (e) { + try{ + // renderer['setHighlightGutterLine'](true); + obj[e.target.id](!!e.target.checked); + } catch (err) { + throw new Error(err); + } + }); + } else { + // this aids in giving the ability to specify settings through + // post and get requests. + // /ace_editor.html?setMode=ace/mode/html&setOverwrite=true + el = egen.createInput(item, val, clss); + el.addEventListener('blur', function (e) { + try{ + if(e.target.value === 'true') { + obj[e.target.id](true); + } else if(e.target.value === 'false') { + obj[e.target.id](false); + } else { + obj[e.target.id](e.target.value); + } + } catch (err) { + throw new Error(err); + } + }); + } + div.appendChild(el); + return div; + } + /** + * Generates selection fields for the menu and populates their options + * using information from `editor.menuOptions` + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {string} item The set function name. + * @param {object} esr A reference to the object having the set function. + * @param {string} clss The name of the object containing the set function. + * @param {string} fn The matching get function's function name. + * @returns {DOMElement} Returns a dom element containing a selection + * element populated with options. The option whose value matches that + * returned from `esr[fn]()` will be selected. + */ + function makeDropdown(item, esr, clss, fn) { + var val = editor.menuOptions[item]; + val = val.map(function (valuex) { + if(valuex.value === esr[fn]()) { + valuex.selected = 'selected'; + } else if(valuex.value === esr.$modeId) { + // is mode + valuex.selected = 'selected'; + } + return valuex; + }); + return createNewEntry(esr, clss, item, val); + } + + /** + * Processes the set functions returned from `getSetFunctions`. First it + * checks for menu options defined in `editor.menuOptons`. If no + * options are specified then it checks whether there is a get function + * (replace set with get) for the setting. When either of those + * conditions are met it will attempt to create a new entry for the + * settings menu and push it into the elements array defined above. + * It can only do so for get functions which return + * strings, numbers, and booleans. A special case is written in for + * `getMode` where it looks at the returned objects `$id` property and + * forwards that through instead. Other special cases could be written + * in but that would get a bit ridiculous. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {object} setObj An item from the array returned by + * `getSetFunctions`. + */ + function handleSet (setObj) { + var item = setObj.functionName; + var esr = setObj.parentObj; + var clss = setObj.parentName; + var val; + var fn = item.replace(/^set/, 'get'); + if(editor.menuOptions[item] !== undefined) { + // has options for select element + elements.push(makeDropdown(item, esr, clss, fn)); + } else if(typeof esr[fn] === 'function') { + // has get function + try { + val = esr[fn](); + if(typeof val === 'object') { + // setMode takes a string, getMode returns an object + // the $id property of that object is the string + // which may be given to setMode... + val = val.$id; + } + // the rest of the get functions return strings, + // booleans, or numbers. + elements.push( + createNewEntry(esr, clss, item, val) + ); + } catch (e) { + // if there are errors it is because the element + // does not belong in the settings menu + } + } + } + + // gather the set functions + getSetFunctions(editor).forEach(function (setObj) { + // populate the elements array with good stuff. + handleSet(setObj); + }); + // sort the menu entries in the elements list so people can find + // the settings in alphabetical order. + cleanupElementsList(); + // dump the entries from the elements list and wrap them up in a div + // then put the div into the generic menu and show it. + overlayPage(wrapElements(), '0', '0', '0', null); + } + /** + * This builds the settings menu and selects + * all the options currently in effect. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {ace.Editor} editor An instance of the ace editor. + */ + module.exports = function (editor) { + addFunctionsForSettingsMenu(editor); + addEditorMenuOptions(editor); + generateMenu(editor); + }; +}); \ No newline at end of file From 2ea0faf97b27d1c9191df99626f3dfe1d565c96d Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Sun, 31 Mar 2013 00:59:39 -0400 Subject: [PATCH 03/39] fixed typo in comment --- lib/ace/ext/element_generator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/ext/element_generator.js b/lib/ace/ext/element_generator.js index 1348c5d6..13d9d833 100644 --- a/lib/ace/ext/element_generator.js +++ b/lib/ace/ext/element_generator.js @@ -101,7 +101,7 @@ module.exports.createLabel = function createLabel (text, labelFor) { return el; }; /** - * Creates a DOM text input element. + * Creates a DOM selection element. * @author * Matthew Christopher Kastor-Inare III
* ☭ Hial Atropa!! ☭ From cd2bef97540c79469e375b3af3ee78e80636d33d Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Sun, 31 Mar 2013 01:16:11 -0400 Subject: [PATCH 04/39] clarified comment on createNewEntry --- lib/ace/ext/show_settings_menu.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js index a65630ad..5e14c62c 100644 --- a/lib/ace/ext/show_settings_menu.js +++ b/lib/ace/ext/show_settings_menu.js @@ -205,8 +205,9 @@ define(function(require, exports, module) { * @param {string} clss Maps to the class of the dom element. This is * the name of the object containing the set function e.g. `editor`, * `session`, `renderer`. - * @param {string} item Maps to the id of the dom element. This is the - * set function name. + * @param {string} item This is the set function name. It maps to the + * id of the dom element (check, select, input) and to the "contains" + * attribute of the div holding both the element and its label. * @param {mixed} val This is the value of the setting. It is mapped to * the dom element's value, checked, or selected option accordingly. */ From d4f4758b17647422a9c18a2063de3dc4bf2e7d44 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Fri, 29 Mar 2013 20:17:44 -0400 Subject: [PATCH 05/39] adds keyboard shortcuts menu I'm not set on the keybinding or the aesthetics of this. please change them at will. The main goal here is to provide some method to list all the keyboard shortcuts dynamically. I mean that when new shortcuts are added they should automatically be put into this menu without anyone writing any extra code. The menu provides a way for end users to easily discover the many built in functions accessible through the keyboard. Admittedly the current keybinding to display this menu is not very convenient or easily guessed. I like the way that the textarea version of ace presents a single clickable corner that is easily identified by users. It would be cool to make this pretty and obvious. --- lib/ace/commands/default_commands.js | 2 +- lib/ace/ext/showKeyboardShortcuts.js | 109 +++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 lib/ace/ext/showKeyboardShortcuts.js diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index 3134fb6b..8ecd7fe5 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -43,7 +43,7 @@ function bindKey(win, mac) { exports.commands = [{ name: "showSettingsMenu", - bindKey: bindKey("Ctrl-q", "Command-q"), + bindKey: bindKey("Ctrl-,", "Command-,"), exec: function (editor) { config.loadModule("ace/ext/show_settings_menu", function (e) { e(editor); diff --git a/lib/ace/ext/showKeyboardShortcuts.js b/lib/ace/ext/showKeyboardShortcuts.js new file mode 100644 index 00000000..b503b993 --- /dev/null +++ b/lib/ace/ext/showKeyboardShortcuts.js @@ -0,0 +1,109 @@ +/*jslint + indent: 4, + maxerr: 50, + white: true, + browser: true, + vars: true +*/ +/*global + define, + getComputedStyle +*/ +define(function(require, exports, module) { + "use strict"; + // this function makes an ugly div to display the contentElement + var overlayPage = function (contentElement, top, right, bottom, left) { + "use strict"; + var div = document.createElement('div'); + var contentContainer = document.createElement('div'); + contentContainer.style.cssText = 'margin: 0px; padding: 0px; border: 0px;' + + 'overflow: auto;'; + contentElement.style.cssText = contentElement.style.cssText + 'overflow: auto;'; + contentContainer.appendChild(contentElement); + + var cl = document.createElement('img'); + if (top) { + top = 'top: ' + top + ';'; + } else { + top = ''; + } + if (right) { + right = 'right: ' + right + ';'; + } else { + right = ''; + } + if (bottom) { + bottom = 'bottom: ' + bottom + ';'; + } else { + bottom = ''; + } + if (left) { + left = 'left: ' + left + ';'; + } else { + left = ''; + } + + cl.src = '/BigRedX.png'; + cl.style.cssText = 'margin: 5px 5px 0 0; padding: 0; ' + + 'float: right; width: 25px; height: 25px; border: 1px solid black;'; + div.style.cssText = 'margin:0; padding:0; position: absolute;' + + top + right + bottom + left + + 'z-index:9999; background-color:white; color:black; overflow: auto;'; + + div.appendChild(cl); + div.appendChild(contentContainer); + document.body.appendChild(div); + + cl.addEventListener('click', function (e) { + div.parentNode.removeChild(div); + div = null; + }); + }; + + // this function grabs all of the editor commands that have keyboard shortcuts + function aceGetKeybordShortcuts (editor) { + "use strict"; + var commands = editor.commands.byName; + var commandName; + var key; + var platform = editor.commands.platform; + var kb = []; + for (commandName in commands) { + try { + key = commands[commandName].bindKey[platform]; + if (key) { + kb.push({ + 'command' : commandName, + 'key' : key + }); + } + } catch (e) { + // errors on properties without bindKey we don't want them + // so the errors don't need handling. + } + } + return kb; + } + + // this function takes the keyboard shortcuts array and + // runs it through some template. + module.exports = function (editor) { + var kb = aceGetKeybordShortcuts(editor); + var el = document.createElement('div'); + // untested. something like this could . . . + // var template = '

Keyboard Shortcuts

' + + // {{#kb}} + // {{{command}}} : {{{key}}} + // {{/kb}} + // '
'; + // mustache.render({'kb' : kb}, template); + + el.innerHTML = '

Keyboard Shortcuts

' + + JSON.stringify(kb, null, ' ') + + '
'; + el.style.cssText = 'margin:0; padding:0; ' + + 'background-color:white; color:black; ' + + 'white-space: pre-wrap;'; + overlayPage(el, '0', '0', '0', null); + } +}); \ No newline at end of file From baaf4dd0b4a22b55e84b336a264bd618a022c71c Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Sat, 30 Mar 2013 23:57:49 -0400 Subject: [PATCH 06/39] Separated logic from presentation, lowercased file names I pulled the code for generating the menu out into its own module called overlay_page. I pulled the code for generating a menu, using overlay_page, out into its own module called show_keyboard_shortcuts. The logic for getting a list of keyboard shortcuts pertinent to the current operating system is by itself in the module get_editor_keyboard_shortcuts. This should make it easy for anyone to change the appearance of the menu without worrying about breaking the code which fetches the data. --- lib/ace/commands/default_commands.js | 2 +- lib/ace/ext/get_editor_keyboard_shortcuts.js | 63 +++++++++++ lib/ace/ext/showKeyboardShortcuts.js | 109 ------------------- lib/ace/ext/show_keyboard_shortcuts.js | 44 ++++++++ 4 files changed, 108 insertions(+), 110 deletions(-) create mode 100644 lib/ace/ext/get_editor_keyboard_shortcuts.js delete mode 100644 lib/ace/ext/showKeyboardShortcuts.js create mode 100644 lib/ace/ext/show_keyboard_shortcuts.js diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index 8ecd7fe5..909aa843 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -45,7 +45,7 @@ exports.commands = [{ name: "showSettingsMenu", bindKey: bindKey("Ctrl-,", "Command-,"), exec: function (editor) { - config.loadModule("ace/ext/show_settings_menu", function (e) { + config.loadModule("ace/ext/show_keyboard_shortcuts", function (e) { e(editor); }); }, diff --git a/lib/ace/ext/get_editor_keyboard_shortcuts.js b/lib/ace/ext/get_editor_keyboard_shortcuts.js new file mode 100644 index 00000000..708dc9cf --- /dev/null +++ b/lib/ace/ext/get_editor_keyboard_shortcuts.js @@ -0,0 +1,63 @@ +/*jslint + indent: 4, + maxerr: 50, + white: true, + browser: true, + vars: true +*/ +/*global + define, + require +*/ + +/** + * Get Editor Keyboard Shortcuts + * @fileOverview Get Editor Keyboard Shortcuts
+ * Gets a map of keyboard shortcuts to command names for the current platform. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +"use strict"; +/** + * Gets a map of keyboard shortcuts to command names for the current platform. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {ace.Editor} editor An editor instance. + * @returns {Array} Returns an array of objects representing the keyboard + * shortcuts for the given editor. + * @example + * var getKbShortcuts = require('./get_keyboard_shortcuts'); + * console.log(getKbShortcuts(editor)); + * // [ + * // {'command' : aCommand, 'key' : 'Control-d'}, + * // {'command' : aCommand, 'key' : 'Control-d'} + * // ] + */ +module.exports.getEditorKeybordShortcuts = function getEditorKeybordShortcuts (editor) { + var commands = editor.commands.byName; + var commandName; + var key; + var platform = editor.commands.platform; + var kb = []; + for (commandName in commands) { + try { + key = commands[commandName].bindKey[platform]; + if (key) { + kb.push({ + 'command' : commandName, + 'key' : key + }); + } + } catch (e) { + // errors on properties without bindKey we don't want them + // so the errors don't need handling. + } + } + return kb; +}; + +}); \ No newline at end of file diff --git a/lib/ace/ext/showKeyboardShortcuts.js b/lib/ace/ext/showKeyboardShortcuts.js deleted file mode 100644 index b503b993..00000000 --- a/lib/ace/ext/showKeyboardShortcuts.js +++ /dev/null @@ -1,109 +0,0 @@ -/*jslint - indent: 4, - maxerr: 50, - white: true, - browser: true, - vars: true -*/ -/*global - define, - getComputedStyle -*/ -define(function(require, exports, module) { - "use strict"; - // this function makes an ugly div to display the contentElement - var overlayPage = function (contentElement, top, right, bottom, left) { - "use strict"; - var div = document.createElement('div'); - var contentContainer = document.createElement('div'); - contentContainer.style.cssText = 'margin: 0px; padding: 0px; border: 0px;' + - 'overflow: auto;'; - contentElement.style.cssText = contentElement.style.cssText + 'overflow: auto;'; - contentContainer.appendChild(contentElement); - - var cl = document.createElement('img'); - if (top) { - top = 'top: ' + top + ';'; - } else { - top = ''; - } - if (right) { - right = 'right: ' + right + ';'; - } else { - right = ''; - } - if (bottom) { - bottom = 'bottom: ' + bottom + ';'; - } else { - bottom = ''; - } - if (left) { - left = 'left: ' + left + ';'; - } else { - left = ''; - } - - cl.src = '/BigRedX.png'; - cl.style.cssText = 'margin: 5px 5px 0 0; padding: 0; ' + - 'float: right; width: 25px; height: 25px; border: 1px solid black;'; - div.style.cssText = 'margin:0; padding:0; position: absolute;' + - top + right + bottom + left + - 'z-index:9999; background-color:white; color:black; overflow: auto;'; - - div.appendChild(cl); - div.appendChild(contentContainer); - document.body.appendChild(div); - - cl.addEventListener('click', function (e) { - div.parentNode.removeChild(div); - div = null; - }); - }; - - // this function grabs all of the editor commands that have keyboard shortcuts - function aceGetKeybordShortcuts (editor) { - "use strict"; - var commands = editor.commands.byName; - var commandName; - var key; - var platform = editor.commands.platform; - var kb = []; - for (commandName in commands) { - try { - key = commands[commandName].bindKey[platform]; - if (key) { - kb.push({ - 'command' : commandName, - 'key' : key - }); - } - } catch (e) { - // errors on properties without bindKey we don't want them - // so the errors don't need handling. - } - } - return kb; - } - - // this function takes the keyboard shortcuts array and - // runs it through some template. - module.exports = function (editor) { - var kb = aceGetKeybordShortcuts(editor); - var el = document.createElement('div'); - // untested. something like this could . . . - // var template = '

Keyboard Shortcuts

' + - // {{#kb}} - // {{{command}}} : {{{key}}} - // {{/kb}} - // '
'; - // mustache.render({'kb' : kb}, template); - - el.innerHTML = '

Keyboard Shortcuts

' + - JSON.stringify(kb, null, ' ') + - '
'; - el.style.cssText = 'margin:0; padding:0; ' + - 'background-color:white; color:black; ' + - 'white-space: pre-wrap;'; - overlayPage(el, '0', '0', '0', null); - } -}); \ No newline at end of file diff --git a/lib/ace/ext/show_keyboard_shortcuts.js b/lib/ace/ext/show_keyboard_shortcuts.js new file mode 100644 index 00000000..5e86e610 --- /dev/null +++ b/lib/ace/ext/show_keyboard_shortcuts.js @@ -0,0 +1,44 @@ +/*jslint + indent: 4, + maxerr: 50, + white: true, + browser: true, + vars: true +*/ +/*global + define, + require +*/ + +/** + * Show Keyboard Shortcuts + * @fileOverview Show Keyboard Shortcuts
+ * Generates a menu which displays the keyboard shortcuts. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { + "use strict"; + var overlayPage = require('./overlay_page').overlayPage; + var getEditorKeybordShortcuts = require('./get_editor_keyboard_shortcuts').getEditorKeybordShortcuts; + /** + * Generates a menu which displays the keyboard shortcuts. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {ace.Editor} editor An instance of the ace editor. + */ + module.exports = function showKeyboardShortcuts (editor) { + var kb = getEditorKeybordShortcuts(editor); + var el = document.createElement('div'); + el.innerHTML = '

Keyboard Shortcuts

' + + JSON.stringify(kb, null, ' ') + + '
'; + el.style.cssText = 'margin:0; padding:0; ' + + 'background-color:white; color:black; ' + + 'white-space: pre-wrap;'; + overlayPage(el, '0', '0', '0', null); + }; +}); \ No newline at end of file From fb7152cb1043f9150db99e0058a90e663eb0cfc8 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Sun, 31 Mar 2013 20:22:35 -0400 Subject: [PATCH 07/39] prettified generic menu --- lib/ace/ext/overlay_page.js | 71 +++++++++++++++---------------------- 1 file changed, 29 insertions(+), 42 deletions(-) diff --git a/lib/ace/ext/overlay_page.js b/lib/ace/ext/overlay_page.js index 25dcbbd7..3cd7efec 100644 --- a/lib/ace/ext/overlay_page.js +++ b/lib/ace/ext/overlay_page.js @@ -37,50 +37,37 @@ define(function(require, exports, module) { * @param {string|number} left absolute position value. */ module.exports.overlayPage = function overlayPage (contentElement, top, right, bottom, left) { - var div = document.createElement('div'); + top = (top) ? 'top: ' + top + ';' : ''; + bottom = (bottom) ? 'bottom: ' + bottom + ';' : ''; + right = (right) ? 'right: ' + right + ';' : ''; + left = (left) ? 'left: ' + left + ';' : ''; + + var closer = document.createElement('div'); var contentContainer = document.createElement('div'); - contentContainer.style.cssText = 'margin: 0px; padding: 0px; border: 0px;' + - 'overflow: auto;'; - contentElement.style.cssText = contentElement.style.cssText + 'overflow: auto;'; - contentContainer.appendChild(contentElement); - - var cl = document.createElement('img'); - if (top) { - top = 'top: ' + top + ';'; - } else { - top = ''; - } - if (right) { - right = 'right: ' + right + ';'; - } else { - right = ''; - } - if (bottom) { - bottom = 'bottom: ' + bottom + ';'; - } else { - bottom = ''; - } - if (left) { - left = 'left: ' + left + ';'; - } else { - left = ''; - } - - cl.src = '/BigRedX.png'; - cl.style.cssText = 'margin: 5px 5px 0 0; padding: 0; ' + - 'float: right; width: 25px; height: 25px; border: 1px solid black;'; - div.style.cssText = 'margin:0; padding:0; position: absolute;' + - top + right + bottom + left + - 'z-index:9999; background-color:white; color:black; overflow: auto;'; - - div.appendChild(cl); - div.appendChild(contentContainer); - document.body.appendChild(div); - - cl.addEventListener('click', function () { - div.parentNode.removeChild(div); - div = null; + + closer.style.cssText = 'margin: 0; padding: 0; ' + + 'position: absolute; top:0; bottom:0; left:0; right:0;' + + 'z-index: 9990; ' + + 'background-color: rgba(0, 0, 0, 0.1);'; + closer.addEventListener('click', function () { + closer.parentNode.removeChild(closer); + closer = null; }); + + contentContainer.style.cssText = 'margin: 0; padding: 0; ' + + 'position: absolute;' + + top + right + bottom + left + + 'z-index: 9991; ' + + 'box-shadow: rgba(126, 126, 126, 0.25) -20px 10px 25px; ' + + 'background-color: rgba(255, 255, 255, 0.6);' + + 'color: black; overflow: auto;'; + contentContainer.addEventListener('click', function (e) { + e.stopPropagation(); + }); + + contentContainer.appendChild(contentElement); + closer.appendChild(contentContainer); + document.body.appendChild(closer); }; }); \ No newline at end of file From 3bca16ac7326c361f7eb48ebefdf4c12702cb85a Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Sun, 31 Mar 2013 20:26:24 -0400 Subject: [PATCH 08/39] fix top margin on kb shortcuts menu --- lib/ace/ext/show_keyboard_shortcuts.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/ace/ext/show_keyboard_shortcuts.js b/lib/ace/ext/show_keyboard_shortcuts.js index 5e86e610..e2469e60 100644 --- a/lib/ace/ext/show_keyboard_shortcuts.js +++ b/lib/ace/ext/show_keyboard_shortcuts.js @@ -33,7 +33,8 @@ define(function(require, exports, module) { module.exports = function showKeyboardShortcuts (editor) { var kb = getEditorKeybordShortcuts(editor); var el = document.createElement('div'); - el.innerHTML = '

Keyboard Shortcuts

' + + el.innerHTML = '

' + + 'Keyboard Shortcuts

' + JSON.stringify(kb, null, ' ') + '
'; el.style.cssText = 'margin:0; padding:0; ' + From 4ec0a6e7067bfbc60bce422a16936e7e77fc77ff Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Sun, 31 Mar 2013 20:47:38 -0400 Subject: [PATCH 09/39] prettified kb menu --- lib/ace/ext/show_keyboard_shortcuts.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/ace/ext/show_keyboard_shortcuts.js b/lib/ace/ext/show_keyboard_shortcuts.js index e2469e60..a88a6e55 100644 --- a/lib/ace/ext/show_keyboard_shortcuts.js +++ b/lib/ace/ext/show_keyboard_shortcuts.js @@ -33,13 +33,12 @@ define(function(require, exports, module) { module.exports = function showKeyboardShortcuts (editor) { var kb = getEditorKeybordShortcuts(editor); var el = document.createElement('div'); - el.innerHTML = '

' + - 'Keyboard Shortcuts

' + - JSON.stringify(kb, null, ' ') + - '
'; - el.style.cssText = 'margin:0; padding:0; ' + - 'background-color:white; color:black; ' + - 'white-space: pre-wrap;'; + var commands = kb.reduce(function (previous, current) { + return previous + '
' + current.command + ' : ' + + current.key + '
'; + }, ''); + el.innerHTML = '

Keyboard Shortcuts

' + commands; + el.style.cssText = 'margin:0; padding:0;'; overlayPage(el, '0', '0', '0', null); }; }); \ No newline at end of file From 52a1dffa9f43ce10b750d2404210961d8866aa73 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Sun, 31 Mar 2013 21:47:12 -0400 Subject: [PATCH 10/39] menus will open only 1 at a time per menu. --- lib/ace/commands/default_commands.js | 5 ----- lib/ace/ext/show_keyboard_shortcuts.js | 29 +++++++++++++++----------- lib/ace/ext/show_settings_menu.js | 12 +++++++---- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index 909aa843..658deb87 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -45,11 +45,6 @@ exports.commands = [{ name: "showSettingsMenu", bindKey: bindKey("Ctrl-,", "Command-,"), exec: function (editor) { - config.loadModule("ace/ext/show_keyboard_shortcuts", function (e) { - e(editor); - }); - }, - readOnly: true }, { name: "selectall", bindKey: bindKey("Ctrl-A", "Command-A"), diff --git a/lib/ace/ext/show_keyboard_shortcuts.js b/lib/ace/ext/show_keyboard_shortcuts.js index a88a6e55..f4db2aa8 100644 --- a/lib/ace/ext/show_keyboard_shortcuts.js +++ b/lib/ace/ext/show_keyboard_shortcuts.js @@ -21,8 +21,6 @@ define(function(require, exports, module) { "use strict"; - var overlayPage = require('./overlay_page').overlayPage; - var getEditorKeybordShortcuts = require('./get_editor_keyboard_shortcuts').getEditorKeybordShortcuts; /** * Generates a menu which displays the keyboard shortcuts. * @author @@ -30,15 +28,22 @@ define(function(require, exports, module) { * ☭ Hial Atropa!! ☭ * @param {ace.Editor} editor An instance of the ace editor. */ - module.exports = function showKeyboardShortcuts (editor) { - var kb = getEditorKeybordShortcuts(editor); - var el = document.createElement('div'); - var commands = kb.reduce(function (previous, current) { - return previous + '
' + current.command + ' : ' + - current.key + '
'; - }, ''); - el.innerHTML = '

Keyboard Shortcuts

' + commands; - el.style.cssText = 'margin:0; padding:0;'; - overlayPage(el, '0', '0', '0', null); + module.exports.showKeyboardShortcuts = function showKeyboardShortcuts (editor) { + // make sure the menu isn't open already. + if(!document.getElementById('kbshortcutmenu')) { + var overlayPage = require('./overlay_page').overlayPage; + var getEditorKeybordShortcuts = require('./get_editor_keyboard_shortcuts').getEditorKeybordShortcuts; + var kb = getEditorKeybordShortcuts(editor); + var el = document.createElement('div'); + var commands = kb.reduce(function (previous, current) { + return previous + '
' + current.command + ' : ' + + current.key + '
'; + }, ''); + + el.id = 'kbshortcutmenu'; + el.innerHTML = '

Keyboard Shortcuts

' + commands + '
'; + el.style.cssText = 'margin:0; padding:0;'; + overlayPage(el, '0', '0', '0', null); + } }; }); \ No newline at end of file diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js index 5e14c62c..01661105 100644 --- a/lib/ace/ext/show_settings_menu.js +++ b/lib/ace/ext/show_settings_menu.js @@ -188,6 +188,7 @@ define(function(require, exports, module) { */ function wrapElements() { var topmenu = document.createElement('div'); + topmenu.id = 'settingsmenu'; elements.forEach(function (element) { topmenu.appendChild(element); }); @@ -364,9 +365,12 @@ define(function(require, exports, module) { * ☭ Hial Atropa!! ☭ * @param {ace.Editor} editor An instance of the ace editor. */ - module.exports = function (editor) { - addFunctionsForSettingsMenu(editor); - addEditorMenuOptions(editor); - generateMenu(editor); + module.exports.showSettingsMenu = function showSettingsMenu (editor) { + // make sure the menu isn't open already. + if(!document.getElementById('settingsmenu')) { + addFunctionsForSettingsMenu(editor); + addEditorMenuOptions(editor); + generateMenu(editor); + } }; }); \ No newline at end of file From cc4d524a8aa1568e10b7d29ccc87873abb778070 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Sun, 31 Mar 2013 22:23:37 -0400 Subject: [PATCH 11/39] prettified settings menu --- lib/ace/ext/show_settings_menu.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js index 01661105..af846834 100644 --- a/lib/ace/ext/show_settings_menu.js +++ b/lib/ace/ext/show_settings_menu.js @@ -188,7 +188,7 @@ define(function(require, exports, module) { */ function wrapElements() { var topmenu = document.createElement('div'); - topmenu.id = 'settingsmenu'; + topmenu.setAttribute('id', 'settingsmenu'); elements.forEach(function (element) { topmenu.appendChild(element); }); @@ -218,9 +218,10 @@ define(function(require, exports, module) { var div = document.createElement('div'); div.setAttribute('contains', item); div.setAttribute('class', 'menuEntry'); - + div.setAttribute('style', 'clear: both;'); + div.appendChild(egen.createLabel(item, item)); - + if(Array.isArray(val)) { el = egen.createSelection(item, val, clss); el.addEventListener('change', function (e) { @@ -265,6 +266,7 @@ define(function(require, exports, module) { } }); } + el.style.cssText = 'float:right;'; div.appendChild(el); return div; } @@ -355,7 +357,7 @@ define(function(require, exports, module) { cleanupElementsList(); // dump the entries from the elements list and wrap them up in a div // then put the div into the generic menu and show it. - overlayPage(wrapElements(), '0', '0', '0', null); + overlayPage(wrapElements(), '0', '0', '0', '75%'); } /** * This builds the settings menu and selects From 6b1e90fbc7215372c7f0c5b1dd5c16aed038e517 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Mon, 1 Apr 2013 00:12:56 -0400 Subject: [PATCH 12/39] fixed position to avoid scrolling away The overlay menu should remain visible when scrolling a long page. The intention is to present information on demand and not leave the menu on screen. If allowed to scroll away the remaining element could interfere with the page. --- lib/ace/ext/overlay_page.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ace/ext/overlay_page.js b/lib/ace/ext/overlay_page.js index 3cd7efec..c6639fe5 100644 --- a/lib/ace/ext/overlay_page.js +++ b/lib/ace/ext/overlay_page.js @@ -46,9 +46,9 @@ module.exports.overlayPage = function overlayPage (contentElement, top, right, b var contentContainer = document.createElement('div'); closer.style.cssText = 'margin: 0; padding: 0; ' + - 'position: absolute; top:0; bottom:0; left:0; right:0;' + + 'position: fixed; top:0; bottom:0; left:0; right:0;' + 'z-index: 9990; ' + - 'background-color: rgba(0, 0, 0, 0.1);'; + 'background-color: rgba(0, 0, 0, 0.2);'; closer.addEventListener('click', function () { closer.parentNode.removeChild(closer); closer = null; From c695db475a5ab425cc120bfb2b2384245e73b422 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Mon, 1 Apr 2013 01:34:38 -0400 Subject: [PATCH 13/39] set wrap limit wraps within 20 chars --- lib/ace/ext/show_settings_menu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js index af846834..c00e114a 100644 --- a/lib/ace/ext/show_settings_menu.js +++ b/lib/ace/ext/show_settings_menu.js @@ -46,7 +46,7 @@ define(function(require, exports, module) { // this allows the settings menu to supply a wrap limit // using a text input field easily editor.session.setWrapLimit = function (limit) { - editor.session.setWrapLimitRange(limit, limit); + editor.session.setWrapLimitRange(limit - 20, limit); }; } /** From c9f0439cf32a65f91966a7b307c7e546487c3b7a Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Mon, 1 Apr 2013 15:15:38 -0400 Subject: [PATCH 14/39] add license block --- lib/ace/ext/add_editor_menu_options.js | 32 ++++++++++++++++++++ lib/ace/ext/element_generator.js | 32 ++++++++++++++++++++ lib/ace/ext/get_editor_keyboard_shortcuts.js | 32 ++++++++++++++++++++ lib/ace/ext/overlay_page.js | 32 ++++++++++++++++++++ lib/ace/ext/show_keyboard_shortcuts.js | 32 ++++++++++++++++++++ lib/ace/ext/show_settings_menu.js | 32 ++++++++++++++++++++ 6 files changed, 192 insertions(+) diff --git a/lib/ace/ext/add_editor_menu_options.js b/lib/ace/ext/add_editor_menu_options.js index 520ead72..7a4a4322 100644 --- a/lib/ace/ext/add_editor_menu_options.js +++ b/lib/ace/ext/add_editor_menu_options.js @@ -1,3 +1,35 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + /*jslint indent: 4, maxerr: 50, diff --git a/lib/ace/ext/element_generator.js b/lib/ace/ext/element_generator.js index 13d9d833..e1cf405d 100644 --- a/lib/ace/ext/element_generator.js +++ b/lib/ace/ext/element_generator.js @@ -1,3 +1,35 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + /*jslint indent: 4, maxerr: 50, diff --git a/lib/ace/ext/get_editor_keyboard_shortcuts.js b/lib/ace/ext/get_editor_keyboard_shortcuts.js index 708dc9cf..96f830e6 100644 --- a/lib/ace/ext/get_editor_keyboard_shortcuts.js +++ b/lib/ace/ext/get_editor_keyboard_shortcuts.js @@ -1,3 +1,35 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + /*jslint indent: 4, maxerr: 50, diff --git a/lib/ace/ext/overlay_page.js b/lib/ace/ext/overlay_page.js index c6639fe5..9ff37f7f 100644 --- a/lib/ace/ext/overlay_page.js +++ b/lib/ace/ext/overlay_page.js @@ -1,3 +1,35 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + /*jslint indent: 4, maxerr: 50, diff --git a/lib/ace/ext/show_keyboard_shortcuts.js b/lib/ace/ext/show_keyboard_shortcuts.js index f4db2aa8..d1d8a97a 100644 --- a/lib/ace/ext/show_keyboard_shortcuts.js +++ b/lib/ace/ext/show_keyboard_shortcuts.js @@ -1,3 +1,35 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + /*jslint indent: 4, maxerr: 50, diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js index c00e114a..9d9810ed 100644 --- a/lib/ace/ext/show_settings_menu.js +++ b/lib/ace/ext/show_settings_menu.js @@ -1,3 +1,35 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + /*jslint indent: 4, maxerr: 50, From f6d1c1167c55450e230018fb19733f5a971518af Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Mon, 1 Apr 2013 15:34:51 -0400 Subject: [PATCH 15/39] adds show kb & settings menu to editor --- lib/ace/commands/default_commands.js | 5 ----- lib/ace/editor.js | 12 ++++++++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index 658deb87..fe58bb53 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -45,11 +45,6 @@ exports.commands = [{ name: "showSettingsMenu", bindKey: bindKey("Ctrl-,", "Command-,"), exec: function (editor) { -}, { - name: "selectall", - bindKey: bindKey("Ctrl-A", "Command-A"), - exec: function(editor) { editor.selectAll(); }, - readOnly: true }, { name: "centerselection", bindKey: bindKey(null, "Ctrl-L"), diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 14174422..8e9307f5 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -47,6 +47,8 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter; var CommandManager = require("./commands/command_manager").CommandManager; var defaultCommands = require("./commands/default_commands").commands; var config = require("./config"); +var showSettingsMenu = require("./ext/show_settings_menu").showSettingsMenu; +var showKeyboardShortcuts = require("./ext/show_keyboard_shortcuts").showKeyboardShortcuts; /** * @@ -2187,6 +2189,16 @@ var Editor = function(renderer, session) { this.renderer.removeEventListener("beforeRender", onBeforeRender); }; }; + + this.showSettingsMenu = function () { + showSettingsMenu(this); + }; + + this.showKeyboardShortcuts = function () { + showKeyboardShortcuts(this); + }; + + this.$resetCursorStyle = function() { var style = this.$cursorStyle || "ace"; From 1518a460ae8aa1414e6309e04be32d69fd4c4f66 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Mon, 1 Apr 2013 15:38:43 -0400 Subject: [PATCH 16/39] adds description to kb & settings menu methods --- lib/ace/editor.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 8e9307f5..87c51790 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -120,6 +120,7 @@ var Editor = function(renderer, session) { } }; + /** * Returns the keyboard handler, such as "vim" or "windows". * @@ -170,6 +171,7 @@ var Editor = function(renderer, session) { selection.removeEventListener("changeSelection", this.$onSelectionChange); } + this.session = session; this.$onDocumentChange = this.onDocumentChange.bind(this); @@ -2190,10 +2192,17 @@ var Editor = function(renderer, session) { }; }; + /** + * Displays a menu for changing settings. + */ this.showSettingsMenu = function () { showSettingsMenu(this); }; + /** + * Displays a menu showing all keyboard shortcuts applicable to the current + * platform. + */ this.showKeyboardShortcuts = function () { showKeyboardShortcuts(this); }; From 340f004fd0b2e289ca2985797a2451f9054789af Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Mon, 1 Apr 2013 15:44:50 -0400 Subject: [PATCH 17/39] adds getFontSize to editor --- lib/ace/editor.js | 8 ++++++++ lib/ace/ext/show_settings_menu.js | 5 ----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 87c51790..d683be2a 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -343,6 +343,14 @@ var Editor = function(renderer, session) { this.renderer.unsetStyle(style); }; + /** + * Gets the current font size of the editor text. + */ + this.getFontSize = function () { + return getComputedStyle( + this.container).getPropertyValue('font-size'); + }; + /** * Set a new font size (in pixels) for the editor text. * @param {String} size A font size ( _e.g._ "12px") diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js index 9d9810ed..311c70c1 100644 --- a/lib/ace/ext/show_settings_menu.js +++ b/lib/ace/ext/show_settings_menu.js @@ -70,11 +70,6 @@ define(function(require, exports, module) { // when building the settings menu matching get and set functions // must be found or the function will be ignored - editor.getFontSize = function () { - return getComputedStyle( - editor.container).getPropertyValue('font-size'); - }; - // this allows the settings menu to supply a wrap limit // using a text input field easily editor.session.setWrapLimit = function (limit) { From b0c08dced18e03aab032832edeff6ad6aa1be2f6 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Mon, 1 Apr 2013 15:57:30 -0400 Subject: [PATCH 18/39] adds setWrapLimit to session --- lib/ace/edit_session.js | 13 ++++++++++++- lib/ace/ext/show_settings_menu.js | 6 ------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index 60b0d4a2..23c568ee 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -1612,7 +1612,18 @@ var EditSession = function(text, mode) { this.getWrapLimit = function() { return this.$wrapLimit; }; - + + /** + * Sets the line length for soft wrap in the editor. Lines will break + * at a minimum of the given length minus 20 chars and at a maximum + * of the given number of chars. + * @param {number} limit The maximum line length in chars, for soft + * wrapping lines. + */ + this.setWrapLimit = function (limit) { + this.setWrapLimitRange(limit - 20, limit); + }; + /** * Returns an object that defines the minimum and maximum of the wrap limit; it looks something like this: * diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js index 311c70c1..3dc1a789 100644 --- a/lib/ace/ext/show_settings_menu.js +++ b/lib/ace/ext/show_settings_menu.js @@ -69,12 +69,6 @@ define(function(require, exports, module) { function addFunctionsForSettingsMenu (editor) { // when building the settings menu matching get and set functions // must be found or the function will be ignored - - // this allows the settings menu to supply a wrap limit - // using a text input field easily - editor.session.setWrapLimit = function (limit) { - editor.session.setWrapLimitRange(limit - 20, limit); - }; } /** * Generates a list of set functions for the settings menu. From 24a00578c64d8ad8ee65f368148dcae522399eaa Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Mon, 1 Apr 2013 16:01:07 -0400 Subject: [PATCH 19/39] removed unnecessary function since I've moved the functions to the editor and session objects themselves I can get rid of this. --- lib/ace/ext/show_settings_menu.js | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js index 3dc1a789..823ca3d1 100644 --- a/lib/ace/ext/show_settings_menu.js +++ b/lib/ace/ext/show_settings_menu.js @@ -58,18 +58,6 @@ define(function(require, exports, module) { var overlayPage = require('./overlay_page').overlayPage; var addEditorMenuOptions = require('./add_editor_menu_options').addEditorMenuOptions; - /** - * These functions are necessary for the settings menu - * to provide a couple really useful settings. - * @author - * Matthew Christopher Kastor-Inare III
- * ☭ Hial Atropa!! ☭ - * @param {ace.Editor} editor An instance of the ace editor. - */ - function addFunctionsForSettingsMenu (editor) { - // when building the settings menu matching get and set functions - // must be found or the function will be ignored - } /** * Generates a list of set functions for the settings menu. * @author @@ -391,7 +379,6 @@ define(function(require, exports, module) { module.exports.showSettingsMenu = function showSettingsMenu (editor) { // make sure the menu isn't open already. if(!document.getElementById('settingsmenu')) { - addFunctionsForSettingsMenu(editor); addEditorMenuOptions(editor); generateMenu(editor); } From 0a289d2468860c2f1d5386a1b93d595397361309 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Mon, 1 Apr 2013 18:12:29 -0400 Subject: [PATCH 20/39] removed left property assignment When the editor takes up the entire window and the window is only half the size of my screen, the menus get crunched up horribly. I'll provide for closing the overlay by pressing esc in case the overlay's contents take up the entire screen. If ace is to be used in very small frames then implementors will need to provide styling information in css to control how the settings menu looks. --- lib/ace/ext/show_settings_menu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js index 823ca3d1..cccc826c 100644 --- a/lib/ace/ext/show_settings_menu.js +++ b/lib/ace/ext/show_settings_menu.js @@ -366,7 +366,7 @@ define(function(require, exports, module) { cleanupElementsList(); // dump the entries from the elements list and wrap them up in a div // then put the div into the generic menu and show it. - overlayPage(wrapElements(), '0', '0', '0', '75%'); + overlayPage(wrapElements(), '0', '0', '0'); } /** * This builds the settings menu and selects From 8244231254fbb61725ffb00253b9fab36137f28e Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Mon, 1 Apr 2013 18:12:58 -0400 Subject: [PATCH 21/39] adds support for closing menus by pressing esc --- lib/ace/ext/overlay_page.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/ace/ext/overlay_page.js b/lib/ace/ext/overlay_page.js index 9ff37f7f..b398d401 100644 --- a/lib/ace/ext/overlay_page.js +++ b/lib/ace/ext/overlay_page.js @@ -77,6 +77,13 @@ module.exports.overlayPage = function overlayPage (contentElement, top, right, b var closer = document.createElement('div'); var contentContainer = document.createElement('div'); + function documentEscListener (e) { + if (e.keyCode === 27) { + closer.click(); + } + document.removeEventListener('keydown', documentEscListener); + } + closer.style.cssText = 'margin: 0; padding: 0; ' + 'position: fixed; top:0; bottom:0; left:0; right:0;' + 'z-index: 9990; ' + @@ -85,6 +92,8 @@ module.exports.overlayPage = function overlayPage (contentElement, top, right, b closer.parentNode.removeChild(closer); closer = null; }); + // click closer if esc key is pressed + document.addEventListener('keydown', documentEscListener); contentContainer.style.cssText = 'margin: 0; padding: 0; ' + 'position: absolute;' + From be52f7316a55d9c5c8f4e49d9fdb49780faf610b Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Mon, 1 Apr 2013 18:24:58 -0400 Subject: [PATCH 22/39] fix typo --- lib/ace/ext/overlay_page.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/ace/ext/overlay_page.js b/lib/ace/ext/overlay_page.js index b398d401..d9ba81f1 100644 --- a/lib/ace/ext/overlay_page.js +++ b/lib/ace/ext/overlay_page.js @@ -78,10 +78,11 @@ module.exports.overlayPage = function overlayPage (contentElement, top, right, b var contentContainer = document.createElement('div'); function documentEscListener (e) { + console.log('xd'); if (e.keyCode === 27) { closer.click(); + document.removeEventListener('keydown', documentEscListener); } - document.removeEventListener('keydown', documentEscListener); } closer.style.cssText = 'margin: 0; padding: 0; ' + From ccae5bd8d51ca896c4c89817717df5a53d88c107 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Mon, 1 Apr 2013 18:28:38 -0400 Subject: [PATCH 23/39] remove console.log --- lib/ace/ext/overlay_page.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ace/ext/overlay_page.js b/lib/ace/ext/overlay_page.js index d9ba81f1..55e03c20 100644 --- a/lib/ace/ext/overlay_page.js +++ b/lib/ace/ext/overlay_page.js @@ -78,7 +78,6 @@ module.exports.overlayPage = function overlayPage (contentElement, top, right, b var contentContainer = document.createElement('div'); function documentEscListener (e) { - console.log('xd'); if (e.keyCode === 27) { closer.click(); document.removeEventListener('keydown', documentEscListener); From b0e496de88935d343afe6fbe52670cdf9bd73c4a Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Thu, 4 Apr 2013 16:58:30 -0400 Subject: [PATCH 24/39] moved utilities to subdirectory --- lib/ace/ext/{ => menu_tools}/add_editor_menu_options.js | 0 lib/ace/ext/{ => menu_tools}/element_generator.js | 0 .../ext/{ => menu_tools}/get_editor_keyboard_shortcuts.js | 0 lib/ace/ext/{ => menu_tools}/overlay_page.js | 0 lib/ace/ext/show_keyboard_shortcuts.js | 4 ++-- lib/ace/ext/show_settings_menu.js | 6 +++--- 6 files changed, 5 insertions(+), 5 deletions(-) rename lib/ace/ext/{ => menu_tools}/add_editor_menu_options.js (100%) rename lib/ace/ext/{ => menu_tools}/element_generator.js (100%) rename lib/ace/ext/{ => menu_tools}/get_editor_keyboard_shortcuts.js (100%) rename lib/ace/ext/{ => menu_tools}/overlay_page.js (100%) diff --git a/lib/ace/ext/add_editor_menu_options.js b/lib/ace/ext/menu_tools/add_editor_menu_options.js similarity index 100% rename from lib/ace/ext/add_editor_menu_options.js rename to lib/ace/ext/menu_tools/add_editor_menu_options.js diff --git a/lib/ace/ext/element_generator.js b/lib/ace/ext/menu_tools/element_generator.js similarity index 100% rename from lib/ace/ext/element_generator.js rename to lib/ace/ext/menu_tools/element_generator.js diff --git a/lib/ace/ext/get_editor_keyboard_shortcuts.js b/lib/ace/ext/menu_tools/get_editor_keyboard_shortcuts.js similarity index 100% rename from lib/ace/ext/get_editor_keyboard_shortcuts.js rename to lib/ace/ext/menu_tools/get_editor_keyboard_shortcuts.js diff --git a/lib/ace/ext/overlay_page.js b/lib/ace/ext/menu_tools/overlay_page.js similarity index 100% rename from lib/ace/ext/overlay_page.js rename to lib/ace/ext/menu_tools/overlay_page.js diff --git a/lib/ace/ext/show_keyboard_shortcuts.js b/lib/ace/ext/show_keyboard_shortcuts.js index d1d8a97a..24412833 100644 --- a/lib/ace/ext/show_keyboard_shortcuts.js +++ b/lib/ace/ext/show_keyboard_shortcuts.js @@ -63,8 +63,8 @@ define(function(require, exports, module) { module.exports.showKeyboardShortcuts = function showKeyboardShortcuts (editor) { // make sure the menu isn't open already. if(!document.getElementById('kbshortcutmenu')) { - var overlayPage = require('./overlay_page').overlayPage; - var getEditorKeybordShortcuts = require('./get_editor_keyboard_shortcuts').getEditorKeybordShortcuts; + var overlayPage = require('./menu_tools/overlay_page').overlayPage; + var getEditorKeybordShortcuts = require('./menu_tools/get_editor_keyboard_shortcuts').getEditorKeybordShortcuts; var kb = getEditorKeybordShortcuts(editor); var el = document.createElement('div'); var commands = kb.reduce(function (previous, current) { diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js index cccc826c..c7951b48 100644 --- a/lib/ace/ext/show_settings_menu.js +++ b/lib/ace/ext/show_settings_menu.js @@ -55,8 +55,8 @@ define(function(require, exports, module) { "use strict"; - var overlayPage = require('./overlay_page').overlayPage; - var addEditorMenuOptions = require('./add_editor_menu_options').addEditorMenuOptions; + var overlayPage = require('./menu_tools/overlay_page').overlayPage; + var addEditorMenuOptions = require('./menu_tools/add_editor_menu_options').addEditorMenuOptions; /** * Generates a list of set functions for the settings menu. @@ -222,7 +222,7 @@ define(function(require, exports, module) { * the dom element's value, checked, or selected option accordingly. */ function createNewEntry(obj, clss, item, val) { - var egen = require('./element_generator'); + var egen = require('./menu_tools/element_generator'); var el; var div = document.createElement('div'); div.setAttribute('contains', item); From 0631a708bcffa9eac1f36c0c0bbb28719bee68f2 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Thu, 4 Apr 2013 17:02:41 -0400 Subject: [PATCH 25/39] removes requires from Editor --- lib/ace/editor.js | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/lib/ace/editor.js b/lib/ace/editor.js index d683be2a..fb8e9dd7 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -47,8 +47,6 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter; var CommandManager = require("./commands/command_manager").CommandManager; var defaultCommands = require("./commands/default_commands").commands; var config = require("./config"); -var showSettingsMenu = require("./ext/show_settings_menu").showSettingsMenu; -var showKeyboardShortcuts = require("./ext/show_keyboard_shortcuts").showKeyboardShortcuts; /** * @@ -2200,21 +2198,6 @@ var Editor = function(renderer, session) { }; }; - /** - * Displays a menu for changing settings. - */ - this.showSettingsMenu = function () { - showSettingsMenu(this); - }; - - /** - * Displays a menu showing all keyboard shortcuts applicable to the current - * platform. - */ - this.showKeyboardShortcuts = function () { - showKeyboardShortcuts(this); - }; - this.$resetCursorStyle = function() { From 9e9cdb3c480fa675dadf46ed74ff7ee1cab0cbee Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Thu, 4 Apr 2013 17:04:18 -0400 Subject: [PATCH 26/39] removes commands from default commands --- lib/ace/commands/default_commands.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index fe58bb53..909aa843 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -45,6 +45,16 @@ exports.commands = [{ name: "showSettingsMenu", bindKey: bindKey("Ctrl-,", "Command-,"), exec: function (editor) { + config.loadModule("ace/ext/show_keyboard_shortcuts", function (e) { + e(editor); + }); + }, + readOnly: true +}, { + name: "selectall", + bindKey: bindKey("Ctrl-A", "Command-A"), + exec: function(editor) { editor.selectAll(); }, + readOnly: true }, { name: "centerselection", bindKey: bindKey(null, "Ctrl-L"), From fb9bc6d3f42b94804033935ba150468bd0535f89 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 13 Apr 2013 20:52:50 +0400 Subject: [PATCH 27/39] prettifies menu option labels removes "set" adds space before uppercase letters. focus handling focus handling --- lib/ace/ext/menu_tools/overlay_page.js | 4 +++- lib/ace/ext/show_keyboard_shortcuts.js | 2 +- lib/ace/ext/show_settings_menu.js | 11 +++++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/ace/ext/menu_tools/overlay_page.js b/lib/ace/ext/menu_tools/overlay_page.js index 55e03c20..36de21d4 100644 --- a/lib/ace/ext/menu_tools/overlay_page.js +++ b/lib/ace/ext/menu_tools/overlay_page.js @@ -68,7 +68,7 @@ define(function(require, exports, module) { * @param {string|number} bottom absolute position value. * @param {string|number} left absolute position value. */ -module.exports.overlayPage = function overlayPage (contentElement, top, right, bottom, left) { +module.exports.overlayPage = function overlayPage (editor, contentElement, top, right, bottom, left) { top = (top) ? 'top: ' + top + ';' : ''; bottom = (bottom) ? 'bottom: ' + bottom + ';' : ''; right = (right) ? 'right: ' + right + ';' : ''; @@ -90,6 +90,7 @@ module.exports.overlayPage = function overlayPage (contentElement, top, right, b 'background-color: rgba(0, 0, 0, 0.2);'; closer.addEventListener('click', function () { closer.parentNode.removeChild(closer); + editor.focus(); closer = null; }); // click closer if esc key is pressed @@ -109,6 +110,7 @@ module.exports.overlayPage = function overlayPage (contentElement, top, right, b contentContainer.appendChild(contentElement); closer.appendChild(contentContainer); document.body.appendChild(closer); + editor.blur(); }; }); \ No newline at end of file diff --git a/lib/ace/ext/show_keyboard_shortcuts.js b/lib/ace/ext/show_keyboard_shortcuts.js index 24412833..14e44f75 100644 --- a/lib/ace/ext/show_keyboard_shortcuts.js +++ b/lib/ace/ext/show_keyboard_shortcuts.js @@ -75,7 +75,7 @@ define(function(require, exports, module) { el.id = 'kbshortcutmenu'; el.innerHTML = '

Keyboard Shortcuts

' + commands + ''; el.style.cssText = 'margin:0; padding:0;'; - overlayPage(el, '0', '0', '0', null); + overlayPage(editor, el, '0', '0', '0', null); } }; }); \ No newline at end of file diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js index c7951b48..5b87f0d9 100644 --- a/lib/ace/ext/show_settings_menu.js +++ b/lib/ace/ext/show_settings_menu.js @@ -229,7 +229,14 @@ define(function(require, exports, module) { div.setAttribute('class', 'menuEntry'); div.setAttribute('style', 'clear: both;'); - div.appendChild(egen.createLabel(item, item)); + div.appendChild(egen.createLabel( + item.replace( + /^set/, '' + ).replace( + /([A-Z])/g, ' $1' + ).trim(), + item + )); if(Array.isArray(val)) { el = egen.createSelection(item, val, clss); @@ -366,7 +373,7 @@ define(function(require, exports, module) { cleanupElementsList(); // dump the entries from the elements list and wrap them up in a div // then put the div into the generic menu and show it. - overlayPage(wrapElements(), '0', '0', '0'); + overlayPage(editor, wrapElements(), '0', '0', '0'); } /** * This builds the settings menu and selects From b1ac3713878667547d094f95580ea6ea2169b767 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Thu, 4 Apr 2013 20:12:01 -0400 Subject: [PATCH 28/39] fixes esc event listener removal --- lib/ace/ext/menu_tools/overlay_page.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/ext/menu_tools/overlay_page.js b/lib/ace/ext/menu_tools/overlay_page.js index 36de21d4..0e18d20e 100644 --- a/lib/ace/ext/menu_tools/overlay_page.js +++ b/lib/ace/ext/menu_tools/overlay_page.js @@ -80,7 +80,6 @@ module.exports.overlayPage = function overlayPage (editor, contentElement, top, function documentEscListener (e) { if (e.keyCode === 27) { closer.click(); - document.removeEventListener('keydown', documentEscListener); } } @@ -89,6 +88,7 @@ module.exports.overlayPage = function overlayPage (editor, contentElement, top, 'z-index: 9990; ' + 'background-color: rgba(0, 0, 0, 0.2);'; closer.addEventListener('click', function () { + document.removeEventListener('keydown', documentEscListener); closer.parentNode.removeChild(closer); editor.focus(); closer = null; From d531866663772bae9c8fa950bfb9cd73120dbac5 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Thu, 4 Apr 2013 20:12:38 -0400 Subject: [PATCH 29/39] augments Editor.prototype --- lib/ace/ext/show_keyboard_shortcuts.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/ace/ext/show_keyboard_shortcuts.js b/lib/ace/ext/show_keyboard_shortcuts.js index 14e44f75..a15dbe41 100644 --- a/lib/ace/ext/show_keyboard_shortcuts.js +++ b/lib/ace/ext/show_keyboard_shortcuts.js @@ -53,6 +53,7 @@ define(function(require, exports, module) { "use strict"; + var Editor = require("ace/editor").Editor; /** * Generates a menu which displays the keyboard shortcuts. * @author
@@ -78,4 +79,7 @@ define(function(require, exports, module) { overlayPage(editor, el, '0', '0', '0', null); } }; + Editor.prototype.showKeyboardShortcuts = function () { + module.exports.showKeyboardShortcuts(this); + }; }); \ No newline at end of file From f5500fefc4848e706c187ef4d3f799b83ea2641b Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Thu, 4 Apr 2013 20:14:02 -0400 Subject: [PATCH 30/39] adds demo show_keyboard_shortcuts --- demo/show_keyboard_shortcuts.html | 41 +++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 demo/show_keyboard_shortcuts.html diff --git a/demo/show_keyboard_shortcuts.html b/demo/show_keyboard_shortcuts.html new file mode 100644 index 00000000..e4f42a65 --- /dev/null +++ b/demo/show_keyboard_shortcuts.html @@ -0,0 +1,41 @@ + + + + + + Editor + + + + +
function foo(items) {
+    var i;
+    for (i = 0; i < items.length; i++) {
+        alert("Ace Rocks " + items[i]);
+    }
+}
+ + + + + + + From 7aac105a07f5a7c47503b784d4b3fc945b0933cd Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Thu, 4 Apr 2013 20:20:02 -0400 Subject: [PATCH 31/39] augments Editor.prototype --- lib/ace/ext/show_settings_menu.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js index 5b87f0d9..7c94e420 100644 --- a/lib/ace/ext/show_settings_menu.js +++ b/lib/ace/ext/show_settings_menu.js @@ -55,6 +55,7 @@ define(function(require, exports, module) { "use strict"; + var Editor = require("ace/editor").Editor; var overlayPage = require('./menu_tools/overlay_page').overlayPage; var addEditorMenuOptions = require('./menu_tools/add_editor_menu_options').addEditorMenuOptions; @@ -390,4 +391,8 @@ define(function(require, exports, module) { generateMenu(editor); } }; + Editor.prototype.showSettingsMenu = function () { + module.exports.showSettingsMenu(this); + }; + }); \ No newline at end of file From 3adba8eb21b9e023883030adfb2ce5f7fad28e2b Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 13 Apr 2013 20:52:58 +0400 Subject: [PATCH 32/39] adds demo show_settings_menu adds keyboard shortcut on init adds keyboard shortcut on init --- demo/show_keyboard_shortcuts.html | 2 +- demo/show_settings_menu.html | 41 ++++++++++++++++++++++++++ lib/ace/ext/show_keyboard_shortcuts.js | 16 ++++++++-- lib/ace/ext/show_settings_menu.js | 18 ++++++++--- 4 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 demo/show_settings_menu.html diff --git a/demo/show_keyboard_shortcuts.html b/demo/show_keyboard_shortcuts.html index e4f42a65..8d456c5b 100644 --- a/demo/show_keyboard_shortcuts.html +++ b/demo/show_keyboard_shortcuts.html @@ -31,8 +31,8 @@ diff --git a/demo/show_settings_menu.html b/demo/show_settings_menu.html new file mode 100644 index 00000000..b23d9a6b --- /dev/null +++ b/demo/show_settings_menu.html @@ -0,0 +1,41 @@ + + + + + + Editor + + + + +
function foo(items) {
+    var i;
+    for (i = 0; i < items.length; i++) {
+        alert("Ace Rocks " + items[i]);
+    }
+}
+ + + + + + + diff --git a/lib/ace/ext/show_keyboard_shortcuts.js b/lib/ace/ext/show_keyboard_shortcuts.js index a15dbe41..d7405aa7 100644 --- a/lib/ace/ext/show_keyboard_shortcuts.js +++ b/lib/ace/ext/show_keyboard_shortcuts.js @@ -61,7 +61,7 @@ define(function(require, exports, module) { * ☭ Hial Atropa!! ☭ * @param {ace.Editor} editor An instance of the ace editor. */ - module.exports.showKeyboardShortcuts = function showKeyboardShortcuts (editor) { + function showKeyboardShortcuts (editor) { // make sure the menu isn't open already. if(!document.getElementById('kbshortcutmenu')) { var overlayPage = require('./menu_tools/overlay_page').overlayPage; @@ -79,7 +79,17 @@ define(function(require, exports, module) { overlayPage(editor, el, '0', '0', '0', null); } }; - Editor.prototype.showKeyboardShortcuts = function () { - module.exports.showKeyboardShortcuts(this); + module.exports.init = function (editor) { + Editor.prototype.showKeyboardShortcuts = function () { + showKeyboardShortcuts(this); + }; + editor.commands.addCommands([{ + name: "showKeyboardShortcuts", + bindKey: {win: "Ctrl-Alt-h", mac: "Command-Alt-h"}, + exec: function(editor, line) { + editor.showKeyboardShortcuts(); + } + }]); }; + }); \ No newline at end of file diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js index 7c94e420..75c7fe88 100644 --- a/lib/ace/ext/show_settings_menu.js +++ b/lib/ace/ext/show_settings_menu.js @@ -384,15 +384,25 @@ define(function(require, exports, module) { * ☭ Hial Atropa!! ☭ * @param {ace.Editor} editor An instance of the ace editor. */ - module.exports.showSettingsMenu = function showSettingsMenu (editor) { + function showSettingsMenu (editor) { // make sure the menu isn't open already. if(!document.getElementById('settingsmenu')) { addEditorMenuOptions(editor); generateMenu(editor); } }; - Editor.prototype.showSettingsMenu = function () { - module.exports.showSettingsMenu(this); - }; + module.exports.init = function (editor) { + Editor.prototype.showSettingsMenu = function () { + showSettingsMenu(this); + }; + editor.commands.addCommands([{ + name: "showSettingsMenu", + bindKey: {win: "Ctrl-q", mac: "Command-q"}, + exec: function(editor, line) { + editor.showSettingsMenu(); + }, + readOnly: true + }]); + }; }); \ No newline at end of file From 1a4af9aff99be8455c26c86cb42cfc0aaf5eeb82 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Thu, 4 Apr 2013 21:38:53 -0400 Subject: [PATCH 33/39] example code explains extension --- demo/show_keyboard_shortcuts.html | 15 ++++++++++----- demo/show_settings_menu.html | 18 ++++++++++++------ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/demo/show_keyboard_shortcuts.html b/demo/show_keyboard_shortcuts.html index 8d456c5b..c55902f6 100644 --- a/demo/show_keyboard_shortcuts.html +++ b/demo/show_keyboard_shortcuts.html @@ -21,12 +21,17 @@ -
function foo(items) {
-    var i;
-    for (i = 0; i < items.length; i++) {
-        alert("Ace Rocks " + items[i]);
+
Editor.prototype.showKeyboardShortcuts = function () {
+    showKeyboardShortcuts(this);
+};
+editor.commands.addCommands([{
+    name: "showKeyboardShortcuts",
+    bindKey: {win: "Ctrl-Alt-h", mac: "Command-Alt-h"},
+    exec: function(editor, line) {
+        editor.showKeyboardShortcuts();
     }
-}
+}]); +
diff --git a/demo/show_settings_menu.html b/demo/show_settings_menu.html index b23d9a6b..72de2357 100644 --- a/demo/show_settings_menu.html +++ b/demo/show_settings_menu.html @@ -21,12 +21,18 @@ -
function foo(items) {
-    var i;
-    for (i = 0; i < items.length; i++) {
-        alert("Ace Rocks " + items[i]);
-    }
-}
+
Editor.prototype.showSettingsMenu = function () {
+    showSettingsMenu(this);
+};
+editor.commands.addCommands([{
+    name: "showSettingsMenu",
+    bindKey: {win: "Ctrl-q", mac: "Command-q"},
+    exec: function(editor, line) {
+        editor.showSettingsMenu();
+    },
+    readOnly: true
+}]);
+
From 47329e944f9293ab719dedb1cd7386910f96c5ee Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Fri, 5 Apr 2013 01:33:56 -0400 Subject: [PATCH 34/39] Merge modelist branch & use it This branch now depends on the modelist being pulled in as a module. I'm using the modelist to generate the menu options for switching modes because it's redundant to have the same massive list in two places. The modelist module also has some awesome features so I choose it over my silly list. :D --- .../ext/menu_tools/add_editor_menu_options.js | 227 +----------------- 1 file changed, 9 insertions(+), 218 deletions(-) diff --git a/lib/ace/ext/menu_tools/add_editor_menu_options.js b/lib/ace/ext/menu_tools/add_editor_menu_options.js index 7a4a4322..61296124 100644 --- a/lib/ace/ext/menu_tools/add_editor_menu_options.js +++ b/lib/ace/ext/menu_tools/add_editor_menu_options.js @@ -66,6 +66,7 @@ define(function(require, exports, module) { * @param {ace.Editor} editor An instance of the ace editor. */ module.exports.addEditorMenuOptions = function addEditorMenuOptions (editor) { + var modelist = require('../modelist'); editor.menuOptions = { "setNewLineMode" : [{ "textContent" : "unix", @@ -167,225 +168,15 @@ module.exports.addEditorMenuOptions = function addEditorMenuOptions (editor) { "value" : "ace/theme/xcode" } ], - "setMode" : [{ - "textContent" : "abap", - "value" : "ace/mode/abap" - }, { - "textContent" : "asciidoc", - "value" : "ace/mode/asciidoc" - }, { - "textContent" : "c9search", - "value" : "ace/mode/c9search" - }, { - "textContent" : "clojure", - "value" : "ace/mode/clojure" - }, { - "textContent" : "coffee", - "value" : "ace/mode/coffee" - }, { - "textContent" : "coldfusion", - "value" : "ace/mode/coldfusion" - }, { - "textContent" : "csharp", - "value" : "ace/mode/csharp" - }, { - "textContent" : "css", - "value" : "ace/mode/css" - }, { - "textContent" : "curly", - "value" : "ace/mode/curly" - }, { - "textContent" : "c_cpp", - "value" : "ace/mode/c_cpp" - }, { - "textContent" : "dart", - "value" : "ace/mode/dart" - }, { - "textContent" : "diff", - "value" : "ace/mode/diff" - }, { - "textContent" : "django", - "value" : "ace/mode/django" - }, { - "textContent" : "dot", - "value" : "ace/mode/dot" - }, { - "textContent" : "ftl", - "value" : "ace/mode/ftl" - }, { - "textContent" : "glsl", - "value" : "ace/mode/glsl" - }, { - "textContent" : "golang", - "value" : "ace/mode/golang" - }, { - "textContent" : "groovy", - "value" : "ace/mode/groovy" - }, { - "textContent" : "haml", - "value" : "ace/mode/haml" - }, { - "textContent" : "haxe", - "value" : "ace/mode/haxe" - }, { - "textContent" : "html", - "value" : "ace/mode/html" - }, { - "textContent" : "jade", - "value" : "ace/mode/jade" - }, { - "textContent" : "java", - "value" : "ace/mode/java" - }, { - "textContent" : "javascript", - "value" : "ace/mode/javascript" - }, { - "textContent" : "json", - "value" : "ace/mode/json" - }, { - "textContent" : "jsp", - "value" : "ace/mode/jsp" - }, { - "textContent" : "jsx", - "value" : "ace/mode/jsx" - }, { - "textContent" : "latex", - "value" : "ace/mode/latex" - }, { - "textContent" : "less", - "value" : "ace/mode/less" - }, { - "textContent" : "liquid", - "value" : "ace/mode/liquid" - }, { - "textContent" : "lisp", - "value" : "ace/mode/lisp" - }, { - "textContent" : "livescript", - "value" : "ace/mode/livescript" - }, { - "textContent" : "logiql", - "value" : "ace/mode/logiql" - }, { - "textContent" : "lsl", - "value" : "ace/mode/lsl" - }, { - "textContent" : "lua", - "value" : "ace/mode/lua" - }, { - "textContent" : "luapage", - "value" : "ace/mode/luapage" - }, { - "textContent" : "lucene", - "value" : "ace/mode/lucene" - }, { - "textContent" : "makefile", - "value" : "ace/mode/makefile" - }, { - "textContent" : "markdown", - "value" : "ace/mode/markdown" - }, { - "textContent" : "objectivec", - "value" : "ace/mode/objectivec" - }, { - "textContent" : "ocaml", - "value" : "ace/mode/ocaml" - }, { - "textContent" : "pascal", - "value" : "ace/mode/pascal" - }, { - "textContent" : "perl", - "value" : "ace/mode/perl" - }, { - "textContent" : "pgsql", - "value" : "ace/mode/pgsql" - }, { - "textContent" : "php", - "value" : "ace/mode/php" - }, { - "textContent" : "powershell", - "value" : "ace/mode/powershell" - }, { - "textContent" : "python", - "value" : "ace/mode/python" - }, { - "textContent" : "r", - "value" : "ace/mode/r" - }, { - "textContent" : "rdoc", - "value" : "ace/mode/rdoc" - }, { - "textContent" : "rhtml", - "value" : "ace/mode/rhtml" - }, { - "textContent" : "ruby", - "value" : "ace/mode/ruby" - }, { - "textContent" : "sass", - "value" : "ace/mode/sass" - }, { - "textContent" : "scad", - "value" : "ace/mode/scad" - }, { - "textContent" : "scala", - "value" : "ace/mode/scala" - }, { - "textContent" : "scheme", - "value" : "ace/mode/scheme" - }, { - "textContent" : "scss", - "value" : "ace/mode/scss" - }, { - "textContent" : "sh", - "value" : "ace/mode/sh" - }, { - "textContent" : "sql", - "value" : "ace/mode/sql" - }, { - "textContent" : "stylus", - "value" : "ace/mode/stylus" - }, { - "textContent" : "svg", - "value" : "ace/mode/svg" - }, { - "textContent" : "tcl", - "value" : "ace/mode/tcl" - }, { - "textContent" : "tex", - "value" : "ace/mode/tex" - }, { - "textContent" : "text", - "value" : "ace/mode/text" - }, { - "textContent" : "textile", - "value" : "ace/mode/textile" - }, { - "textContent" : "tmsnippet", - "value" : "ace/mode/tmsnippet" - }, { - "textContent" : "tm_snippet", - "value" : "ace/mode/tm_snippet" - }, { - "textContent" : "toml", - "value" : "ace/mode/toml" - }, { - "textContent" : "typescript", - "value" : "ace/mode/typescript" - }, { - "textContent" : "vbscript", - "value" : "ace/mode/vbscript" - }, { - "textContent" : "xml", - "value" : "ace/mode/xml" - }, { - "textContent" : "xquery", - "value" : "ace/mode/xquery" - }, { - "textContent" : "yaml", - "value" : "ace/mode/yaml" - } - ] + "setMode" : [] }; + + modelist.modes.forEach(function (mode) { + editor.menuOptions.setMode.push({ + 'textContent' : mode.name, + 'value' : mode.mode + }); + }); }; From dd33d82528869f9534f8864b810986db35a14118 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Fri, 5 Apr 2013 16:46:18 -0400 Subject: [PATCH 35/39] build now generates themes.js This module simply exports an array of themes available so we can use it. --- Makefile.dryice.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Makefile.dryice.js b/Makefile.dryice.js index d544aad6..1d258db7 100755 --- a/Makefile.dryice.js +++ b/Makefile.dryice.js @@ -309,6 +309,8 @@ var buildAce = function(options) { for(var key in defaults) if (!options.hasOwnProperty(key)) options[key] = defaults[key]; + + generateThemesModule(options.themes); addSuffix(options); @@ -487,6 +489,15 @@ var detectTextModules = function(input, source) { detectTextModules.onRead = true; copy.filter.addDefines = detectTextModules; +function generateThemesModule(themes) { + var themelist = [ + 'define(function(require, exports, module) {', + '\n\nmodule.exports.themes = ' + JSON.stringify(themes, null, ' '), + ';\n\n});' + ].join(''); + fs.writeFileSync('./lib/ace/ext/themelist_utils/themes.js', themelist, 'utf8'); +} + function inlineTextModules(text) { var lastDep = ""; return text.replace(/, *['"]ace\/requirejs\/text!(.*?)['"]|= *require\(['"](?:ace|[.\/]+)\/requirejs\/text!(.*?)['"]\)/g, function(_, dep, call) { From 2107796de5f9c4cfccf3790013c4eed18290cb11 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Fri, 5 Apr 2013 16:47:11 -0400 Subject: [PATCH 36/39] autogenerated themes.js during build --- lib/ace/ext/themelist_utils/themes.js | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 lib/ace/ext/themelist_utils/themes.js diff --git a/lib/ace/ext/themelist_utils/themes.js b/lib/ace/ext/themelist_utils/themes.js new file mode 100644 index 00000000..6b20770a --- /dev/null +++ b/lib/ace/ext/themelist_utils/themes.js @@ -0,0 +1,36 @@ +define(function(require, exports, module) { + +module.exports.themes = [ + "ambiance", + "chaos", + "chrome", + "clouds", + "clouds_midnight", + "cobalt", + "crimson_editor", + "dawn", + "dreamweaver", + "eclipse", + "github", + "idle_fingers", + "kr_theme", + "merbivore", + "merbivore_soft", + "monokai", + "mono_industrial", + "pastel_on_dark", + "solarized_dark", + "solarized_light", + "terminal", + "textmate", + "tomorrow", + "tomorrow_night", + "tomorrow_night_blue", + "tomorrow_night_bright", + "tomorrow_night_eighties", + "twilight", + "vibrant_ink", + "xcode" +]; + +}); \ No newline at end of file From 5ea87bd96dac1ce558045131971b435c348af3e6 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Fri, 5 Apr 2013 16:48:06 -0400 Subject: [PATCH 37/39] themelist consumes themes.js & mimics modelist --- lib/ace/ext/themelist.js | 88 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 lib/ace/ext/themelist.js diff --git a/lib/ace/ext/themelist.js b/lib/ace/ext/themelist.js new file mode 100644 index 00000000..9610e691 --- /dev/null +++ b/lib/ace/ext/themelist.js @@ -0,0 +1,88 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/*jslint + indent: 4, + maxerr: 50, + white: true, + browser: true, + vars: true +*/ +/*global + define, + require +*/ + +/** + * Generates a list of themes available when ace was built. + * @fileOverview Generates a list of themes available when ace was built. + * @author
+ * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +"use strict"; + +/** + * An array containing information about available themes. + */ +module.exports.themes = require('ace/ext/themelist_utils/themes').themes; + +/** + * Creates a theme description. + * @param {string} name The file name of the theme. + * @returns {ThemeDescription} Returns a theme description object which has + * three properties: the name gives the filename, the desc gives a menu + * friendly name, and the theme gives the string to set the theme with + * `setTheme` + */ +module.exports.ThemeDescription = function(name) { + this.name = name; + this.desc = name.split('_' + ).map( + function (namePart) { + return namePart[0].toUpperCase() + namePart.slice(1); + } + ).join(' '); + this.theme = "ace/theme/" + name; +}; + +module.exports.themesByName = {}; + +module.exports.themes = module.exports.themes.map(function (name) { + module.exports.themesByName[name] = new module.exports.ThemeDescription(name); + return module.exports.themesByName[name]; +}); + +}); + From 60616deec06b22bdf6f1aac9d79f3a2ae171fb79 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Fri, 5 Apr 2013 16:49:18 -0400 Subject: [PATCH 38/39] add_editor_menu_options uses themelist to generate theme options --- .../ext/menu_tools/add_editor_menu_options.js | 106 +++--------------- 1 file changed, 13 insertions(+), 93 deletions(-) diff --git a/lib/ace/ext/menu_tools/add_editor_menu_options.js b/lib/ace/ext/menu_tools/add_editor_menu_options.js index 61296124..9e000685 100644 --- a/lib/ace/ext/menu_tools/add_editor_menu_options.js +++ b/lib/ace/ext/menu_tools/add_editor_menu_options.js @@ -52,7 +52,7 @@ * Matthew Christopher Kastor-Inare III
* ☭ Hial Atropa!! ☭ */ - + define(function(require, exports, module) { 'use strict'; @@ -67,6 +67,7 @@ define(function(require, exports, module) { */ module.exports.addEditorMenuOptions = function addEditorMenuOptions (editor) { var modelist = require('../modelist'); + var themelist = require('../themelist'); editor.menuOptions = { "setNewLineMode" : [{ "textContent" : "unix", @@ -79,103 +80,22 @@ module.exports.addEditorMenuOptions = function addEditorMenuOptions (editor) { "value" : "auto" } ], - "setTheme" : [{ - "textContent" : "ambiance", - "value" : "ace/theme/ambiance" - }, { - "textContent" : "chaos", - "value" : "ace/theme/chaos" - }, { - "textContent" : "chrome", - "value" : "ace/theme/chrome" - }, { - "textContent" : "clouds", - "value" : "ace/theme/clouds" - }, { - "textContent" : "clouds_midnight", - "value" : "ace/theme/clouds_midnight" - }, { - "textContent" : "cobalt", - "value" : "ace/theme/cobalt" - }, { - "textContent" : "crimson_editor", - "value" : "ace/theme/crimson_editor" - }, { - "textContent" : "dawn", - "value" : "ace/theme/dawn" - }, { - "textContent" : "dreamweaver", - "value" : "ace/theme/dreamweaver" - }, { - "textContent" : "eclipse", - "value" : "ace/theme/eclipse" - }, { - "textContent" : "github", - "value" : "ace/theme/github" - }, { - "textContent" : "idle_fingers", - "value" : "ace/theme/idle_fingers" - }, { - "textContent" : "kr", - "value" : "ace/theme/kr" - }, { - "textContent" : "merbivore", - "value" : "ace/theme/merbivore" - }, { - "textContent" : "merbivore_soft", - "value" : "ace/theme/merbivore_soft" - }, { - "textContent" : "monokai", - "value" : "ace/theme/monokai" - }, { - "textContent" : "mono_industrial", - "value" : "ace/theme/mono_industrial" - }, { - "textContent" : "pastel_on_dark", - "value" : "ace/theme/pastel_on_dark" - }, { - "textContent" : "solarized_dark", - "value" : "ace/theme/solarized_dark" - }, { - "textContent" : "solarized_light", - "value" : "ace/theme/solarized_light" - }, { - "textContent" : "textmate", - "value" : "ace/theme/textmate" - }, { - "textContent" : "tomorrow", - "value" : "ace/theme/tomorrow" - }, { - "textContent" : "tomorrow_night", - "value" : "ace/theme/tomorrow_night" - }, { - "textContent" : "tomorrow_night_blue", - "value" : "ace/theme/tomorrow_night_blue" - }, { - "textContent" : "tomorrow_night_bright", - "value" : "ace/theme/tomorrow_night_bright" - }, { - "textContent" : "tomorrow_night_eighties", - "value" : "ace/theme/tomorrow_night_eighties" - }, { - "textContent" : "twilight", - "value" : "ace/theme/twilight" - }, { - "textContent" : "vibrant_ink", - "value" : "ace/theme/vibrant_ink" - }, { - "textContent" : "xcode", - "value" : "ace/theme/xcode" - } - ], + "setTheme" : [], "setMode" : [] }; - modelist.modes.forEach(function (mode) { - editor.menuOptions.setMode.push({ + editor.menuOptions.setTheme = themelist.themes.map(function (theme) { + return { + 'textContent' : theme.desc, + 'value' : theme.theme + }; + }); + + editor.menuOptions.setMode = modelist.modes.map(function (mode) { + return { 'textContent' : mode.name, 'value' : mode.mode - }); + }; }); }; From 408b190bb0d173b32f17573fcaa627ba029873d4 Mon Sep 17 00:00:00 2001 From: Matthew Kastor Date: Fri, 5 Apr 2013 17:50:02 -0400 Subject: [PATCH 39/39] refactored settings menu extension --- .../ext/menu_tools/generate_settings_menu.js | 272 ++++++++++++++ lib/ace/ext/menu_tools/get_set_functions.js | 155 ++++++++ lib/ace/ext/show_settings_menu.js | 340 +----------------- 3 files changed, 440 insertions(+), 327 deletions(-) create mode 100644 lib/ace/ext/menu_tools/generate_settings_menu.js create mode 100644 lib/ace/ext/menu_tools/get_set_functions.js diff --git a/lib/ace/ext/menu_tools/generate_settings_menu.js b/lib/ace/ext/menu_tools/generate_settings_menu.js new file mode 100644 index 00000000..cc81fa44 --- /dev/null +++ b/lib/ace/ext/menu_tools/generate_settings_menu.js @@ -0,0 +1,272 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/*jslint + indent: 4, + maxerr: 50, + white: true, + browser: true, + vars: true +*/ +/*global + define +*/ + +/** + * Generates the settings menu + * @fileOverview Generates the settings menu. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +'use strict'; +/** + * Generates an interactive menu with settings useful to end users. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {ace.Editor} editor An instance of the ace editor. + */ +module.exports.generateSettingsMenu = function generateSettingsMenu (editor) { + var addEditorMenuOptions = require('./add_editor_menu_options').addEditorMenuOptions; + var getSetFunctions = require('./get_set_functions').getSetFunctions; + /** + * container for dom elements that will go in the menu. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + var elements = []; + /** + * Sorts the menu entries (elements var) so they'll appear in alphabetical order + * the sort is performed based on the value of the contains property + * of each element. Since this is an `array.sort` the array is sorted + * in place. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + function cleanupElementsList() { + elements.sort(function (a, b) { + var x = a.getAttribute('contains'); + var y = b.getAttribute('contains'); + return x.localeCompare(y); + }); + } + /** + * Wraps all dom elements contained in the elements var with a single + * div. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + function wrapElements() { + var topmenu = document.createElement('div'); + topmenu.setAttribute('id', 'settingsmenu'); + elements.forEach(function (element) { + topmenu.appendChild(element); + }); + return topmenu; + } + /** + * Creates a new menu entry. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {object} obj This is a reference to the object containing the + * set function. It is used to set up event listeners for when the + * menu options change. + * @param {string} clss Maps to the class of the dom element. This is + * the name of the object containing the set function e.g. `editor`, + * `session`, `renderer`. + * @param {string} item This is the set function name. It maps to the + * id of the dom element (check, select, input) and to the "contains" + * attribute of the div holding both the element and its label. + * @param {mixed} val This is the value of the setting. It is mapped to + * the dom element's value, checked, or selected option accordingly. + */ + function createNewEntry(obj, clss, item, val) { + var egen = require('./element_generator'); + var el; + var div = document.createElement('div'); + div.setAttribute('contains', item); + div.setAttribute('class', 'menuEntry'); + div.setAttribute('style', 'clear: both;'); + + div.appendChild(egen.createLabel( + item.replace( + /^set/, '' + ).replace( + /([A-Z])/g, ' $1' + ).trim(), + item + )); + + if(Array.isArray(val)) { + el = egen.createSelection(item, val, clss); + el.addEventListener('change', function (e) { + try{ + editor.menuOptions[e.target.id].forEach(function (x) { + if(x.textContent !== e.target.textContent) { + delete x.selected; + } + }); + // editor.session['setMode']('ace/mode/javascript') + obj[e.target.id](e.target.value); + } catch (err) { + throw new Error(err); + } + }); + } else if(typeof val === 'boolean') { + el = egen.createCheckbox(item, val, clss); + el.addEventListener('change', function (e) { + try{ + // renderer['setHighlightGutterLine'](true); + obj[e.target.id](!!e.target.checked); + } catch (err) { + throw new Error(err); + } + }); + } else { + // this aids in giving the ability to specify settings through + // post and get requests. + // /ace_editor.html?setMode=ace/mode/html&setOverwrite=true + el = egen.createInput(item, val, clss); + el.addEventListener('blur', function (e) { + try{ + if(e.target.value === 'true') { + obj[e.target.id](true); + } else if(e.target.value === 'false') { + obj[e.target.id](false); + } else { + obj[e.target.id](e.target.value); + } + } catch (err) { + throw new Error(err); + } + }); + } + el.style.cssText = 'float:right;'; + div.appendChild(el); + return div; + } + /** + * Generates selection fields for the menu and populates their options + * using information from `editor.menuOptions` + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {string} item The set function name. + * @param {object} esr A reference to the object having the set function. + * @param {string} clss The name of the object containing the set function. + * @param {string} fn The matching get function's function name. + * @returns {DOMElement} Returns a dom element containing a selection + * element populated with options. The option whose value matches that + * returned from `esr[fn]()` will be selected. + */ + function makeDropdown(item, esr, clss, fn) { + var val = editor.menuOptions[item]; + val = val.map(function (valuex) { + if(valuex.value === esr[fn]()) { + valuex.selected = 'selected'; + } else if(valuex.value === esr.$modeId) { + // is mode + valuex.selected = 'selected'; + } + return valuex; + }); + return createNewEntry(esr, clss, item, val); + } + /** + * Processes the set functions returned from `getSetFunctions`. First it + * checks for menu options defined in `editor.menuOptions`. If no + * options are specified then it checks whether there is a get function + * (replace set with get) for the setting. When either of those + * conditions are met it will attempt to create a new entry for the + * settings menu and push it into the elements array defined above. + * It can only do so for get functions which return + * strings, numbers, and booleans. A special case is written in for + * `getMode` where it looks at the returned objects `$id` property and + * forwards that through instead. Other special cases could be written + * in but that would get a bit ridiculous. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {object} setObj An item from the array returned by + * `getSetFunctions`. + */ + function handleSet (setObj) { + var item = setObj.functionName; + var esr = setObj.parentObj; + var clss = setObj.parentName; + var val; + var fn = item.replace(/^set/, 'get'); + if(editor.menuOptions[item] !== undefined) { + // has options for select element + elements.push(makeDropdown(item, esr, clss, fn)); + } else if(typeof esr[fn] === 'function') { + // has get function + try { + val = esr[fn](); + if(typeof val === 'object') { + // setMode takes a string, getMode returns an object + // the $id property of that object is the string + // which may be given to setMode... + val = val.$id; + } + // the rest of the get functions return strings, + // booleans, or numbers. + elements.push( + createNewEntry(esr, clss, item, val) + ); + } catch (e) { + // if there are errors it is because the element + // does not belong in the settings menu + } + } + } + addEditorMenuOptions(editor); + // gather the set functions + getSetFunctions(editor).forEach(function (setObj) { + // populate the elements array with good stuff. + handleSet(setObj); + }); + // sort the menu entries in the elements list so people can find + // the settings in alphabetical order. + cleanupElementsList(); + // dump the entries from the elements list and wrap them up in a div + return wrapElements(); +}; + +}); \ No newline at end of file diff --git a/lib/ace/ext/menu_tools/get_set_functions.js b/lib/ace/ext/menu_tools/get_set_functions.js new file mode 100644 index 00000000..ba5a757b --- /dev/null +++ b/lib/ace/ext/menu_tools/get_set_functions.js @@ -0,0 +1,155 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2013 Matthew Christopher Kastor-Inare III, Atropa Inc. Intl + * All rights reserved. + * + * Contributed to Ajax.org under the BSD license. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/*jslint + indent: 4, + maxerr: 50, + white: true, + browser: true, + vars: true +*/ +/*global + define +*/ + +/** + * Get Set Functions + * @fileOverview Get Set Functions
+ * Gets various functions for setting settings. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + +define(function(require, exports, module) { +'use strict'; +/** + * Generates a list of set functions for the settings menu. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + * @param {object} editor The editor instance + * @return {array} Returns an array of objects. Each object contains the + * following properties: functionName, parentObj, and parentName. The + * function name will be the name of a method beginning with the string + * `set` which was found. The parent object will be a reference to the + * object having the method matching the function name. The parent name + * will be a string representing the identifier of the parent object e.g. + * `editor`, `session`, or `renderer`. + */ +module.exports.getSetFunctions = function getSetFunctions (editor) { + /** + * Output array. Will hold the objects described above. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + var out = []; + /** + * This object provides a map between the objects which will be + * traversed and the parent name which will appear in the output. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + var my = { + 'editor' : editor, + 'session' : editor.session, + 'renderer' : editor.renderer + }; + /** + * This array will hold the set function names which have already been + * found so that they are not added to the output multiple times. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + var opts = []; + /** + * This is a list of set functions which will not appear in the settings + * menu. I don't know what to do with setKeyboardHandler. When I tried + * to use it, it didn't appear to be working. Someone who knows better + * could remove it from this list and add it's options to + * add_editor_menu_options.js + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + var skip = [ + 'setOption', + 'setUndoManager', + 'setDocument', + 'setValue', + 'setBreakpoints', + 'setScrollTop', + 'setScrollLeft', + 'setSelectionStyle', + 'setWrapLimitRange', + 'setKeyboardHandler' + ]; + + + /** + * This will search the objects mapped to the `my` variable above. When + * it finds a set function in the object that is not listed in the + * `skip` list or the `opts` list it will push a new object to the + * output array. + * @author + * Matthew Christopher Kastor-Inare III
+ * ☭ Hial Atropa!! ☭ + */ + [ + 'renderer', + 'session', + 'editor' + ].forEach(function (esra) { + var fn; + var esr = my[esra]; + var clss = esra; + for(fn in esr) { + if(skip.indexOf(fn) === -1) { + if(/^set/.test(fn) && opts.indexOf(fn) === -1) { + // found set function + opts.push(fn); + out.push({ + 'functionName' : fn, + 'parentObj' : esr, + 'parentName' : clss + }); + } + } + } + }); + return out; +}; + +}); \ No newline at end of file diff --git a/lib/ace/ext/show_settings_menu.js b/lib/ace/ext/show_settings_menu.js index 75c7fe88..15eb8027 100644 --- a/lib/ace/ext/show_settings_menu.js +++ b/lib/ace/ext/show_settings_menu.js @@ -55,344 +55,30 @@ define(function(require, exports, module) { "use strict"; - var Editor = require("ace/editor").Editor; - var overlayPage = require('./menu_tools/overlay_page').overlayPage; - var addEditorMenuOptions = require('./menu_tools/add_editor_menu_options').addEditorMenuOptions; - /** - * Generates a list of set functions for the settings menu. - * @author - * Matthew Christopher Kastor-Inare III
- * ☭ Hial Atropa!! ☭ - * @param {object} editor The editor instance - * @return {array} Returns an array of objects. Each object contains the - * following properties: functionName, parentObj, and parentName. The - * function name will be the name of a method beginning with the string - * `set` which was found. The parent object will be a reference to the - * object having the method matching the function name. The parent name - * will be a string representing the identifier of the parent object e.g. - * `editor`, `session`, or `renderer`. - */ - function getSetFunctions (editor) { - /** - * Output array. Will hold the objects described above. - * @author - * Matthew Christopher Kastor-Inare III
- * ☭ Hial Atropa!! ☭ - */ - var out = []; - /** - * This object provides a map between the objects which will be - * traversed and the parent name which will appear in the output. - * @author - * Matthew Christopher Kastor-Inare III
- * ☭ Hial Atropa!! ☭ - */ - var my = { - 'editor' : editor, - 'session' : editor.session, - 'renderer' : editor.renderer - }; - /** - * This array will hold the set function names which have already been - * found so that they are not added to the output multiple times. - * @author - * Matthew Christopher Kastor-Inare III
- * ☭ Hial Atropa!! ☭ - */ - var opts = []; - /** - * This is a list of set functions which will not appear in the settings - * menu. I don't know what to do with setKeyboardHandler. When I tried - * to use it, it didn't appear to be working. Someone who knows better - * could remove it from this list and add it's options to - * add_editor_menu_options.js - * @author - * Matthew Christopher Kastor-Inare III
- * ☭ Hial Atropa!! ☭ - */ - var skip = [ - 'setOption', - 'setUndoManager', - 'setDocument', - 'setValue', - 'setBreakpoints', - 'setScrollTop', - 'setScrollLeft', - 'setSelectionStyle', - 'setWrapLimitRange', - 'setKeyboardHandler' - ]; - - - /** - * This will search the objects mapped to the `my` variable above. When - * it finds a set function in the object that is not listed in the - * `skip` list or the `opts` list it will push a new object to the - * output array. - * @author - * Matthew Christopher Kastor-Inare III
- * ☭ Hial Atropa!! ☭ - */ - [ - 'renderer', - 'session', - 'editor' - ].forEach(function (esra) { - var fn; - var esr = my[esra]; - var clss = esra; - for(fn in esr) { - if(skip.indexOf(fn) === -1) { - if(/^set/.test(fn) && opts.indexOf(fn) === -1) { - // found set function - opts.push(fn); - out.push({ - 'functionName' : fn, - 'parentObj' : esr, - 'parentName' : clss - }); - } - } - } - }); - return out; - } - /** - * Generates an interactive menu with settings useful to end users. - * @author - * Matthew Christopher Kastor-Inare III
- * ☭ Hial Atropa!! ☭ - * @param {ace.Editor} editor An instance of the ace editor. - */ - function generateMenu (editor) { - /** - * container for dom elements that will go in the menu. - * @author - * Matthew Christopher Kastor-Inare III
- * ☭ Hial Atropa!! ☭ - */ - var elements = []; - /** - * Sorts the menu entries (elements var) so they'll appear in alphabetical order - * the sort is performed based on the value of the contains property - * of each element. Since this is an `array.sort` the array is sorted - * in place. - * @author - * Matthew Christopher Kastor-Inare III
- * ☭ Hial Atropa!! ☭ - */ - function cleanupElementsList() { - elements.sort(function (a, b) { - var x = a.getAttribute('contains'); - var y = b.getAttribute('contains'); - return x.localeCompare(y); - }); - } - /** - * Wraps all dom elements contained in the elements var with a single - * div. - * @author - * Matthew Christopher Kastor-Inare III
- * ☭ Hial Atropa!! ☭ - */ - function wrapElements() { - var topmenu = document.createElement('div'); - topmenu.setAttribute('id', 'settingsmenu'); - elements.forEach(function (element) { - topmenu.appendChild(element); - }); - return topmenu; - } - - /** - * Creates a new menu entry. - * @author - * Matthew Christopher Kastor-Inare III
- * ☭ Hial Atropa!! ☭ - * @param {object} obj This is a reference to the object containing the - * set function. It is used to set up event listeners for when the - * menu options change. - * @param {string} clss Maps to the class of the dom element. This is - * the name of the object containing the set function e.g. `editor`, - * `session`, `renderer`. - * @param {string} item This is the set function name. It maps to the - * id of the dom element (check, select, input) and to the "contains" - * attribute of the div holding both the element and its label. - * @param {mixed} val This is the value of the setting. It is mapped to - * the dom element's value, checked, or selected option accordingly. - */ - function createNewEntry(obj, clss, item, val) { - var egen = require('./menu_tools/element_generator'); - var el; - var div = document.createElement('div'); - div.setAttribute('contains', item); - div.setAttribute('class', 'menuEntry'); - div.setAttribute('style', 'clear: both;'); - - div.appendChild(egen.createLabel( - item.replace( - /^set/, '' - ).replace( - /([A-Z])/g, ' $1' - ).trim(), - item - )); - - if(Array.isArray(val)) { - el = egen.createSelection(item, val, clss); - el.addEventListener('change', function (e) { - try{ - editor.menuOptions[e.target.id].forEach(function (x) { - if(x.textContent !== e.target.textContent) { - delete x.selected; - } - }); - // editor.session['setMode']('ace/mode/javascript') - obj[e.target.id](e.target.value); - } catch (err) { - throw new Error(err); - } - }); - } else if(typeof val === 'boolean') { - el = egen.createCheckbox(item, val, clss); - el.addEventListener('change', function (e) { - try{ - // renderer['setHighlightGutterLine'](true); - obj[e.target.id](!!e.target.checked); - } catch (err) { - throw new Error(err); - } - }); - } else { - // this aids in giving the ability to specify settings through - // post and get requests. - // /ace_editor.html?setMode=ace/mode/html&setOverwrite=true - el = egen.createInput(item, val, clss); - el.addEventListener('blur', function (e) { - try{ - if(e.target.value === 'true') { - obj[e.target.id](true); - } else if(e.target.value === 'false') { - obj[e.target.id](false); - } else { - obj[e.target.id](e.target.value); - } - } catch (err) { - throw new Error(err); - } - }); - } - el.style.cssText = 'float:right;'; - div.appendChild(el); - return div; - } - /** - * Generates selection fields for the menu and populates their options - * using information from `editor.menuOptions` - * @author - * Matthew Christopher Kastor-Inare III
- * ☭ Hial Atropa!! ☭ - * @param {string} item The set function name. - * @param {object} esr A reference to the object having the set function. - * @param {string} clss The name of the object containing the set function. - * @param {string} fn The matching get function's function name. - * @returns {DOMElement} Returns a dom element containing a selection - * element populated with options. The option whose value matches that - * returned from `esr[fn]()` will be selected. - */ - function makeDropdown(item, esr, clss, fn) { - var val = editor.menuOptions[item]; - val = val.map(function (valuex) { - if(valuex.value === esr[fn]()) { - valuex.selected = 'selected'; - } else if(valuex.value === esr.$modeId) { - // is mode - valuex.selected = 'selected'; - } - return valuex; - }); - return createNewEntry(esr, clss, item, val); - } - - /** - * Processes the set functions returned from `getSetFunctions`. First it - * checks for menu options defined in `editor.menuOptons`. If no - * options are specified then it checks whether there is a get function - * (replace set with get) for the setting. When either of those - * conditions are met it will attempt to create a new entry for the - * settings menu and push it into the elements array defined above. - * It can only do so for get functions which return - * strings, numbers, and booleans. A special case is written in for - * `getMode` where it looks at the returned objects `$id` property and - * forwards that through instead. Other special cases could be written - * in but that would get a bit ridiculous. - * @author - * Matthew Christopher Kastor-Inare III
- * ☭ Hial Atropa!! ☭ - * @param {object} setObj An item from the array returned by - * `getSetFunctions`. - */ - function handleSet (setObj) { - var item = setObj.functionName; - var esr = setObj.parentObj; - var clss = setObj.parentName; - var val; - var fn = item.replace(/^set/, 'get'); - if(editor.menuOptions[item] !== undefined) { - // has options for select element - elements.push(makeDropdown(item, esr, clss, fn)); - } else if(typeof esr[fn] === 'function') { - // has get function - try { - val = esr[fn](); - if(typeof val === 'object') { - // setMode takes a string, getMode returns an object - // the $id property of that object is the string - // which may be given to setMode... - val = val.$id; - } - // the rest of the get functions return strings, - // booleans, or numbers. - elements.push( - createNewEntry(esr, clss, item, val) - ); - } catch (e) { - // if there are errors it is because the element - // does not belong in the settings menu - } - } - } - - // gather the set functions - getSetFunctions(editor).forEach(function (setObj) { - // populate the elements array with good stuff. - handleSet(setObj); - }); - // sort the menu entries in the elements list so people can find - // the settings in alphabetical order. - cleanupElementsList(); - // dump the entries from the elements list and wrap them up in a div - // then put the div into the generic menu and show it. - overlayPage(editor, wrapElements(), '0', '0', '0'); - } - /** - * This builds the settings menu and selects - * all the options currently in effect. + * This displays the settings menu if it is not already being shown. * @author * Matthew Christopher Kastor-Inare III
* ☭ Hial Atropa!! ☭ * @param {ace.Editor} editor An instance of the ace editor. */ function showSettingsMenu (editor) { + var overlayPage = require('./menu_tools/overlay_page').overlayPage; + var generateSettingsMenu = require( + './menu_tools/generate_settings_menu').generateSettingsMenu; // make sure the menu isn't open already. if(!document.getElementById('settingsmenu')) { - addEditorMenuOptions(editor); - generateMenu(editor); + overlayPage(editor, generateSettingsMenu(editor), '0', '0', '0'); } - }; - + } + /** + * Initializes the settings menu extension. It adds the showSettingsMenu + * method to the given editor object and adds the showSettingsMenu command + * to the editor with appropriate keyboard shortcuts. + * @param {ace.Editor} editor An instance of the Editor. + */ module.exports.init = function (editor) { + var Editor = require("ace/editor").Editor; Editor.prototype.showSettingsMenu = function () { showSettingsMenu(this); };