├── alignment ├── alignment.css └── alignment.js ├── clips ├── clips.css └── clips.js ├── textdirection.js ├── limiter.js ├── LICENSE ├── counter.js ├── inlinestyle.js ├── textexpander.js ├── imagemanager.js ├── definedlinks.js ├── filemanager.js ├── video.js ├── README.md ├── fullscreen.js ├── source.js ├── codemirror.js ├── properties.js └── table.js /alignment/alignment.css: -------------------------------------------------------------------------------- 1 | .text-center { 2 | text-align: center; 3 | } 4 | .text-right { 5 | text-align: right; 6 | } -------------------------------------------------------------------------------- /clips/clips.css: -------------------------------------------------------------------------------- 1 | b.label-red { 2 | color: #fff; 3 | background: #c92020; 4 | padding: 0 7px; 5 | font-size: 11px; 6 | text-transform: uppercase; 7 | font-weight: normal; 8 | display: inline-block; 9 | border-radius: 4px; 10 | } -------------------------------------------------------------------------------- /textdirection.js: -------------------------------------------------------------------------------- 1 | (function($) 2 | { 3 | $.Redactor.prototype.textdirection = function() 4 | { 5 | return { 6 | langs: { 7 | en: { 8 | "change-text-direction": "RTL-LTR", 9 | "left-to-right": "Left to Right", 10 | "right-to-left": "Right to Left" 11 | } 12 | }, 13 | init: function() 14 | { 15 | var that = this; 16 | var dropdown = {}; 17 | 18 | dropdown.ltr = { title: that.lang.get('left-to-right'), func: that.textdirection.setLtr }; 19 | dropdown.rtl = { title: that.lang.get('right-to-left'), func: that.textdirection.setRtl }; 20 | 21 | var button = this.button.add('textdirection', this.lang.get('change-text-direction')); 22 | this.button.addDropdown(button, dropdown); 23 | }, 24 | setRtl: function() 25 | { 26 | this.buffer.set(); 27 | this.block.addAttr('dir', 'rtl'); 28 | }, 29 | setLtr: function() 30 | { 31 | this.buffer.set(); 32 | this.block.removeAttr('dir'); 33 | } 34 | }; 35 | }; 36 | })(jQuery); -------------------------------------------------------------------------------- /limiter.js: -------------------------------------------------------------------------------- 1 | (function($) 2 | { 3 | $.Redactor.prototype.limiter = function() 4 | { 5 | return { 6 | init: function() 7 | { 8 | if (!this.opts.limiter) 9 | { 10 | return; 11 | } 12 | 13 | this.core.editor().on('keydown.redactor-plugin-limiter', $.proxy(function(e) 14 | { 15 | var key = e.which; 16 | var ctrl = e.ctrlKey || e.metaKey; 17 | 18 | if (key === this.keyCode.BACKSPACE 19 | || key === this.keyCode.DELETE 20 | || key === this.keyCode.ESC 21 | || key === this.keyCode.SHIFT 22 | || (ctrl && key === 65) 23 | || (ctrl && key === 82) 24 | || (ctrl && key === 116) 25 | ) 26 | { 27 | return; 28 | } 29 | 30 | var text = this.core.editor().text(); 31 | text = text.replace(/\u200B/g, ''); 32 | 33 | var count = text.length; 34 | if (count >= this.opts.limiter) 35 | { 36 | return false; 37 | } 38 | 39 | 40 | }, this)); 41 | 42 | } 43 | }; 44 | }; 45 | })(jQuery); -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Imperavi LLC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /counter.js: -------------------------------------------------------------------------------- 1 | (function($) 2 | { 3 | $.Redactor.prototype.counter = function() 4 | { 5 | return { 6 | init: function() 7 | { 8 | if (typeof this.opts.callbacks.counter === 'undefined') 9 | { 10 | return; 11 | } 12 | 13 | 14 | 15 | this.core.editor().on('keyup.redactor-plugin-counter', $.proxy(this.counter.count, this)); 16 | }, 17 | count: function() 18 | { 19 | var words = 0, characters = 0, spaces = 0; 20 | var html = this.code.get(); 21 | 22 | var text = html.replace(/<\/(.*?)>/gi, ' '); 23 | text = text.replace(/<(.*?)>/gi, ''); 24 | text = text.replace(/\t/gi, ''); 25 | text = text.replace(/\n/gi, ' '); 26 | text = text.replace(/\r/gi, ' '); 27 | text = text.replace(/\u200B/g, ''); 28 | text = $.trim(text); 29 | 30 | if (text !== '') 31 | { 32 | var arrWords = text.split(/\s+/); 33 | var arrSpaces = text.match(/\s/g); 34 | 35 | words = (arrWords) ? arrWords.length : 0; 36 | spaces = (arrSpaces) ? arrSpaces.length : 0; 37 | 38 | characters = text.length; 39 | 40 | } 41 | 42 | this.core.callback('counter', { words: words, characters: characters, spaces: spaces }); 43 | 44 | } 45 | }; 46 | }; 47 | })(jQuery); -------------------------------------------------------------------------------- /inlinestyle.js: -------------------------------------------------------------------------------- 1 | (function($) 2 | { 3 | $.Redactor.prototype.inlinestyle = function() 4 | { 5 | return { 6 | langs: { 7 | en: { 8 | "style": "Style" 9 | } 10 | }, 11 | init: function() 12 | { 13 | var tags = { 14 | "marked": { 15 | title: "Marked", 16 | args: ['mark'] 17 | }, 18 | "code": { 19 | title: "Code", 20 | args: ['code'] 21 | }, 22 | "sample": { 23 | title: "Sample", 24 | args: ['samp'] 25 | }, 26 | "variable": { 27 | title: "Variable", 28 | args: ['var'] 29 | }, 30 | "shortcut": { 31 | title: "Shortcut", 32 | args: ['kbd'] 33 | }, 34 | "cite": { 35 | title: "Cite", 36 | args: ['cite'] 37 | }, 38 | "sup": { 39 | title: "Superscript", 40 | args: ['sup'] 41 | }, 42 | "sub": { 43 | title: "Subscript", 44 | args: ['sub'] 45 | } 46 | }; 47 | 48 | 49 | var that = this; 50 | var dropdown = {}; 51 | 52 | $.each(tags, function(i, s) 53 | { 54 | dropdown[i] = { title: s.title, func: 'inline.format', args: s.args }; 55 | }); 56 | 57 | 58 | var button = this.button.addAfter('format', 'inline', this.lang.get('style')); 59 | this.button.addDropdown(button, dropdown); 60 | 61 | } 62 | 63 | 64 | }; 65 | }; 66 | })(jQuery); -------------------------------------------------------------------------------- /textexpander.js: -------------------------------------------------------------------------------- 1 | (function($) 2 | { 3 | $.Redactor.prototype.textexpander = function() 4 | { 5 | return { 6 | init: function() 7 | { 8 | if (!this.opts.textexpander) 9 | { 10 | return; 11 | } 12 | 13 | this.$editor.on('keyup.redactor-plugin-textexpander', $.proxy(function(e) 14 | { 15 | var key = e.which; 16 | if (key === this.keyCode.SPACE) 17 | { 18 | var current = this.selection.current(); 19 | var cloned = $(current).clone(); 20 | 21 | var $div = $('