├── .github └── FUNDING.yml ├── LICENSE.md ├── bower.json ├── buttons.css ├── buttons.js ├── readme.md └── screenshot.png /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: samdark 4 | patreon: samdark 5 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The Yii framework is free software. It is released under the terms of 2 | the following BSD License. 3 | 4 | Copyright © 2016 by Alexander Makarov 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions 9 | are met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in 15 | the documentation and/or other materials provided with the 16 | distribution. 17 | * Neither the name of Yii Software LLC nor the names of its 18 | contributors may be used to endorse or promote products derived 19 | from this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codemirror-buttons", 3 | "version": "1.0.4", 4 | "homepage": "https://github.com/samdark/codemirror-buttons", 5 | "authors": [ 6 | "Alexander Makarov " 7 | ], 8 | "description": "CodeMirror buttons", 9 | "main": "buttons.js", 10 | "keywords": [ 11 | "codemirror", 12 | "buttons", 13 | "ui" 14 | ], 15 | "license": "BSD", 16 | "dependencies": { 17 | "CodeMirror": "*" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /buttons.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-buttonsPanel { 2 | margin-bottom: .5em; 3 | } 4 | 5 | .CodeMirror-buttonsPanel button { 6 | padding: .5em; 7 | width: 4em; 8 | margin-right: .5em; 9 | text-align: center; 10 | } 11 | -------------------------------------------------------------------------------- /buttons.js: -------------------------------------------------------------------------------- 1 | (function (mod) { 2 | if (typeof exports === 'object' && typeof module === 'object') { // CommonJS 3 | mod( 4 | require('codemirror/lib/codemirror'), 5 | require('codemirror/addon/display/panel') 6 | ); 7 | } 8 | else if (typeof define === 'function' && define.amd) { // AMD 9 | define([ 10 | 'codemirror/lib/codemirror', 11 | 'codemirror/addon/display/panel' 12 | ], mod); 13 | } 14 | else { // Plain browser env 15 | mod(CodeMirror); 16 | } 17 | })(function (CodeMirror) { 18 | "use strict"; 19 | 20 | var PANEL_ELEMENT_CLASS = "CodeMirror-buttonsPanel"; 21 | 22 | CodeMirror.defineOption("buttons", [], function (cm, value, old) { 23 | var panelNode = document.createElement("div"); 24 | panelNode.className = PANEL_ELEMENT_CLASS; 25 | for (var i = 0, len = value.length; i < len; i++) { 26 | var button = createButton(cm, value[i]); 27 | panelNode.appendChild(button); 28 | } 29 | cm.addPanel(panelNode); 30 | }); 31 | 32 | function createButton(cm, config) { 33 | var buttonNode; 34 | 35 | if (config.el) { 36 | if (typeof config.el === 'function') { 37 | buttonNode = config.el(cm); 38 | } else { 39 | buttonNode = config.el; 40 | } 41 | } else { 42 | buttonNode = document.createElement('button'); 43 | buttonNode.innerHTML = config.label; 44 | buttonNode.setAttribute('type', 'button'); 45 | buttonNode.setAttribute('tabindex', '-1'); 46 | 47 | buttonNode.addEventListener('click', function (e) { 48 | e.preventDefault(); 49 | cm.focus(); 50 | config.callback(cm); 51 | }); 52 | 53 | if (config.class) { 54 | buttonNode.className = config.class; 55 | } 56 | 57 | if (config.title) { 58 | buttonNode.setAttribute('title', config.title); 59 | } 60 | } 61 | 62 | if (config.hotkey) { 63 | var map = {}; 64 | map[config.hotkey] = config.callback; 65 | cm.addKeyMap(CodeMirror.normalizeKeyMap(map)); 66 | } 67 | 68 | return buttonNode; 69 | } 70 | }); 71 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | CodeMirror buttons addon 2 | ======================== 3 | 4 | Adds a panel with buttons specified via config. 5 | 6 | 7 | 8 | ## Usage 9 | 10 | Include scripts needed into webpage. 11 | 12 | ```html 13 | 14 | 15 | 16 | ``` 17 | 18 | Initialize CodeMirror specifying buttons as an array in `buttons` config property. 19 | 20 | ```javascript 21 | var editor = CodeMirror.fromTextArea(document.getElementById('text'), { 22 | mode: 'gfm', 23 | buttons: [ 24 | { 25 | hotkey: 'Ctrl-B', 26 | class: 'bold', 27 | label: 'B', 28 | callback: function (cm) { 29 | var selection = cm.getSelection(); 30 | cm.replaceSelection('**' + selection + '**'); 31 | if (!selection) { 32 | var cursorPos = cm.getCursor(); 33 | cm.setCursor(cursorPos.line, cursorPos.ch - 2); 34 | } 35 | } 36 | }, 37 | { 38 | hotkey: 'Ctrl-I', 39 | class: 'italic', 40 | label: 'I', 41 | callback: function (cm) { 42 | var selection = cm.getSelection(); 43 | cm.replaceSelection('*' + selection + '*'); 44 | if (!selection) { 45 | var cursorPos = cm.getCursor(); 46 | cm.setCursor(cursorPos.line, cursorPos.ch - 1); 47 | } 48 | } 49 | }, 50 | { 51 | class: 'inline-code', 52 | label: 'code', 53 | callback: function (cm) { 54 | var selection = cm.getSelection(); 55 | cm.replaceSelection("`" + selection + "`"); 56 | if (!selection) { 57 | var cursorPos = cm.getCursor(); 58 | cm.setCursor(cursorPos.line, cursorPos.ch - 1); 59 | } 60 | } 61 | }, 62 | { 63 | class: 'block-php', 64 | label: '<php>', 65 | callback: function (cm) { 66 | var selection = cm.getSelection(); 67 | cm.replaceSelection("```php\n', 89 | callback: function (cm) { 90 | cm.replaceSelection("> " + cm.getSelection()); 91 | } 92 | }, 93 | { 94 | class: 'ul', 95 | label: 'ul', 96 | callback: function (cm) { 97 | cm.replaceSelection("- " + cm.getSelection()); 98 | } 99 | }, 100 | { 101 | class: 'ol', 102 | label: 'ol', 103 | callback: function (cm) { 104 | cm.replaceSelection("1. " + cm.getSelection()); 105 | } 106 | }, 107 | { 108 | class: 'a', 109 | label: 'a', 110 | callback: function (cm) { 111 | var selection = cm.getSelection(); 112 | var text = ''; 113 | var link = ''; 114 | 115 | if (selection.match(/^https?:\/\//)) { 116 | link = selection; 117 | } else { 118 | text = selection; 119 | } 120 | cm.replaceSelection('[' + text + '](' + link + ')'); 121 | 122 | var cursorPos = cm.getCursor(); 123 | if (!selection) { 124 | cm.setCursor(cursorPos.line, cursorPos.ch - 3); 125 | } else if (link) { 126 | cm.setCursor(cursorPos.line, cursorPos.ch - (3 + link.length)); 127 | } else { 128 | cm.setCursor(cursorPos.line, cursorPos.ch - 1); 129 | } 130 | } 131 | } 132 | ], 133 | }); 134 | ``` 135 | 136 | Altrnatively, instead of setting individual options, you can supply either DOM node or a callback returning DOM node 137 | using `el` key: 138 | 139 | ```javascript 140 | { 141 | el: function(cm) { 142 | return document.getElementById('mybutton'); 143 | } 144 | } 145 | ``` 146 | 147 | Optionally use stylesheet included to make buttons look a bit better: 148 | 149 | ```html 150 | 151 | ``` 152 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samdark/codemirror-buttons/c2eff18822aa25d1245452ce48b53f98a1275a26/screenshot.png --------------------------------------------------------------------------------