diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c3060d9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 蓝眼
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index fda8c87..3e5438e 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,47 @@
-# 蓝眼云盘前端项目
+
-### [配套后端`tank`](https://github.com/eyebluecn/tank)
+# 蓝眼云盘前端
+##### [在线Demo](http://tank.eyeblue.cn) (体验账号: demo@tank.eyeblue.cn 密码:123456)
+##### [配套后端tank](https://github.com/eyebluecn/tank)
-### [在线体验](http://tank.zicpo.cn)
+### 简介
+蓝眼云盘是 [蓝眼系列开源软件](https://github.com/eyebluecn) 中的第一个
+- 主要用于快速搭建私人云盘,可以简单理解为部署在自己服务器上的[百度云盘](https://pan.baidu.com/)。
+- 蓝眼云盘提供了编程接口,可以使用接口上传文件,作为其他网站、系统、app的资源存储器,可以当作单机版的[七牛云](https://www.qiniu.com)或[阿里云OSS](https://www.aliyun.com/product/oss)使用。
+蓝眼云盘可以作为团队内部或个人私有的云盘使用,亦可当作专门处理图片,音频,视频等二进制文件的第三方编程辅助工具。
+如果您觉得蓝眼云盘对您有帮助,请不要吝惜您的star :smile:
+### 运行
+```
+npm install
-> 详细文档正在撰写中,敬请期待...
+npm run dev
+```
+如果你有自己的tank后端,也可以在`config/index.js`中`proxyTable.target`修改为自己tank所在地址
+### 打包
+
+```
+npm run build
+```
+ 打包的结果在`dist`文件夹下,将该文件夹下的内容放置在[后端tank](https://github.com/eyebluecn/tank)的`build/html`文件夹下即可。
+
+ #### 更多详细配置请参考[后端说明](https://github.com/eyebluecn/tank)
+
+### Contribution
+
+感谢所有蓝眼云盘的贡献者 [@zicla](https://github.com/zicla),[@seaheart](https://github.com/seaheart),@heying,[@hxsherry](https://github.com/hxsherry)
+
+如果您也想参与进来,请尽情的fork, star, post issue, pull requests
+
+### License
+
+[MIT](http://opensource.org/licenses/MIT)
+
+Copyright (c) 2017-present, eyeblue.cn
diff --git a/config/index.js b/config/index.js
index 72f149b..7c1d7a7 100644
--- a/config/index.js
+++ b/config/index.js
@@ -33,7 +33,8 @@ module.exports = {
assetsPublicPath: '/',
proxyTable: {
'/api': {
- target: 'http://tank.zicpo.cn',
+ target: 'http://tank.eyeblue.cn',
+ //target: 'http://localhost:6010',
changeOrigin: true,
pathRewrite: {
'^/api': '/api'
diff --git a/src/App.vue b/src/App.vue
index 7f775fe..dfaf29b 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,18 +1,17 @@
-
' + title + '
'); - // 先添加到body,计算完再 remove - E.$body.append($tempDiv); - editor.ready(function () { - let editor = this; - let titleWidth = $tempDiv.outerWidth() + 5; // 多出 5px 的冗余 - let currentWidth = $tip.outerWidth(); - let currentMarginLeft = parseFloat($tip.css('margin-left'), 10); - // 计算完,拿到数据,则弃用 - $tempDiv.remove(); - $tempDiv = null; - - // 重新设置样式 - $tip.css({ - width: titleWidth, - 'margin-left': currentMarginLeft + (currentWidth - titleWidth) / 2 - }); - - // 存储 - self.tipWidth = titleWidth; - }); - } - - // $tip.append($triangle); - $tip.append(title); - $menuItem.append($tip); - - function show() { - $tip.show(); - } - - function hide() { - $tip.hide(); - } - - let timeoutId; - $menuItem.find('a').on('mouseenter', function (e) { - if (!self.active() && !self.disabled()) { - timeoutId = setTimeout(show, 200); - } - }).on('mouseleave', function (e) { - timeoutId && clearTimeout(timeoutId); - hide(); - }).on('click', hide); - }; - - // 绑定事件 - Menu.fn.bindEvent = function () { - let self = this; - - let $domNormal = self.$domNormal; - let $domSelected = self.$domSelected; - - // 试图获取该菜单定义的事件(未selected),没有则自己定义 - let clickEvent = self.clickEvent; - if (!clickEvent) { - clickEvent = function (e) { - // -----------dropPanel dropList modal----------- - let dropObj = self.dropPanel || self.dropList || self.modal; - if (dropObj && dropObj.show) { - if (dropObj.isShowing) { - dropObj.hide(); - } else { - dropObj.show(); - } - return; - } - - // -----------command----------- - let editor = self.editor; - let commandName; - let commandValue; - - let selected = self.selected; - if (selected) { - commandName = self.commandNameSelected; - commandValue = self.commandValueSelected; - } else { - commandName = self.commandName; - commandValue = self.commandValue; - } - - if (commandName) { - // 执行命令 - editor.command(e, commandName, commandValue); - } else { - // 提示 - E.warn('菜单 "' + self.id + '" 未定义click事件'); - e.preventDefault(); - } - }; - } - // 获取菜单定义的selected情况下的点击事件 - let clickEventSelected = self.clickEventSelected || clickEvent; - - // 将事件绑定到菜单dom上 - $domNormal.click(function (e) { - if (!self.disabled()) { - clickEvent.call(self, e); - self.updateSelected(); - } - e.preventDefault(); - }); - $domSelected.click(function (e) { - if (!self.disabled()) { - clickEventSelected.call(self, e); - self.updateSelected(); - } - e.preventDefault(); - }); - }; - - // 更新选中状态 - Menu.fn.updateSelected = function () { - let self = this; - let editor = self.editor; - - // 试图获取用户自定义的判断事件 - let updateSelectedEvent = self.updateSelectedEvent; - if (!updateSelectedEvent) { - // 用户未自定义,则设置默认值 - updateSelectedEvent = function () { - let self = this; - let editor = self.editor; - let commandName = self.commandName; - let commandValue = self.commandValue; - - if (commandValue) { - if (editor.queryCommandValue(commandName).toLowerCase() === commandValue.toLowerCase()) { - return true; - } - } else if (editor.queryCommandState(commandName)) { - return true; - } - - return false; - }; - } - - // 获取结果 - let result = updateSelectedEvent.call(self); - result = !!result; - - // 存储结果、显示效果 - self.changeSelectedState(result); - }; - - // 切换选中状态、显示效果 - Menu.fn.changeSelectedState = function (state) { - let self = this; - let selected = self.selected; - - if (state != null && typeof state === 'boolean') { - if (selected === state) { - // 计算结果和当前的状态一样 - return; - } - // 存储结果 - self.selected = state; - - // 切换菜单的显示 - if (state) { - // 选中 - self.$domNormal.hide(); - self.$domSelected.show(); - } else { - // 未选中 - self.$domNormal.show(); - self.$domSelected.hide(); - } - } // if - }; - - // 点击菜单,显示了 dropPanel modal 时,菜单的状态 - Menu.fn.active = function (active) { - if (active == null) { - return this._activeState; - } - this._activeState = active; - }; - Menu.fn.activeStyle = function (active) { - let selected = this.selected; - let $dom = this.$domNormal; - let $domSelected = this.$domSelected; - - if (active) { - $dom.addClass('active'); - $domSelected.addClass('active'); - } else { - $dom.removeClass('active'); - $domSelected.removeClass('active'); - } - - // 记录状态 ( menu hover 时会取状态用 ) - this.active(active); - }; - - // 菜单的启用和禁用 - Menu.fn.disabled = function (opt) { - // 参数为空,取值 - if (opt == null) { - return !!this._disabled; - } - - if (this._disabled === opt) { - // 要设置的参数值和当前参数只一样,无需再次设置 - return; - } - - let $dom = this.$domNormal; - let $domSelected = this.$domSelected; - - // 设置样式 - if (opt) { - $dom.addClass('disable'); - $domSelected.addClass('disable'); - } else { - $dom.removeClass('disable'); - $domSelected.removeClass('disable'); - } - - // 存储 - this._disabled = opt; - }; - - }); -// dropList 构造函数 - _e(function (E, $) { - - // 定义构造函数 - let DropList = function (editor, menu, opt) { - this.editor = editor; - this.menu = menu; - - // list 的数据源,格式 {'commandValue': 'title', ...} - this.data = opt.data; - // 要为每个item自定义的模板 - this.tpl = opt.tpl; - // 为了执行 editor.commandForElem 而传入的elem查询方式 - this.selectorForELemCommand = opt.selectorForELemCommand; - - // 执行事件前后的钩子 - this.beforeEvent = opt.beforeEvent; - this.afterEvent = opt.afterEvent; - - // 初始化 - this.init(); - }; - - DropList.fn = DropList.prototype; - - // 暴露给 E - E.DropList = DropList; - }); -// dropList fn bind - _e(function (E, $) { - - let DropList = E.DropList; - - // init - DropList.fn.init = function () { - let self = this; - - // 生成dom对象 - self.initDOM(); - - // 绑定command事件 - self.bindEvent(); - - // 声明隐藏的事件 - self.initHideEvent(); - }; - - // 初始化dom结构 - DropList.fn.initDOM = function () { - let self = this; - let data = self.data; - let tpl = self.tpl || '{#title}'; - let $list = $(''); - - let itemContent; - let $item; - $.each(data, function (commandValue, title) { - itemContent = tpl.replace(/{#commandValue}/ig, commandValue).replace(/{#title}/ig, title); - $item = $(''); - $item.append(itemContent); - $list.append($item); - }); - - self.$list = $list; - }; - - // 绑定事件 - DropList.fn.bindEvent = function () { - let self = this; - let editor = self.editor; - let menu = self.menu; - let commandName = menu.commandName; - let selectorForELemCommand = self.selectorForELemCommand; - let $list = self.$list; - - // 执行事件前后的钩子函数 - let beforeEvent = self.beforeEvent; - let afterEvent = self.afterEvent; - - $list.on('click', 'a[commandValue]', function (e) { - // 正式命令执行之前 - if (beforeEvent && typeof beforeEvent === 'function') { - beforeEvent.call(e); - } - - // 执行命令 - let commandValue = $(e.currentTarget).attr('commandValue'); - if (menu.selected && editor.isRangeEmpty() && selectorForELemCommand) { - // 当前处于选中状态,并且选中内容为空 - editor.commandForElem(selectorForELemCommand, e, commandName, commandValue); - } else { - // 当前未处于选中状态,或者有选中内容。则执行默认命令 - editor.command(e, commandName, commandValue); - } - - // 正式命令之后的钩子 - if (afterEvent && typeof afterEvent === 'function') { - afterEvent.call(e); - } - }); - }; - - // 点击其他地方,立即隐藏 droplist - DropList.fn.initHideEvent = function () { - let self = this; - - // 获取 list elem - let thisList = self.$list.get(0); - - E.$body.on('click', function (e) { - if (!self.isShowing) { - return; - } - let trigger = e.target; - - // 获取菜单elem - let menu = self.menu; - let menuDom; - if (menu.selected) { - menuDom = menu.$domSelected.get(0); - } else { - menuDom = menu.$domNormal.get(0); - } - - if (menuDom === trigger || $.contains(menuDom, trigger)) { - // 说明由本菜单点击触发的 - return; - } - - if (thisList === trigger || $.contains(thisList, trigger)) { - // 说明由本list点击触发的 - return; - } - - // 其他情况,隐藏 list - self.hide(); - }); - - E.$window.scroll(function () { - self.hide(); - }); - - E.$window.on('resize', function () { - self.hide(); - }); - }; - - }); -// dropListfn api - _e(function (E, $) { - - let DropList = E.DropList; - - // 渲染 - DropList.fn._render = function () { - let self = this; - let editor = self.editor; - let $list = self.$list; - - // 渲染到页面 - editor.$editorContainer.append($list); - - // 记录状态 - self.rendered = true; - }; - - // 定位 - DropList.fn._position = function () { - let self = this; - let $list = self.$list; - let editor = self.editor; - let menu = self.menu; - let $menuContainer = editor.menuContainer.$menuContainer; - let $menuDom = menu.selected ? menu.$domSelected : menu.$domNormal; - // 注意这里的 offsetParent() 要返回 .menu-item 的 position - // 因为 .menu-item 是 position:relative - let menuPosition = $menuDom.offsetParent().position(); - - // 取得 menu 的位置、尺寸属性 - let menuTop = menuPosition.top; - let menuLeft = menuPosition.left; - let menuHeight = $menuDom.offsetParent().height(); - let menuWidth = $menuDom.offsetParent().width(); - - // 取得 list 的尺寸属性 - let listWidth = $list.outerWidth(); - // let listHeight = $list.outerHeight(); - - // 取得 $txt 的尺寸 - let txtWidth = editor.txt.$txt.outerWidth(); - - // ------------开始计算------------- - - // 初步计算 list 位置属性 - let top = menuTop + menuHeight; - let left = menuLeft + menuWidth / 2; - let marginLeft = 0 - menuWidth / 2; - - // 如果超出了有边界,则要左移(且和右侧有间隙) - let valWithTxt = (left + listWidth) - txtWidth; - if (valWithTxt > -10) { - marginLeft = marginLeft - valWithTxt - 10; - } - // 设置样式 - $list.css({ - top: top, - left: left, - 'margin-left': marginLeft - }); - - // 如果因为向下滚动而导致菜单fixed,则再加一步处理 - if (editor._isMenufixed) { - top = top + (($menuContainer.offset().top + $menuContainer.outerHeight()) - $list.offset().top); - - // 重新设置top - $list.css({ - top: top - }); - } - }; - - // 显示 - DropList.fn.show = function () { - let self = this; - let menu = self.menu; - if (!self.rendered) { - // 第一次show之前,先渲染 - self._render(); - } - - if (self.isShowing) { - return; - } - - let $list = self.$list; - $list.show(); - - // 定位 - self._position(); - - // 记录状态 - self.isShowing = true; - - // 菜单状态 - menu.activeStyle(true); - }; - - // 隐藏 - DropList.fn.hide = function () { - let self = this; - let menu = self.menu; - if (!self.isShowing) { - return; - } - - let $list = self.$list; - $list.hide(); - - // 记录状态 - self.isShowing = false; - - // 菜单状态 - menu.activeStyle(false); - }; - }); -// dropPanel 构造函数 - _e(function (E, $) { - - // 定义构造函数 - let DropPanel = function (editor, menu, opt) { - this.editor = editor; - this.menu = menu; - this.$content = opt.$content; - this.width = opt.width || 200; - this.height = opt.height; - this.onRender = opt.onRender; - - // init - this.init(); - }; - - DropPanel.fn = DropPanel.prototype; - - // 暴露给 E - E.DropPanel = DropPanel; - }); -// dropPanel fn bind - _e(function (E, $) { - - let DropPanel = E.DropPanel; - - // init - DropPanel.fn.init = function () { - let self = this; - - // 生成dom对象 - self.initDOM(); - - // 声明隐藏的事件 - self.initHideEvent(); - }; - - // init DOM - DropPanel.fn.initDOM = function () { - let self = this; - let $content = self.$content; - let width = self.width; - let height = self.height; - let $panel = $(''); - let $triangle = $(''); - - $panel.css({ - width: width, - height: height ? height : 'auto' - }); - $panel.append($triangle); - $panel.append($content); - - // 添加对象数据 - self.$panel = $panel; - self.$triangle = $triangle; - }; - - // 点击其他地方,立即隐藏 dropPanel - DropPanel.fn.initHideEvent = function () { - let self = this; - - // 获取 panel elem - let thisPanle = self.$panel.get(0); - - E.$body.on('click', function (e) { - if (!self.isShowing) { - return; - } - let trigger = e.target; - - // 获取菜单elem - let menu = self.menu; - let menuDom; - if (menu.selected) { - menuDom = menu.$domSelected.get(0); - } else { - menuDom = menu.$domNormal.get(0); - } - - if (menuDom === trigger || $.contains(menuDom, trigger)) { - // 说明由本菜单点击触发的 - return; - } - - if (thisPanle === trigger || $.contains(thisPanle, trigger)) { - // 说明由本panel点击触发的 - return; - } - - // 其他情况,隐藏 panel - self.hide(); - }); - - E.$window.scroll(function (e) { - self.hide(); - }); - - E.$window.on('resize', function () { - self.hide(); - }); - }; - - }); -// dropPanel fn api - _e(function (E, $) { - - let DropPanel = E.DropPanel; - - // 渲染 - DropPanel.fn._render = function () { - let self = this; - let onRender = self.onRender; - let editor = self.editor; - let $panel = self.$panel; - - // 渲染到页面 - editor.$editorContainer.append($panel); - - // 渲染后的回调事件 - onRender && onRender.call(self); - - // 记录状态 - self.rendered = true; - }; - - // 定位 - DropPanel.fn._position = function () { - let self = this; - let $panel = self.$panel; - let $triangle = self.$triangle; - let editor = self.editor; - let $menuContainer = editor.menuContainer.$menuContainer; - let menu = self.menu; - let $menuDom = menu.selected ? menu.$domSelected : menu.$domNormal; - // 注意这里的 offsetParent() 要返回 .menu-item 的 position - // 因为 .menu-item 是 position:relative - let menuPosition = $menuDom.offsetParent().position(); - - // 取得 menu 的位置、尺寸属性 - let menuTop = menuPosition.top; - let menuLeft = menuPosition.left; - let menuHeight = $menuDom.offsetParent().height(); - let menuWidth = $menuDom.offsetParent().width(); - - // 取得 panel 的尺寸属性 - let panelWidth = $panel.outerWidth(); - // let panelHeight = $panel.outerHeight(); - - // 取得 $txt 的尺寸 - let txtWidth = editor.txt.$txt.outerWidth(); - - // ------------开始计算------------- - - // 初步计算 panel 位置属性 - let top = menuTop + menuHeight; - let left = menuLeft + menuWidth / 2; - let marginLeft = 0 - panelWidth / 2; - let marginLeft2 = marginLeft; // 下文用于和 marginLeft 比较,来设置三角形tip的位置 - - // 如果超出了左边界,则移动回来(要和左侧有10px间隙) - if ((0 - marginLeft) > (left - 10)) { - marginLeft = 0 - (left - 10); - } - - // 如果超出了有边界,则要左移(且和右侧有10px间隙) - let valWithTxt = (left + panelWidth + marginLeft) - txtWidth; - if (valWithTxt > -10) { - marginLeft = marginLeft - valWithTxt - 10; - } - - // 设置样式 - $panel.css({ - top: top, - left: left, - 'margin-left': marginLeft - }); - - // 如果因为向下滚动而导致菜单fixed,则再加一步处理 - if (editor._isMenufixed) { - top = top + (($menuContainer.offset().top + $menuContainer.outerHeight()) - $panel.offset().top); - - // 重新设置top - $panel.css({ - top: top - }); - } - - // 设置三角形 tip 的位置 - $triangle.css({ - 'margin-left': marginLeft2 - marginLeft - 5 - }); - }; - - // focus 第一个 input - DropPanel.fn.focusFirstInput = function () { - let self = this; - let $panel = self.$panel; - $panel.find('input[type=text],textarea').each(function () { - let $input = $(this); - if ($input.attr('disabled') == null) { - $input.focus(); - return false; - } - }); - }; - - // 显示 - DropPanel.fn.show = function () { - let self = this; - let menu = self.menu; - if (!self.rendered) { - // 第一次show之前,先渲染 - self._render(); - } - - if (self.isShowing) { - return; - } - - let $panel = self.$panel; - $panel.show(); - - // 定位 - self._position(); - - // 记录状态 - self.isShowing = true; - - // 菜单状态 - menu.activeStyle(true); - - if (E.w3cRange) { - // 高级浏览器 - self.focusFirstInput(); - } else { - // 兼容 IE8 input placeholder - E.placeholderForIE8($panel); - } - }; - - // 隐藏 - DropPanel.fn.hide = function () { - let self = this; - let menu = self.menu; - if (!self.isShowing) { - return; - } - - let $panel = self.$panel; - $panel.hide(); - - // 记录状态 - self.isShowing = false; - - // 菜单状态 - menu.activeStyle(false); - }; - - }); -// modal 构造函数 - _e(function (E, $) { - - // 定义构造函数 - let Modal = function (editor, menu, opt) { - this.editor = editor; - this.menu = menu; - this.$content = opt.$content; - - this.init(); - }; - - Modal.fn = Modal.prototype; - - // 暴露给 E - E.Modal = Modal; - }); -// modal fn bind - _e(function (E, $) { - - let Modal = E.Modal; - - Modal.fn.init = function () { - let self = this; - - // 初始化dom - self.initDom(); - - // 初始化隐藏事件 - self.initHideEvent(); - }; - - // 初始化dom - Modal.fn.initDom = function () { - let self = this; - let $content = self.$content; - let $modal = $(''); - let $close = $('' + $keydownDivElem.html() + '
'); - $keydownDivElem.after($pElem); - $keydownDivElem.remove(); - } - - $txt.on('keydown keyup', function (e) { - if (e.keyCode !== 13) { - return; - } - // 查找合法标签 - let rangeElem = editor.getRangeElem(); - let targetElem = editor.getLegalTags(rangeElem); - let $targetElem; - let $pElem; - - if (!targetElem) { - // 没找到合法标签,就去查找 div - targetElem = editor.getSelfOrParentByName(rangeElem, 'div'); - if (!targetElem) { - return; - } - $targetElem = $(targetElem); - - if (e.type === 'keydown') { - // 异步执行(同步执行会出现问题) - $keydownDivElem = $targetElem; - setTimeout(divHandler, 0); - } - - if (e.type === 'keyup') { - // 将 div 的内容移动到 p 里面,并移除 div - $pElem = $('' + $targetElem.html() + '
'); - $targetElem.after($pElem); - $targetElem.remove(); - - // 如果是回车结束,将选区定位到行首 - editor.restoreSelectionByElem($pElem.get(0), 'start'); - } - } - }); - }; - - // enter时,用 p 包裹 text - Txt.fn.bindEnterForText = function () { - let self = this; - let $txt = self.$txt; - let handle; - $txt.on('keyup', function (e) { - if (e.keyCode !== 13) { - return; - } - if (!handle) { - handle = function () { - self.wrapImgAndText(); - }; - } - setTimeout(handle); - }); - }; - - // tab 时,插入4个空格 - Txt.fn.bindTabEvent = function () { - let self = this; - let editor = self.editor; - let $txt = self.$txt; - - $txt.on('keydown', function (e) { - if (e.keyCode !== 9) { - // 只监听 tab 按钮 - return; - } - // 如果浏览器支持 insertHtml 则插入4个空格。如果不支持,就不管了 - if (editor.queryCommandSupported('insertHtml')) { - editor.command(e, 'insertHtml', ' '); - } - }); - }; - - // 处理粘贴内容 - Txt.fn.bindPasteFilter = function () { - let self = this; - let editor = self.editor; - let resultHtml = ''; //存储最终的结果 - let $txt = self.$txt; - let legalTags = editor.config.legalTags; - let legalTagArr = legalTags.split(','); - - $txt.on('paste', function (e) { - if (!editor.config.pasteFilter) { - // 配置中取消了粘贴过滤 - return; - } - - let currentNodeName = editor.getRangeElem().nodeName; - if (currentNodeName === 'TD' || currentNodeName === 'TH') { - // 在表格的单元格中粘贴,忽略所有内容。否则会出现异常情况 - return; - } - - resultHtml = ''; // 先清空 resultHtml - - let pasteHtml, $paste; - let data = e.clipboardData || e.originalEvent.clipboardData; - let ieData = window.clipboardData; - - if (editor.config.pasteText) { - // 只粘贴纯文本 - - if (data && data.getData) { - // w3c - pasteHtml = data.getData('text/plain'); - } else if (ieData && ieData.getData) { - // IE - pasteHtml = ieData.getData('text'); - } else { - // 其他情况 - return; - } - - // 拼接为标签 - if (pasteHtml) { - resultHtml = '
' + pasteHtml + '
'; - } - - } else { - // 粘贴过滤了样式的、只有标签的 html - - if (data && data.getData) { - // w3c - - // 获取粘贴过来的html - pasteHtml = data.getData('text/html'); - if (pasteHtml) { - // 创建dom - $paste = $(''); - // 拼接 - resultHtml = '
' + pasteHtml + '
'; - - // 查询链接 - resultHtml = resultHtml.replace(/(https?:\/\/.*?)<\/p>/ig, function (match, link) { - return '
'; - }); - } - } - - } else if (ieData && ieData.getData) { - // IE 直接从剪切板中取出纯文本格式 - resultHtml = ieData.getData('text'); - if (!resultHtml) { - return; - } - // 拼接为标签 - resultHtml = '
' + resultHtml + '
'; - resultHtml = resultHtml.replace(new RegExp('\n', 'g'), ''); - } else { - // 其他情况 - return; - } - } - - // 执行命令 - if (resultHtml) { - editor.command(e, 'insertHtml', resultHtml); - - // 删除内容为空的 p 和嵌套的 p - self.clearEmptyOrNestP(); - } - }); - - // 处理粘贴的内容 - function handle(elem) { - if (!elem || !elem.nodeType || !elem.nodeName) { - return; - } - let $elem; - let nodeName = elem.nodeName.toLowerCase(); - let nodeType = elem.nodeType; - let childNodesClone; - - // 只处理文本和普通node标签 - if (nodeType !== 3 && nodeType !== 1) { - return; - } - - $elem = $(elem); - - // 如果是容器,则继续深度遍历 - if (nodeName === 'div') { - childNodesClone = []; - $.each(elem.childNodes, function (index, item) { - // elem.childNodes 可获取TEXT节点,而 $elem.children() 就获取不到 - // 先将 elem.childNodes 拷贝一份,一面在循环递归过程中 elem 发生变化 - childNodesClone.push(item); - }); - // 遍历子元素,执行操作 - $.each(childNodesClone, function () { - handle(this); - }); - return; - } - - if (legalTagArr.indexOf(nodeName) >= 0) { - // 如果是合法标签之内的,则根据元素类型,获取值 - resultHtml += getResult(elem); - } else if (nodeType === 3) { - // 如果是文本,则直接插入 p 标签 - resultHtml += '
' + elem.textContent + '
'; - } else if (nodeName === 'br') { - //- Txt.fn.insertEmptyP = function () { - let $txt = this.$txt; - let $children = $txt.children(); - - if ($children.length === 0) { - $txt.append($('
'); - }); - - // 处理文字 - for (i = 0; i < childrenLength; i++) { - childNode = childNodes[i]; - if (childNode.nodeType === 3 && childNode.textContent && $.trim(childNode.textContent)) { - $(childNode).wrap('
'); - } - } - }; - - // 清空内容为空的
,以及重复包裹的
(在windows下的chrome粘贴文字之后,会出现上述情况) - Txt.fn.clearEmptyOrNestP = function () { - let $txt = this.$txt; - let $pList = $txt.find('p'); - - $pList.each(function () { - let $p = $(this); - let $children = $p.children(); - let childrenLength = $children.length; - let $firstChild; - let content = $.trim($p.html()); - - // 内容为空的p - if (!content) { - $p.remove(); - return; - } - - // 嵌套的p - if (childrenLength === 1) { - $firstChild = $children.first(); - if ($firstChild.get(0) && $firstChild.get(0).nodeName === 'P') { - $p.html($firstChild.html()); - } - } - }); - }; - - // 获取 scrollTop - Txt.fn.scrollTop = function (val) { - let self = this; - let editor = self.editor; - let $txt = self.$txt; - - if (editor.useMaxHeight) { - return $txt.parent().scrollTop(val); - } else { - return $txt.scrollTop(val); - } - }; - - // 鼠标hover时候,显示p、head的高度 - Txt.fn.showHeightOnHover = function () { - let editor = this.editor; - let $editorContainer = editor.$editorContainer; - let menuContainer = editor.menuContainer; - let $txt = this.$txt; - let $tip = $(''); - let isTipInTxt = false; - - function addAndShowTip($target) { - if (!isTipInTxt) { - $editorContainer.append($tip); - isTipInTxt = true; - } - - let txtTop = $txt.position().top; - let txtHeight = $txt.outerHeight(); - - let height = $target.height(); - let top = $target.position().top; - let marginTop = parseInt($target.css('margin-top'), 10); - let paddingTop = parseInt($target.css('padding-top'), 10); - let marginBottom = parseInt($target.css('margin-bottom'), 10); - let paddingBottom = parseInt($target.css('padding-bottom'), 10); - - // 计算初步的结果 - let resultHeight = height + paddingTop + marginTop + paddingBottom + marginBottom; - let resultTop = top + menuContainer.height(); - - // let spaceValue; - - // // 判断是否超出下边界 - // spaceValue = (resultTop + resultHeight) - (txtTop + txtHeight); - // if (spaceValue > 0) { - // resultHeight = resultHeight - spaceValue; - // } - - // // 判断是否超出了下边界 - // spaceValue = txtTop > resultTop; - // if (spaceValue) { - // resultHeight = resultHeight - spaceValue; - // top = top + spaceValue; - // } - - // 按照最终结果渲染 - $tip.css({ - height: height + paddingTop + marginTop + paddingBottom + marginBottom, - top: top + menuContainer.height() - }); - } - - function removeTip() { - if (!isTipInTxt) { - return; - } - $tip.remove(); - isTipInTxt = false; - } - - $txt.on('mouseenter', 'ul,ol,blockquote,p,h1,h2,h3,h4,h5,table,pre', function (e) { - addAndShowTip($(e.currentTarget)); - }).on('mouseleave', function () { - removeTip(); - }); - }; - - }); -// 工具函数 - _e(function (E, $) { - - // IE8 [].indexOf() - if (!Array.prototype.indexOf) { - //IE低版本不支持 arr.indexOf - Array.prototype.indexOf = function (elem) { - let i = 0, - length = this.length; - for (; i < length; i++) { - if (this[i] === elem) { - return i; - } - } - return -1; - }; - //IE低版本不支持 arr.lastIndexOf - Array.prototype.lastIndexOf = function (elem) { - let length = this.length; - for (length = length - 1; length >= 0; length--) { - if (this[length] === elem) { - return length; - } - } - return -1; - }; - } - - // IE8 Date.now() - if (!Date.now) { - Date.now = function () { - return new Date().valueOf(); - }; - } - - // console.knock && console.warn && console.error - let console = window.console; - let emptyFn = function () { - }; - $.each(['info', 'log', 'warn', 'error'], function (key, value) { - if (console == null) { - E[value] = emptyFn; - } else { - E[value] = function (info) { - // 通过配置来控制打印输出 - if (E.config && E.config.printLog) { - console[value]('wangEditor提示: ' + info); - } - }; - } - }); - - // 获取随机数 - E.random = function () { - return Math.random().toString().slice(2); - }; - - // 浏览器是否支持 placeholder - E.placeholder = 'placeholder' in document.createElement('input'); - - // 兼容IE8的 input placeholder - E.placeholderForIE8 = function ($container) { - if (E.placeholder) { - return; - } - $container.find('input[placeholder]').each(function () { - let $input = $(this); - let placeholder = $input.attr('placeholder'); - - if ($input.val() === '') { - $input.css('color', '#666'); - $input.val(placeholder); - - $input.on('focus.placeholder click.placeholder', function () { - $input.val(''); - $input.css('color', '#333'); - $input.off('focus.placeholder click.placeholder'); - }); - } - }); - }; - }); -// 语言包 - _e(function (E, $) { - E.langs = {}; - - // 中文 - E.langs['zh-cn'] = { - bold: '粗体', - underline: '下划线', - italic: '斜体', - forecolor: '文字颜色', - bgcolor: '背景色', - strikethrough: '删除线', - eraser: '清空格式', - source: '源码', - quote: '引用', - fontfamily: '字体', - fontsize: '字号', - head: '标题', - orderlist: '有序列表', - unorderlist: '无序列表', - alignleft: '左对齐', - aligncenter: '居中', - alignright: '右对齐', - link: '链接', - text: '文本', - submit: '提交', - cancel: '取消', - unlink: '取消链接', - table: '表格', - emotion: '表情', - img: '图片', - video: '视频', - 'width': '宽', - 'height': '高', - location: '位置', - loading: '加载中', - searchlocation: '搜索位置', - dynamicMap: '动态地图', - clearLocation: '清除位置', - langDynamicOneLocation: '动态地图只能显示一个位置', - insertcode: '插入代码', - undo: '撤销', - redo: '重复', - fullscreen: '全屏', - openLink: '打开链接' - }; - - // 英文 - E.langs.en = { - bold: 'Bold', - underline: 'Underline', - italic: 'Italic', - forecolor: 'Color', - bgcolor: 'Backcolor', - strikethrough: 'Strikethrough', - eraser: 'Eraser', - source: 'Codeview', - quote: 'Quote', - fontfamily: 'Font family', - fontsize: 'Font size', - head: 'Head', - orderlist: 'Ordered list', - unorderlist: 'Unordered list', - alignleft: 'Align left', - aligncenter: 'Align center', - alignright: 'Align right', - link: 'Insert link', - text: 'Text', - submit: 'Submit', - cancel: 'Cancel', - unlink: 'Unlink', - table: 'Table', - emotion: 'Emotions', - img: 'Image', - video: 'Video', - 'width': 'width', - 'height': 'height', - location: 'Location', - loading: 'Loading', - searchlocation: 'search', - dynamicMap: 'Dynamic', - clearLocation: 'Clear', - langDynamicOneLocation: 'Only one location in dynamic map', - insertcode: 'Insert Code', - undo: 'Undo', - redo: 'Redo', - fullscreen: 'Full screnn', - openLink: 'open link' - }; - }); -// 全局配置 - _e(function (E, $) { - - E.config = {}; - - // 全屏时的 z-index - E.config.zindex = 10000; - - // 是否打印log - E.config.printLog = true; - - // 菜单吸顶:false - 不吸顶;number - 吸顶,值为top值 - E.config.menuFixed = 0; - - // 编辑源码时,过滤 javascript - E.config.jsFilter = true; - - // 编辑器允许的标签 - E.config.legalTags = 'p,h1,h2,h3,h4,h5,h6,blockquote,table,ul,ol,pre'; - - // 语言包 - E.config.lang = E.langs['zh-cn']; - - // 菜单配置 - E.config.menus = [ - 'source', - '|', - 'bold', - 'underline', - 'italic', - 'strikethrough', - 'eraser', - 'forecolor', - 'bgcolor', - '|', - 'quote', - 'fontfamily', - 'fontsize', - 'head', - 'unorderlist', - 'orderlist', - 'alignleft', - 'aligncenter', - 'alignright', - '|', - 'link', - 'unlink', - 'table', - 'emotion', - '|', - 'img', - 'video', - 'location', - 'insertcode', - '|', - 'undo', - 'redo', - 'fullscreen' - ]; - - // 颜色配置 - E.config.colors = { - // 'value': 'title' - '#880000': '暗红色', - '#800080': '紫色', - '#ff0000': '红色', - '#ff00ff': '鲜粉色', - '#000080': '深蓝色', - '#0000ff': '蓝色', - '#00ffff': '湖蓝色', - '#008080': '蓝绿色', - '#008000': '绿色', - '#808000': '橄榄色', - '#00ff00': '浅绿色', - '#ffcc00': '橙黄色', - '#808080': '灰色', - '#c0c0c0': '银色', - '#000000': '黑色', - '#ffffff': '白色' - }; - - // 字体 - E.config.familys = [ - '宋体', '黑体', '楷体', '微软雅黑', - 'Arial', 'Verdana', 'Georgia', - 'Times New Roman', 'Microsoft JhengHei', - 'Trebuchet MS', 'Courier New', 'Impact', 'Comic Sans MS', 'Consolas' - ]; - - // 字号 - E.config.fontsizes = { - // 格式:'value': 'title' - 1: '12px', - 2: '13px', - 3: '16px', - 4: '18px', - 5: '24px', - 6: '32px', - 7: '48px' - }; - - // 表情包 - E.config.emotionsShow = 'icon'; // 显示项,默认为'icon',也可以配置成'value' - E.config.emotions = { - // 'default': { - // title: '默认', - // data: './emotions.data' - // }, - 'weibo': { - title: '微博表情', - data: [ - { - icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/7a/shenshou_thumb.gif', - value: '[草泥马]' - }, - { - icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/60/horse2_thumb.gif', - value: '[神马]' - }, - { - icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/bc/fuyun_thumb.gif', - value: '[浮云]' - }, - { - icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/c9/geili_thumb.gif', - value: '[给力]' - }, - { - icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/f2/wg_thumb.gif', - value: '[围观]' - }, - { - icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/70/vw_thumb.gif', - value: '[威武]' - }, - { - icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/6e/panda_thumb.gif', - value: '[熊猫]' - }, - { - icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/81/rabbit_thumb.gif', - value: '[兔子]' - }, - { - icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/bc/otm_thumb.gif', - value: '[奥特曼]' - }, - { - icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/15/j_thumb.gif', - value: '[囧]' - }, - { - icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/89/hufen_thumb.gif', - value: '[互粉]' - }, - { - icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/c4/liwu_thumb.gif', - value: '[礼物]' - }, - { - icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/ac/smilea_thumb.gif', - value: '[呵呵]' - }, - { - icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/0b/tootha_thumb.gif', - value: '[哈哈]' - } - ] - } - }; - - // 百度地图的key - E.config.mapAk = 'TVhjYjq1ICT2qqL5LdS8mwas'; - - // 上传图片的配置 - // server地址 - E.config.uploadImgUrl = ''; - // 超时时间 - E.config.uploadTimeout = 20 * 1000; - // 用于存储上传回调事件 - E.config.uploadImgFns = {}; - // 自定义上传图片的filename - // E.config.uploadImgFileName = 'customFileName'; - - // 自定义上传,设置为 true 之后,显示上传图标 - E.config.customUpload = false; - // 自定义上传的init事件 - // E.config.customUploadInit = function () {....}; - - // 自定义上传时传递的参数(如 token) - E.config.uploadParams = { - /* token: 'abcdef12345' */ - }; - - // 自定义上传是的header参数 - E.config.uploadHeaders = { - /* 'Accept' : 'text/x-json' */ - }; - - // 隐藏网络图片,默认为 false - E.config.hideLinkImg = false; - - // 是否过滤粘贴内容 - E.config.pasteFilter = true; - - // 是否粘贴纯文本,当 editor.config.pasteFilter === false 时候,此配置将失效 - E.config.pasteText = false; - - // 插入代码时,默认的语言 - E.config.codeDefaultLang = 'javascript'; - - }); -// 全局UI - _e(function (E, $) { - - E.UI = {}; - - // 为菜单自定义配置的UI - E.UI.menus = { - // 这个 default 不加引号,在 IE8 会报错 - 'default': { - normal: '', - selected: '.selected' - }, - bold: { - normal: '', - selected: '.selected' - }, - underline: { - normal: '', - selected: '.selected' - }, - italic: { - normal: '', - selected: '.selected' - }, - forecolor: { - normal: '', - selected: '.selected' - }, - bgcolor: { - normal: '', - selected: '.selected' - }, - strikethrough: { - normal: '', - selected: '.selected' - }, - eraser: { - normal: '', - selected: '.selected' - }, - quote: { - normal: '', - selected: '.selected' - }, - source: { - normal: '', - selected: '.selected' - }, - fontfamily: { - normal: '', - selected: '.selected' - }, - fontsize: { - normal: '', - selected: '.selected' - }, - head: { - normal: '', - selected: '.selected' - }, - orderlist: { - normal: '', - selected: '.selected' - }, - unorderlist: { - normal: '', - selected: '.selected' - }, - alignleft: { - normal: '', - selected: '.selected' - }, - aligncenter: { - normal: '', - selected: '.selected' - }, - alignright: { - normal: '', - selected: '.selected' - }, - link: { - normal: '', - selected: '.selected' - }, - unlink: { - normal: '', - selected: '.selected' - }, - table: { - normal: '', - selected: '.selected' - }, - emotion: { - normal: '', - selected: '.selected' - }, - img: { - normal: '', - selected: '.selected' - }, - video: { - normal: '', - selected: '.selected' - }, - location: { - normal: '', - selected: '.selected' - }, - insertcode: { - normal: '', - selected: '.selected' - }, - undo: { - normal: '', - selected: '.selected' - }, - redo: { - normal: '', - selected: '.selected' - }, - fullscreen: { - normal: '', - selected: '' - } - }; - - }); -// 对象配置 - _e(function (E, $) { - - E.fn.initDefaultConfig = function () { - let editor = this; - editor.config = $.extend({}, E.config); - editor.UI = $.extend({}, E.UI); - }; - - }); -// 增加 container - _e(function (E, $) { - - E.fn.addEditorContainer = function () { - this.$editorContainer = $(''); - }; - - }); -// 增加编辑区域对象 - _e(function (E, $) { - - E.fn.addTxt = function () { - let editor = this; - let txt = new E.Txt(editor); - - editor.txt = txt; - }; - - }); -// 增加menuContainer对象 - _e(function (E, $) { - - E.fn.addMenuContainer = function () { - let editor = this; - editor.menuContainer = new E.MenuContainer(editor); - }; - - }); -// 增加menus - _e(function (E, $) { - - // 存储创建菜单的函数 - E.createMenuFns = []; - E.createMenu = function (fn) { - E.createMenuFns.push(fn); - }; - - // 创建所有菜单 - E.fn.addMenus = function () { - let editor = this; - let menuIds = editor.config.menus; - - // 检验 menuId 是否在配置中存在 - function check(menuId) { - if (menuIds.indexOf(menuId) >= 0) { - return true; - } - return false; - } - - // 遍历所有的菜单创建函数,并执行 - $.each(E.createMenuFns, function (k, createMenuFn) { - createMenuFn.call(editor, check); - }); - }; - - }); -// bold菜单 - _e(function (E, $) { - - E.createMenu(function (check) { - let menuId = 'bold'; - if (!check(menuId)) { - return; - } - - let editor = this; - let lang = editor.config.lang; - - // 创建 menu 对象 - let menu = new E.Menu({ - editor: editor, - id: menuId, - title: lang.bold, - commandName: 'Bold' - }); - - // 定义选中状态下的click事件 - menu.clickEventSelected = function (e) { - let isRangeEmpty = editor.isRangeEmpty(); - if (!isRangeEmpty) { - // 如果选区有内容,则执行基础命令 - editor.command(e, 'Bold'); - } else { - // 如果选区没有内容 - editor.commandForElem('b,strong,h1,h2,h3,h4,h5', e, 'Bold'); - } - }; - - // 增加到editor对象中 - editor.menus[menuId] = menu; - }); - - }); -// underline菜单 - _e(function (E, $) { - - E.createMenu(function (check) { - let menuId = 'underline'; - if (!check(menuId)) { - return; - } - - let editor = this; - let lang = editor.config.lang; - - // 创建 menu 对象 - let menu = new E.Menu({ - editor: editor, - id: menuId, - title: lang.underline, - commandName: 'Underline' - }); - - // 定义选中状态下的click事件 - menu.clickEventSelected = function (e) { - let isRangeEmpty = editor.isRangeEmpty(); - if (!isRangeEmpty) { - // 如果选区有内容,则执行基础命令 - editor.command(e, 'Underline'); - } else { - // 如果选区没有内容 - editor.commandForElem('u,a', e, 'Underline'); - } - }; - - // 增加到editor对象中 - editor.menus[menuId] = menu; - }); - - }); -// italic 菜单 - _e(function (E, $) { - - E.createMenu(function (check) { - let menuId = 'italic'; - if (!check(menuId)) { - return; - } - let editor = this; - let lang = editor.config.lang; - - // 创建 menu 对象 - let menu = new E.Menu({ - editor: editor, - id: menuId, - title: lang.italic, - commandName: 'Italic' - }); - - // 定义选中状态下的click事件 - menu.clickEventSelected = function (e) { - let isRangeEmpty = editor.isRangeEmpty(); - if (!isRangeEmpty) { - // 如果选区有内容,则执行基础命令 - editor.command(e, 'Italic'); - } else { - // 如果选区没有内容 - editor.commandForElem('i', e, 'Italic'); - } - }; - - // 增加到editor对象中 - editor.menus[menuId] = menu; - }); - - }); -// forecolor 菜单 - _e(function (E, $) { - - E.createMenu(function (check) { - let menuId = 'forecolor'; - if (!check(menuId)) { - return; - } - let editor = this; - let lang = editor.config.lang; - let configColors = editor.config.colors; - - // 创建 menu 对象 - let menu = new E.Menu({ - editor: editor, - id: menuId, - title: lang.forecolor - }); - - // 创建 dropPanel - let $content = $(''); - $.each(configColors, function (k, v) { - $content.append( - [ - '' - ].join('') - ); - }); - $content.on('click', 'a[commandValue]', function (e) { - // 执行命令 - let $elem = $(this); - let commandValue = $elem.attr('commandValue'); - - if (menu.selected && editor.isRangeEmpty()) { - // 当前处于选中状态,并且选中内容为空 - editor.commandForElem('font[color]', e, 'forecolor', commandValue); - } else { - // 当前未处于选中状态,或者有选中内容。则执行默认命令 - editor.command(e, 'forecolor', commandValue); - } - }); - menu.dropPanel = new E.DropPanel(editor, menu, { - $content: $content, - width: 125 - }); - - // 定义 update selected 事件 - menu.updateSelectedEvent = function () { - let rangeElem = editor.getRangeElem(); - rangeElem = editor.getSelfOrParentByName(rangeElem, 'font[color]'); - if (rangeElem) { - return true; - } - return false; - }; - - // 增加到editor对象中 - editor.menus[menuId] = menu; - }); - - }); -// bgcolor 菜单 - _e(function (E, $) { - - E.createMenu(function (check) { - let menuId = 'bgcolor'; - if (!check(menuId)) { - return; - } - let editor = this; - let lang = editor.config.lang; - let configColors = editor.config.colors; - - // 检查元素是否有 background-color: 内联样式 - function checkElemFn(elem) { - let cssText; - if (elem && elem.style && elem.style.cssText != null) { - cssText = elem.style.cssText; - if (cssText && cssText.indexOf('background-color:') >= 0) { - return true; - } - } - return false; - } - - // 创建 menu 对象 - let menu = new E.Menu({ - editor: editor, - id: menuId, - title: lang.bgcolor - }); - - // 创建 dropPanel - let $content = $(''); - $.each(configColors, function (k, v) { - $content.append( - [ - '' - ].join('') - ); - }); - $content.on('click', 'a[commandValue]', function (e) { - // 执行命令 - - let $elem = $(this); - let commandValue = $elem.attr('commandValue'); - - if (menu.selected && editor.isRangeEmpty()) { - // 当前处于选中状态,并且选中内容为空。使用 commandForElem 执行命令 - editor.commandForElem({ - selector: 'span,font', - check: checkElemFn - }, e, 'BackColor', commandValue); - } else { - // 当前未处于选中状态,或者有选中内容。则执行默认命令 - editor.command(e, 'BackColor', commandValue); - } - }); - menu.dropPanel = new E.DropPanel(editor, menu, { - $content: $content, - width: 125 - }); - - // 定义 update selected 事件 - menu.updateSelectedEvent = function () { - let rangeElem = editor.getRangeElem(); - rangeElem = editor.getSelfOrParentByName(rangeElem, 'span,font', checkElemFn); - - if (rangeElem) { - return true; - } - return false; - }; - - // 增加到editor对象中 - editor.menus[menuId] = menu; - }); - - }); -// strikethrough 菜单 - _e(function (E, $) { - - E.createMenu(function (check) { - let menuId = 'strikethrough'; - if (!check(menuId)) { - return; - } - let editor = this; - let lang = editor.config.lang; - - // 创建 menu 对象 - let menu = new E.Menu({ - editor: editor, - id: menuId, - title: lang.strikethrough, - commandName: 'StrikeThrough' - }); - - // 定义选中状态下的click事件 - menu.clickEventSelected = function (e) { - let isRangeEmpty = editor.isRangeEmpty(); - if (!isRangeEmpty) { - // 如果选区有内容,则执行基础命令 - editor.command(e, 'StrikeThrough'); - } else { - // 如果选区没有内容 - editor.commandForElem('strike', e, 'StrikeThrough'); - } - }; - - // 增加到editor对象中 - editor.menus[menuId] = menu; - }); - - }); -// eraser 菜单 - _e(function (E, $) { - - E.createMenu(function (check) { - let menuId = 'eraser'; - if (!check(menuId)) { - return; - } - let editor = this; - let lang = editor.config.lang; - - // 创建 menu 对象 - let menu = new E.Menu({ - editor: editor, - id: menuId, - title: lang.eraser, - commandName: 'RemoveFormat' - }); - - // 定义点击事件 - menu.clickEvent = function (e) { - let isRangeEmpty = editor.isRangeEmpty(); - - if (!isRangeEmpty) { - // 选区不是空的,则执行默认命令 - editor.command(e, 'RemoveFormat'); - return; - } - - let $clearElem; - - // 自定义的命令函数 - function commandFn() { - let editor = this; - let rangeElem; - let pElem, $pElem; - let quoteElem, $quoteElem; - let listElem, $listElem; - - // 获取选区 elem - rangeElem = editor.getRangeElem(); - // 第一步,获取 quote 父元素 - quoteElem = editor.getSelfOrParentByName(rangeElem, 'blockquote'); - if (quoteElem) { - $quoteElem = $(quoteElem); - $clearElem = $('
' + $quoteElem.text() + '
'); - $quoteElem.after($clearElem).remove(); - } - // 第二步,获取 p h 父元素 - pElem = editor.getSelfOrParentByName(rangeElem, 'p,h1,h2,h3,h4,h5'); - if (pElem) { - $pElem = $(pElem); - $clearElem = $('' + $pElem.text() + '
'); - $pElem.after($clearElem).remove(); - } - // 第三步,获取list - listElem = editor.getSelfOrParentByName(rangeElem, 'ul,ol'); - if (listElem) { - $listElem = $(listElem); - $clearElem = $('' + $listElem.text() + '
'); - $listElem.after($clearElem).remove(); - } - } - - // 自定义 callback 事件 - function callback() { - // callback中,设置range为clearElem - let editor = this; - if ($clearElem) { - editor.restoreSelectionByElem($clearElem.get(0)); - } - } - - // 执行自定义命令 - editor.customCommand(e, commandFn, callback); - }; - - // 增加到editor对象中 - editor.menus[menuId] = menu; - }); - - }); -// source 菜单 - _e(function (E, $) { - - E.createMenu(function (check) { - let menuId = 'source'; - if (!check(menuId)) { - return; - } - let editor = this; - let lang = editor.config.lang; - let txtHtml; - - // 创建 menu 对象 - let menu = new E.Menu({ - editor: editor, - id: menuId, - title: lang.source - }); - - menu.isShowCode = false; - - // 更新内容 - function updateValue() { - let $code = menu.$codeTextarea; - let $txt = editor.txt.$txt; - let value = $.trim($code.val()); // 取值 - - if (!value) { - value = '