diff --git a/config/admin.php b/config/admin.php index 315fc53..2bd18c6 100644 --- a/config/admin.php +++ b/config/admin.php @@ -73,6 +73,8 @@ 'image' => 'images', 'file' => 'files', ], + //文件上传类型 + 'mimes'=>'jpeg,bmp,png,gif,jpg', ], 'database' => [ // Database connection for following tables. diff --git a/public/10.js b/public/10.js index eec3c83..db98d6e 100644 --- a/public/10.js +++ b/public/10.js @@ -1,4687 +1 @@ -(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[10],{ - -/***/ "./node_modules/wangeditor/release/wangEditor.js": -/*!*******************************************************!*\ - !*** ./node_modules/wangeditor/release/wangEditor.js ***! - \*******************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -(function (global, factory) { - true ? module.exports = factory() : - undefined; -}(this, (function () { 'use strict'; - -/* - poly-fill -*/ - -var polyfill = function () { - - // Object.assign - if (typeof Object.assign != 'function') { - Object.assign = function (target, varArgs) { - // .length of function is 2 - if (target == null) { - // TypeError if undefined or null - throw new TypeError('Cannot convert undefined or null to object'); - } - - var to = Object(target); - - for (var index = 1; index < arguments.length; index++) { - var nextSource = arguments[index]; - - if (nextSource != null) { - // Skip over if undefined or null - for (var nextKey in nextSource) { - // Avoid bugs when hasOwnProperty is shadowed - if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { - to[nextKey] = nextSource[nextKey]; - } - } - } - } - return to; - }; - } - - // IE 中兼容 Element.prototype.matches - if (!Element.prototype.matches) { - Element.prototype.matches = Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector || function (s) { - var matches = (this.document || this.ownerDocument).querySelectorAll(s), - i = matches.length; - while (--i >= 0 && matches.item(i) !== this) {} - return i > -1; - }; - } -}; - -/* - DOM 操作 API -*/ - -// 根据 html 代码片段创建 dom 对象 -function createElemByHTML(html) { - var div = void 0; - div = document.createElement('div'); - div.innerHTML = html; - return div.children; -} - -// 是否是 DOM List -function isDOMList(selector) { - if (!selector) { - return false; - } - if (selector instanceof HTMLCollection || selector instanceof NodeList) { - return true; - } - return false; -} - -// 封装 document.querySelectorAll -function querySelectorAll(selector) { - var result = document.querySelectorAll(selector); - if (isDOMList(result)) { - return result; - } else { - return [result]; - } -} - -// 记录所有的事件绑定 -var eventList = []; - -// 创建构造函数 -function DomElement(selector) { - if (!selector) { - return; - } - - // selector 本来就是 DomElement 对象,直接返回 - if (selector instanceof DomElement) { - return selector; - } - - this.selector = selector; - var nodeType = selector.nodeType; - - // 根据 selector 得出的结果(如 DOM,DOM List) - var selectorResult = []; - if (nodeType === 9) { - // document 节点 - selectorResult = [selector]; - } else if (nodeType === 1) { - // 单个 DOM 节点 - selectorResult = [selector]; - } else if (isDOMList(selector) || selector instanceof Array) { - // DOM List 或者数组 - selectorResult = selector; - } else if (typeof selector === 'string') { - // 字符串 - selector = selector.replace('/\n/mg', '').trim(); - if (selector.indexOf('<') === 0) { - // 如
设置标题
'), - type: 'list', // droplist 以列表形式展示 - list: [{ $elem: $('正文
'), value: '' }], - onClick: function onClick(value) { - // 注意 this 是指向当前的 Head 对象 - _this._command(value); - } - }); -} - -// 原型 -Head.prototype = { - constructor: Head, - - // 执行命令 - _command: function _command(value) { - var editor = this.editor; - - var $selectionElem = editor.selection.getSelectionContainerElem(); - if (editor.$textElem.equal($selectionElem)) { - // 不能选中多行来设置标题,否则会出现问题 - // 例如选中的是
xxx
yyy
来设置标题,设置之后会成为字号
'), - type: 'list', // droplist 以列表形式展示 - list: [{ $elem: $('x-small'), value: '1' }, { $elem: $('small'), value: '2' }, { $elem: $('normal'), value: '3' }, { $elem: $('large'), value: '4' }, { $elem: $('x-large'), value: '5' }, { $elem: $('xx-large'), value: '6' }], - onClick: function onClick(value) { - // 注意 this 是指向当前的 FontSize 对象 - _this._command(value); - } - }); -} - -// 原型 -FontSize.prototype = { - constructor: FontSize, - - // 执行命令 - _command: function _command(value) { - var editor = this.editor; - editor.cmd.do('fontSize', value); - } -}; - -/* - menu - fontName -*/ - -// 构造函数 -function FontName(editor) { - var _this = this; - - this.editor = editor; - this.$elem = $(' '); - this.type = 'droplist'; - - // 当前是否 active 状态 - this._active = false; - - // 获取配置的字体 - var config = editor.config; - var fontNames = config.fontNames || []; - - // 初始化 droplist - this.droplist = new DropList(this, { - width: 100, - $title: $('字体
'), - type: 'list', // droplist 以列表形式展示 - list: fontNames.map(function (fontName) { - return { $elem: $('' + fontName + ''), value: fontName }; - }), - onClick: function onClick(value) { - // 注意 this 是指向当前的 FontName 对象 - _this._command(value); - } - }); -} - -// 原型 -FontName.prototype = { - constructor: FontName, - - _command: function _command(value) { - var editor = this.editor; - editor.cmd.do('fontName', value); - } -}; - -/* - panel -*/ - -var emptyFn = function emptyFn() {}; - -// 记录已经显示 panel 的菜单 -var _isCreatedPanelMenus = []; - -// 构造函数 -function Panel(menu, opt) { - this.menu = menu; - this.opt = opt; -} - -// 原型 -Panel.prototype = { - constructor: Panel, - - // 显示(插入DOM) - show: function show() { - var _this = this; - - var menu = this.menu; - if (_isCreatedPanelMenus.indexOf(menu) >= 0) { - // 该菜单已经创建了 panel 不能再创建 - return; - } - - var editor = menu.editor; - var $body = $('body'); - var $textContainerElem = editor.$textContainerElem; - var opt = this.opt; - - // panel 的容器 - var $container = $(''); - var width = opt.width || 300; // 默认 300px - $container.css('width', width + 'px').css('margin-left', (0 - width) / 2 + 'px'); - - // 添加关闭按钮 - var $closeBtn = $(''); - $container.append($closeBtn); - $closeBtn.on('click', function () { - _this.hide(); - }); - - // 准备 tabs 容器 - var $tabTitleContainer = $('设置列表
'), - type: 'list', // droplist 以列表形式展示 - list: [{ $elem: $(' 有序列表'), value: 'insertOrderedList' }, { $elem: $(' 无序列表'), value: 'insertUnorderedList' }], - onClick: function onClick(value) { - // 注意 this 是指向当前的 List 对象 - _this._command(value); - } - }); -} - -// 原型 -List.prototype = { - constructor: List, - - // 执行命令 - _command: function _command(value) { - var editor = this.editor; - var $textElem = editor.$textElem; - editor.selection.restoreSelection(); - if (editor.cmd.queryCommandState(value)) { - return; - } - editor.cmd.do(value); - - // 验证列表是否被包裹在之内 - var $selectionElem = editor.selection.getSelectionContainerElem(); - if ($selectionElem.getNodeName() === 'LI') { - $selectionElem = $selectionElem.parent(); - } - if (/^ol|ul$/i.test($selectionElem.getNodeName()) === false) { - return; - } - if ($selectionElem.equal($textElem)) { - // 证明是顶级标签,没有被
包裹 - return; - } - var $parent = $selectionElem.parent(); - if ($parent.equal($textElem)) { - // $parent 是顶级标签,不能删除 - return; - } - - $selectionElem.insertAfter($parent); - $parent.remove(); - }, - - // 试图改变 active 状态 - tryChangeActive: function tryChangeActive(e) { - var editor = this.editor; - var $elem = this.$elem; - if (editor.cmd.queryCommandState('insertUnOrderedList') || editor.cmd.queryCommandState('insertOrderedList')) { - this._active = true; - $elem.addClass('w-e-active'); - } else { - this._active = false; - $elem.removeClass('w-e-active'); - } - } -}; - -/* - menu - justify -*/ -// 构造函数 -function Justify(editor) { - var _this = this; - - this.editor = editor; - this.$elem = $('
'); - this.type = 'droplist'; - - // 当前是否 active 状态 - this._active = false; - - // 初始化 droplist - this.droplist = new DropList(this, { - width: 100, - $title: $('对齐方式
'), - type: 'list', // droplist 以列表形式展示 - list: [{ $elem: $(' 靠左'), value: 'justifyLeft' }, { $elem: $(' 居中'), value: 'justifyCenter' }, { $elem: $(' 靠右'), value: 'justifyRight' }], - onClick: function onClick(value) { - // 注意 this 是指向当前的 List 对象 - _this._command(value); - } - }); -} - -// 原型 -Justify.prototype = { - constructor: Justify, - - // 执行命令 - _command: function _command(value) { - var editor = this.editor; - editor.cmd.do(value); - } -}; - -/* - menu - Forecolor -*/ -// 构造函数 -function ForeColor(editor) { - var _this = this; - - this.editor = editor; - this.$elem = $(' '); - this.type = 'droplist'; - - // 获取配置的颜色 - var config = editor.config; - var colors = config.colors || []; - - // 当前是否 active 状态 - this._active = false; - - // 初始化 droplist - this.droplist = new DropList(this, { - width: 120, - $title: $('文字颜色
'), - type: 'inline-block', // droplist 内容以 block 形式展示 - list: colors.map(function (color) { - return { $elem: $(''), value: color }; - }), - onClick: function onClick(value) { - // 注意 this 是指向当前的 ForeColor 对象 - _this._command(value); - } - }); -} - -// 原型 -ForeColor.prototype = { - constructor: ForeColor, - - // 执行命令 - _command: function _command(value) { - var editor = this.editor; - editor.cmd.do('foreColor', value); - } -}; - -/* - menu - BackColor -*/ -// 构造函数 -function BackColor(editor) { - var _this = this; - - this.editor = editor; - this.$elem = $(' '); - this.type = 'droplist'; - - // 获取配置的颜色 - var config = editor.config; - var colors = config.colors || []; - - // 当前是否 active 状态 - this._active = false; - - // 初始化 droplist - this.droplist = new DropList(this, { - width: 120, - $title: $('背景色
'), - type: 'inline-block', // droplist 内容以 block 形式展示 - list: colors.map(function (color) { - return { $elem: $(''), value: color }; - }), - onClick: function onClick(value) { - // 注意 this 是指向当前的 BackColor 对象 - _this._command(value); - } - }); -} - -// 原型 -BackColor.prototype = { - constructor: BackColor, - - // 执行命令 - _command: function _command(value) { - var editor = this.editor; - editor.cmd.do('backColor', value); - } -}; - -/* - menu - quote -*/ -// 构造函数 -function Quote(editor) { - this.editor = editor; - this.$elem = $(' '); - this.type = 'click'; - - // 当前是否 active 状态 - this._active = false; -} - -// 原型 -Quote.prototype = { - constructor: Quote, - - onClick: function onClick(e) { - var editor = this.editor; - var $selectionElem = editor.selection.getSelectionContainerElem(); - var nodeName = $selectionElem.getNodeName(); - - if (!UA.isIE()) { - if (nodeName === 'BLOCKQUOTE') { - // 撤销 quote - editor.cmd.do('formatBlock', ''); - } else { - // 转换为 quote - editor.cmd.do('formatBlock', '
'); - } - return; - } - - // IE 中不支持 formatBlock,要用其他方式兼容 - var content = void 0, - $targetELem = void 0; - if (nodeName === 'P') { - // 将 P 转换为 quote - content = $selectionElem.text(); - $targetELem = $('' + content + ''); - $targetELem.insertAfter($selectionElem); - $selectionElem.remove(); - return; - } - if (nodeName === 'BLOCKQUOTE') { - // 撤销 quote - content = $selectionElem.text(); - $targetELem = $('' + content + '
'); - $targetELem.insertAfter($selectionElem); - $selectionElem.remove(); - } - }, - - tryChangeActive: function tryChangeActive(e) { - var editor = this.editor; - var $elem = this.$elem; - var reg = /^BLOCKQUOTE$/i; - var cmdValue = editor.cmd.queryCommandValue('formatBlock'); - if (reg.test(cmdValue)) { - this._active = true; - $elem.addClass('w-e-active'); - } else { - this._active = false; - $elem.removeClass('w-e-active'); - } - } -}; - -/* - menu - code -*/ -// 构造函数 -function Code(editor) { - this.editor = editor; - this.$elem = $(' '); - this.type = 'panel'; - - // 当前是否 active 状态 - this._active = false; -} - -// 原型 -Code.prototype = { - constructor: Code, - - onClick: function onClick(e) { - var editor = this.editor; - var $startElem = editor.selection.getSelectionStartElem(); - var $endElem = editor.selection.getSelectionEndElem(); - var isSeleEmpty = editor.selection.isSelectionEmpty(); - var selectionText = editor.selection.getSelectionText(); - var $code = void 0; - - if (!$startElem.equal($endElem)) { - // 跨元素选择,不做处理 - editor.selection.restoreSelection(); - return; - } - if (!isSeleEmpty) { - // 选取不是空,用包裹即可 - $code = $('
' + selectionText + '
'); - editor.cmd.do('insertElem', $code); - editor.selection.createRangeByElem($code, false); - editor.selection.restoreSelection(); - return; - } - - // 选取是空,且没有夸元素选择,则插入- if (this._active) { - // 选中状态,将编辑内容 - this._createPanel($startElem.html()); - } else { - // 未选中状态,将创建内容 - this._createPanel(); - } - }, - - _createPanel: function _createPanel(value) { - var _this = this; - - // value - 要编辑的内容 - value = value || ''; - var type = !value ? 'new' : 'edit'; - var textId = getRandom('texxt'); - var btnId = getRandom('btn'); - - var panel = new Panel(this, { - width: 500, - // 一个 Panel 包含多个 tab - tabs: [{ - // 标题 - title: '插入代码', - // 模板 - tpl: '
\n \n\n', - // 事件绑定 - events: [ - // 插入代码 - { - selector: '#' + btnId, - type: 'click', - fn: function fn() { - var $text = $('#' + textId); - var text = $text.val() || $text.html(); - text = replaceHtmlSymbol(text); - if (type === 'new') { - // 新插入 - _this._insertCode(text); - } else { - // 编辑更新 - _this._updateCode(text); - } - - // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 - return true; - } - }] - } // first tab end - ] // tabs end - }); // new Panel end - - // 显示 panel - panel.show(); - - // 记录属性 - this.panel = panel; - }, - - // 插入代码 - _insertCode: function _insertCode(value) { - var editor = this.editor; - editor.cmd.do('insertHTML', '' + value + '
'); - }, - - // 更新代码 - _updateCode: function _updateCode(value) { - var editor = this.editor; - var $selectionELem = editor.selection.getSelectionContainerElem(); - if (!$selectionELem) { - return; - } - $selectionELem.html(value); - editor.selection.restoreSelection(); - }, - - // 试图改变 active 状态 - tryChangeActive: function tryChangeActive(e) { - var editor = this.editor; - var $elem = this.$elem; - var $selectionELem = editor.selection.getSelectionContainerElem(); - if (!$selectionELem) { - return; - } - var $parentElem = $selectionELem.parent(); - if ($selectionELem.getNodeName() === 'CODE' && $parentElem.getNodeName() === 'PRE') { - this._active = true; - $elem.addClass('w-e-active'); - } else { - this._active = false; - $elem.removeClass('w-e-active'); - } - } -}; - -/* - menu - emoticon -*/ -// 构造函数 -function Emoticon(editor) { - this.editor = editor; - this.$elem = $(' '); - this.type = 'panel'; - - // 当前是否 active 状态 - this._active = false; -} - -// 原型 -Emoticon.prototype = { - constructor: Emoticon, - - onClick: function onClick() { - this._createPanel(); - }, - - _createPanel: function _createPanel() { - var _this = this; - - var editor = this.editor; - var config = editor.config; - // 获取表情配置 - var emotions = config.emotions || []; - - // 创建表情 dropPanel 的配置 - var tabConfig = []; - emotions.forEach(function (emotData) { - var emotType = emotData.type; - var content = emotData.content || []; - - // 这一组表情最终拼接出来的 html - var faceHtml = ''; - - // emoji 表情 - if (emotType === 'emoji') { - content.forEach(function (item) { - if (item) { - faceHtml += '' + item + ''; - } - }); - } - // 图片表情 - if (emotType === 'image') { - content.forEach(function (item) { - var src = item.src; - var alt = item.alt; - if (src) { - // 加一个 data-w-e 属性,点击图片的时候不再提示编辑图片 - faceHtml += ''; - } - }); - } - - tabConfig.push({ - title: emotData.title, - tpl: '
' + faceHtml + '', - events: [{ - selector: 'span.w-e-item', - type: 'click', - fn: function fn(e) { - var target = e.target; - var $target = $(target); - var nodeName = $target.getNodeName(); - - var insertHtml = void 0; - if (nodeName === 'IMG') { - // 插入图片 - insertHtml = $target.parent().html(); - } else { - // 插入 emoji - insertHtml = '' + $target.html() + ''; - } - - _this._insert(insertHtml); - // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 - return true; - } - }] - }); - }); - - var panel = new Panel(this, { - width: 300, - height: 200, - // 一个 Panel 包含多个 tab - tabs: tabConfig - }); - - // 显示 panel - panel.show(); - - // 记录属性 - this.panel = panel; - }, - - // 插入表情 - _insert: function _insert(emotHtml) { - var editor = this.editor; - editor.cmd.do('insertHTML', emotHtml); - } -}; - -/* - menu - table -*/ -// 构造函数 -function Table(editor) { - this.editor = editor; - this.$elem = $(' '); - this.type = 'panel'; - - // 当前是否 active 状态 - this._active = false; -} - -// 原型 -Table.prototype = { - constructor: Table, - - onClick: function onClick() { - if (this._active) { - // 编辑现有表格 - this._createEditPanel(); - } else { - // 插入新表格 - this._createInsertPanel(); - } - }, - - // 创建插入新表格的 panel - _createInsertPanel: function _createInsertPanel() { - var _this = this; - - // 用到的 id - var btnInsertId = getRandom('btn'); - var textRowNum = getRandom('row'); - var textColNum = getRandom('col'); - - var panel = new Panel(this, { - width: 250, - // panel 包含多个 tab - tabs: [{ - // 标题 - title: '插入表格', - // 模板 - tpl: '\n', - // 事件绑定 - events: [{ - // 点击按钮,插入表格 - selector: '#' + btnInsertId, - type: 'click', - fn: function fn() { - var rowNum = parseInt($('#' + textRowNum).val()); - var colNum = parseInt($('#' + textColNum).val()); - - if (rowNum && colNum && rowNum > 0 && colNum > 0) { - // form 数据有效 - _this._insert(rowNum, colNum); - } - - // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 - return true; - } - }] - } // first tab end - ] // tabs end - }); // panel end - - // 展示 panel - panel.show(); - - // 记录属性 - this.panel = panel; - }, - - // 插入表格 - _insert: function _insert(rowNum, colNum) { - // 拼接 table 模板 - var r = void 0, - c = void 0; - var html = '\n \u521B\u5EFA\n \n \u884C\n \n \u5217\u7684\u8868\u683C\n
\n \n'; - for (r = 0; r < rowNum; r++) { - html += '
'; - if (r === 0) { - for (c = 0; c < colNum; c++) { - html += ' '; - } - html += ''; - } - } else { - for (c = 0; c < colNum; c++) { - html += ' '; - } - } - html += ' '; - - // 执行命令 - var editor = this.editor; - editor.cmd.do('insertHTML', html); - - // 防止 firefox 下出现 resize 的控制点 - editor.cmd.do('enableObjectResizing', false); - editor.cmd.do('enableInlineTableEditing', false); - }, - - // 创建编辑表格的 panel - _createEditPanel: function _createEditPanel() { - var _this2 = this; - - // 可用的 id - var addRowBtnId = getRandom('add-row'); - var addColBtnId = getRandom('add-col'); - var delRowBtnId = getRandom('del-row'); - var delColBtnId = getRandom('del-col'); - var delTableBtnId = getRandom('del-table'); - - // 创建 panel 对象 - var panel = new Panel(this, { - width: 320, - // panel 包含多个 tab - tabs: [{ - // 标题 - title: '编辑表格', - // 模板 - tpl: '
\n\n ', - // 事件绑定 - events: [{ - // 增加行 - selector: '#' + addRowBtnId, - type: 'click', - fn: function fn() { - _this2._addRow(); - // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 - return true; - } - }, { - // 增加列 - selector: '#' + addColBtnId, - type: 'click', - fn: function fn() { - _this2._addCol(); - // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 - return true; - } - }, { - // 删除行 - selector: '#' + delRowBtnId, - type: 'click', - fn: function fn() { - _this2._delRow(); - // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 - return true; - } - }, { - // 删除列 - selector: '#' + delColBtnId, - type: 'click', - fn: function fn() { - _this2._delCol(); - // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 - return true; - } - }, { - // 删除表格 - selector: '#' + delTableBtnId, - type: 'click', - fn: function fn() { - _this2._delTable(); - // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 - return true; - } - }] - }] - }); - // 显示 panel - panel.show(); - }, - - // 获取选中的单元格的位置信息 - _getLocationData: function _getLocationData() { - var result = {}; - var editor = this.editor; - var $selectionELem = editor.selection.getSelectionContainerElem(); - if (!$selectionELem) { - return; - } - var nodeName = $selectionELem.getNodeName(); - if (nodeName !== 'TD' && nodeName !== 'TH') { - return; - } - - // 获取 td index - var $tr = $selectionELem.parent(); - var $tds = $tr.children(); - var tdLength = $tds.length; - $tds.forEach(function (td, index) { - if (td === $selectionELem[0]) { - // 记录并跳出循环 - result.td = { - index: index, - elem: td, - length: tdLength - }; - return false; - } - }); - - // 获取 tr index - var $tbody = $tr.parent(); - var $trs = $tbody.children(); - var trLength = $trs.length; - $trs.forEach(function (tr, index) { - if (tr === $tr[0]) { - // 记录并跳出循环 - result.tr = { - index: index, - elem: tr, - length: trLength - }; - return false; - } - }); - - // 返回结果 - return result; - }, - - // 增加行 - _addRow: function _addRow() { - // 获取当前单元格的位置信息 - var locationData = this._getLocationData(); - if (!locationData) { - return; - } - var trData = locationData.tr; - var $currentTr = $(trData.elem); - var tdData = locationData.td; - var tdLength = tdData.length; - - // 拼接即将插入的字符串 - var newTr = document.createElement('tr'); - var tpl = '', - i = void 0; - for (i = 0; i < tdLength; i++) { - tpl += ''; - } - newTr.innerHTML = tpl; - // 插入 - $(newTr).insertAfter($currentTr); - }, - - // 增加列 - _addCol: function _addCol() { - // 获取当前单元格的位置信息 - var locationData = this._getLocationData(); - if (!locationData) { - return; - } - var trData = locationData.tr; - var tdData = locationData.td; - var tdIndex = tdData.index; - var $currentTr = $(trData.elem); - var $trParent = $currentTr.parent(); - var $trs = $trParent.children(); - - // 遍历所有行 - $trs.forEach(function (tr) { - var $tr = $(tr); - var $tds = $tr.children(); - var $currentTd = $tds.get(tdIndex); - var name = $currentTd.getNodeName().toLowerCase(); - - // new 一个 td,并插入 - var newTd = document.createElement(name); - $(newTd).insertAfter($currentTd); - }); - }, - - // 删除行 - _delRow: function _delRow() { - // 获取当前单元格的位置信息 - var locationData = this._getLocationData(); - if (!locationData) { - return; - } - var trData = locationData.tr; - var $currentTr = $(trData.elem); - $currentTr.remove(); - }, - - // 删除列 - _delCol: function _delCol() { - // 获取当前单元格的位置信息 - var locationData = this._getLocationData(); - if (!locationData) { - return; - } - var trData = locationData.tr; - var tdData = locationData.td; - var tdIndex = tdData.index; - var $currentTr = $(trData.elem); - var $trParent = $currentTr.parent(); - var $trs = $trParent.children(); - - // 遍历所有行 - $trs.forEach(function (tr) { - var $tr = $(tr); - var $tds = $tr.children(); - var $currentTd = $tds.get(tdIndex); - // 删除 - $currentTd.remove(); - }); - }, - - // 删除表格 - _delTable: function _delTable() { - var editor = this.editor; - var $selectionELem = editor.selection.getSelectionContainerElem(); - if (!$selectionELem) { - return; - } - var $table = $selectionELem.parentUntil('table'); - if (!$table) { - return; - } - $table.remove(); - }, - - // 试图改变 active 状态 - tryChangeActive: function tryChangeActive(e) { - var editor = this.editor; - var $elem = this.$elem; - var $selectionELem = editor.selection.getSelectionContainerElem(); - if (!$selectionELem) { - return; - } - var nodeName = $selectionELem.getNodeName(); - if (nodeName === 'TD' || nodeName === 'TH') { - this._active = true; - $elem.addClass('w-e-active'); - } else { - this._active = false; - $elem.removeClass('w-e-active'); - } - } -}; - -/* - menu - video -*/ -// 构造函数 -function Video(editor) { - this.editor = editor; - this.$elem = $(' '); - this.type = 'panel'; - - // 当前是否 active 状态 - this._active = false; -} - -// 原型 -Video.prototype = { - constructor: Video, - - onClick: function onClick() { - this._createPanel(); - }, - - _createPanel: function _createPanel() { - var _this = this; - - // 创建 id - var textValId = getRandom('text-val'); - var btnId = getRandom('btn'); - - // 创建 panel - var panel = new Panel(this, { - width: 350, - // 一个 panel 多个 tab - tabs: [{ - // 标题 - title: '插入视频', - // 模板 - tpl: ' \n \n', - // 事件绑定 - events: [{ - selector: '#' + btnId, - type: 'click', - fn: function fn() { - var $text = $('#' + textValId); - var val = $text.val().trim(); - - // 测试用视频地址 - // - - if (val) { - // 插入视频 - _this._insert(val); - } - - // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 - return true; - } - }] - } // first tab end - ] // tabs end - }); // panel end - - // 显示 panel - panel.show(); - - // 记录属性 - this.panel = panel; - }, - - // 插入视频 - _insert: function _insert(val) { - var editor = this.editor; - editor.cmd.do('insertHTML', val + ' \n'); - } -}; - -/* - menu - img -*/ -// 构造函数 -function Image(editor) { - this.editor = editor; - var imgMenuId = getRandom('w-e-img'); - this.$elem = $(' '); - editor.imgMenuId = imgMenuId; - this.type = 'panel'; - - // 当前是否 active 状态 - this._active = false; -} - -// 原型 -Image.prototype = { - constructor: Image, - - onClick: function onClick() { - var editor = this.editor; - var config = editor.config; - if (config.qiniu) { - return; - } - if (this._active) { - this._createEditPanel(); - } else { - this._createInsertPanel(); - } - }, - - _createEditPanel: function _createEditPanel() { - var editor = this.editor; - - // id - var width30 = getRandom('width-30'); - var width50 = getRandom('width-50'); - var width100 = getRandom('width-100'); - var delBtn = getRandom('del-btn'); - - // tab 配置 - var tabsConfig = [{ - title: '编辑图片', - tpl: '
\n\n ', - events: [{ - selector: '#' + width30, - type: 'click', - fn: function fn() { - var $img = editor._selectedImg; - if ($img) { - $img.css('max-width', '30%'); - } - // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 - return true; - } - }, { - selector: '#' + width50, - type: 'click', - fn: function fn() { - var $img = editor._selectedImg; - if ($img) { - $img.css('max-width', '50%'); - } - // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 - return true; - } - }, { - selector: '#' + width100, - type: 'click', - fn: function fn() { - var $img = editor._selectedImg; - if ($img) { - $img.css('max-width', '100%'); - } - // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 - return true; - } - }, { - selector: '#' + delBtn, - type: 'click', - fn: function fn() { - var $img = editor._selectedImg; - if ($img) { - $img.remove(); - } - // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭 - return true; - } - }] - }]; - - // 创建 panel 并显示 - var panel = new Panel(this, { - width: 300, - tabs: tabsConfig - }); - panel.show(); - - // 记录属性 - this.panel = panel; - }, - - _createInsertPanel: function _createInsertPanel() { - var editor = this.editor; - var uploadImg = editor.uploadImg; - var config = editor.config; - - // id - var upTriggerId = getRandom('up-trigger'); - var upFileId = getRandom('up-file'); - var linkUrlId = getRandom('link-url'); - var linkBtnId = getRandom('link-btn'); - - // tabs 的配置 - var tabsConfig = [{ - title: '上传图片', - tpl: '\n', - events: [{ - // 触发选择图片 - selector: '#' + upTriggerId, - type: 'click', - fn: function fn() { - var $file = $('#' + upFileId); - var fileElem = $file[0]; - if (fileElem) { - fileElem.click(); - } else { - // 返回 true 可关闭 panel - return true; - } - } - }, { - // 选择图片完毕 - selector: '#' + upFileId, - type: 'change', - fn: function fn() { - var $file = $('#' + upFileId); - var fileElem = $file[0]; - if (!fileElem) { - // 返回 true 可关闭 panel - return true; - } - - // 获取选中的 file 对象列表 - var fileList = fileElem.files; - if (fileList.length) { - uploadImg.uploadImg(fileList); - } - - // 返回 true 可关闭 panel - return true; - } - }] - }, // first tab end - { - title: '网络图片', - tpl: '\n \n\n \n\n \n', - events: [{ - selector: '#' + linkBtnId, - type: 'click', - fn: function fn() { - var $linkUrl = $('#' + linkUrlId); - var url = $linkUrl.val().trim(); - - if (url) { - uploadImg.insertLinkImg(url); - } - - // 返回 true 表示函数执行结束之后关闭 panel - return true; - } - }] - } // second tab end - ]; // tabs end - - // 判断 tabs 的显示 - var tabsConfigResult = []; - if ((config.uploadImgShowBase64 || config.uploadImgServer || config.customUploadImg) && window.FileReader) { - // 显示“上传图片” - tabsConfigResult.push(tabsConfig[0]); - } - if (config.showLinkImg) { - // 显示“网络图片” - tabsConfigResult.push(tabsConfig[1]); - } - - // 创建 panel 并显示 - var panel = new Panel(this, { - width: 300, - tabs: tabsConfigResult - }); - panel.show(); - - // 记录属性 - this.panel = panel; - }, - - // 试图改变 active 状态 - tryChangeActive: function tryChangeActive(e) { - var editor = this.editor; - var $elem = this.$elem; - if (editor._selectedImg) { - this._active = true; - $elem.addClass('w-e-active'); - } else { - this._active = false; - $elem.removeClass('w-e-active'); - } - } -}; - -/* - 所有菜单的汇总 -*/ - -// 存储菜单的构造函数 -var MenuConstructors = {}; - -MenuConstructors.bold = Bold; - -MenuConstructors.head = Head; - -MenuConstructors.fontSize = FontSize; - -MenuConstructors.fontName = FontName; - -MenuConstructors.link = Link; - -MenuConstructors.italic = Italic; - -MenuConstructors.redo = Redo; - -MenuConstructors.strikeThrough = StrikeThrough; - -MenuConstructors.underline = Underline; - -MenuConstructors.undo = Undo; - -MenuConstructors.list = List; - -MenuConstructors.justify = Justify; - -MenuConstructors.foreColor = ForeColor; - -MenuConstructors.backColor = BackColor; - -MenuConstructors.quote = Quote; - -MenuConstructors.code = Code; - -MenuConstructors.emoticon = Emoticon; - -MenuConstructors.table = Table; - -MenuConstructors.video = Video; - -MenuConstructors.image = Image; - -/* - 菜单集合 -*/ -// 构造函数 -function Menus(editor) { - this.editor = editor; - this.menus = {}; -} - -// 修改原型 -Menus.prototype = { - constructor: Menus, - - // 初始化菜单 - init: function init() { - var _this = this; - - var editor = this.editor; - var config = editor.config || {}; - var configMenus = config.menus || []; // 获取配置中的菜单 - - // 根据配置信息,创建菜单 - configMenus.forEach(function (menuKey) { - var MenuConstructor = MenuConstructors[menuKey]; - if (MenuConstructor && typeof MenuConstructor === 'function') { - // 创建单个菜单 - _this.menus[menuKey] = new MenuConstructor(editor); - } - }); - - // 添加到菜单栏 - this._addToToolbar(); - - // 绑定事件 - this._bindEvent(); - }, - - // 添加到菜单栏 - _addToToolbar: function _addToToolbar() { - var editor = this.editor; - var $toolbarElem = editor.$toolbarElem; - var menus = this.menus; - var config = editor.config; - // config.zIndex 是配置的编辑区域的 z-index,菜单的 z-index 得在其基础上 +1 - var zIndex = config.zIndex + 1; - objForEach(menus, function (key, menu) { - var $elem = menu.$elem; - if ($elem) { - // 设置 z-index - $elem.css('z-index', zIndex); - $toolbarElem.append($elem); - } - }); - }, - - // 绑定菜单 click mouseenter 事件 - _bindEvent: function _bindEvent() { - var menus = this.menus; - var editor = this.editor; - objForEach(menus, function (key, menu) { - var type = menu.type; - if (!type) { - return; - } - var $elem = menu.$elem; - var droplist = menu.droplist; - var panel = menu.panel; - - // 点击类型,例如 bold - if (type === 'click' && menu.onClick) { - $elem.on('click', function (e) { - if (editor.selection.getRange() == null) { - return; - } - menu.onClick(e); - }); - } - - // 下拉框,例如 head - if (type === 'droplist' && droplist) { - $elem.on('mouseenter', function (e) { - if (editor.selection.getRange() == null) { - return; - } - // 显示 - droplist.showTimeoutId = setTimeout(function () { - droplist.show(); - }, 200); - }).on('mouseleave', function (e) { - // 隐藏 - droplist.hideTimeoutId = setTimeout(function () { - droplist.hide(); - }, 0); - }); - } - - // 弹框类型,例如 link - if (type === 'panel' && menu.onClick) { - $elem.on('click', function (e) { - e.stopPropagation(); - if (editor.selection.getRange() == null) { - return; - } - // 在自定义事件中显示 panel - menu.onClick(e); - }); - } - }); - }, - - // 尝试修改菜单状态 - changeActive: function changeActive() { - var menus = this.menus; - objForEach(menus, function (key, menu) { - if (menu.tryChangeActive) { - setTimeout(function () { - menu.tryChangeActive(); - }, 100); - } - }); - } -}; - -/* - 粘贴信息的处理 -*/ - -// 获取粘贴的纯文本 -function getPasteText(e) { - var clipboardData = e.clipboardData || e.originalEvent && e.originalEvent.clipboardData; - var pasteText = void 0; - if (clipboardData == null) { - pasteText = window.clipboardData && window.clipboardData.getData('text'); - } else { - pasteText = clipboardData.getData('text/plain'); - } - - return replaceHtmlSymbol(pasteText); -} - -// 获取粘贴的html -function getPasteHtml(e, filterStyle, ignoreImg) { - var clipboardData = e.clipboardData || e.originalEvent && e.originalEvent.clipboardData; - var pasteText = void 0, - pasteHtml = void 0; - if (clipboardData == null) { - pasteText = window.clipboardData && window.clipboardData.getData('text'); - } else { - pasteText = clipboardData.getData('text/plain'); - pasteHtml = clipboardData.getData('text/html'); - } - if (!pasteHtml && pasteText) { - pasteHtml = ' \n' + replaceHtmlSymbol(pasteText) + '
'; - } - if (!pasteHtml) { - return; - } - - // 过滤word中状态过来的无用字符 - var docSplitHtml = pasteHtml.split('