From c2a5f177879c1ec09ac6432c856f96a7f43dd52f Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Wed, 8 Feb 2017 16:15:42 +0100 Subject: [PATCH] Upgraded to Redactor II 2.0.0 --- .../files/js/3rdParty/redactor2/redactor.js | 295 +++++++++++++++--- .../js/3rdParty/redactor2/redactor.min.js | 13 +- 2 files changed, 251 insertions(+), 57 deletions(-) diff --git a/wcfsetup/install/files/js/3rdParty/redactor2/redactor.js b/wcfsetup/install/files/js/3rdParty/redactor2/redactor.js index e35da6c437..4cf1f81202 100644 --- a/wcfsetup/install/files/js/3rdParty/redactor2/redactor.js +++ b/wcfsetup/install/files/js/3rdParty/redactor2/redactor.js @@ -1,11 +1,11 @@ /* Redactor II - Version 1.4 - Updated: January 11, 2017 + Version 2.0 + Updated: February 5, 2017 http://imperavi.com/redactor/ - Copyright (c) 2009-2016, Imperavi LLC. + Copyright (c) 2009-2017, Imperavi LLC. License: http://imperavi.com/redactor/license/ Usage: $('#content').redactor(); @@ -101,7 +101,7 @@ // Options $.Redactor = Redactor; - $.Redactor.VERSION = '1.4'; + $.Redactor.VERSION = '2.0'; $.Redactor.modules = ['air', 'autosave', 'block', 'buffer', 'build', 'button', 'caret', 'clean', 'code', 'core', 'detect', 'dropdown', 'events', 'file', 'focus', 'image', 'indent', 'inline', 'insert', 'keydown', 'keyup', 'lang', 'line', 'link', 'linkify', 'list', 'marker', 'modal', 'observe', 'offset', 'paragraphize', 'paste', 'placeholder', @@ -1114,30 +1114,22 @@ }, setUndo: function() { - this.selection.save(); + var saved = this.selection.saveInstant(); var last = this.opts.buffer[this.opts.buffer.length-1]; var current = this.core.editor().html(); if (last !== current) { - this.opts.buffer.push(current); + this.opts.buffer.push([current, saved]); } - this.selection.restore(); + this.selection.restoreInstant(); }, setRedo: function() { - this.selection.save(); - this.opts.rebuffer.push(this.core.editor().html()); - this.selection.restore(); - }, - getUndo: function() - { - this.core.editor().html(this.opts.buffer.pop()); - }, - getRedo: function() - { - this.core.editor().html(this.opts.rebuffer.pop()); + var saved = this.selection.saveInstant(); + this.opts.rebuffer.push([this.core.editor().html(), saved]); + this.selection.restoreInstant(); }, add: function() { @@ -1150,10 +1142,12 @@ return; } + var buffer = this.opts.buffer.pop(); + this.buffer.set('redo'); - this.buffer.getUndo(); + this.core.editor().html(buffer[0]); - this.selection.restore(); + this.selection.restoreInstant(buffer[1]); }, redo: function() { @@ -1162,10 +1156,12 @@ return; } + var buffer = this.opts.rebuffer.pop(); + this.buffer.set('undo'); - this.buffer.getRedo(); + this.core.editor().html(buffer[0]); - this.selection.restore(); + this.selection.restoreInstant(buffer[1]); }, clear: function() { @@ -1213,6 +1209,7 @@ // call this.build.callEditor(); + }, createContainerBox: function() { @@ -1244,7 +1241,7 @@ // place this.$box.insertAfter(this.$element).append(this.$editor).append(this.$element); - this.$editor.addClass('redactor-editor'); + this.$editor.addClass('redactor-layer'); if (this.opts.overrideStyles) { @@ -1521,6 +1518,7 @@ format: { title: this.lang.get('format'), + icon: true, dropdown: { p: @@ -1573,30 +1571,35 @@ bold: { title: this.lang.get('bold-abbr'), + icon: true, label: this.lang.get('bold'), func: 'inline.format' }, italic: { title: this.lang.get('italic-abbr'), + icon: true, label: this.lang.get('italic'), func: 'inline.format' }, deleted: { title: this.lang.get('deleted-abbr'), + icon: true, label: this.lang.get('deleted'), func: 'inline.format' }, underline: { title: this.lang.get('underline-abbr'), + icon: true, label: this.lang.get('underline'), func: 'inline.format' }, lists: { title: this.lang.get('lists'), + icon: true, dropdown: { unorderedlist: @@ -1642,36 +1645,43 @@ ul: { title: '• ' + this.lang.get('bulletslist'), + icon: true, func: 'list.toggle' }, ol: { title: '1. ' + this.lang.get('numberslist'), + icon: true, func: 'list.toggle' }, outdent: { title: this.lang.get('outdent'), + icon: true, func: 'indent.decrease' }, indent: { title: this.lang.get('indent'), + icon: true, func: 'indent.increase' }, image: { title: this.lang.get('image'), + icon: true, func: 'image.show' }, file: { title: this.lang.get('file'), + icon: true, func: 'file.show' }, link: { title: this.lang.get('link'), + icon: true, dropdown: { link: @@ -1707,6 +1717,7 @@ horizontalrule: { title: this.lang.get('horizontalrule'), + icon: true, func: 'line.insert' } }; @@ -1766,6 +1777,33 @@ }, this)); }, + buildButtonTooltip: function($btn, title) + { + if (this.opts.air) + { + return; + } + + var $tooltip = $(''); + $tooltip.addClass('re-button-tooltip'); + $tooltip.html(title); + + $btn.append($tooltip); + $btn.on('mouseover', function() + { + if ($(this).hasClass('redactor-button-disabled')) + { + return; + } + + $tooltip.show(); + $tooltip.css('margin-left', -($tooltip.innerWidth()/2)); + + }).on('mouseout', function() + { + $tooltip.hide(); + }); + }, build: function(btnName, btnObject) { if (this.opts.toolbar === false) @@ -1773,13 +1811,25 @@ return; } - var $button = $('').html(btnObject.title); - $button.attr({ 'role': 'button', 'aria-label': btnObject.title, 'tabindex': '-1' }); + var title = (typeof btnObject.label !== 'undefined') ? btnObject.label : btnObject.title; + var $button = $('') + + $button.addClass('re-button re-' + btnName); + $button.attr({ 'role': 'button', 'aria-label': title, 'tabindex': '-1' }); - if (typeof btnObject.label !== 'undefined') + if (typeof btnObject.icon !== 'undefined') + { + var $icon = $(''); + $icon.addClass('re-icon-' + btnName); + + $button.append($icon); + $button.addClass('re-button-icon'); + + this.button.buildButtonTooltip($button, title); + } + else { - $button.attr('aria-label', btnObject.label); - $button.attr('title', btnObject.label); + $button.html(btnObject.title); } // click @@ -2027,7 +2077,16 @@ }, setIcon: function($btn, icon) { - $btn.html(icon); + $btn.html(icon).addClass('re-button-icon'); + this.button.buildButtonTooltip($btn, $btn.attr('alt')); + }, + changeIcon: function(key, newIconClass) + { + var $btn = this.button.get(key); + if ($btn.length !== 0) + { + $btn.find('i').removeAttr('class').addClass('re-icon-' + newIconClass); + } }, addCallback: function($btn, callback) { @@ -2450,7 +2509,7 @@ } // add span marker - $div.find('span').attr('data-redactor-span', true); + $div.find('span, a').attr('data-redactor-span', true); html = $div.html(); @@ -2520,7 +2579,7 @@ }); // remove span without attributes & span marker - $div.find('span').removeAttr('data-redactor-span').each(function() + $div.find('span, a').removeAttr('data-redactor-span').each(function() { if (this.attributes.length === 0) { @@ -2588,8 +2647,7 @@ // remove all newlines if (this.opts.removeNewlines) { - html = html.replace(/\n/g, ""); - html = html.replace(/\r\n/g, ""); + html = html.replace(/\r?\n/g, ""); } return html; @@ -3506,7 +3564,7 @@ // help label $('#redactor-voice-' + this.uuid).remove(); - this.core.editor().removeClass('redactor-in redactor-styles redactor-structure redactor-editor-img-edit'); + this.core.editor().removeClass('redactor-in redactor-styles redactor-structure redactor-layer-img-edit'); // caret service this.core.editor().off('keydown.redactor-remove-textnode'); @@ -3547,7 +3605,7 @@ this.$element.removeClass('redactor-click-to-edit'); // common - this.core.editor().removeClass('redactor-editor'); + this.core.editor().removeClass('redactor-layer'); this.core.editor().removeAttr('contenteditable'); var html = this.code.get(); @@ -4035,6 +4093,7 @@ var event = this.core.getEvent(); var type = (event === 'click' || event === 'arrow') ? false : 'click'; + this.core.addEvent(type); this.utils.disableSelectAll(); this.core.callback('click', e); @@ -5034,8 +5093,18 @@ this.selection.save(); - $newList.append($current); - $prev.append($newList); + var $ol = $prev.find('ol').first(); + if ($ol.length === 1) + { + $ol.append($current); + } + else + { + var listTag = $list[0].tagName; + var $newList = $('<' + listTag + ' />'); + $newList.append($current); + $prev.append($newList); + } this.selection.restore(); } @@ -5270,7 +5339,6 @@ }, setNodesStriked: function(nodes, tag, attr) { - for (var i = 0; i < nodes.length; i++) { var nodeTag = (nodes[i].tagName) ? nodes[i].tagName.toLowerCase() : undefined; @@ -5350,20 +5418,40 @@ document.execCommand('strikethrough'); - this.selection.save(); + this.selection.saveInstant(); var self = this; this.core.editor().find('strike').each(function() { - var $el = self.utils.replaceToTag(this, tag); + var $el = self.utils.replaceToTag(this, tag); for (var key in attr) { self.inline.setAttr($el, key, attr[key], type); } + + // remove inside + var $inside = $el.find(tag); + if ($inside.length !== 0) + { + for (var key in attr) + { + self.inline.setAttr($inside, key, attr[key], 'remove'); + } + } + + // same parent + var $parent = $el.parent(); + if ($parent.html() == $el[0].outerHTML) + { + for (var key in attr) + { + self.inline.setAttr($parent, key, attr[key], 'remove'); + } + } }); - this.selection.restore(); + this.selection.restoreInstant(); }, formatCollapsed: function(tag, attr, value, type) { @@ -5399,7 +5487,6 @@ { this.inline.insertInline(tag, attr, value, type); } - }, insertBreakpoint: function(inline, currentTag) { @@ -6158,6 +6245,26 @@ // backspace & delete if (key === this.keyCode.BACKSPACE || key === this.keyCode.DELETE) { + if (this.observe.image && typeof this.observe.image !== 'undefined') + { + e.preventDefault(); + + var $prev = this.observe.image.closest('figure, p').prev() + this.image.remove(false); + this.observe.image = false; + + if ($prev && $prev.length !== 0) + { + this.caret.end($prev); + } + else + { + this.core.editor().focus(); + } + + return; + } + this.keydown.onBackspaceAndDeleteBefore(); } @@ -6825,7 +6932,6 @@ return { init: function(e) { - if (this.rtePaste) { return; @@ -6979,7 +7085,7 @@ // if hr is previous element var $prev = $block.prev(); - if ($prev && $prev[0].tagName === 'HR') + if ($prev && $prev.length !== 0 && $prev[0].tagName === 'HR') { e.preventDefault(); $prev.remove(); @@ -8289,7 +8395,7 @@ { if (this.opts.imageEditable) { - this.core.editor().addClass('redactor-editor-img-edit'); + this.core.editor().addClass('redactor-layer-img-edit'); this.core.editor().find('img').each($.proxy(function(i, img) { var $img = $(img); @@ -9317,9 +9423,10 @@ return node.nextSibling; } }, + saved: {}, save: function() { - this.marker.insert(); + this.marker.insert(); this.savedSel = this.core.editor().html(); }, restore: function(removeMarkers) @@ -9350,8 +9457,98 @@ this.marker.remove(); this.savedSel = false; } - }, + saveInstant: function() + { + var el = this.core.editor()[0]; + var doc = el.ownerDocument, win = doc.defaultView; + var sel = win.getSelection(); + + if (!sel.getRangeAt || !sel.rangeCount) + { + return; + } + + var range = sel.getRangeAt(0); + var selectionRange = range.cloneRange(); + + selectionRange.selectNodeContents(el); + selectionRange.setEnd(range.startContainer, range.startOffset); + + var start = selectionRange.toString().length; + + return this.saved = { + start: start, + end: start + range.toString().length, + node: range.startContainer + }; + }, + restoreInstant: function(saved) + { + if (typeof saved === 'undefined' && !this.saved) + { + return; + } + + this.saved = (typeof saved !== 'undefined') ? saved : this.saved; + + var $node = this.core.editor().find(this.saved.node); + if ($node.length !== 0 && $node.text().trim().replace(/\u200B/g, '').length === 0) + { + try { + var range = document.createRange(); + range.setStart($node[0], 0); + + var sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + } + catch(e) {} + + return; + } + + + var el = this.core.editor()[0]; + var doc = el.ownerDocument, win = doc.defaultView; + var charIndex = 0, range = doc.createRange(); + + range.setStart(el, 0); + range.collapse(true); + + var nodeStack = [el], node, foundStart = false, stop = false; + while (!stop && (node = nodeStack.pop())) + { + if (node.nodeType == 3) + { + var nextCharIndex = charIndex + node.length; + if (!foundStart && this.saved.start >= charIndex && this.saved.start <= nextCharIndex) + { + range.setStart(node, this.saved.start - charIndex); + foundStart = true; + } + + if (foundStart && this.saved.end >= charIndex && this.saved.end <= nextCharIndex) + { + range.setEnd(node, this.saved.end - charIndex); + stop = true; + } + charIndex = nextCharIndex; + } + else + { + var i = node.childNodes.length; + while (i--) + { + nodeStack.push(node.childNodes[i]); + } + } + } + + var sel = win.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + }, node: function(node) { $(node).prepend(this.marker.get(1)); @@ -10771,7 +10968,7 @@ }, animate: function(callback) { - this.$element.addClass('animated').css('display', '').removeClass('hide'); + this.$element.addClass('redactor-animated').css('display', '').removeClass('hide'); this.$element.addClass(this.opts.prefix + this.queue[0]); this.set(this.opts.duration + 's', this.opts.delay + 's', this.opts.iterate, this.opts.timing); @@ -10807,7 +11004,7 @@ }, clean: function() { - this.$element.removeClass('animated'); + this.$element.removeClass('redactor-animated'); this.$element.removeClass(this.opts.prefix + this.queue[0]); this.set('', '', '', ''); diff --git a/wcfsetup/install/files/js/3rdParty/redactor2/redactor.min.js b/wcfsetup/install/files/js/3rdParty/redactor2/redactor.min.js index aab02e55d8..bbb166bee6 100644 --- a/wcfsetup/install/files/js/3rdParty/redactor2/redactor.min.js +++ b/wcfsetup/install/files/js/3rdParty/redactor2/redactor.min.js @@ -1,8 +1,5 @@ -!function(t){"use strict";function e(t,i){return new e.prototype.init(t,i)}Function.prototype.bind||(Function.prototype.bind=function(t){var e=this;return function(){return e.apply(t)}});var i=0;t.fn.redactor=function(i){var o=[],r=Array.prototype.slice.call(arguments,1);return this.each("string"==typeof i?function(){var e,s=t.data(this,"redactor");if("-1"!==i.search(/\./)?(e=i.split("."),"undefined"!=typeof s[e[0]]&&(e=s[e[0]][e[1]])):e=s[i],"undefined"!=typeof s&&t.isFunction(e)){var n=e.apply(s,r);void 0!==n&&n!==s&&o.push(n)}else t.error('No such method "'+i+'" for Redactor')}:function(){t.data(this,"redactor",{}),t.data(this,"redactor",e(this,i))}),0===o.length?this:1===o.length?o[0]:o},t.Redactor=e,t.Redactor.VERSION="1.4",t.Redactor.modules=["air","autosave","block","buffer","build","button","caret","clean","code","core","detect","dropdown","events","file","focus","image","indent","inline","insert","keydown","keyup","lang","line","link","linkify","list","marker","modal","observe","offset","paragraphize","paste","placeholder","progress","selection","shortcuts","storage","toolbar","upload","uploads3","utils","browser"],t.Redactor.settings={},t.Redactor.opts={animation:!1,lang:"en",direction:"ltr",spellcheck:!0,overrideStyles:!0,scrollTarget:document,focus:!1,focusEnd:!1,clickToEdit:!1,structure:!1,tabindex:!1,minHeight:!1,maxHeight:!1,maxWidth:!1,plugins:!1,callbacks:{},placeholder:!1,linkify:!0,enterKey:!0,pastePlainText:!1,pasteImages:!0,pasteLinks:!0,pasteBlockTags:["pre","h1","h2","h3","h4","h5","h6","table","tbody","thead","tfoot","th","tr","td","ul","ol","li","blockquote","p","figure","figcaption"],pasteInlineTags:["br","strong","ins","code","del","span","samp","kbd","sup","sub","mark","var","cite","small","b","u","em","i"],preClass:!1,preSpaces:4,tabAsSpaces:!1,tabKey:!0,autosave:!1,autosaveName:!1,autosaveFields:!1,imageUpload:null,imageUploadParam:"file",imageUploadFields:!1,imageUploadForms:!1,imageTag:"figure",imageEditable:!0,imageCaption:!0,imagePosition:!1,imageResizable:!1,imageFloatMargin:"10px",dragImageUpload:!0,multipleImageUpload:!0,clipboardImageUpload:!0,fileUpload:null,fileUploadParam:"file",fileUploadFields:!1,fileUploadForms:!1,dragFileUpload:!0,s3:!1,linkNewTab:!1,linkTooltip:!0,linkNofollow:!1,linkSize:30,pasteLinkTarget:!1,videoContainerClass:"video-container",toolbar:!0,toolbarFixed:!0,toolbarFixedTarget:document,toolbarFixedTopOffset:0,toolbarExternal:!1,air:!1,airWidth:!1,formatting:["p","blockquote","pre","h1","h2","h3","h4","h5","h6"],formattingAdd:!1,buttons:["format","bold","italic","deleted","lists","image","file","link"],buttonsHide:[],buttonsHideOnMobile:[],script:!0,removeNewlines:!1,removeComments:!0,replaceTags:{b:"strong",i:"em",strike:"del"},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:!1,activeButtons:["deleted","italic","bold"],activeButtonsStates:{b:"bold",strong:"bold",i:"italic",em:"italic",del:"deleted",strike:"deleted"},langs:{en:{format:"Format",image:"Image",file:"File",link:"Link",bold:"Bold",italic:"Italic",deleted:"Strikethrough",underline:"Underline","bold-abbr":"B","italic-abbr":"I","deleted-abbr":"S","underline-abbr":"U",lists:"Lists","link-insert":"Insert link","link-edit":"Edit link","link-in-new-tab":"Open link in new tab",unlink:"Unlink",cancel:"Cancel",close:"Close",insert:"Insert",save:"Save",delete:"Delete",text:"Text",edit:"Edit",title:"Title",paragraph:"Normal text",quote:"Quote",code:"Code",heading1:"Heading 1",heading2:"Heading 2",heading3:"Heading 3",heading4:"Heading 4",heading5:"Heading 5",heading6:"Heading 6",filename:"Name",optional:"optional",unorderedlist:"Unordered List",orderedlist:"Ordered List",outdent:"Outdent",indent:"Indent",horizontalrule:"Line","upload-label":"Drop file here or ",caption:"Caption",bulletslist:"Bullets",numberslist:"Numbers","image-position":"Position",none:"None",left:"Left",right:"Right",center:"Center","accessibility-help-label":"Rich text editor"}},type:"textarea",inline:!1,buffer:[],rebuffer:[],inlineTags:["a","span","strong","strike","b","u","em","i","code","del","ins","samp","kbd","sup","sub","mark","var","cite","small"],blockTags:["pre","ul","ol","li","p","h1","h2","h3","h4","h5","h6","dl","dt","dd","div","td","blockquote","output","figcaption","figure","address","section","header","footer","aside","article","iframe"],paragraphize:!0,paragraphizeBlocks:["table","div","pre","form","ul","ol","h1","h2","h3","h4","h5","h6","dl","blockquote","figcaption","address","section","header","footer","aside","article","object","style","script","iframe","select","input","textarea","button","option","map","area","math","hr","fieldset","legend","hgroup","nav","figure","details","menu","summary","p"],emptyHtml:"

",invisibleSpace:"​",imageTypes:["image/png","image/jpeg","image/gif"],userAgent:navigator.userAgent.toLowerCase(),observe:{dropdowns:[]},regexps:{linkyoutube:/https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.\-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/gi,linkvimeo:/https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/,linkimage:/((https?|www)[^\s]+\.)(jpe?g|png|gif)(\?[^\s-]+)?/gi,url:/(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/gi}},e.fn=t.Redactor.prototype={keyCode:{BACKSPACE:8,DELETE:46,UP:38,DOWN:40,ENTER:13,SPACE:32,ESC:27,TAB:9,CTRL:17,META:91,SHIFT:16,ALT:18,RIGHT:39,LEFT:37,LEFT_WIN:91},init:function(e,o){return this.$element=t(e),this.uuid=i++,this.loadOptions(o),this.loadModules(),this.opts.clickToEdit&&!this.$element.hasClass("redactor-click-to-edit")?this.loadToEdit(o):(this.$element.hasClass("redactor-click-to-edit")&&this.$element.removeClass("redactor-click-to-edit"),this.reIsBlock=new RegExp("^("+this.opts.blockTags.join("|").toUpperCase()+")$","i"),this.reIsInline=new RegExp("^("+this.opts.inlineTags.join("|").toUpperCase()+")$","i"),this.opts.dragImageUpload=null===this.opts.imageUpload?!1:this.opts.dragImageUpload,this.opts.dragFileUpload=null===this.opts.fileUpload?!1:this.opts.dragFileUpload,this.formatting={},this.lang.load(),t.extend(this.opts.shortcuts,this.opts.shortcutsAdd),this.$editor=this.$element,this.detectType(),this.core.callback("start"),this.core.callback("startToEdit"),this.start=!0,void this.build.start())},detectType:function(){this.build.isInline()||this.opts.inline?this.opts.type="inline":this.build.isTag("DIV")?this.opts.type="div":this.build.isTag("PRE")&&(this.opts.type="pre")},loadToEdit:function(e){this.$element.on("click.redactor-click-to-edit",t.proxy(function(){this.initToEdit(e)},this)),this.$element.addClass("redactor-click-to-edit")},initToEdit:function(e){t.extend(e.callbacks,{startToEdit:function(){this.insert.node(this.marker.get(),!1)},initToEdit:function(){this.selection.restore(),this.clickToCancelStorage=this.code.get(),t(this.opts.clickToCancel).off(".redactor-click-to-edit"),t(this.opts.clickToCancel).show().on("click.redactor-click-to-edit",t.proxy(function(i){i.preventDefault(),this.core.destroy(),this.events.syncFire=!1,this.$element.html(this.clickToCancelStorage),this.core.callback("cancel",this.clickToCancelStorage),this.events.syncFire=!0,this.clickToCancelStorage="",t(this.opts.clickToCancel).hide(),t(this.opts.clickToSave).hide(),this.$element.on("click.redactor-click-to-edit",t.proxy(function(){this.initToEdit(e)},this)),this.$element.addClass("redactor-click-to-edit")},this)),t(this.opts.clickToSave).off(".redactor-click-to-edit"),t(this.opts.clickToSave).show().on("click.redactor-click-to-edit",t.proxy(function(i){i.preventDefault(),this.core.destroy(),this.core.callback("save",this.code.get()),t(this.opts.clickToCancel).hide(),t(this.opts.clickToSave).hide(),this.$element.on("click.redactor-click-to-edit",t.proxy(function(){this.initToEdit(e)},this)),this.$element.addClass("redactor-click-to-edit")},this))}}),this.$element.redactor(e),this.$element.off(".redactor-click-to-edit")},loadOptions:function(e){var i={};"undefined"!=typeof t.Redactor.settings.namespace?this.$element.hasClass(t.Redactor.settings.namespace)&&(i=t.Redactor.settings):i=t.Redactor.settings,this.opts=t.extend({},t.extend(!0,{},t.Redactor.opts),t.extend(!0,{},i),this.$element.data(),e)},getModuleMethods:function(t){return Object.getOwnPropertyNames(t).filter(function(e){return"function"==typeof t[e]})},loadModules:function(){for(var e=t.Redactor.modules.length,i=0;e>i;i++)this.bindModuleMethods(t.Redactor.modules[i])},bindModuleMethods:function(t){if("undefined"!=typeof this[t]){this[t]=this[t]();for(var e=this.getModuleMethods(this[t]),i=e.length,o=0;i>o;o++)this[t][e[o]]=this[t][e[o]].bind(this)}},air:function(){return{enabled:!1,collapsed:function(){this.opts.air&&this.selection.get().collapseToStart()},collapsedEnd:function(){this.opts.air&&this.selection.get().collapseToEnd()},build:function(){this.detect.isMobile()||(this.button.hideButtons(),this.button.hideButtonsOnMobile(),0!==this.opts.buttons.length&&(this.$air=this.air.createContainer(),this.opts.airWidth!==!1&&this.$air.css("width",this.opts.airWidth),this.air.append(),this.button.$toolbar=this.$air,this.button.setFormatting(),this.button.load(this.$air),this.core.editor().on("mouseup.redactor",this,t.proxy(function(t){""!==this.selection.text()&&this.air.show(t)},this))))},append:function(){this.$air.appendTo("body")},createContainer:function(){return t("