/* Redactor v9.0 beta 2 Updated: February 13, 2013 http://redactorjs.com/ Copyright (c) 2009-2013, Imperavi Inc. License: http://imperavi.com/redactor/license/ Usage: $('#content').redactor(); */ var rwindow, rdocument; if (typeof RELANG === 'undefined') { var RELANG = {}; } var RLANG = { html: 'HTML', video: 'Insert Video', image: 'Insert Image', table: 'Table', link: 'Link', link_insert: 'Insert link', unlink: 'Unlink', formatting: 'Formatting', paragraph: 'Paragraph', quote: 'Quote', code: 'Code', header1: 'Header 1', header2: 'Header 2', header3: 'Header 3', header4: 'Header 4', 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', image_web_link: 'Image Web Link', text: 'Text', mailto: 'Email', web: 'URL', video_html_code: 'Video Embed Code', 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)' }; 'use strict'; (function($){ // 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'); if (typeof instance !== 'undefined') { var arr = options.split('.'); var func = arr.length == 1 ? instance[options] : instance[arr[0]][arr[1]]; if ($.isFunction(func)) { var methodVal = func.call(instance, args); if (methodVal !== undefined && methodVal !== instance) { val.push(methodVal); } } } }); } else { this.each(function() { if (!$.data(this, 'redactor')) { $.data(this, 'redactor', new Redactor(this, options)); } }); } if (val.length == 0) { return this; } else if (val.length == 1) { return val[0]; } else { return val; } }; // Initialization var Redactor = function(el, options) { this.$element = this.$el = $(el); // Lang if (typeof options !== 'undefined' && typeof options.lang !== 'undefined' && typeof RELANG[options.lang] !== 'undefined') { RLANG = $.extend({}, RLANG, RELANG[options.lang]); } // Options this.opts = $.extend({ iframe: false, fullpage: false, css: false, // url lang: 'en', direction: 'ltr', // ltr or rtl callback: false, // function keyupCallback: false, // function keydownCallback: false, // function execCommandCallback: false, // function syncBeforeCallback: false, // function syncAfterCallback: false, // function focus: false, tabindex: false, autoresize: true, minHeight: false, plugins: false, // array air: false, airButtons: ['formatting', '|', 'bold', 'italic', 'deleted', '|', 'unorderedlist', 'orderedlist', 'outdent', 'indent', '|', 'fontcolor', 'backcolor'], mobile: true, wym: false, cleanup: true, source: true, shortcuts: true, visual: true, placeholder: false, linebreaks: false, paragraphy: true, convertDivs: false, convertLinks: true, formattingPre: false, autosave: false, // false or url autosaveCallback: false, // function interval: 60, // seconds fixed: false, fixedTop: 0, // pixels fixedBox: false, toolbarExternal: false, // ID selector linkAnchor: false, linkEmail: false, imageGetJson: false, // url (ex. /folder/images.json ) or false imageUpload: false, // url imageUploadCallback: false, // function imageUploadErrorCallback: false, // function imageDeleteCallback: false, // function fileUpload: false, // url fileUploadCallback: false, // function fileUploadErrorCallback: false, // function uploadCrossDomain: false, uploadFields: false, observeImages: true, overlay: true, // modal overlay allowedTags: false, deniedTags: false, clearTags: ['script', 'html', 'head', 'title', 'link', 'body', 'style', 'meta', 'applet'], boldTag: 'strong', italicTag: 'em', buttonsCustom: {}, buttonsAdd: [], buttons: ['html', '|', 'formatting', '|', 'bold', 'italic', 'deleted', 'underline', '|', 'unorderedlist', 'orderedlist', 'outdent', 'indent', '|', 'image', 'video', 'file', 'table', 'link', '|', 'fontcolor', 'backcolor', '|', 'alignment', '|', 'horizontalrule'], // 'underline', 'alignleft', 'aligncenter', 'alignright', 'justify' formattingTags: ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4'], activeButtons: ['deleted', 'italic', 'bold', 'underline', 'unorderedlist', 'orderedlist', 'table'], // 'alignleft', 'aligncenter', 'alignright', 'justify' activeButtonsStates: { b: 'bold', strong: 'bold', i: 'italic', em: 'italic', del: 'deleted', strike: 'deleted', ul: 'unorderedlist', ol: 'orderedlist', u: 'underline', table: 'table' }, colors: [ '#ffffff', '#000000', '#eeece1', '#1f497d', '#4f81bd', '#c0504d', '#9bbb59', '#8064a2', '#4bacc6', '#f79646', '#ffff00', '#f2f2f2', '#7f7f7f', '#ddd9c3', '#c6d9f0', '#dbe5f1', '#f2dcdb', '#ebf1dd', '#e5e0ec', '#dbeef3', '#fdeada', '#fff2ca', '#d8d8d8', '#595959', '#c4bd97', '#8db3e2', '#b8cce4', '#e5b9b7', '#d7e3bc', '#ccc1d9', '#b7dde8', '#fbd5b5', '#ffe694', '#bfbfbf', '#3f3f3f', '#938953', '#548dd4', '#95b3d7', '#d99694', '#c3d69b', '#b2a2c7', '#b7dde8', '#fac08f', '#f2c314', '#a5a5a5', '#262626', '#494429', '#17365d', '#366092', '#953734', '#76923c', '#5f497a', '#92cddc', '#e36c09', '#c09100', '#7f7f7f', '#0c0c0c', '#1d1b10', '#0f243e', '#244061', '#632423', '#4f6128', '#3f3151', '#31859b', '#974806', '#7f6000'], // private textareamode: false, buffer: false, emptyHtml: '

', invisibleSpace: '​', alignmentTags: ['H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'P', 'TD', 'DIV', 'BLOCKQUOTE'], // modal windows container modal_file: String() + '
' + '
' + '' + '' + '
' + '' + '
' + '

' + '
', modal_image_edit: String() + '
' + '' + '' + '' + '' + '' + '' + '
' + '', modal_image: String() + '
' + '
' + '' + RLANG.upload + '' + '' + RLANG.choose + '' + '' + RLANG.link + '' + '
' + '
' + '
' + '' + '
' + '' + '
' + '' + '
' + '', modal_link: String() + '
' + '
' + '
' + 'URL' + 'Email' + '' + RLANG.anchor + '' + '
' + '' + '
' + '' + '' + '' + '
' + '' + '' + '
' + '
' + '', modal_table: String() + '
' + '' + '' + '' + '' + '
' + '', modal_video: String() + '
' + '
' + '' + '' + '
' + '
'+ '', toolbar: { html: { title: RLANG.html, func: 'toggle' }, formatting: { title: RLANG.formatting, func: 'show', dropdown: { p: { title: RLANG.paragraph, func: 'format.blocks' }, blockquote: { title: RLANG.quote, func: 'quote.toggle', className: 'redactor_format_blockquote' }, pre: { title: RLANG.code, func: 'format.blocks', className: 'redactor_format_pre' }, h1: { title: RLANG.header1, func: 'format.blocks', className: 'redactor_format_h1' }, h2: { title: RLANG.header2, func: 'format.blocks', className: 'redactor_format_h2' }, h3: { title: RLANG.header3, func: 'format.blocks', className: 'redactor_format_h3' }, h4: { title: RLANG.header4, func: 'format.blocks', className: 'redactor_format_h4' } } }, bold: { title: RLANG.bold, exec: 'bold' }, italic: { title: RLANG.italic, exec: 'italic' }, deleted: { title: RLANG.deleted, exec: 'strikethrough' }, underline: { title: RLANG.underline, exec: 'underline' }, unorderedlist: { title: '• ' + RLANG.unorderedlist, exec: 'insertunorderedlist' }, orderedlist: { title: '1. ' + RLANG.orderedlist, exec: 'insertorderedlist' }, outdent: { title: '< ' + RLANG.outdent, func: 'indenting.outdent' }, indent: { title: '> ' + RLANG.indent, func: 'indenting.indent' }, image: { title: RLANG.image, func: 'image.show' }, video: { title: RLANG.video, func: 'video.show' }, file: { title: RLANG.file, func: 'file.show' }, table: { title: RLANG.table, func: 'show', dropdown: { insert_table: { title: RLANG.insert_table, func: 'table.show' }, separator_drop1: { name: 'separator' }, insert_row_above: { title: RLANG.insert_row_above, func: 'table.insertRowAbove' }, insert_row_below: { title: RLANG.insert_row_below, func: 'table.insertRowBelow' }, insert_column_left: { title: RLANG.insert_column_left, func: 'table.insertColumnLeft' }, insert_column_right: { title: RLANG.insert_column_right, func: 'table.insertColumnRight' }, separator_drop2: { name: 'separator' }, add_head: { title: RLANG.add_head, func: 'table.addHead' }, delete_head: { title: RLANG.delete_head, func: 'table.deleteHead' }, separator_drop3: { name: 'separator' }, delete_column: { title: RLANG.delete_column, func: 'table.deleteColumn' }, delete_row: { title: RLANG.delete_row, func: 'table.deleteRow' }, delete_table: { title: RLANG.delete_table, func: 'table.deleteTable' } } }, link: { title: RLANG.link, func: 'show', dropdown: { link: { title: RLANG.link_insert, func: 'link.show' }, unlink: { title: RLANG.unlink, exec: 'unlink' } } }, fontcolor: { title: RLANG.fontcolor, func: 'show' }, backcolor: { title: RLANG.backcolor, func: 'show' }, alignment: { title: RLANG.alignment, func: 'show', dropdown: { alignleft: { title: RLANG.align_left, func: 'alignment.left' }, aligncenter: { title: RLANG.align_center, func: 'alignment.center' }, alignright: { title: RLANG.align_right, func: 'alignment.right' }, justify: { title: RLANG.align_justify, func: 'alignment.justify' } } }, alignleft: { title: RLANG.align_left, func: 'alignment.left' }, aligncenter: { title: RLANG.align_center, func: 'alignment.center' }, alignright: { title: RLANG.align_right, func: 'alignment.right' }, justify: { title: RLANG.align_justify, func: 'alignment.justify' }, horizontalrule: { exec: 'inserthorizontalrule', title: RLANG.horizontalrule } } }, options, this.$el.data()); this.dropdowns = []; // Init this.init(); }; // Functionality Redactor.prototype = { // Initialization init: function() { // get dimensions this.height = this.$el.css('height'); this.width = this.$el.css('width'); this.opts.buffer = this.opts.rebuffer = []; this.codeactions = false; rdocument = this.document = document; rwindow = this.window = window; if (this.opts.fullpage) this.opts.iframe = true; if (this.opts.iframe) this.opts.autoresize = false; // setup formatting permissions if (this.opts.linebreaks === false) { if (this.opts.allowedTags !== false && $.inArray('p', this.opts.allowedTags) == '-1') { this.opts.allowedTags.push('p'); } if (this.opts.deniedTags !== false) { var pos = $.inArray('p', this.opts.deniedTags); if (pos != '-1') { this.opts.deniedTags.splice(pos, pos); } } } // Build this.build.start.call(this); }, afterBuild: function() { // extend buttons if (this.opts.air) { this.opts.buttons = this.opts.airButtons; } else if (this.opts.toolbar !== false) { if (this.opts.source === false) { var index = this.opts.buttons.indexOf('html'); var next = this.opts.buttons[index+1]; this.opts.buttons.splice(index, 1); if (typeof next !== 'undefined' && next === '|') { this.opts.buttons.splice(index, 1); } } $.extend(this.opts.toolbar, this.opts.buttonsCustom); $.each(this.opts.buttonsAdd, $.proxy(function(i,s) { this.opts.buttons.push(s); }, this)); } // formatting tags if (this.opts.toolbar !== false) { if (this.opts.linebreaks) { var num = $.inArray('p', this.opts.formattingTags); if (num === 0) { delete this.opts.formattingTags[0]; } } $.each(this.opts.toolbar.formatting.dropdown, $.proxy(function(i,s) { if ($.inArray(i, this.opts.formattingTags) == '-1') { delete this.opts.toolbar.formatting.dropdown[i]; } }, this)); } // air enable this.air.enable.call(this); // toolbar this.toolbar.build.call(this); // PLUGINS if (typeof this.opts.plugins === 'object') { $.each(this.opts.plugins, $.proxy(function(i,s) { if (typeof RedactorPlugins[s] !== 'undefined') { $.extend(this, RedactorPlugins[s]); if (typeof RedactorPlugins[s].init !== 'undefined') { this.init(); } } }, this)); } // buttons response if (this.opts.activeButtons !== false && this.opts.toolbar !== false) { this.$editor.on('click.redactor keyup.redactor', $.proxy(this.observe.formatting, this)); } // events if (this.opts.linebreaks === true) { this.$editor.on("keyup.redactor mouseup.redactor", $.proxy(function() { var that = this.$editor[0]; if (this.utils.oldIE.call(this) === false && (!that.lastChild || that.lastChild.nodeName.toLowerCase() != "br")) { that.appendChild(document.createElement("br")); } }, this)); } // paste var oldsafari = false; if (this.utils.browser.call(this, 'webkit') && navigator.userAgent.indexOf('Chrome') === -1) { var arr = this.utils.browser.call(this, 'version').split('.'); if (arr[0] < 536) { oldsafari = true; } } if (this.utils.isMobile.call(this, true) === false && oldsafari === false) { this.$editor.bind('paste.redactor', $.proxy(function(e) { if (this.opts.cleanup === false) return true; this.pasteRunning = true; this.selection.save.call(this); if (!this.selectall) { if (this.opts.autoresize === true) { this.$editor.height(this.$editor.height()); this.saveScroll = this.document.body.scrollTop; } else { this.saveScroll = this.$editor.scrollTop(); } } var frag = this.utils.extractContent.call(this); setTimeout($.proxy(function() { var pastedFrag = this.utils.extractContent.call(this); this.$editor.append(frag); this.selection.restore.call(this); var html = this.utils.getFragmentHtml.call(this, pastedFrag); this.paste.clean.call(this, html); this.pasteRunning = false; if (this.opts.autoresize === true) { this.$editor.css('height', 'auto'); } }, this), 1); }, this)); } // formatting this.$editor.on('keydown.redactor', $.proxy(function(e) { var key = e.which; var parent = this.selection.getParent.call(this); var current = this.selection.getElement.call(this); var pre = false; var ctrl = e.ctrlKey || e.metaKey; // callback keydown if (typeof this.opts.keydownCallback === 'function') { this.opts.keydownCallback(this, e); } if ((parent && $(parent).get(0).tagName === 'PRE') || (current && $(current).get(0).tagName === 'PRE')) { pre = true; if (key === 40) this.format.insertAfterLastElement.call(this, current); } // down if (key === 40) { if (parent && $(parent).get(0).tagName === 'BLOCKQUOTE') this.format.insertAfterLastElement.call(this, parent); if (current && $(current).get(0).tagName === 'BLOCKQUOTE') this.format.insertAfterLastElement.call(this, current); } // Enter pre if (pre === true && key === 13) { this.buffer.set.call(this); e.preventDefault(); var html = $(current).parent().text(); this.insert.nodeAtCaret.call(this, document.createTextNode('\n')); if (html.search(/\s$/) == -1) { this.insert.nodeAtCaret.call(this, document.createTextNode('\n')); } this.sync(); return false; } else if (key === 13 && !e.shiftKey && !e.ctrlKey && !e.metaKey) // Enter { this.buffer.set.call(this); var element = this.selection.getNode.call(this); if (this.opts.linebreaks === false && parent === false && current === false) { e.preventDefault(); var text = this.utils.getObjectText.call(this, element); var node1 = $('

' + text + '

'); if (text != '') { var node2 = $('

' + this.opts.invisibleSpace + '

'); $(element).replaceWith(node1); node1.after(node2); this.selection.start.call(this, node2); } else { $(element).replaceWith(node1); this.selection.end.call(this, node1); } this.sync(); return false; } else if ($(element).closest('h1, h2, h3, h4, h5, h6, ol, ul, li, p, td', this.$editor[0]).size() == 0 && !this.utils.browser.call(this, 'mozilla')) { // Inserting br on Enter e.preventDefault(); this.format.insertLineBreak.call(this); return false; } else { // Native line break for blocks elements h1, h2, h3, h4, h5, h6, ol, ul, li, p, td setTimeout($.proxy(this.format.newLine, this), 1); } } else if (key === 13 && (e.ctrlKey || e.shiftKey)) // Shift+Enter or Ctrl+Enter { this.buffer.set.call(this); e.preventDefault(); this.format.insertLineBreak.call(this); } // SHORCTCUTS if (ctrl) { if (key == 65) { this.selectall = true; } else if (key != 91 && key != 17) { this.selectall = false; } this.shortcuts.set.call(this, e, key); } // Tab if (key === 9 && this.opts.shortcuts) { e.preventDefault(); if (pre === true && !e.shiftKey) { this.buffer.set.call(this); this.insert.nodeAtCaret.call(this, document.createTextNode('\t')); this.sync(); return false; } else { if (!e.shiftKey) { this.indenting.indent.call(this); return false; } else { this.indenting.outdent.call(this); return false; } } } }, this)); this.$editor.on('keyup.redactor', $.proxy(function(e) { var key = e.which; // convert links if (this.opts.convertLinks && key === 13) { this.$editor.linkify(); } // callback as you type if (typeof this.opts.keyupCallback === 'function') { this.opts.keyupCallback(this, e); } // if empty if (this.opts.linebreaks === false && (key === 8 || key === 46)) { return this.format.empty.call(this, e); } this.sync(); }, this)); // autosave if (this.opts.autosave !== false) { this.autosave(); } // observers setTimeout($.proxy(this.observe.start, this), 1); // FF fix if (this.utils.browser.call(this, 'mozilla')) { try { this.document.execCommand('enableObjectResizing', false, false); this.document.execCommand('enableInlineTableEditing', false, false); } catch (e) {} } // focus if (this.opts.focus) { setTimeout($.proxy(this.focus.set, this), 100); } // fixed if (this.opts.fixed) { this.observe.scroll.call(this); $(document).scroll($.proxy(this.observe.scroll, this)); } // code mode if (this.opts.visual === false) { setTimeout($.proxy(function() { this.opts.visual = true; this.toggle(); }, this), 200); } // callback if (typeof this.opts.callback === 'function') { this.opts.callback(this); } if (this.opts.toolbar !== false) { this.$toolbar.find('a').attr('tabindex', '-1'); } }, // SHORTCUTS shortcuts: { set: function(e, key) { if (key === 90) { if (this.opts.buffer.length != 0) { e.preventDefault(); this.buffer.get.call(this); } else if (e.shiftKey) { if (this.opts.rebuffer.length != 0) { e.preventDefault(); this.buffer.redo.call(this); } else this.shortcuts.load.call(this, e, 'redo'); // Ctrl + Shift + z } else this.shortcuts.load.call(this, e, 'undo'); // Ctrl + z } if (this.opts.shortcuts) { if (key === 77) this.shortcuts.load.call(this, e, 'removeFormat'); // Ctrl + m else if (key === 66) this.shortcuts.load.call(this, e, 'bold'); // Ctrl + b else if (key === 73) this.shortcuts.load.call(this, e, 'italic'); // Ctrl + i else if (key === 74) this.shortcuts.load.call(this, e, 'insertunorderedlist'); // Ctrl + j else if (key === 75) this.shortcuts.load.call(this, e, 'insertorderedlist'); // Ctrl + k else if (key === 76) this.shortcuts.load.call(this, e, 'superscript'); // Ctrl + l else if (key === 72) this.shortcuts.load.call(this, e, 'subscript'); // Ctrl + h } }, load: function(e, cmd) { e.preventDefault(); this.exec.command.call(this, cmd, false); } }, // BUILD build: { start: function() { // content this.content = ''; // container this.$box = $('
'); // air box if (this.opts.air) { this.$air = $(''); } // mobile if (this.utils.oldIE.call(this) || (this.opts.mobile === false && this.utils.isMobile.call(this) === true)) { if (this.$el.get(0).tagName === 'TEXTAREA') { this.$box.insertAfter(this.$el).append(this.$el); } else { this.$editor = this.$el; this.$el = $('').css('height', this.height).val($.trim(this.$editor.html())); this.$editor.hide(); this.$box.insertAfter(this.$editor).append(this.$el); } return true; } // build if (this.opts.iframe) { this.iframe.start.call(this); } else if (this.$el.get(0).tagName === 'TEXTAREA') { this.opts.textrareamode = true; this.build.textarea.call(this); } else { this.build.element.call(this); } if (!this.opts.iframe) { this.build.options.call(this); this.afterBuild.call(this); } }, textarea: function() { this.$editor = $('
'); this.build.addClasses.call(this, this.$editor); this.content = $.trim(this.$el.val()); this.$el.attr('dir', this.opts.direction); this.$box.insertAfter(this.$el).append(this.$editor).append(this.$el); this.build.enable.call(this); }, element: function() { this.$editor = this.$el; this.$el = $('').attr('dir', this.opts.direction).css('height', this.height); this.content = $.trim(this.$editor.html()); this.$box.insertAfter(this.$editor).append(this.$editor).append(this.$el); this.build.enable.call(this); }, addClasses: function(el) { var classlist = this.$el.get(0).className.split(/\s+/); $.each(classlist, function(i,s) { el.addClass('redactor_' + s); }); }, enable: function() { this.$editor.addClass('redactor_editor').attr('contenteditable', true).attr('dir', this.opts.direction); this.$el.hide(); this.build.clean.call(this); this.placeholder.start.call(this); this.code.set.call(this, this.content, false); }, options: function() { var $el = this.$editor; if (this.opts.iframe) $el = this.$frame; if (this.opts.tabindex) $el.attr('tabindex', this.opts.tabindex); if (this.opts.minHeight) $el.css('min-height', this.opts.minHeight + 'px'); if (this.opts.wym) this.$editor.addClass('redactor_editor_wym'); if (!this.opts.autoresize) $el.css('height', this.height); }, clean: function(html) { if (typeof html === 'undefined') html = this.content; html = this.clean.savePreCode.call(this, html); if (!this.opts.fullpage) html = this.clean.stripTags.call(this, html, false); if (this.opts.paragraphy) html = this.clean.paragraphy.call(this, html); if (this.opts.linebreaks) html = html.replace(/\n/g, '
'); return this.content = html; } }, // IFRAME iframe: { start: function() { this.iframe.create.call(this); if (this.$el.get(0).tagName === 'TEXTAREA') { this.opts.textrareamode = true; this.content = $.trim(this.$el.val()); this.$el.attr('dir', this.opts.direction); this.iframe.append.call(this, this.$el); } else { this.$elold = this.$el.hide(); this.$el = $('').attr('dir', this.opts.direction).css('height', this.height); this.content = $.trim(this.$elold.html()); this.iframe.append.call(this, this.$elold); } if (this.opts.fullpage) { this.iframe.page.call(this); if (this.content === '') this.content = this.opts.emptyHtml; this.$frame.contents()[0].write(this.content); } this.iframe.load.call(this, true); }, append: function(el) { this.$box.insertAfter(el).append(this.$frame).append(this.$el); this.$el.hide(); }, create: function() { this.$frame = null; this.initbuild = true; var that = this; this.$frame = $(''); html = html.replace(/\[video(.*?)\]([\w\W]*?)\[\/video\]/gi, '$2'); html = html.replace(/\[audio(.*?)\]([\w\W]*?)\[\/audio\]/gi, '$2'); html = html.replace(/\[embed(.*?)\]([\w\W]*?)\[\/embed\]/gi, '$2'); html = html.replace(/\[object(.*?)\]([\w\W]*?)\[\/object\]/gi, '$2'); html = html.replace(/\[param(.*?)\]/gi, ''); html = html.replace(/\[img(.*?)\]/gi, ''); // convert div to p if (this.opts.convertDivs) { html = html.replace(/([\w\W]*?)<\/div>/gi, '

$2

'); } // remove span html = html.replace(/([\w\W]*?)<\/span>/gi, '$2'); html = html.replace(/\n{3,}/gi, '\n'); // remove dirty p html = html.replace(/

/gi, '

'); html = html.replace(/<\/p><\/p>/gi, '

'); if (this.opts.linebreaks === true) { html = html.replace(/([\w\W]*?)<\/p>/gi, '$2
'); } // FF fix if (this.utils.browser.call(this, 'mozilla')) { html = html.replace(/
$/gi, ''); } this.paste.insert.call(this, html); }, pre: function(s) { s = s.replace(/
/gi, '\n'); s = s.replace(/<\/p>/gi, '\n'); s = s.replace(/<\/div>/gi, '\n'); var tmp = this.document.createElement("div"); tmp.innerHTML = s; return tmp.textContent||tmp.innerText; }, insert: function(html) { if (this.selectall) { if (this.opts.linebreaks === false) { this.$editor.html(this.opts.emptyHtml); } this.focus.set.call(this); } this.insert.exec.call(this, html); this.selectall = false; if (this.opts.autoresize === true) $(this.document.body).scrollTop(this.saveScroll); else this.$editor.scrollTop(this.saveScroll); } }, // ALIGNMENT alignment: { left: function() { this.alignment.set.call(this, '', 'JustifyLeft'); }, right: function() { this.alignment.set.call(this, 'right', 'JustifyRight'); }, center: function() { this.alignment.set.call(this, 'center', 'JustifyCenter'); }, justify: function() { this.alignment.set.call(this, 'justify', 'JustifyFull'); }, set: function(type, cmd) { // buffer this.buffer.set.call(this); if (this.utils.oldIE.call(this)) { this.document.execCommand(cmd, false, false); return true; } this.selection.save.call(this); var elements = this.selection.getBlocks.call(this); var element = this.selection.getBlock.call(this); if (elements.length === 0) { elements.push(element); } $.each(elements, $.proxy(function(i,s) { var $el = false; if ($.inArray(s.tagName, this.opts.alignmentTags) !== -1) { $el = $(s); } else { $el = $(s).closest(this.opts.alignmentTags.toString().toLowerCase(), this.$editor[0]); } if ($el) { $el.css('text-align', type); this.utils.removeEmptyStyleAttr.call(this, $el); } }, this)); this.selection.restore.call(this); this.sync(); } }, // INDENTING indenting: { indent: function() { this.indenting.start.call(this, 'indent'); }, outdent: function() { this.indenting.start.call(this, 'outdent'); }, start: function(cmd) { var elements = this.selection.getBlocks.call(this); var element = this.selection.getBlock.call(this); if (!this.utils.isParentRedactor.call(this, element)) { return false; } // buffer this.buffer.set.call(this); var parent = $(element).closest('h1, h2, h3, h4, h5, h6, p, li, div, blockquote'); if (parent[0].tagName == 'LI') { this.exec.command.call(this, cmd, false); } else { if (elements.length === 0) { elements.push(element); } // indent block tags $.each(elements, $.proxy(function(i,s) { this.indenting.process.call(this, s, cmd); }, this)); } }, process: function(element, cmd) { if (!this.utils.isParentRedactor.call(this, element)) { return false; } var parent = $(element).closest('h1, h2, h3, h4, h5, h6, p, li, div, blockquote'); // blockquote if (parent[0].tagName == 'P' && parent.parent()[0].tagName == 'BLOCKQUOTE') { parent = parent.parent(); } // others if (parent.size() != 0 && !parent.hasClass('redactor_editor')) { // increase if (cmd === 'indent') { parent.css('margin-left', (this.utils.normalize.call(this, parent.css('margin-left')) + 20) + 'px'); } // decrease else { var marginLeft = this.utils.normalize.call(this, parent.css('margin-left')) - 20; if (marginLeft <= 0) { parent.css('margin-left', ''); if (parent.attr('style') == '') { parent.removeAttr('style'); } } else { parent.css('margin-left', marginLeft + 'px'); } } } this.sync(); } }, // EXECCOMMAND exec: { command: function(cmd, param) { if (this.opts.visual == false) { this.$el.focus(); return false; } try { var parentel = this.selection.getParent.call(this); var currentel = this.selection.getElement.call(this); var pre = false; if ((parentel && $(parentel).get(0).tagName === 'PRE') || (currentel && $(currentel).get(0).tagName === 'PRE')) { pre = true; } var parent; // lists if (!this.utils.browser.call(this, 'mozilla')) { if (cmd === 'insertunorderedlist' || cmd === 'insertorderedlist') { this.buffer.set.call(this); setTimeout($.proxy(function() { this.selection.saveDynamic.call(this); var html = this.$editor.html(); html = html.replace(/
    ([\w\W]*?)<\/ul><\/p>/gi, '$2
'); html = html.replace(/
    ([\w\W]*?)<\/ol><\/p>/gi, '$2
'); this.$editor.html(html); this.selection.restoreDynamic.call(this); }, this), 1); } if (cmd === 'outdent' || cmd === 'indent') { this.buffer.set.call(this); setTimeout($.proxy(function() { this.selection.saveDynamic.call(this); var html = this.$editor.html(); html = html.replace(/<\/li>([\w\W]*?)<\/ul>/gi, '$2'); html = html.replace(/<\/li>([\w\W]*?)<\/ol>/gi, '$2'); this.$editor.html(html); this.selection.restoreDynamic.call(this); }, this), 1); } } if (cmd === 'insertunorderedlist') { this.button.inactive.call(this, 'orderedlist'); } else if (cmd === 'insertorderedlist') { this.button.inactive.call(this, 'unorderedlist'); } if (cmd === 'inserthtml') { this.insert.html.call(this, param, false); } else if (cmd === 'unlink') { parent = this.selection.getElement.call(this); if ($(parent).get(0).tagName === 'A') $(parent).replaceWith($(parent).text()); else this.exec.run.call(this, cmd, param); } else { if (cmd === 'inserthorizontalrule' && this.utils.browser.call(this, 'msie')) this.$editor.focus(); if (cmd === 'formatblock' && this.utils.browser.call(this, 'mozilla')) this.$editor.focus(); if (pre && this.opts.formattingPre) return false; this.exec.run.call(this, cmd, param); } if (cmd === 'inserthorizontalrule') { this.$editor.find('hr').removeAttr('id'); if (this.opts.linebreaks === false) { this.$editor.focus(); var p = $('

' + this.opts.invisibleSpace + '

'); this.insert.nodeAtCaret.call(this, p[0]); this.$editor.focus(); this.selection.start.call(this, p, 0); } } if (pre && this.opts.formattingPre && (cmd === 'italic' || cmd === 'bold' || cmd === 'strikethrough'|| cmd === 'underline')) { return false; } setTimeout($.proxy(this.sync, this), 10); if (typeof this.opts.execCommandCallback === 'function') { this.opts.execCommandCallback(this, cmd, param); } if (this.opts.air) { this.$air.hide(); } } catch (e) { } }, run: function(cmd, param) { if (cmd === 'formatblock' && this.utils.browser.call(this, 'msie')) { param = '<' + param + '>'; } this.document.execCommand(cmd, false, param); } }, // QUOTE quote: { toggle: function() { this.buffer.set.call(this); var html = false; var nodes = this.selection.getBlocks.call(this); if (nodes.length === 0) { nodes = [this.selection.getBlock.call(this)]; } if (!nodes) { this.exec.command.call(this, 'formatblock', 'blockquote'); } $.each(nodes, $.proxy(function(i, node) { if (node === false || typeof node.tagName === 'undefined') { this.exec.command.call(this, 'formatblock', 'blockquote'); } else if (node.tagName === 'BLOCKQUOTE') { if (this.opts.linebreaks === true) { this.selection.save.call(this); var node1 = $('')[0]; var node2 = $('')[0]; this.insert.beforeCaret.call(this, node1); this.insert.afterCaret.call(this, node2); this.selection.restore.call(this); } html = this.quote.html.call(this, node); } else if (node.tagName === 'PRE') { html = '
' + this.quote.html.call(this, node) + '
'; } else { var parent = $(node).parent(); if (parent[0].tagName === 'BLOCKQUOTE') { html = $(parent).html(); node = parent; } else { html = $('
' + this.utils.outerHtml.call(this, node) + '
'); } } if (html !== false) { if (this.opts.linebreaks === false) { var el = $(html); $(node).replaceWith(el); this.selection.start.call(this, el); } else { $(node).replaceWith(html); var node1 = $(this.$editor.find('span#insert-marker-1')); var node2 = $(this.$editor.find('span#insert-marker-2')); if (node1.size() !== 0 && node2.size() !== 0) { this.selection.set.call(this, node1[0], 0, node2[0], 0); node1.remove(); node2.remove(); } else { this.focus.set.call(this); } } } }, this)); this.sync(); }, html: function(node) { var html = $(node).html(); if (this.opts.linebreaks === false) { html = '

' + html + '

'; } return html; } }, // FORMAT format: { empty: function(e) { var html = $.trim(this.$editor.html()); html = html.replace(//i, ''); var thtml = html.replace(/

\s?<\/p>/gi, ''); if (html === '' || thtml === '') { e.preventDefault(); var node = $(this.opts.emptyHtml).get(0); this.$editor.html(node); this.selection.set.call(this, node, 0, node, 0); this.sync(); return false; } else { this.sync(); } }, newLine: function() { var parent = this.selection.getElement.call(this); if (parent === false || (this.opts.iframe && parent.tagName === 'BODY') || (this.opts.iframe === false && parent.tagName === 'DIV' && $(parent).hasClass('redactor_editor'))) { var element = $(this.selection.getNode.call(this)); // Replace div to p if (this.opts.linebreaks === false) { if ((element.get(0).tagName === 'DIV' || element.get(0).tagName === 'H6') && (element.html() === '' || element.html() === '
')) { // replace with paragraph var newElement = $('

').append(element.clone().get(0).childNodes); element.replaceWith(newElement); this.selection.start.call(this, newElement); } } else { // Replace div, p to br if (element.size() != 0 && (element[0].tagName === 'DIV' || element[0].tagName === 'P') && (element.html() === '' || element.html() === '
')) { this.format.replaceLineBreak.call(this, element); } } } if (parent.tagName === 'P' && this.opts.linebreaks === true) { this.format.replaceLineBreak.call(this, parent); } this.sync(); }, insertAfterLastElement: function(element) { if (this.utils.isEndOfElement.call(this) && this.opts.linebreaks === false) { if (this.$editor.contents().last()[0] !== element) { return false; } this.buffer.set.call(this); var node = $(this.opts.emptyHtml); $(element).after(node); this.selection.start.call(this, node); } }, insertLineBreak: function() { var br = $('
' + this.opts.invisibleSpace); this.insert.nodeAtCaret.call(this, br[0]); }, replaceLineBreak: function(element) { var node = this.document.createTextNode('\uFEFF'); $(element).replaceWith(node); this.selection.start.call(this, $(node)); }, blocks: function(tag) { this.buffer.set.call(this); var nodes = this.selection.getBlocks.call(this); var last; if (nodes.length === 0) { this.format.block.call(this, tag, false, true); } else { $.each(nodes, $.proxy(function(i, node) { last = this.format.block.call(this, tag, node, false); }, this)); this.selection.end.call(this, last); } this.sync(); }, block: function(tag, block, offset) { if (block === false) { block = this.selection.getBlock.call(this); } if (block === false) { if (this.opts.linebreaks === true) { this.exec.command.call(this, 'formatblock', tag); } return true; } if (offset !== false) { var offset = this.selection.caretOffset.call(this, block); } var contents = ''; if (tag !== 'pre') { contents = $(block).contents(); } else { contents = this.clean.encodeEntities.call(this, $(block).text()); } if (this.opts.linebreaks === true && tag === 'p') { $(block).replaceWith(contents); return $(contents); } else { var node = $('<' + tag + '>').append(contents); $(block).replaceWith(node); if (offset !== false) { this.selection.caret.call(this, node[0], offset); } } return node; }, changeTag: function(from, to) { this.selection.save.call(this); var elements = this.$editor.find(from); $.each(elements, $.proxy(function(i,s) { $(s).replaceWith(function() { return $('<' + to + '/>').append($(this).contents()); }); }, this)); setTimeout($.proxy(this.selection.restore, this), 10); } }, // BLOCK CLASS AND STYLE block: { removeAttr: function(attr) { var nodes = this.selection.getBlocks.call(this); if (nodes.length === 0) { $(this.selection.getBlock.call(this)).removeAttr(attr); } else { $(nodes).removeAttr(attr); } }, setAttr: function(attr, value) { var nodes = this.selection.getBlocks.call(this); if (nodes.length === 0) { $(this.selection.getBlock.call(this)).attr(attr, value); } else { $.each(nodes, function(i,s) { $(s).attr(attr, value); }); } }, removeStyle: function(rule) { var nodes = this.selection.getBlocks.call(this); if (nodes.length === 0) { var $block = $(this.selection.getBlock.call(this)); $block.css(rule, ''); this.utils.removeEmptyStyleAttr.call(this, $block); } else { $(nodes).css(rule, ''); $.each(nodes, $.proxy(function(i,s) { this.utils.removeEmptyStyleAttr.call(this, s); }, this)); } }, setStyle: function(rule, value) { var nodes = this.selection.getBlocks.call(this); if (nodes.length === 0) { $(this.selection.getBlock.call(this)).css(rule, value); } else { $.each(nodes, function(i,s) { $(s).css(rule, value); }); } }, removeClass: function(className) { var nodes = this.selection.getBlocks.call(this); if (nodes.length === 0) { $(this.selection.getBlock.call(this)).removeClass(className); } else { $(nodes).removeClass(className); } }, setClass: function(className) { var nodes = this.selection.getBlocks.call(this); if (nodes.length === 0) { $(this.selection.getBlock.call(this)).addClass(className); } else { $.each(nodes, function(i,s) { $(block).addClass(className); }); } } }, // INLINE CLASS AND STYLE inline: { removeClass: function(className) { var nodes = this.selection.getNodes.call(this); nodes.push(this.selection.getElement.call(this)); $.each(nodes, function(i,s) { if ($(s).hasClass(className)) { $(s).removeClass(className); } }); }, setClass: function(className) { var current = this.selection.getElement.call(this); if ($(current).hasClass(className)) { return true; } this.inline.methods.call(this, 'addClass', className); }, removeStyle: function(rule) { var nodes = this.selection.getNodes.call(this); nodes.push(this.selection.getElement.call(this)); $.each(nodes, $.proxy(function(i,s) { if (s.tagName === 'SPAN') { $(s).css(rule, '') this.utils.removeEmptyStyleAttr.call(this, s); } }, this)); }, setStyle: function(rule, value) { this.inline.methods.call(this, 'css', rule, value); }, removeAttr: function(attr) { var nodes = this.selection.getNodes.call(this); nodes.push(this.selection.getElement.call(this)); $.each(nodes, function(i,s) { if ($(s).attr(attr)) { $(s).removeAttr(attr); } }); }, setAttr: function(attr, value) { this.inline.methods.call(this, 'attr', attr, value); }, methods: function(type, attr, value) { this.document.execCommand("fontSize", false, 4); var fonts = this.$editor.find('font'); var last; $.each(fonts, $.proxy(function(i,s) { last = this.inline.setMethods.call(this, type, s, attr, value); }, this)); if (last) this.selection.end.call(this, last); }, setMethods: function(type, s, attr, value) { var parent = $(s).parent(); if (parent && parent[0].tagName === 'SPAN') { var el = parent; $(s).replaceWith($(s).html()); } else { var el = $('').append($(s).contents()); $(s).replaceWith(el); } if (type === 'addClass') $(el).addClass(attr); else if (type === 'css') $(el).css(attr, value); else if (type === 'attr') $(el).attr(attr, value); return el; }, format: function(tag) { this.document.execCommand("fontSize", false, 4); var fonts = this.$editor.find('font'); var last; $.each(fonts, function(i,s) { var el = $('<' + tag + '/>').append($(s).contents()); $(s).replaceWith(el); last = el; }); if (last) this.selection.end.call(this, last); }, removeFormat: function(tag) { var utag = tag.toUpperCase(); var nodes = this.selection.getNodes.call(this); nodes.push(this.selection.getElement.call(this)); $.each(nodes, function(i,s) { if (s.tagName === utag) { $(s).replaceWith($(s).contents()); } }); } }, // SELECTION selection: { save: function() { this.$editor.focus(); this.savedSel = this.selection.origin.call(this); this.savedSelObj = this.selection.focus.call(this); }, restore: function() { if (typeof this.savedSel !== 'undefined' && this.savedSel !== null && this.savedSelObj !== null && this.savedSel[0].tagName !== 'BODY') { if (this.opts.iframe === false && $(this.savedSel[0]).closest('.redactor_editor').size() == 0) { this.focus.set.call(this); } else { if (this.utils.browser.call(this, 'opera')) this.$editor.focus(); this.selection.set.call(this, this.savedSel[0], this.savedSel[1], this.savedSelObj[0], this.savedSelObj[1]); if (this.utils.browser.call(this, 'mozilla')) this.$editor.focus(); } } else { this.focus.set.call(this); } }, saveDynamic: function() { var id = 'buffer-marker-'; $(this.$editor.find('span#' + id + '1')).remove(); $(this.$editor.find('span#' + id + '2')).remove(); var node1 = $('')[0]; var node2 = $('')[0]; this.insert.beforeCaret.call(this, node1); this.insert.afterCaret.call(this, node2); this.$editor.focus(); this.selection.set.call(this, node1, 0, node2, 0); }, restoreDynamic: function() { var id = 'buffer-marker-'; this.$editor.focus(); var node1 = $(this.$editor.find('span#' + id + '1')); var node2 = $(this.$editor.find('span#' + id + '2')); if (node1.size() !== 0 && node2.size() !== 0) { this.selection.set.call(this, node1[0], 0, node2[0], 0); node1.remove(); node2.remove(); } else { this.focus.set.call(this); } }, all: function() { var sel, range; if (this.window.getSelection && this.document.createRange) { range = this.document.createRange(); range.selectNodeContents(this.$editor[0]); sel = this.window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } else if (this.document.body.createTextRange) { range = this.document.body.createTextRange(); range.moveToElementText(this.$editor[0]); range.select(); } }, get: function() { var doc = this.document; if (this.window.getSelection) { return this.window.getSelection(); } else if (doc.getSelection) { return doc.getSelection(); } else // IE { return doc.selection.createRange(); } return false; }, origin: function() { var sel; if (!((sel = this.selection.get.call(this)) && (sel.anchorNode != null))) { return null; } return [sel.anchorNode, sel.anchorOffset]; }, focus: function() { var sel; if (!((sel = this.selection.get.call(this)) && (sel.focusNode != null))) { return null; } return [sel.focusNode, sel.focusOffset]; }, getTextNodesIn: function(node) { var textNodes = []; if (node.nodeType == 3) { textNodes.push(node); } else { var children = node.childNodes; for (var i = 0, len = children.length; i < len; ++i) { textNodes.push.apply(textNodes, this.selection.getTextNodesIn.call(this, children[i])); } } return textNodes; }, caretOffset: function(element) { var caretOffset = 0; if (typeof this.window.getSelection != "undefined") { var range = this.window.getSelection().getRangeAt(0); var preCaretRange = range.cloneRange(); preCaretRange.selectNodeContents(element); preCaretRange.setEnd(range.endContainer, range.endOffset); caretOffset = $.trim(preCaretRange.toString()).length; } else if (typeof this.document.selection != "undefined" && this.document.selection.type != "Control") { var textRange = this.document.selection.createRange(); var preCaretTextRange = this.document.body.createTextRange(); preCaretTextRange.moveToElementText(element); preCaretTextRange.setEndPoint("EndToEnd", textRange); caretOffset = $.trim(preCaretTextRange.text).length; } return caretOffset; }, caret: function (el, start, end) { if (typeof end === 'undefined') { end = start; } if (this.document.createRange && this.window.getSelection) { var range = this.document.createRange(); range.selectNodeContents(el); var textNodes = this.selection.getTextNodesIn.call(this, el); var foundStart = false; var charCount = 0, endCharCount; for (var i = 0, textNode; textNode = textNodes[i++];) { endCharCount = charCount + textNode.length; if (!foundStart && start >= charCount && (start < endCharCount || (start == endCharCount && i < textNodes.length))) { range.setStart(textNode, start - charCount); foundStart = true; } if (foundStart && end <= endCharCount) { range.setEnd(textNode, end - charCount); break; } charCount = endCharCount; } var sel = this.window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } else if (this.document.selection && this.document.body.createTextRange) { var textRange = this.document.body.createTextRange(); textRange.moveToElementText(el); textRange.collapse(true); textRange.moveEnd("character", end); textRange.moveStart("character", start); textRange.select(); } }, element: function(node) { this.selection.set.call(this, node[0], 1, node[0], 0); }, start: function(node) { this.selection.set.call(this, node[0], 0, node[0], 0); }, end: function(node) { this.selection.set.call(this, node[0], 1, node[0], 1); }, set: function (orgn, orgo, focn, foco) { if (focn == null) { focn = orgn; } if (foco == null) { foco = orgo; } var sel = this.selection.get.call(this); if (!sel) { return; } if (sel.collapse && sel.extend) { sel.collapse(orgn, orgo); sel.extend(focn, foco); } else // IE9 { r = this.document.createRange(); r.setStart(orgn, orgo); r.setEnd(focn, foco); try { sel.removeAllRanges(); } catch (e) {} sel.addRange(r); } }, getNode: function() { var el = false; if (typeof this.window.getSelection !== 'undefined') { var s = this.window.getSelection(); if (s.rangeCount > 0) { el = this.selection.get.call(this).getRangeAt(0).startContainer; } } else if (typeof this.document.selection !== 'undefined') { el = this.selection.get.call(this); } return this.utils.isParentRedactor.call(this, el); }, getElement: function() { var el = false; if (typeof this.window.getSelection !== 'undefined') { var s = this.window.getSelection(); if (s.rangeCount > 0) { el = s.getRangeAt(0).startContainer.parentNode; } } else if (typeof this.document.selection !== 'undefined') { el = this.selection.get.call(this).parentElement(); } return this.utils.isParentRedactor.call(this, el); }, getParent: function() { var el = this.selection.getElement.call(this); if (el) { return this.utils.isParentRedactor.call(this, $(el).parent()[0]); } else { return false; } }, text: function() { var text = ''; if (this.window.getSelection) { text = this.window.getSelection().toString(); } else if (this.document.selection && this.document.selection.type != "Control") { text = this.document.selection.createRange().text; } return text; }, html: function() { var html = ''; if (this.window.getSelection) { var sel = this.window.getSelection(); if (sel.rangeCount) { var container = this.document.createElement("div"); for (var i = 0, len = sel.rangeCount; i < len; ++i) { container.appendChild(sel.getRangeAt(i).cloneContents()); } html = container.innerHTML; } } else if (this.document.selection) { if (this.document.selection.type === "Text") { html = this.document.selection.createRange().htmlText; } } return html; }, nodeTestBlocks: function(node) { return node.nodeType == 1 && /^(P|H[1-6]|DIV|LI|BLOCKQUOTE|PRE|ADDRESS|SECTION|HEADER|FOOTER|ASIDE|ARTICLE)$/i.test(node.nodeName); }, getBlock: function(node) { if (typeof node === 'undefined') { node = this.selection.getNode.call(this); } while (node) { if (this.selection.nodeTestBlocks.call(this, node)) { if ($(node).hasClass('redactor_editor')) { return false; } return node; } node = node.parentNode; } return false; }, nextNode: function(node) { if (node.hasChildNodes()) { return node.firstChild; } else { while (node && !node.nextSibling) { node = node.parentNode; } if (!node) { return null; } return node.nextSibling; } }, getRangeSelectedNodes: function(range) { var node = range.startContainer; var endNode = range.endContainer; if (node == endNode) { return [node]; } var rangeNodes = []; while (node && node != endNode) { rangeNodes.push( node = this.selection.nextNode.call(this, node) ); } node = range.startContainer; while (node && node != range.commonAncestorContainer) { rangeNodes.unshift(node); node = node.parentNode; } return rangeNodes; }, getNodes: function() { var nodes = []; var finalnodes = []; if (this.window.getSelection) { var sel = this.window.getSelection(); if (!sel.isCollapsed) { nodes = this.selection.getRangeSelectedNodes.call(this, sel.getRangeAt(0)); } } $.each(nodes, $.proxy(function(i,node) { if (this.opts.iframe === false && $(node).parents('div.redactor_editor').size() == 0) { return false; } finalnodes.push(node); }, this)); return finalnodes; }, getBlocks: function() { var nodes = this.selection.getNodes.call(this); var newnodes = []; $.each(nodes, $.proxy(function(i,node) { if (this.opts.iframe === false && $(node).parents('div.redactor_editor').size() == 0) { return false; } if (this.selection.nodeTestBlocks.call(this, node)) { newnodes.push(node); } }, this)); return newnodes; }, remove: function() { if (this.window.getSelection) { this.window.getSelection().removeAllRanges(); } else if (document.selection) { this.document.selection.empty(); } } }, // TABLE table: { show: function() { this.selection.save.call(this); this.modal.init.call(this, RLANG.table, this.opts.modal_table, 300, $.proxy(function() { $('#redactor_insert_table_btn').click($.proxy(this.table.insert, this)); setTimeout(function() { $('#redactor_table_rows').focus(); }, 200); }, this) ); }, insert: function() { var rows = $('#redactor_table_rows').val(); var columns = $('#redactor_table_columns').val(); var table_box = $('

'); var tableid = Math.floor(Math.random() * 99999); var table = $('
'); for (var i = 0; i < rows; i++) { var row = $(''); for (var z = 0; z < columns; z++) { var column = $('' + this.opts.invisibleSpace + ''); $(row).append(column); } $(table).append(row); } $(table_box).append(table); var html = $(table_box).html(); this.selection.restore.call(this); this.insert.force.call(this, html); this.modal.close.call(this); this.observe.tables.call(this); }, observer: function(e) { this.$table = $(e.target).closest('table'); this.$table_tr = this.$table.find('tr'); this.$table_td = this.$table.find('td'); this.$tbody = $(e.target).closest('tbody'); this.$thead = $(this.$table).find('thead'); this.$current_td = $(e.target); this.$current_tr = $(e.target).closest('tr'); }, deleteTable: function() { this.buffer.set.call(this); $(this.$table).remove(); this.$table = false; this.sync(); }, deleteRow: function() { this.buffer.set.call(this); $(this.$current_tr).remove(); this.sync(); }, deleteColumn: function() { this.buffer.set.call(this); var index = $(this.$current_td).get(0).cellIndex; $(this.$table).find('tr').each(function() { $(this).find('td').eq(index).remove(); }); this.sync(); }, addHead: function() { this.buffer.set.call(this); if ($(this.$table).find('thead').size() !== 0) { this.table.deleteHead.call(this); } else { var tr = $(this.$table).find('tr').first().clone(); tr.find('td').html(this.opts.invisibleSpace); this.$thead = $(''); this.$thead.append(tr); $(this.$table).prepend(this.$thead); this.sync(); } }, deleteHead: function() { this.buffer.set.call(this); $(this.$thead).remove(); this.$thead = false; this.sync(); }, insertRowAbove: function() { this.table.insertRow.call(this, 'before'); }, insertRowBelow: function() { this.table.insertRow.call(this, 'after'); }, insertColumnLeft: function() { this.table.insertColumn.call(this, 'before'); }, insertColumnRight: function() { this.table.insertColumn.call(this, 'after'); }, insertRow: function(type) { this.buffer.set.call(this); var new_tr = $(this.$current_tr).clone(); new_tr.find('td').html(this.opts.invisibleSpace); if (type === 'after') { $(this.$current_tr).after(new_tr); } else { $(this.$current_tr).before(new_tr); } this.sync(); }, insertColumn: function(type) { this.buffer.set.call(this); var index = 0; this.$current_tr.find('td').each($.proxy(function(i,s) { if ($(s)[0] === this.$current_td[0]) { index = i; } }, this)); this.$table_tr.each($.proxy(function(i,s) { var current = $(s).find('td').eq(index); var td = current.clone(); td.html(this.opts.invisibleSpace); if (type === 'after') $(current).after(td); else $(current).before(td); }, this)); this.sync(); } }, // VIDEO video: { show: function() { this.selection.save.call(this); this.modal.init.call(this, RLANG.video, this.opts.modal_video, 600, $.proxy(function() { $('#redactor_insert_video_btn').click($.proxy(this.video.insert, this)); setTimeout(function() { $('#redactor_insert_video_area').focus(); }, 200); }, this) ); }, insert: function() { var data = $('#redactor_insert_video_area').val(); data = this.clean.stripTags.call(this, data); this.selection.restore.call(this); this.exec.command.call(this, 'inserthtml', data); this.modal.close.call(this); } }, // IMAGE image: { show: function() { this.selection.save.call(this); var callback = $.proxy(function() { // json if (this.opts.imageGetJson !== false) { $.getJSON(this.opts.imageGetJson, $.proxy(function(data) { var folders = {}; var z = 0; // folders $.each(data, $.proxy(function(key, val) { if (typeof val.folder !== 'undefined') { z++; folders[val.folder] = z; } }, this)); var folderclass = false; $.each(data, $.proxy(function(key, val) { // title var thumbtitle = ''; if (typeof val.title !== 'undefined') { thumbtitle = val.title; } var folderkey = 0; if (!$.isEmptyObject(folders) && typeof val.folder !== 'undefined') { folderkey = folders[val.folder]; if (folderclass === false) { folderclass = '.redactorfolder' + folderkey; } } var img = $(''); $('#redactor_image_box').append(img); $(img).click($.proxy(this.image.thumb, this)); }, this)); // folders if (!$.isEmptyObject(folders)) { $('.redactorfolder').hide(); $(folderclass).show(); var onchangeFunc = function(e) { $('.redactorfolder').hide(); $('.redactorfolder' + $(e.target).val()).show(); } var select = $('', {'type': "hidden", 'name': k, 'value': v}); $(this.form).append(hidden); }, this)); } var oldElement = this.uploadOptions.input; var newElement = $(oldElement).clone(); $(oldElement).attr('id', fileId); $(oldElement).before(newElement); $(oldElement).appendTo(this.form); $(this.form).css('position', 'absolute'); $(this.form).css('top', '-2000px'); $(this.form).css('left', '-2000px'); $(this.form).appendTo('body'); this.form.submit(); } else { f.attr('target', name); f.attr('method', 'POST'); f.attr('enctype', 'multipart/form-data'); f.attr('action', this.uploadOptions.url); this.element.submit(); } }, loaded : function() { var i = $('#' + this.id)[0]; var d; if (i.contentDocument) d = i.contentDocument; else if (i.contentWindow) d = i.contentWindow.document; else d = window.frames[this.id].document; // Success if (this.uploadOptions.success) { if (typeof d !== 'undefined') { // Remove bizarre
 tag wrappers around our json data:
						var rawString = d.body.innerHTML;
						var jsonString = rawString.match(/\{(.|\n)*\}/)[0];
						jsonString = jsonString.replace(/^\[/, '');
						jsonString = jsonString.replace(/\]$/, '');
						var json = $.parseJSON(jsonString);

						if (typeof json.error == 'undefined')
						{
							this.uploadOptions.success(json);
						}
						else
						{
							this.uploadOptions.error(this, json);
							this.modal.close.call(this);
						}
					}
					else
					{
						this.modal.close.call(this);
						alert('Upload failed!');
					}
				}

				this.element.attr('action', this.element_action);
				this.element.attr('target', '');

			}
		},

		// DRAGUPLOAD
		dragupload:
		{
			init: function(el, options)
			{
				this.draguploadOptions = $.extend({

					url: false,
					success: false,
					error: false,
					preview: false,
					uploadFields: false,

					text: RLANG.drop_file_here,
					atext: RLANG.or_choose

				}, options);

				if (window.FormData === undefined)
				{
					return false;
				}

				this.droparea = $('
'); this.dropareabox = $('
' + this.draguploadOptions.text + '
'); this.dropalternative = $('
' + this.draguploadOptions.atext + '
'); this.droparea.append(this.dropareabox); $(el).before(this.droparea); $(el).before(this.dropalternative); // drag over this.dropareabox.bind('dragover', $.proxy(function() { return this.dragupload.ondrag.call(this); }, this)); // drag leave this.dropareabox.bind('dragleave', $.proxy(function() { return this.dragupload.ondragleave.call(this); }, this)); var uploadProgress = $.proxy(function(e) { var percent = parseInt(e.loaded / e.total * 100, 10); this.dropareabox.text('Loading ' + percent + '%'); }, this); var xhr = jQuery.ajaxSettings.xhr(); if (xhr.upload) { xhr.upload.addEventListener('progress', uploadProgress, false); } var provider = function () { return xhr; }; // drop this.dropareabox.get(0).ondrop = $.proxy(function(e) { e.preventDefault(); this.dropareabox.removeClass('hover').addClass('drop'); var file = e.dataTransfer.files[0]; var fd = new FormData(); // append hidden fields if (this.draguploadOptions.uploadFields !== false && typeof this.draguploadOptions.uploadFields === 'object') { $.each(this.draguploadOptions.uploadFields, $.proxy(function(k,v) { if (v.toString().indexOf('#') === 0) { v = $(v).val(); } fd.append(k, v); }, this)); } // append file data fd.append('file', file); $.ajax({ url: this.draguploadOptions.url, dataType: 'html', data: fd, xhr: provider, cache: false, contentType: false, processData: false, type: 'POST', success: $.proxy(function(data) { data = data.replace(/^\[/, ''); data = data.replace(/\]$/, ''); var json = $.parseJSON(data); if (typeof json.error == 'undefined') { this.draguploadOptions.success(json); } else { this.draguploadOptions.error(this, json); this.draguploadOptions.success(false); } }, this) }); }, this); }, ondrag: function() { this.dropareabox.addClass('hover'); return false; }, ondragleave: function() { this.dropareabox.removeClass('hover'); return false; } }, // UTILITIES utils: { browser: function(browser) { var ua = navigator.userAgent.toLowerCase(); var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || /(msie) ([\w.]+)/.exec(ua) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; if (browser == 'version') { return match[2]; } if (browser == 'webkit') { return (match[1] == 'chrome' || match[1] == 'webkit'); } return match[1] == browser; }, outerHtml: function(s) { return $('
').append($(s).eq(0).clone()).html(); }, getObjectText: function(obj) { return obj.textContent ? obj.textContent : obj.innerText; }, oldIE: function() { if (this.utils.browser.call(this, 'msie') && parseInt(this.utils.browser.call(this, 'version'), 10) < 9) { return true; } return false; }, normalize: function(str) { return parseInt(str.replace('px',''), 10); }, removeEmptyStyleAttr: function(el) { if ($(el).attr('style') == '') $(el).removeAttr('style'); }, extractBlockContentsFromCaret: function() { var sel = this.window.getSelection(); if (sel.rangeCount) { var selRange = sel.getRangeAt(0); var blockEl = this.selection.getBlock.call(this, selRange.endContainer); if (blockEl) { var range = selRange.cloneRange(); range.selectNodeContents(blockEl); range.setStart(selRange.endContainer, selRange.endOffset); return range.extractContents(); } } }, getFragmentHtml: function (fragment) { var cloned = fragment.cloneNode(true); var div = this.document.createElement('div'); div.appendChild(cloned); return div.innerHTML; }, extractContent: function() { var node = this.$editor.get(0); var frag = this.document.createDocumentFragment(), child; while ((child = node.firstChild)) { frag.appendChild(child); } return frag; }, isParentRedactor: function(el) { if (!el) return false; if (this.opts.iframe) return el; if ($(el).parents('div.redactor_editor').size() == 0 || $(el).hasClass('redactor_editor')) return false; else return el; }, isEndOfElement: function() { var current = this.selection.getBlock.call(this); var offset = this.selection.caretOffset.call(this, current); var text = $.trim($(current).text()).replace(/\n\r\n/g, ''); var len = text.length; if (offset == len) return true; else return false; }, // Mobile isMobile: function(ipad) { if (ipad === true && /(iPhone|iPod|iPad|BlackBerry|Android)/.test(navigator.userAgent)) { return true; } else if (/(iPhone|iPod|BlackBerry|Android)/.test(navigator.userAgent)) { return true; } else { return false; } } } }; })(jQuery); (function($) { "use strict"; var protocol = 'http://'; var url1 = /(^|<|\s)(www\..+?\..+?)(\s|>|$)/g, url2 = /(^|<|\s)(((https?|ftp):\/\/|mailto:).+?)(\s|>|$)/g, linkifyThis = function () { var childNodes = this.childNodes, i = childNodes.length; while (i--) { var n = childNodes[i]; if (n.nodeType === 3) { var html = n.nodeValue; if (html && (html.match(url1) || html.match(url2))) { html = html.replace(/&/g, '&') .replace(//g, '>') .replace(url1, '$1$2$3') .replace(url2, '$1$2$5'); $(n).after(html).remove(); } } else if (n.nodeType === 1 && !/^(a|button|textarea)$/i.test(n.tagName)) { linkifyThis.call(n); } } }; $.fn.linkify = function () { this.each(linkifyThis); }; })(jQuery); /* jQuery plugin textselect * version: 0.9 * author: Josef Moravec, josef.moravec@gmail.com * updated: Imperavi Inc. * */ (function ($) { $.event.special.textselect = { setup: function (data, namespaces) { $(this).data("textselected", false); $(this).data("ttt", data); $(this).bind('mouseup', $.event.special.textselect.handler) }, teardown: function (data) { $(this).unbind('mouseup', $.event.special.textselect.handler) }, handler: function (event) { var data = $(this).data("ttt"); var text = $.event.special.textselect.getSelectedText(data).toString(); if (text != '') { $(this).data("textselected", true); event.type = "textselect"; event.text = text; $.event.dispatch.apply(this, arguments) } }, getSelectedText: function (data) { var text = ''; if (rwindow.getSelection) { text = rwindow.getSelection() } else if (rdocument.getSelection) { text = rdocument.getSelection() } else if (rdocument.selection) { text = rdocument.selection.createRange().text } return text } }; $.event.special.textunselect = { setup: function (data, namespaces) { $(this).data("rttt", data); $(this).data("textselected", false); $(this).bind('mouseup', $.event.special.textunselect.handler); $(this).bind('keyup', $.event.special.textunselect.handlerKey) }, teardown: function (data) { $(this).unbind('mouseup', $.event.special.textunselect.handler) }, handler: function (event) { if ($(this).data("textselected")) { var data = $(this).data("rttt"); var text = $.event.special.textselect.getSelectedText(data).toString(); if (text == '') { $(this).data("textselected", false); event.type = "textunselect"; $.event.dispatch.apply(this, arguments) } } }, handlerKey: function (event) { if ($(this).data("textselected")) { var data = $(this).data("rttt"); var text = $.event.special.textselect.getSelectedText(data).toString(); if ((event.keyCode = 27) && (text == '')) { $(this).data("textselected", false); event.type = "textunselect"; $.event.dispatch.apply(this, arguments) } } } } })(jQuery);