/* Redactor v10.0.2 Updated: October 12, 2014 http://imperavi.com/redactor/ Copyright (c) 2009-2014, Imperavi LLC. License: http://imperavi.com/redactor/license/ Usage: $('#content').redactor(); */ (function($) { 'use strict'; if (!Function.prototype.bind) { Function.prototype.bind = function(scope) { var fn = this; return function() { return fn.apply(scope); }; }; } var uuid = 0; var reUrlYoutube = /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.\-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig; var reUrlVimeo = /https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/; // Plugin $.fn.redactor = function(options) { var val = []; var args = Array.prototype.slice.call(arguments, 1); if (typeof options === 'string') { this.each(function() { var instance = $.data(this, 'redactor'); var func; if (options.search(/\./) != '-1') { func = options.split('.'); if (typeof instance[func[0]] != 'undefined') { func = instance[func[0]][func[1]]; } } else { func = instance[options]; } if (typeof instance !== 'undefined' && $.isFunction(func)) { var methodVal = func.apply(instance, args); if (methodVal !== undefined && methodVal !== instance) { val.push(methodVal); } } else { $.error('No such method "' + options + '" for Redactor'); } }); } else { this.each(function() { $.data(this, 'redactor', {}); $.data(this, 'redactor', Redactor(this, options)); }); } if (val.length === 0) return this; else if (val.length === 1) return val[0]; else return val; }; // Initialization function Redactor(el, options) { return new Redactor.prototype.init(el, options); } // Functionality $.Redactor = Redactor; $.Redactor.VERSION = '10.0.2'; $.Redactor.modules = ['core', 'build', 'lang', 'toolbar', 'button', 'dropdown', 'code', 'clean', 'tidy', 'paragraphize', 'tabifier', 'focus', 'placeholder', 'autosave', 'buffer', 'indent', 'alignment', 'paste', 'keydown', 'keyup', 'shortcuts', 'line', 'list', 'block', 'inline', 'insert', 'caret', 'selection', 'observe', 'link', 'image', 'file', 'modal', 'progress', 'upload', 'utils']; $.Redactor.opts = { // settings lang: 'en', direction: 'ltr', // ltr or rtl plugins: false, // array focus: false, focusEnd: false, placeholder: false, visual: true, tabindex: false, minHeight: false, maxHeight: false, linebreaks: false, replaceDivs: true, paragraphize: true, cleanStyleOnEnter: false, enterKey: true, cleanOnPaste: true, cleanSpaces: true, pastePlainText: false, autosave: false, // false or url autosaveName: false, autosaveInterval: 60, // seconds autosaveOnChange: false, linkTooltip: true, linkProtocol: 'http', linkNofollow: false, linkSize: 50, imageEditable: true, imageLink: true, imagePosition: true, imageFloatMargin: '10px', imageResizable: true, imageUpload: false, imageUploadParam: 'file', uploadImageField: false, dragImageUpload: true, fileUpload: false, fileUploadParam: 'file', dragFileUpload: true, s3: false, convertLinks: true, convertUrlLinks: true, convertImageLinks: true, convertVideoLinks: true, preSpaces: 4, // or false tabAsSpaces: false, // true or number of spaces tabFocus: true, scrollTarget: false, toolbar: true, toolbarFixed: true, toolbarFixedTarget: document, toolbarFixedTopOffset: 0, // pixels toolbarExternal: false, // ID selector toolbarOverflow: false, buttonSource: false, buttons: ['html', 'formatting', 'bold', 'italic', 'deleted', 'unorderedlist', 'orderedlist', 'outdent', 'indent', 'image', 'file', 'link', 'alignment', 'horizontalrule'], // + 'underline' buttonsHide: [], buttonsHideOnMobile: [], formatting: ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'], formattingAdd: false, tabifier: true, deniedTags: ['html', 'head', 'link', 'body', 'meta', 'script', 'style', 'applet'], allowedTags: false, // or array removeComments: false, replaceTags: [ ['strike', 'del'] ], replaceStyles: [ ['font-weight:\\s?bold', "strong"], ['font-style:\\s?italic', "em"], ['text-decoration:\\s?underline', "u"], ['text-decoration:\\s?line-through', 'del'] ], removeDataAttr: false, removeAttr: false, // or multi array allowedAttr: false, // or multi array removeWithoutAttr: ['span'], // or false removeEmpty: ['p'], // or false; activeButtons: ['deleted', 'italic', 'bold', 'underline', 'unorderedlist', 'orderedlist', 'alignleft', 'aligncenter', 'alignright', 'justify'], activeButtonsStates: { b: 'bold', strong: 'bold', i: 'italic', em: 'italic', del: 'deleted', strike: 'deleted', ul: 'unorderedlist', ol: 'orderedlist', u: 'underline' }, shortcuts: { 'ctrl+shift+m, meta+shift+m': { func: 'inline.removeFormat' }, 'ctrl+b, meta+b': { func: 'inline.format', params: ['bold'] }, 'ctrl+i, meta+i': { func: 'inline.format', params: ['italic'] }, 'ctrl+h, meta+h': { func: 'inline.format', params: ['superscript'] }, 'ctrl+l, meta+l': { func: 'inline.format', params: ['subscript'] }, 'ctrl+k, meta+k': { func: 'link.show' }, 'ctrl+shift+7': { func: 'list.toggle', params: ['orderedlist'] }, 'ctrl+shift+8': { func: 'list.toggle', params: ['unorderedlist'] } }, shortcutsAdd: false, // private buffer: [], rebuffer: [], emptyHtml: '

', invisibleSpace: '​', imageTypes: ['image/png', 'image/jpeg', 'image/gif'], indentValue: 20, verifiedTags: ['a', 'img', 'b', 'strong', 'sub', 'sup', 'i', 'em', 'u', 'small', 'strike', 'del', 'cite', 'ul', 'ol', 'li'], // and for span tag special rule inlineTags: ['strong', 'b', 'u', 'em', 'i', 'code', 'del', 'ins', 'samp', 'kbd', 'sup', 'sub', 'mark', 'var', 'cite', 'small'], alignmentTags: ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'DL', 'DT', 'DD', 'DIV', 'TD', 'BLOCKQUOTE', 'OUTPUT', 'FIGCAPTION', 'ADDRESS', 'SECTION', 'HEADER', 'FOOTER', 'ASIDE', 'ARTICLE'], blockLevelElements: ['PRE', 'UL', 'OL', 'LI'], // lang langs: { en: { html: 'HTML', video: 'Insert Video', image: 'Insert Image', table: 'Table', link: 'Link', link_insert: 'Insert link', link_edit: 'Edit link', unlink: 'Unlink', formatting: 'Formatting', paragraph: 'Normal text', quote: 'Quote', code: 'Code', header1: 'Header 1', header2: 'Header 2', header3: 'Header 3', header4: 'Header 4', header5: 'Header 5', bold: 'Bold', italic: 'Italic', fontcolor: 'Font Color', backcolor: 'Back Color', unorderedlist: 'Unordered List', orderedlist: 'Ordered List', outdent: 'Outdent', indent: 'Indent', cancel: 'Cancel', insert: 'Insert', save: 'Save', _delete: 'Delete', insert_table: 'Insert Table', insert_row_above: 'Add Row Above', insert_row_below: 'Add Row Below', insert_column_left: 'Add Column Left', insert_column_right: 'Add Column Right', delete_column: 'Delete Column', delete_row: 'Delete Row', delete_table: 'Delete Table', rows: 'Rows', columns: 'Columns', add_head: 'Add Head', delete_head: 'Delete Head', title: 'Title', image_position: 'Position', none: 'None', left: 'Left', right: 'Right', center: 'Center', image_web_link: 'Image Web Link', text: 'Text', mailto: 'Email', web: 'URL', video_html_code: 'Video Embed Code or Youtube/Vimeo Link', file: 'Insert File', upload: 'Upload', download: 'Download', choose: 'Choose', or_choose: 'Or choose', drop_file_here: 'Drop file here', align_left: 'Align text to the left', align_center: 'Center text', align_right: 'Align text to the right', align_justify: 'Justify text', horizontalrule: 'Insert Horizontal Rule', deleted: 'Deleted', anchor: 'Anchor', link_new_tab: 'Open link in new tab', underline: 'Underline', alignment: 'Alignment', filename: 'Name (optional)', edit: 'Edit' } } }; // Functionality Redactor.fn = $.Redactor.prototype = { keyCode: { BACKSPACE: 8, DELETE: 46, DOWN: 40, ENTER: 13, SPACE: 32, ESC: 27, TAB: 9, CTRL: 17, META: 91, SHIFT: 16, ALT: 18, LEFT: 37, LEFT_WIN: 91 }, // Initialization init: function(el, options) { this.$element = $(el); this.uuid = uuid++; // if paste event detected = true this.rtePaste = false; this.$pasteBox = false; this.loadOptions(options); this.loadModules(); // formatting storage this.formatting = {}; // block level tags $.merge(this.opts.blockLevelElements, this.opts.alignmentTags); this.reIsBlock = new RegExp('^(' + this.opts.blockLevelElements.join('|' ) + ')$', 'i'); // setup allowed and denied tags this.tidy.setupAllowed(); // load lang this.lang.load(); // extend shortcuts $.extend(this.opts.shortcuts, this.opts.shortcutsAdd); // start callback this.core.setCallback('start'); // build this.start = true; this.build.run(); }, loadOptions: function(options) { this.opts = $.extend( {}, $.extend(true, {}, $.Redactor.opts), this.$element.data(), options ); }, getModuleMethods: function(object) { return Object.getOwnPropertyNames(object).filter(function(property) { return typeof object[property] == 'function'; }); }, loadModules: function() { var len = $.Redactor.modules.length; for (var i = 0; i < len; i++) { this.bindModuleMethods($.Redactor.modules[i]); } }, bindModuleMethods: function(module) { if (typeof this[module] == 'undefined') return; // init module this[module] = this[module](); var methods = this.getModuleMethods(this[module]); var len = methods.length; // bind methods for (var z = 0; z < len; z++) { this[module][methods[z]] = this[module][methods[z]].bind(this); } }, core: function() { return { getObject: function() { return $.extend({}, this); }, getEditor: function() { return this.$editor; }, getBox: function() { return this.$box; }, getElement: function() { return this.$element; }, getTextarea: function() { return this.$textarea; }, getToolbar: function() { return (this.$toolbar) ? this.$toolbar : false; }, addEvent: function(name) { this.core.event = name; }, getEvent: function() { return this.core.event; }, setCallback: function(type, e, data) { var callback = this.opts[type + 'Callback']; if ($.isFunction(callback)) { return (typeof data == 'undefined') ? callback.call(this, e) : callback.call(this, e, data); } else { return (typeof data == 'undefined') ? e : data; } }, destroy: function() { this.core.setCallback('destroy'); // off events and remove data this.$element.off('.redactor').removeData('redactor'); this.$editor.off('.redactor'); // common this.$editor.removeClass('redactor-editor redactor-linebreaks redactor-placeholder'); this.$editor.removeAttr('contenteditable'); var html = this.code.get(); if (this.build.isTextarea()) { this.$box.after(this.$element); this.$box.remove(); this.$element.val(html).show(); } else { this.$box.after(this.$editor); this.$box.remove(); this.$element.html(html).show(); } // paste box if (this.$pasteBox) this.$pasteBox.remove(); // modal if (this.$modalBox) this.$modalBox.remove(); if (this.$modalOverlay) this.$modalOverlay.remove(); // buttons tooltip $('.redactor-toolbar-tooltip').remove(); // autosave clearInterval(this.autosaveInterval); } }; }, build: function() { return { run: function() { this.build.createContainerBox(); this.build.loadContent(); this.build.loadEditor(); this.build.enableEditor(); this.build.setCodeAndCall(); }, isTextarea: function() { return (this.$element[0].tagName === 'TEXTAREA'); }, createContainerBox: function() { this.$box = $('
'); }, createTextarea: function() { this.$textarea = $('