').addClass(this.prefix + '-toolbar');\n this.$container.append(this.$toolbar);\n this.$container.addClass('is-' + this.prefix + '-toolbar');\n },\n _buildSticky: function _buildSticky() {\n if (this.opts.toolbar.sticky) {\n this._toggleSticky('add', this.opts.toolbar.stickyTopOffset + 'px');\n\n this._startEvent();\n }\n },\n _buildButtons: function _buildButtons() {\n var count = this._createButtons(this.opts.buttons.editor);\n\n this._checkIntialToolbar(count);\n },\n _buildActiveButtons: function _buildActiveButtons() {\n var obj = this.app.observer.buildActiveButtons(this.customButtons);\n this.aTags = obj.tags;\n this.aTypes = obj.types;\n },\n _checkIntialToolbar: function _checkIntialToolbar(count) {\n if (count === 0 && !this.opts.topbar) {\n var instance = this.app.blocks.getFirst();\n var buttons = instance.toolbar;\n this.$toolbar.html('');\n\n this._createButtons(buttons, instance);\n\n this.disable();\n }\n },\n _findButtons: function _findButtons() {\n return this.$toolbar.find('.' + this.prefix + '-button-toolbar');\n },\n _findButton: function _findButton(name) {\n return this.$toolbar.find('[data-name=' + name + ']');\n },\n _createButtons: function _createButtons(buttons, instance) {\n var items = buttons;\n\n if (instance) {\n items = $R.extend(true, {}, buttons, this.customButtons);\n }\n\n var count = 0;\n\n for (var name in items) {\n if (name === 'add' && !this.opts.addbar) continue;\n if (name === 'html' && !this.opts.source) continue;\n if (name === 'format' && !this.opts.format) continue;\n if (instance && !instance.isAllowedButton(name, items[name])) continue;\n if (this._isHidden(name)) continue;\n this.app.create('button', name, items[name], this.$toolbar, 'toolbar');\n count++;\n }\n\n return count;\n },\n _isHidden: function _isHidden(name) {\n return this.opts.toolbar.hide.indexOf(name) !== -1;\n },\n _setActiveKeys: function _setActiveKeys(keys) {\n for (var i = 0; i < keys.length; i++) {\n this._findButton(keys[i]).addClass(this.activeClass);\n }\n },\n _getObservedTags: function _getObservedTags(tag, inlines) {\n var tags = [];\n\n if (tag) {\n tags.push(tag);\n }\n\n if (inlines.length > 0) {\n for (var i = 0; i < inlines.length; i++) {\n tags.push(inlines[i].tagName.toLowerCase());\n }\n }\n\n return tags;\n },\n _toggleSticky: function _toggleSticky(type, top) {\n var func = type === 'remove' ? 'removeClass' : 'addClass';\n this.$container[func](this.prefix + '-toolbar-sticky');\n this.$container.css('top', top);\n },\n _startEvent: function _startEvent() {\n this.app.scroll.getTarget().on('scroll.' + this.eventname, this._observeSticky.bind(this));\n },\n _stopEvent: function _stopEvent() {\n this.app.scroll.getTarget().off('.' + this.eventname);\n },\n _observeSticky: function _observeSticky() {\n if (this.app.source.is()) {\n this.$container.css('top', 0);\n return;\n }\n\n var $scrollTarget = this.app.scroll.getTarget();\n var paddingTop = this.app.scroll.isTarget() ? parseInt($scrollTarget.css('padding-top')) : 0;\n this.$container.css('top', 0 - paddingTop + this.opts.toolbar.stickyTopOffset + 'px');\n\n if (this.isSticky()) {\n this.app.broadcast('toolbar.sticky');\n } else {\n this.app.broadcast('toolbar.static');\n }\n }\n });\n RedactorX.add('module', 'button', {\n init: function init(name, obj, $container, type) {\n // build\n if (_typeof(name) === 'object') {\n this.name = name.name;\n this.obj = obj;\n\n this._buildFromElement(name.element);\n } else if (name) {\n this.type = type || false;\n this.name = name;\n\n var res = this._observe(obj);\n\n this.obj = typeof res === 'undefined' ? obj : res;\n\n if (this.obj) {\n this._build(name, $container);\n }\n }\n },\n setColor: function setColor(stack, data) {\n var name = stack.getName();\n\n if (name === 'background' || name === 'text-color') {\n var key = name === 'background' ? 'background-color' : 'color';\n this.setBackground(data[key]);\n }\n },\n isButton: function isButton() {\n return true;\n },\n isControl: function isControl() {\n return this._has('control');\n },\n getName: function getName() {\n return this.name;\n },\n getTitle: function getTitle() {\n return this.title;\n },\n getParams: function getParams() {\n return this._has('params') ? this.obj.params : false;\n },\n getOffset: function getOffset() {\n return this.$button.offset();\n },\n getDimension: function getDimension() {\n return {\n width: this.$button.width(),\n height: this.$button.height()\n };\n },\n getElement: function getElement() {\n return this.$button;\n },\n setBackground: function setBackground(color) {\n this._background('add', color);\n },\n resetBackground: function resetBackground() {\n this._background('remove', '');\n },\n // private\n _has: function _has(name) {\n return this.obj.hasOwnProperty(name);\n },\n _observe: function _observe(obj) {\n if (obj.hasOwnProperty('observer')) {\n obj = this.app.api(obj.observer, obj, this.name);\n }\n\n return obj;\n },\n _background: function _background(type, color) {\n var func = type === 'remove' ? 'removeClass' : 'addClass';\n this.$icon[func](this.prefix + '-button-icon-color').css({\n 'background-color': color,\n 'color': color !== '' ? this.app.color.invert(color) : ''\n });\n },\n _buildFromElement: function _buildFromElement(element) {\n this.$button = this.dom(element);\n this.$button.addClass(this.prefix + '-button-target');\n\n this._buildData();\n },\n _build: function _build(name, $container) {\n this._buildTitle();\n\n this._buildElement();\n\n this._buildIcon();\n\n this._buildData($container);\n },\n _buildData: function _buildData($container) {\n // data\n this.$button.attr({\n 'tabindex': '-1',\n 'data-name': this.name,\n 'data-command': this.obj.command || false\n });\n this.$button.dataset('instance', this); // func\n\n var func = this._has('command') ? '_catch' : '_stop'; // events\n\n this.$button.on('click.' + this.prefix + '-button', this[func].bind(this));\n this.$button.on('dragstart.' + this.prefix + '-button', function (e) {\n e.preventDefault();\n return;\n });\n\n if ($container) {\n this._buildTooltip();\n\n this._buildBackground();\n\n this._buildPosition($container);\n }\n },\n _buildTitle: function _buildTitle() {\n this.title = typeof this.obj.title !== 'undefined' ? this.lang.parse(this.obj.title) : '';\n },\n _buildElement: function _buildElement() {\n this.$button = this.dom('
');\n this.$button.addClass(this.prefix + '-button ' + this.prefix + '-button-target');\n\n if (this.type) {\n this.$button.addClass(this.prefix + '-button-' + this.type);\n }\n\n if (this._has('classname')) {\n this.$button.addClass(this.obj.classname);\n }\n },\n _buildIcon: function _buildIcon() {\n var isIcon = this._has('icon');\n\n var span = '
';\n this.$icon = this._buildIconElement();\n\n if (isIcon && this.obj.icon !== true) {\n if (this.obj.icon.search(/) !== -1) {\n span = this.obj.icon;\n } else {\n span = '
';\n }\n }\n\n this.$icon.append(span);\n this.$button.append(this.$icon);\n },\n _buildIconElement: function _buildIconElement() {\n return this.dom('
').addClass(this.prefix + '-button-icon');\n },\n _buildTooltip: function _buildTooltip() {\n if (this.type === 'toolbar') {\n this.app.tooltip.build(this.$button, this.title);\n }\n },\n _buildBackground: function _buildBackground() {\n if (this._has('background')) {\n this.setBackground(this.obj.background);\n }\n },\n _buildPosition: function _buildPosition($container) {\n if (this._has('position')) {\n var pos = this.obj.position;\n\n if (pos === 'first') {\n $container.prepend(this.$button);\n } else if (_typeof(pos) === 'object') {\n var type = pos.hasOwnProperty('after') ? 'after' : 'before';\n var name = pos[type];\n\n var $el = this._findPositionElement(name, $container);\n\n if ($el) {\n $el[type](this.$button);\n } else {\n $container.append(this.$button);\n }\n }\n } else {\n $container.append(this.$button);\n }\n },\n _findPositionElement: function _findPositionElement(name, $container) {\n var $el;\n\n if (Array.isArray(name)) {\n for (var i = 0; i < name.length; i++) {\n $el = $container.find('[data-name=' + name[i] + ']');\n if ($el.length !== 0) break;\n }\n } else {\n $el = $container.find('[data-name=' + name + ']');\n }\n\n return $el.length !== 0 ? $el : 0;\n },\n _stop: function _stop(e) {\n e.preventDefault();\n e.stopPropagation();\n },\n _catch: function _catch(e) {\n e.preventDefault();\n e.stopPropagation();\n var $btn = this.dom(e.target).closest('.' + this.prefix + '-button-target');\n if ($btn.hasClass('disable')) return; // editor focus\n\n this.app.editor.setFocus();\n var command = $btn.attr('data-command');\n var name = $btn.attr('data-name');\n var instance = $btn.dataget('instance'); // command\n\n this.app.api(command, this.getParams(), instance, name, e);\n this.app.tooltip.close();\n }\n });\n RedactorX.add('module', 'tooltip', {\n init: function init() {\n this.classname = this.prefix + '-tooltip';\n this.eventname = this.prefix + '-button-' + this.uuid;\n },\n stop: function stop() {\n this.close();\n },\n build: function build($btn, title) {\n title = this._cleanTitle(title);\n\n if (title) {\n $btn.attr('data-tooltip', title);\n $btn.on('mouseover.' + this.eventname, this.open.bind(this));\n $btn.on('mouseout.' + this.eventname, this.close.bind(this));\n }\n },\n open: function open(e) {\n var $btn = this._getButton(e);\n\n if (this.app.popup.isOpen() || $btn.hasClass('disable')) {\n return;\n } // create\n\n\n this.$tooltip = this._create($btn); // position\n\n this._setPosition($btn);\n\n this._fixBSModal(); // append\n\n\n this.app.$body.append(this.$tooltip);\n },\n close: function close() {\n this.app.$body.find('.' + this.classname).remove();\n },\n // private\n _create: function _create($btn) {\n return this.dom('').addClass(this.classname).html($btn.attr('data-tooltip'));\n },\n _cleanTitle: function _cleanTitle(title) {\n return title ? title.replace(/(<([^>]+)>)/gi, '') : false;\n },\n _setPosition: function _setPosition($btn) {\n var offset = $btn.offset();\n var height = $btn.height();\n this.$tooltip.css({\n top: offset.top + height + 'px',\n left: offset.left + 'px'\n });\n },\n _fixBSModal: function _fixBSModal() {\n if (this.opts.bsmodal) {\n this.$tooltip.css('z-index', 1051);\n }\n },\n _getButton: function _getButton(e) {\n return this.dom(e.target).closest('.' + this.prefix + '-button-target');\n }\n });\n RedactorX.add('module', 'codemirror', {\n init: function init() {\n this.cm = false;\n },\n create: function create(params) {\n if (!this.is()) return;\n var opts = _typeof(this.opts.codemirror) === 'object' ? this.opts.codemirror : {};\n var instance = this.opts.codemirrorSrc ? this.opts.codemirrorSrc : CodeMirror;\n this.cm = instance.fromTextArea(this.dom(params.el).get(), opts);\n if (params.height) this.cm.setSize(null, params.height);\n if (params.focus) this.cm.focus();\n return this.cm;\n },\n destroy: function destroy(html) {\n if (this.cm) {\n this.cm.toTextArea();\n this.cm = false;\n }\n },\n is: function is() {\n return this.opts.codemirror;\n },\n val: function val(html) {\n if (this.is() && this.cm) {\n html = this.cm.getValue();\n }\n\n return html;\n }\n });\n RedactorX.add('module', 'addbar', {\n init: function init() {\n this.custom = {};\n },\n popup: function popup(params, button) {\n if (!this.opts.addbar) return; // create\n\n this.app.popup.create('addbar', {\n width: '380px',\n items: this.buildItems()\n }); // open\n\n var obj = button.isButton || button.isControl ? {\n button: button\n } : {};\n this.app.popup.open(obj);\n },\n add: function add(name, obj) {\n this.custom[name] = obj;\n this.custom[name].container = true;\n this.custom[name].command = obj.command ? obj.command : 'block.add';\n\n if (obj.template) {\n this.custom[name].params = {\n template: obj.template\n };\n }\n },\n buildItems: function buildItems() {\n var items = {};\n var buttons = this.opts.buttons.addbar;\n var obj = this.opts.buttonsObj;\n\n for (var i = 0; i < buttons.length; i++) {\n var index = buttons[i];\n var name = index === 'text' ? 'paragraph' : index;\n if (this._isHidden(name)) continue;\n items[index] = obj[index];\n items[index].container = true;\n items[index].icon = true;\n items[index].params = {\n name: name\n };\n } // extend\n\n\n for (var key in this.opts.addbar.add) {\n if (this._isHidden(key)) continue;\n items[key] = this.opts.addbar.add[key];\n items[key].container = true;\n items[key].command = 'block.add';\n items[key].params = {\n template: this.opts.addbar.add[key].template\n };\n } // extend items\n\n\n items = $R.extend(true, {}, items, this.custom);\n return items;\n },\n // private\n _isHidden: function _isHidden(name) {\n return this.opts.addbar.hide.indexOf(name) !== -1;\n }\n });\n RedactorX.add('module', 'format', {\n popup: function popup(params, button) {\n var instance = this.app.block.get();\n var tag = instance ? instance.getTag() : false;\n var tags = this.opts.format; // build items\n\n var items = {};\n\n for (var i = 0; i < tags.length; i++) {\n var key = tags[i];\n items[key] = {\n title: this.opts.formatObj[key].title,\n params: {\n tag: key\n },\n command: 'block.format',\n shortcut: this.opts.formatObj[key].shortcut,\n active: key === tag\n };\n }\n\n this.app.popup.create('format', {\n width: '300px',\n items: items\n });\n this.app.popup.open({\n button: button\n });\n },\n set: function set(params) {\n this.app.popup.close(); // meta selection\n\n if (this.app.blocks.isMeta()) {\n return;\n }\n\n var format = {\n type: this.opts.formatObj[params.tag].type,\n tag: params.tag\n };\n var blocks = this.app.blocks.getSelectedBlocks('editable');\n var instance = this.app.block.get();\n\n if (instance) {\n this.setSingle(instance, format);\n } else if (blocks.length !== 0) {\n this.setMultiple(blocks, format);\n }\n },\n setSingle: function setSingle(instance, format) {\n var isEmpty = instance.isEmpty();\n var caret = isEmpty ? 'start' : false;\n var $items; // current params\n\n this.tag = instance.getTag();\n this.type = instance.getType();\n this.$block = instance.getBlock(); // selection\n\n if (!isEmpty) {\n this.app.selection.saveMarker();\n } // check same\n\n\n if (this._isSameTag(format)) {\n format = this._checkSameFormat(format);\n } // format\n\n\n if (format) {\n if (this._isListToText(format, 'list')) {\n $items = this._formatListToText(format);\n } else if (this._isTextToList(format, 'list')) {\n this._formatTextToList(format, caret);\n } else {\n this._replaceTo(instance, format, caret);\n }\n } // restore\n\n\n if (!isEmpty) {\n this.app.selection.restoreMarker();\n }\n\n if ($items) {\n var $block = this.app.selection.getDataBlock();\n this.app.block.set($block, caret);\n } // broadcast\n\n\n instance = this.app.block.get();\n this.app.editor.build();\n this.app.broadcast('block.format', {\n instance: instance\n });\n },\n setMultiple: function setMultiple(blocks, format) {\n this.app.selection.saveMarker();\n var instance, $newBlock, tag;\n\n for (var i = 0; i < blocks.length; i++) {\n tag = blocks[i].tagName.toLowerCase();\n\n if (tag !== format.tag) {\n // text to list\n if (['ul', 'ol'].indexOf(tag) === -1 && ['ul', 'ol'].indexOf(format.tag) !== -1) {\n instance = this.app.create('block.' + format.type);\n $newBlock = instance.getBlock();\n var $item = this.dom('').html(blocks[i].innerHTML);\n $newBlock.append($item);\n var $block = this.dom(blocks[i]);\n $block.after($newBlock);\n $block.remove();\n } // list to text\n else if (['ul', 'ol'].indexOf(tag) !== -1 && ['ul', 'ol'].indexOf(format.tag) === -1) {\n var $block = this.dom(blocks[i]);\n var $items = $block.find('li');\n $items.find('ul, ol').each(function ($node) {\n $node.parent().after($node);\n });\n $items.find('ul, ol').unwrap();\n $items.each(function ($node) {\n var $item = this.dom('<' + format.tag + '>');\n $item.html($node.html());\n $node.remove();\n this.app.create('block.' + format.type, $item);\n $block.before($item);\n }.bind(this));\n $block.remove();\n } else {\n $newBlock = this.app.element.replaceToTag(blocks[i], format.tag);\n $newBlock.removeAttr('style class data-' + this.prefix + '-style-cache'); // new instance\n\n instance = this.app.create('block.' + format.type, $newBlock);\n }\n }\n }\n\n this.app.selection.restoreMarker();\n this.app.editor.build();\n this.app.editor.unsetSelectAll();\n this.app.broadcast('block.format', {\n instance: instance\n });\n },\n // private\n _isSameTag: function _isSameTag(format) {\n return this.tag === format.tag && this.type === format.type;\n },\n _checkSameFormat: function _checkSameFormat(format) {\n if (['heading', 'list', 'address'].indexOf(this.type) !== -1) {\n format = this._buildDefaultFormat();\n } else if (this.type === 'paragraph') {\n format = false;\n }\n\n return format;\n },\n _buildDefaultFormat: function _buildDefaultFormat() {\n return {\n type: 'paragraph',\n tag: 'p'\n };\n },\n _formatListToText: function _formatListToText(format) {\n var $items = this._getListItems();\n\n this._createItems($items, format);\n\n this.$block.remove();\n return $items;\n },\n _formatTextToList: function _formatTextToList(format, caret) {\n var newInstance = this.app.create('block.' + format.type, '<' + format.tag + '>');\n var $newBlock = newInstance.getBlock();\n var tag = '';\n var $item = this.dom(tag).html(this.$block.html());\n $newBlock.append($item); // parse instance\n\n this.app.create('block.' + format.type, $newBlock);\n this.$block.after($newBlock);\n this.$block.remove(); // set\n\n this.app.block.set($newBlock, caret);\n },\n _replaceTo: function _replaceTo(instance, format, caret) {\n var $block = instance.getBlock();\n var $newBlock = this.app.element.replaceToTag($block, format.tag); // clean classes & styles\n\n $newBlock.removeAttr('style class data-' + this.prefix + '-style-cache'); // new instance\n\n this.app.create('block.' + format.type, $newBlock); // set\n\n this.app.block.set($newBlock, caret);\n },\n _createItems: function _createItems($items, format) {\n $items.each(function ($node) {\n var $item = this.dom('<' + format.tag + '>');\n $item.html($node.html());\n $node.remove();\n this.app.create('block.' + format.type, $item);\n this.$block.before($item);\n }.bind(this));\n },\n _isListToText: function _isListToText(format, type) {\n return this.type === type && ['heading', 'address', 'paragraph'].indexOf(format.type) !== -1;\n },\n _isTextToList: function _isTextToList(format, type) {\n return format.type === type && ['heading', 'address', 'paragraph', 'list'].indexOf(this.type) !== -1;\n },\n _getListItems: function _getListItems() {\n var $items = this.$block.find('li');\n $items.find('ul, ol').each(function ($node) {\n $node.parent().after($node);\n });\n $items.find('ul, ol').unwrap();\n return $items;\n }\n });\n RedactorX.add('module', 'list', {\n indent: function indent(params, itemInstance) {\n var sel = this.app.selection.get();\n var item = this.app.selection.getBlock();\n var $item = this.dom(item);\n var $prev = $item.prevElement();\n var prev = $prev.get();\n var isIndent = sel.collapsed && item && prev && prev.tagName === 'LI';\n this.app.selection.save(item);\n\n if (isIndent) {\n $prev = this.dom(prev);\n var $prevChild = $prev.children('ul, ol');\n var $list = $item.closest('ul, ol');\n\n if ($prevChild.length !== 0) {\n $prevChild.append($item);\n } else {\n var listTag = $list.get().tagName.toLowerCase();\n var $newList = this.dom('<' + listTag + '>');\n $newList.append($item);\n $prev.append($newList);\n }\n }\n\n this.app.selection.restore();\n return isIndent;\n },\n outdent: function outdent(params, itemInstance) {\n var sel = this.app.selection.get();\n var item = this.app.selection.getBlock();\n var $item = this.dom(item);\n var isOutdent = false;\n\n if (sel.collapsed && item) {\n var $listItem = $item.parent();\n var $liItem = $listItem.closest('li');\n var $prev = $item.prevElement();\n var $next = $item.nextElement();\n var prev = $prev.get();\n var next = $next.get();\n var nextItems, $newList;\n var isTop = prev === false;\n var isMiddle = prev !== false && next !== false;\n this.app.selection.save(item); // out\n\n if ($liItem.length !== 0) {\n if (isMiddle) {\n nextItems = this._getAllNext($item.get());\n $newList = this.dom('<' + $listItem.get().tagName.toLowerCase() + '>');\n\n for (var i = 0; i < nextItems.length; i++) {\n $newList.append(nextItems[i]);\n }\n\n $liItem.after($item);\n $item.append($newList);\n } else {\n $liItem.after($item);\n\n if ($listItem.children().length === 0) {\n $listItem.remove();\n } else {\n if (isTop) $item.append($listItem);\n }\n }\n\n isOutdent = true;\n }\n\n this.app.selection.restore();\n }\n\n return isOutdent;\n },\n // private\n _getAllNext: function _getAllNext(next) {\n var nodes = [];\n\n while (next) {\n var $next = this.dom(next).nextElement();\n next = $next.get();\n if (next) nodes.push(next);else return nodes;\n }\n\n return nodes;\n }\n });\n RedactorX.add('module', 'embed', {\n popups: {\n insert: {\n insert: {\n title: '## buttons.insert ##',\n command: 'embed.insert',\n type: 'primary'\n },\n cancel: {\n title: '## buttons.cancel ##',\n command: 'popup.close'\n }\n },\n save: {\n save: {\n title: '## buttons.save ##',\n command: 'embed.save',\n type: 'primary'\n },\n remove: {\n title: '## buttons.delete ##',\n command: 'embed.remove',\n type: 'danger',\n right: true\n },\n cancel: {\n title: '## buttons.cancel ##',\n command: 'popup.close'\n }\n },\n edit: {\n title: '## embed.embed ##',\n width: '100%',\n form: {\n embed: {\n type: 'textarea',\n label: '## embed.description ##',\n rows: 6\n },\n caption: {\n type: 'input',\n label: '## embed.caption ##'\n },\n responsive: {\n type: 'checkbox',\n text: '## embed.responsive-video ##'\n }\n }\n }\n },\n build: function build(scripts) {\n if (scripts) {\n this._callScripts(scripts);\n } else {\n this._findScripts();\n }\n },\n observe: function observe() {\n if (!this.opts.embed) return false;\n },\n popup: function popup() {\n var popup = this.popups.edit;\n popup.footer = this.popups.insert;\n this.app.popup.create('embed', popup);\n this.app.popup.open({\n focus: 'embed'\n }); // codemirror\n\n this._buildCodemirror();\n },\n edit: function edit(params) {\n var instance = this.app.block.get();\n var popup = this.popups.edit;\n popup.footer = this.popups.save;\n var data = {\n embed: instance.getEmbedCode(),\n caption: instance.getCaption(),\n responsive: instance.isResponsive()\n }; // popup & data\n\n this.app.popup.create('embed', popup);\n this.app.popup.setData(data); // open\n\n this.app.popup.open({\n focus: 'embed'\n }); // codemirror\n\n this._buildCodemirror();\n },\n insert: function insert() {\n this.app.popup.close(); // data\n\n var data = this.app.popup.getData();\n\n var code = this._getEmbedCode(data);\n\n if (code === '') {\n return;\n } // create\n\n\n var instance = this._createInstance(data, code);\n\n this.app.block.add({\n instance: instance\n });\n },\n save: function save() {\n this.app.popup.close(); // data\n\n var current = this.app.block.get();\n var data = this.app.popup.getData();\n\n var code = this._getEmbedCode(data);\n\n if (code === '') {\n this.app.block.remove();\n return;\n } // create\n\n\n var instance = this._createInstance(data, code, current); // change\n\n\n if (this._isNeedToChange(data, instance, current)) {\n this.app.block.change(instance);\n }\n },\n remove: function remove() {\n this.app.popup.close();\n this.app.block.remove();\n },\n // private\n _buildCodemirror: function _buildCodemirror() {\n var $input = this.app.popup.getInput('embed');\n this.app.codemirror.create({\n el: $input,\n height: '200px',\n focus: true\n });\n this.app.popup.updatePosition();\n },\n _findScripts: function _findScripts() {\n var scripts = this.app.editor.getEditor().find('[data-' + this.prefix + '-type=embed]').find('script').getAll();\n this.build.call(this, scripts);\n },\n _callScripts: function _callScripts(scripts) {\n for (var i = 0; i < scripts.length; i++) {\n if (scripts[i].src !== '') {\n var src = scripts[i].src;\n this.app.$doc.find('head script[src=\"' + src + '\"]').remove();\n var $script = this.dom('